def processMessageDefer(game, isDefer, author): log.debug("Processing defer message: {}".format(str(isDefer))) authorHomeAway = utils.getHomeAwayString(utils.isCoachHome(game, author)) if isDefer: log.debug("User deferred, {} is receiving".format( utils.reverseHomeAway(authorHomeAway))) state.setStateTouchback(game, utils.reverseHomeAway(authorHomeAway)) game['receivingNext'] = authorHomeAway game['waitingOn'] = utils.reverseHomeAway(game['waitingOn']) game['dirty'] = True utils.sendDefensiveNumberMessage(game) return True, "{} deferred and will receive the ball in the second half. The game has started!\n\n{}\n\n{}".format( game[authorHomeAway]['name'], utils.getCurrentPlayString(game), utils.getWaitingOnString(game)) else: log.debug( "User elected to receive, {} is receiving".format(authorHomeAway)) state.setStateTouchback(game, authorHomeAway) game['receivingNext'] = utils.reverseHomeAway(authorHomeAway) game['waitingOn'] = utils.reverseHomeAway(game['waitingOn']) game['dirty'] = True utils.sendDefensiveNumberMessage(game) return True, "{} elected to receive. The game has started!\n\n{}\n\n{}".format( game[authorHomeAway]['name'], utils.getCurrentPlayString(game), utils.getWaitingOnString(game))
def processMessageDefenseNumber(game, message, author): numberMessage = None resultMessage = None log.debug("Processing defense number message") if message.find(globals.intFoul) > -1: log.debug('defense will commit an intentional foul') game['status']['ifoul'] = True else: number, resultMessage = utils.extractPlayNumber(message) if resultMessage is not None and not game['status']['ifoul']: return False, resultMessage elif resultMessage is None and not game['status']['ifoul']: log.debug("Saving defense number: {}".format(number)) database.saveDefensiveNumber(game['dataID'], number) else: log.debug('saving defesive number as 0 due to an intentional foul') database.saveDefensiveNumber(game['dataID'],0) log.debug("offense is currently {}".format(game['play']['offensiveNumber'])) log.debug("we were waiting on {}".format(game['waitingOn'])) if game['status']['techFoul']: game['waitingOn'] = game['status']['possession'] game['play']['defensiveNumber'] = False game['play']['offensiveNumber'] = True game['play']['playResult'] = '' log.debug('we are currently awiting on {}'.format(game['waitingOn'])) else: state.setWaitingOn(game) log.debug("we are now waiting on {}".format(game['waitingOn'])) log.debug("offene is is {}".format(game['play']['offensiveNumber'])) game['dirty'] = True log.debug("Sending offense play comment") if not game['status']['free']: resultMessage = "{} has submitted their number. {} you're up\ .\n\n{}\n\n{} reply with {} and your number. [Play list]({})".format( game[utils.reverseHomeAway(game['waitingOn'])]['name'], game[game['waitingOn']]['name'], utils.getCurrentPlayString(game), utils.getCoachString(game, game['waitingOn']), utils.listSuggestedPlays(game), "https://www.reddit.com/r/TestFakeCBB/wiki/refbot" ) else: resultMessage = "{} has submitted their number for your free throw. {} you're up\ .\n\n{}\n\n{} reply with a free throw number between **1** and **{}**".format( game[utils.reverseHomeAway(game['waitingOn'])]['name'], game[game['waitingOn']]['name'], utils.getCurrentPlayString(game), utils.getCoachString(game, game['waitingOn']), globals.maxRange ) utils.sendGameComment(game, resultMessage, {'action': 'play'}) if not game['status']['ifoul']: result = ["I've got {} as your number.".format(number)] else: result = ["You called an intentional foul"] return True, '\n\n'.join(result)
def turnover(game): game['status']['down'] = 1 game['status']['yards'] = 10 game['status']['possession'] = utils.reverseHomeAway(game['status']['possession']) game['status']['location'] = 100 - game['status']['location'] game['waitingAction'] = 'play' game['waitingOn'] = utils.reverseHomeAway(game['waitingOn'])
def updateTime(game, play, result, offenseHomeAway): if result == 'FREE': return '' elif result == 'FREEDONE': timeOffClock = 0 elif play == 'foul': log.debug('doing the stuff') timeOffClock = globals.ifoulTime else: timeOffClock = getTimeByPlay(game, play) log.debug("time off the clock was {}".format(timeOffClock)) log.debug("Time off clock: {} : {}".format(game['status']['clock'], timeOffClock)) game['status']['clock'] -= timeOffClock log.debug('clock after subtraction is {}'.format(game['status']['clock'])) timeMessage = "{} left".format(utils.renderTime(game['status']['clock'])) if game['status']['clock'] <= 0: log.debug("End of half: {}".format(game['status']['half'])) actualTimeOffClock = timeOffClock + game['status']['clock'] game['status']['clock'] = 0 if not game['status']['free']: if play.lower() in (globals.steal3Pt, globals.stealDunk): utils.addStat(game, 'posTime', actualTimeOffClock, utils.reverseHomeAway(offenseHomeAway)) else: utils.addStat(game, 'posTime', actualTimeOffClock, offenseHomeAway) timeMessage = endHalf(game) if game['status']['halfType'] != 'end' and game['status']['half'] > 2: log.debug('Setting OverTime information') game['status']['clock'] = globals.otLength game['score']['halves'].append({'home':0,'away':0}) log.debug('Going to null the tip numbers out and make them all false in the game object.') database.nullTipNumbers(game['dataID']) game['tip']['homeTip'] = False game['tip']['awayTip'] = False coaches = [game['home']['coaches'][0], game['away']['coaches'][0]] utils.sendTipNumberMessages(game, coaches) else: actualTimeOffClock = timeOffClock if play.lower() in (globals.steal3Pt, globals.stealDunk): utils.addStat(game, 'posTime', actualTimeOffClock, utils.reverseHomeAway(offenseHomeAway)) else: utils.addStat(game, 'posTime', actualTimeOffClock, offenseHomeAway) if game['status']['clock'] <= 0 and game['status']['halfType'] == 'end': return "The play took {} seconds, {}".format(actualTimeOffClock, timeMessage) elif game['status']['clock'] <= 0 and game['status']['halfType'] =='overtimeNormal': return "The play took {} seconds, {}".format(actualTimeOffClock, timeMessage) elif game['status']['clock'] <= 0 and game['status']['halfType'] not in ('end', 'overtimeNormal') and game['status']['free']: return "The play took {} seconds, No time left on the clock".format(actualTimeOffClock) else: return "The play took {} seconds, {}".format(actualTimeOffClock, timeMessage)
def sub2Pt(game, made, fouled, off=False): ''' This function is used for all three point type plays. If a 2 point is missed then it only adds to the stat of attepmts. If it is made then it adds the score and then adds 2 point made and 2 total points to score. ''' team = game['status']['possession'] utils.addStat(game,'2PtAttempted',1,team) ##if the shot was made if made: score2Points(game, team) utils.addStat(game,'2PtMade',1,team) if fouled: log.debug('Just scored 2 and going to set 1 foul for the one and one on') setFouls(game, 1) elif not made and not fouled and not off: log.debug('Going to add a defensive rebound on a 2 point shot to the other team') utils.addStat(game,'defRebound', 1, utils.reverseHomeAway(team)) elif off: utils.addStat(game, 'offRebound',1,team) elif fouled and not made: setFouls(game, 2) log.debug('Missed a 2 point shot but going to set 2 free throws') else: log.warning("OOPS. should not be here in sub2Pt")
def sub3Pt(game, made, fouled, off=False): ''' This function is used for all three point type plays. If a 3 point is missed then it only adds to the stat of attepmts. If it is made then it adds the score and then adds 3 point made and 3 total points to score. if fouled, then f_type is sent ''' team = game['status']['possession'] utils.addStat(game, '3PtAttempted', 1, team) if made: score3Points(game, team) utils.addStat(game, '3PtMade', 1, team) if fouled: log.debug( 'Going to set foul information for a 3 point shot made with an and one' ) setFouls(game, 1) elif not made and not fouled and not off: log.debug( 'Going to add a defensive rebound on a 3 point shot to the other team' ) utils.addStat(game, 'defRebound', 1, utils.reverseHomeAway(team)) elif off: utils.addStat(game, 'offRebound', 1, team) elif fouled and not made: log.debug("going to set foul information for an agent ") setFouls(game, 3) else: log.warning("should not be here in the sub3Pt function")
def getNumberDiffForGame(game, offenseNumber): defenseNumber = database.getDefensiveNumber(game['dataID']) if defenseNumber is None: log.warning("Something went wrong, couldn't get a defensive number for that game") return -1 straightDiff = abs(offenseNumber - defenseNumber) aroundRightDiff = abs(abs(globals.maxRange-offenseNumber) + defenseNumber) aroundLeftDiff = abs(offenseNumber + abs(globals.maxRange-defenseNumber)) difference = min([straightDiff, aroundRightDiff, aroundLeftDiff]) game['play']['onum'] = offenseNumber game['play']['dnum'] = defenseNumber game['play']['diff'] = difference current = game['status']['possession'] other = utils.reverseHomeAway(current) game[current]['offDiffs'].append(difference) game[other]['defDiffs'].append(difference) numberMessage = "Offense: {}\n\nDefense: {}\n\nDifference: {}".format(offenseNumber, defenseNumber, difference) log.debug("Offense: {} Defense: {} Result: {}".format(offenseNumber, defenseNumber, difference)) return difference, numberMessage
def technicalFouls(game): log.debug('Going to keep setup Technical Free throw stuff') ##set waiting on and possession badPerson = game['waitingOn'] offendPerson = utils.reverseHomeAway(game['waitingOn']) ## if badPerson is the in possesion then possession flips if badPerson == game['status']['possession']: game['status']['possession'] = offendPerson game['play']['defensiveNumber'] = True game['play']['offensisiveNumber'] = False game[badPerson]['fouls'] += 1 ##set free stats game['status']['frees'] = 2 game['status']['free'] = True game['status']['freeType'] = 'TF' game['waitingAction'] = 'play' game['status']['freeStatus'] = 2 game['status']['techFoul'] = True ##Set foul types if SB and DB change if globals.singleBonus <= game[badPerson]['fouls'] < globals.doubleBonus: game[offendPerson]['bonus'] = 'SB' elif globals.doubleBonus <= game[badPerson]['fouls']: game[offendPerson]['bonus'] = 'DB' currentDel = game[badPerson]['playclockPenalties'] leftDel = 3 - currentDel delayMessage = '{0} has commited a delay of game. They have commited {3} so far. {4} more and they will forfeit their game. {1} will now be shooting \ two free throws and they will get the ball after. /u/{2} reply to the DM that \ I send you.'.format(game[badPerson]['name'],game[offendPerson]['name'], game[badPerson]['coaches'][0], currentDel, leftDel) utils.sendGameComment(game, delayMessage, {'action': 'play'}) utils.sendDelayDefensiveNumberMessage(game)
def endHalf(game): timeMessage = 'Default Message' game['status']['clock'] = 0 if game['status']['half'] == 1: timeMessage = "end of the first half" game['status']['clock'] = globals.halfLength game['status']['possession'] = utils.reverseHomeAway( game['status']['wonTip']) game['waitingOn'] = game['status']['wonTip'] game['status']['waitingAction'] = 'play' game['status']['half'] = 2 game['status']['changePosWaitCheck'] = False for team in ('home', 'away'): game[team][bonus] = 'N' else: if game['status']['half'] >= 2: if game['score']['home'] == game['score']['away']: game['status']['tipped'] = False game['status']['half'] += 1 if game['status']['half'] == 3: log.debug( "Score tied at end of 2nd half, going to overtime") timeMessage = "end of regulation. The score is tied, we're going to overtime!" else: log.debut( 'Score still tied at the end of OT {}: Going into OT{}' .format(game['status']['half'] - 1, game['status']['half'])) timeMessage = 'End of OT number {}, going into OT {}'.format( game['status']['half'] - 1, game['status']['half']) if database.getGameDeadline( game['dataID']) > datetime.utcnow() and 0 == 1: game['status']['halfType'] = 'overtimeTime' else: game['status']['halfType'] = 'overtimeNormal' game['waitingAction'] = 'tip' else: log.debug("End of game") if game['score']['home'] > game['score']['away']: victor = 'home' else: victor = 'away' timeMessage = "that's the end of the game! {} has won!".format( utils.flair(game[victor])) game['status']['halfType'] = 'end' game['waitingAction'] = 'end' utils.createPostGameThread(game) database.endGame(game['thread']) try: for team in ['home', 'away']: utils.setStatsForSheet(game, team) except: log.debug( 'Cannot insert stats for teams with gameid {}'.format( game['dataID'])) hins, ains = utils.insertStatData(game) return timeMessage
def setBlock(game,turnover): current = game['status']['possession'] utils.addStat(game,'blocks', 1, utils.reverseHomeAway(current)) shotType = utils.coinToss() if shotType: sub2Pt(game, False, False) else: sub3Pt(game, False, False)
def setWaitingOn(game): log.debug('going to set waitingOn. It is currently set to {}'.format( game['waitingOn'])) ##use this to set waitingOn. MOvfe all waiting on logic to homeRecord current = game['status']['possession'] other = utils.reverseHomeAway(current) log.debug("logging various useful information") log.debug("current is {}".format(current)) log.debug("other is {}".format(other)) log.debug("just fouled is {}".format(game['play']['fouled'])) log.debug("shooting free throws is {}".format(game['status']['free'])) log.debug("play result was {}".format(game['play']['playResult'])) if game['status']['techFoul'] and not game['status']['free']: log.debug('Just finished shooting technical fouls.') switchDefOff(game) game['status']['techFoul'] = False game['waitingOn'] = other elif not game['status']['changePosWaitCheck']: switchDefOff(game) game['status']['changePosWaitCheck'] = True log.debug('Not changing waiting on here because we did it elsewhere') elif (game['status']['free'] or game['status']['fouledOnly']) and game['play']['offensiveNumber']: log.debug( 'shooting a free throw or only fouled, possession should stay the same' ) ##just sent an offensive play and is now shooting a free throw or ##fouled and possession stays the same. game['waitingOn'] = other switchDefOff(game) game['status']['fouledOnly'] = False elif game['play']['playResult'] == 'offrebound': log.debug('offensive rebound and changing stuff') switchDefOff(game) game['waitingOn'] = other elif game['status']['free'] and game['play']['defensiveNumber']: log.debug( 'offensive player was fouled and defnsive player sent their number' ) ##offensive player was fouled and the defending team just ##sent their number in game['waitingOn'] = current switchDefOff(game) elif game['play']['defensiveNumber']: log.debug('switching waitingOn since defesne person sent num+') ##someone just sent the defnesive number so we are switching ##waiting on to the offensive player switchDefOff(game) game['waitingOn'] = current elif game['play']['offensiveNumber']: switchDefOff(game) game['play']['playResult'] = '' log.debug('we are currently awiting on {}'.format(game['waitingOn']))
def changePossession(game): log.debug('determing if we need to change possesion.') log.debug('the play result is {}'.format(game['play']['playResult'])) isIn = game['play']['playResult'].lower() in globals.switchPossessions log.debug('is this a switch posession? Well the result is {} as long as we did not finish shooting a technical free throw'.format(isIn)) if game['status']['techFoul'] and not game['status']['free']: log.debug('Should be not switching possession due to still shooting a technical free throw.') elif not game['status']['changePosWaitCheck']: log.debug('not changing possession because end of half') elif isIn and not game['status']['free']: log.debug('We should be switching possession') current = game['status']['possession'] game['status']['possession'] = utils.reverseHomeAway(current)
def executeGain(game, play, yards): if play not in globals.movementPlays: log.warning("This doesn't look like a valid movement play: {}".format(play)) return "error", None, "Something went wrong trying to move the ball" previousLocation = game['status']['location'] log.debug("Ball moved from {} to {}".format(previousLocation, previousLocation + yards)) game['status']['location'] = previousLocation + yards if game['status']['location'] > 100: log.debug("Ball passed the line, touchdown offense") utils.addStatRunPass(game, play, 100 - previousLocation) scoreTouchdown(game, game['status']['possession']) return "touchdown", 100 - previousLocation, "{} with a {} yard {} into the end zone for a touchdown!".format(game[game['status']['possession']]['name'], yards, play) elif game['status']['location'] < 0: log.debug("Ball went back over the line, safety for the defense") utils.addStatRunPass(game, play, previousLocation * -1) scoreSafety(game, utils.reverseHomeAway(game['status']['possession'])) if play == "run": resultMessage = "The runner is taken down in the end zone for a safety." elif play == "pass": resultMessage = "Sack! The quarterback is taken down in the endzone for a safety." else: resultMessage = "It's a safety!" return "touchback", 0 - previousLocation, resultMessage else: log.debug("Ball moved, but didn't enter an endzone, checking and updating play status") utils.addStatRunPass(game, play, yards) yardsRemaining = game['status']['yards'] - yards if yardsRemaining <= 0: log.debug("First down") game['status']['yards'] = 10 game['status']['down'] = 1 return "gain", game['status']['location'] - previousLocation, "{} play for {} yards, first down".format(play.capitalize(), yards) else: log.debug("Not a first down, incrementing down") game['status']['down'] += 1 if game['status']['down'] > 4: log.debug("Turnover on downs") turnover(game) return "turnover", game['status']['location'] - previousLocation, "{} play for {} yards, but that's not enough for the first down. Turnover on downs".format(play.capitalize(), yards) else: log.debug("Now {} down and {}".format(utils.getDownString(game['status']['down']), yardsRemaining)) game['status']['yards'] = yardsRemaining return "gain", game['status']['location'] - previousLocation, "{} play for {} yards, {} and {}".format(play.capitalize(), yards, utils.getDownString(game['status']['down']), yardsRemaining)
def executePunt(game, yards): log.debug("Ball punted for {} yards".format(yards)) game['status']['location'] = game['status']['location'] + yards if game['status']['location'] > 100: log.debug("Punted into the end zone, touchback") setStateTouchback(game, utils.reverseHomeAway(game['status']['possession'])) if game['status']['location'] > 110: return "The punt goes out the back of the end zone, touchback" else: return "The punt goes into the end zone, touchback" else: log.debug("Punt caught, setting up turnover") turnover(game) return "It's a {} yard punt".format(yards)
def processMessageTip(game, message): number, error = utils.extractPlayNumber(message.body) if error is not None: return False, "Didn't send me a number. Reply to the original message and send me a number this time" author = str(message.author).lower() log.debug('author is {}'.format(author)) log.debug('number is {}'.format(number)) log.debug("Processing tip ball where game is dirty is {}".format(game['dirty'])) log.debug('is author in {} or {}'.format(game['away']['coaches'], game['home']['coaches'])) if author in game['away']['coaches']: resultMessage, worked = state.tipResults(game, 'away', number) elif author in game['home']['coaches']: resultMessage, worked = state.tipResults(game, 'home', number) else: return False, 'ooops' log.debug('Now checking if game is dirty and tip off is complete') log.debug('Dirty is {}'.format(game['dirty'])) if game['tip']['awayTip'] and game['tip']['homeTip']: awayTip = int(database.getTipById(game['dataID'],'awayTip')) homeTip = int(database.getTipById(game['dataID'],'homeTip')) botTip = utils.rngNumber() tipWinner = utils.getTipWinner(awayTip, homeTip, botTip) game['status']['wonTip'] = tipWinner game['waitingOn'] = utils.reverseHomeAway(tipWinner) game['status']['possession'] = tipWinner game['play']['defensiveNumber'] = True game['play']['offensiveNumber'] = False log.debug("sending initial defensive play comment to {}".format(game['waitingOn'])) resultMessage = "/u/{} has won the tippoff . /u/{} Will get a DM to start the action. \ \naway tip number: {}\ \nhome tip number: {}\ \nbot tip number: {}".format( game[tipWinner]['coaches'][0], game[game['waitingOn']]['coaches'][0], awayTip, homeTip, botTip ) defMessage = "You lost the tipoff . Please send me a number to start the game getween **1** and **{}**".format(globals.maxRange) log.debug('defensive message is {}'.format(defMessage)) game['dirty'] = True utils.sendDefensiveNumberMessage(game, defMessage) game['waitingAction'] = 'play' game['tip']['justTipped'] = True return True, resultMessage return worked, resultMessage
def processMessageDefenseNumber(game, message, author): log.debug("Processing defense number message") number, resultMessage = utils.extractPlayNumber(message) if resultMessage is not None: return False, resultMessage log.debug("Saving defense number: {}".format(number)) database.saveDefensiveNumber(game['dataID'], number) timeoutMessage = None if message.find("timeout") > 0: if game['status']['timeouts'][utils.reverseHomeAway( game['status']['possession'])] > 0: game['status']['requestedTimeout'][utils.reverseHomeAway( game['status']['possession'])] = 'requested' timeoutMessage = "Timeout requested successfully" else: timeoutMessage = "You requested a timeout, but you don't have any left" game['waitingOn'] = utils.reverseHomeAway(game['waitingOn']) game['dirty'] = True log.debug("Sending offense play comment") resultMessage = "{} has submitted their number. {} you're up.\n\n{}\n\n{} reply with {} and your number. [Play list]({})".format( game[utils.reverseHomeAway(game['waitingOn'])]['name'], game[game['waitingOn']]['name'], utils.getCurrentPlayString(game), utils.getCoachString(game, game['waitingOn']), utils.listSuggestedPlays(game), "https://www.reddit.com/r/FakeCollegeFootball/wiki/refbot") utils.sendGameComment(game, resultMessage, {'action': 'play'}) result = ["I've got {} as your number.".format(number)] if timeoutMessage is not None: result.append(timeoutMessage) return True, '\n\n'.join(result)
def getPlayResult(game, play, number): playDict = wiki.getPlay(play) if playDict is None: log.warning("{} is not a valid play".format(play)) return None log.debug("Getting play result for: {}".format(play)) if play in globals.movementPlays: offense = game[game['status']['possession']]['offense'] defense = game[utils.reverseHomeAway(game['status']['possession'])]['defense'] log.debug("Movement play offense, defense: {} : {}".format(offense, defense)) playMajorRange = playDict[offense][defense] else: playMajorRange = playDict playMinorRange = findNumberInRangeDict(100 - game['status']['location'], playMajorRange) return findNumberInRangeDict(number, playMinorRange)
def setFouls(game,f_type): ''' Pass in f_type which is used to determine if we are doing an after shot or a nonshooting foul. If f_type is zero then we will check if we are in the bonus to determine next action. Else we will shoot that many f_type number of free throws ''' team = game['status']['possession'] otherTeam = utils.reverseHomeAway(team) game[otherTeam]['fouls'] += 1 if globals.singleBonus <= game[otherTeam]['fouls'] < globals.doubleBonus: game[team]['bonus'] = 'SB' elif globals.doubleBonus <= game[otherTeam]['fouls']: game[team]['bonus'] = 'DB' if f_type == 0: return setBonusFouls(game, team, otherTeam) else: game['status']['frees'] = f_type game['status']['free'] = True game['status']['freeStatus'] = f_type
def executePlay(game, play, number, numberMessage): startingPossessionHomeAway = game['status']['possession'] actualResult = None yards = None resultMessage = "Something went wrong, I should never have reached this" diffMessage = None success = True if game['status']['conversion']: if play in globals.conversionPlays: if number == -1: log.debug("Trying to execute a normal play, but didn't have a number") resultMessage = numberMessage success = False else: numberResult, diffMessage = getNumberDiffForGame(game, number) log.debug("Executing conversion play: {}".format(play)) result = getPlayResult(game, play, numberResult) if result['result'] == 'twoPoint': log.debug("Successful two point conversion") resultMessage = "The two point conversion is successful" scoreTwoPoint(game, game['status']['possession']) elif result['result'] == 'pat': log.debug("Successful PAT") resultMessage = "The PAT was successful" scorePAT(game, game['status']['possession']) elif result['result'] == 'touchback': log.debug("Attempt unsuccessful") if play == "twoPoint": resultMessage = "The two point conversion attempt was unsuccessful" elif play == "pat": resultMessage = "The PAT attempt was unsuccessful" else: resultMessage = "Conversion unsuccessful" setStateTouchback(game, utils.reverseHomeAway(game['status']['possession'])) database.clearDefensiveNumber(game['dataID']) else: resultMessage = "It looks like you're trying to get the extra point after a touchdown, but this isn't a valid play" success = False else: if play in globals.normalPlays: if number == -1: log.debug("Trying to execute a normal play, but didn't have a number") resultMessage = numberMessage success = False else: numberResult, diffMessage = getNumberDiffForGame(game, number) log.debug("Executing normal play: {}".format(play)) result = getPlayResult(game, play, numberResult) if result['result'] == 'gain': if 'yards' not in result: log.warning("Result is a gain, but I couldn't find any yards") resultMessage = "Result of play is a number of yards, but something went wrong and I couldn't find what number" success = False else: log.debug("Result is a gain of {} yards".format(result['yards'])) gainResult, yards, resultMessage = executeGain(game, play, result['yards']) if gainResult != "error": if yards is not None: actualResult = gainResult else: success = False elif result['result'] == 'touchdown': log.debug("Result is a touchdown") resultMessage = "It's a {} into the endzone! Touchdown {}!".format(play, game[game['status']['possession']]['name']) previousLocation = game['status']['location'] utils.addStatRunPass(game, play, 100 - previousLocation) scoreTouchdown(game, game['status']['possession']) actualResult = "touchdown" yards = 100 - previousLocation elif result['result'] == 'fieldGoal': log.debug("Result is a field goal") resultMessage = "The {} yard field goal is good!".format(100 - game['status']['location'] + 17) utils.addStat(game, 'fieldGoalsScored', 1) scoreFieldGoal(game, game['status']['possession']) actualResult = "fieldGoal" elif result['result'] == 'punt': if 'yards' not in result: log.warning("Result is a punt, but I couldn't find any yards") resultMessage = "Result of play is a successful punt, but something went wrong and I couldn't find how long a punt" log.debug("Successful punt of {} yards".format(result['yards'])) resultMessage = executePunt(game, result['yards']) actualResult = "punt" elif result['result'] == 'turnover': log.debug("Play results in a turnover") if play == "run": utils.addStat(game, 'turnoverInterceptions', 1) resultMessage = "Fumble! The ball is dropped, {} recovers!".format(game[utils.reverseHomeAway(game['status']['possession'])]['name']) elif play == "pass": utils.addStat(game, 'turnoverFumble', 1) resultMessage = "Picked off! The pass is intercepted, {} ball!".format(game[utils.reverseHomeAway(game['status']['possession'])]['name']) elif play == "fieldGoal" or play == "punt": utils.addStat(game, 'turnoverFumble', 1) resultMessage = "It's a miss!" else: utils.addStat(game, 'turnoverFumble', 1) resultMessage = "It's a turnover!" turnover(game) actualResult = "turnover" elif result['result'] == 'turnoverTouchdown': log.debug("Play results in a turnover and run back") if play == "run": resultMessage = "Fumble! The ball is dropped and it's run all the way back. Touchdown {}!".format(game[utils.reverseHomeAway(game['status']['possession'])]['name']) elif play == "pass": resultMessage = "Picked off! The pass is intercepted and it's run all the way back. Touchdown {}!".format(game[utils.reverseHomeAway(game['status']['possession'])]['name']) elif play == "fieldGoal" or play == "punt": resultMessage = "It's blocked! The ball is picked up and run all the back. Touchdown {}!".format(game[utils.reverseHomeAway(game['status']['possession'])]['name']) else: resultMessage = "It's a turnover and run back for a touchdown!" scoreTouchdown(game, utils.reverseHomeAway(game['status']['possession'])) actualResult = "turnoverTouchdown" if success and play == 'fieldGoal': utils.addStat(game, 'fieldGoalsAttempted', 1) database.clearDefensiveNumber(game['dataID']) elif play in globals.timePlays: if play == 'kneel': log.debug("Running kneel play") actualResult = "kneel" game['status']['down'] += 1 if game['status']['down'] > 4: log.debug("Turnover on downs") turnover(game) resultMessage = "Turnover on downs" else: resultMessage = "The quarterback takes a knee" elif play == 'spike': log.debug("Running spike play") actualResult = "spike" game['status']['down'] += 1 if game['status']['down'] > 4: log.debug("Turnover on downs") turnover(game) resultMessage = "Turnover on downs" else: resultMessage = "The quarterback spikes the ball" else: resultMessage = "{} isn't a valid play at the moment".format(play) success = False messages = [resultMessage] if actualResult is not None: timeMessage = updateTime(game, play, actualResult, yards, startingPossessionHomeAway) messages.append(timeMessage) if diffMessage is not None: messages.append(diffMessage) return success, '\n\n'.join(messages)
def updateTime(game, play, result, yards, offenseHomeAway): if result in ['touchdown', 'touchback']: actualResult = "gain" else: actualResult = result if result == 'spike': timeOffClock = 1 else: if result == 'kneel': timeOffClock = 1 else: timeOffClock = getTimeByPlay(play, actualResult, yards) if result in ["gain", "kneel"]: if game['status']['requestedTimeout'][offenseHomeAway] == 'requested': log.debug("Using offensive timeout") game['status']['requestedTimeout'][offenseHomeAway] = 'used' game['status']['timeouts'][offenseHomeAway] -= 1 elif game['status']['requestedTimeout'][utils.reverseHomeAway(offenseHomeAway)] == 'requested': log.debug("Using defensive timeout") game['status']['requestedTimeout'][utils.reverseHomeAway(offenseHomeAway)] = 'used' game['status']['timeouts'][utils.reverseHomeAway(offenseHomeAway)] -= 1 else: if result == 'kneel': timeOffClock += 39 else: timeOffClock += getTimeAfterForOffense(game, offenseHomeAway) log.debug("Time off clock: {} : {}".format(game['status']['clock'], timeOffClock)) game['status']['clock'] -= timeOffClock timeMessage = "{} left".format(utils.renderTime(game['status']['clock'])) if game['status']['clock'] < 0: log.debug("End of quarter: {}".format(game['status']['quarter'])) actualTimeOffClock = timeOffClock + game['status']['clock'] if game['status']['quarter'] == 1: timeMessage = "end of the first quarter" elif game['status']['quarter'] == 3: timeMessage = "end of the third quarter" else: if game['status']['quarter'] == 4: if game['score']['home'] == game['score']['away']: timeMessage = "full time! The score is tied, but unfortunately overtime is not implemented yet." else: timeMessage = "full time!" game['status']['clock'] = 0 game['waitingAction'] = 'end' else: if game['status']['quarter'] == 2: timeMessage = "end of the first half" setStateTouchback(game, game['receivingNext']) game['receivingNext'] = utils.reverseHomeAway(game['receivingNext']) game['status']['timeouts'] = {'home': 3, 'away': 3} if game['status']['quarter'] < 4: game['status']['quarter'] += 1 game['status']['clock'] = globals.quarterLength else: actualTimeOffClock = timeOffClock utils.addStat(game, 'posTime', actualTimeOffClock, offenseHomeAway) return "The play took {} seconds, {}".format(timeOffClock, timeMessage)
def setTurnovers(game,turnover): s_turnover = "{}{}".format(turnover,'s') current = game['status']['possession'] if turnover == 'steal': utils.addStat(game, s_turnover, 1, utils.reverseHomeAway(current)) utils.addStat(game, 'turnovers', 1, current)
def processMessage(message): ## Determine if comment or dm if isinstance(message, praw.models.Message): isMessage = True else: isMessage = False log.debug("Processing a comment from /u/{} with id {} and body {}".format(str(message.author), message.id,message.body)) response = None success = None updateWaiting = True dataTable = None resultMessage = None tipped = False if message.parent_id is not None and (message.parent_id.startswith("t1") or message.parent_id.startswith("t4")): if isMessage: parent = reddit.getMessage(message.parent_id[3:]) else: parent = reddit.getComment(message.parent_id[3:]) if parent is not None and str(parent.author).lower() == globals.ACCOUNT_NAME: dataTable = utils.extractTableFromMessage(parent.body) if dataTable is not None: if 'action' not in dataTable: dataTable = None else: dataTable['source'] = parent.fullname log.debug("Found a valid datatable in parent message: {}".format(str(dataTable))) body = message.body.lower() author = str(message.author) game = None if dataTable is not None: game = utils.getGameByUser(author) log.debug('game is {}'.format(game)) if game is not None: utils.setLogGameID(game['thread'], game['dataID']) print('the action is {}'.format(dataTable['action'])) waitingOn = utils.isGameWaitingOn(game, author, dataTable['action'], dataTable['source']) log.debug("waitingOn is {}".format(waitingOn)) if waitingOn is not None: response = waitingOn success = False updateWaiting = False elif game['errored']: log.debug("Game is errored, skipping") response = "This game is currently in an error state, /u/{} has been contacted to take a look".format(globals.OWNER) success = False updateWaiting = False else: log.debug('Trying to process tip, offense, or defense') ##this is where we start the game basically if dataTable['action'] == 'tip' and isMessage: log.debug('About to process tip message from {}'.format(str(message.author))) success, response = processMessageTip(game, message) if success: game['dirty'] = True log.debug("The tip message's success was {} and the message's content reads {}".format(success, response)) elif dataTable['action'] == 'play' and isMessage: success, response = processMessageDefenseNumber(game, body, str(message.author)) elif dataTable['action'] == 'play' and not isMessage: pos = game['status']['possession'] success, response = processMessageOffensePlay(game, body, str(message.author)) utils.sendPlayResultMessage(utils.reverseHomeAway(pos),game, response) else: log.debug("Couldn't get a game for /u/{}".format(author)) else: log.debug("Parsing non-datatable message with body {} from author {}".format(body, str(message.author).lower())) if "newgame" in body and isMessage: response = processMessageNewGame(message.body, str(message.author)) if "kick" in body and isMessage and str(message.author).lower() == globals.OWNER: response = processMessageKickGame(message.body) if "pause" in body and isMessage and str(message.author).lower() in wiki.admins: response = processMessagePauseGame(message.body) if "abandon" in body and isMessage and str(message.author).lower() in wiki.admins: log.debug('Going to abandon a game') response = processMessageAbandonGame(message.body) if "refresh" in body and isMessage and str(message.author).lower() in wiki.admins: response = utils.processRefresh() message.mark_read() if response is not None: if success is not None and not success and dataTable is not None and utils.extractTableFromMessage(response) is None: log.debug("Embedding datatable in reply on failure") response = utils.embedTableInMessage(response, dataTable) if updateWaiting and game is not None: game['waitingId'] = 'return' log.debug("About to send reply Message") if game is not None: log.debug("game is not none") if game['tip']['justTipped']: log.debug('sending the winning tip message to the game thread') ##send the tip update to the game thread instead of to the last ## person who sent a tip number resultMessage = utils.sendGameCommentAfterTip(game, response) game['tip']['justTipped'] = False game['tip']['tipped'] = True else: resultMessage = reddit.replyMessage(message, response) else: resultMessage = reddit.replyMessage(message, response) log.debug("result of sending reply message was {}".format(resultMessage)) if resultMessage is None: log.warning("Could not send message") elif game is not None and game['waitingId'] == 'return': game['waitingId'] = resultMessage.fullname log.debug('About to send. WaitingID is {} when waitingID was return'.format(game['waitingId'])) game['dirty'] = True log.debug("Message/comment replied, now waiting on: {}".format(game['waitingId'])) else: if isMessage: log.debug("Couldn't understand message") resultMessage = reddit.replyMessage(message, "Could not understand you. Please try again or message /u/zenverak if you need help.") if resultMessage is None: log.warning("Could not send message") if game is not None: if game['status']['sendDef']: utils.sendDefensiveNumberMessage(game) game['status']['sendDef'] = False if game is not None and game['dirty']: log.debug("Game is dirty, updating thread") utils.updateGameThread(game)
def executePlay(game, play, number, numberMessage): startingPossessionHomeAway = game['status']['possession'] actualResult = None resultMessage = "Something went wrong, I should never have reached this" diffMessage = None success = True timeMessage = None fouled = False log.debug("starting to execute Play with play being {} and number being {}".format(play, number)) if game['status']['free'] != False: result = "FREE" if number == -1: log.debug("Trying to shoot a free throw play, but didn't have a number") resultMessage = numberMessage success = False return False, resultMessage elif number > -1: game['status']['frees'] -= 1 utils.addStat(game,'FTAttempted',1,startingPossessionHomeAway) numberResult, diffMessage = getNumberDiffForGame(game, number) freeResult = getFreeThrowResult(game,numberResult) if freeResult: game['play']['result'] = 'Free Made' log.debug("Successful Free Throw") tempMessage = ["{}'s Free throw was successful.\n\n ".format(game[game['status']['possession']]['name'])] utils.addStat(game,'FTMade',1,startingPossessionHomeAway) scoreFreeThrow(game, startingPossessionHomeAway) tempMessage.append("\nThe score is now **{}**: {}, **{}**: {}".format(game['away']['name'],game['score']['away'], game['home']['name'], game['score']['home'])) resultMessage = ''.join(tempMessage) if game['status']['free'] == '1and1Start': game['status']['frees'] = 1 game['status']['free'] = True else: game['play']['result'] = 'Free Missed' log.debug("failed free throw") resultMessage = "You missed the free throw." if game['status']['frees'] == 0: game['status']['free'] = False game['waitingAction'] = 'play' game['play']['playResult'] = 'freeDone' game['freeThrows']['freeType'] = None result = "FREEDONE" else: pass ## database.clearDefensiveNumber(game['dataID']) else: resultMessage = "It looks like /]you're trying to get the extra point after a touchdown, but this isn't a valid play" success = False elif game['status']['ifoul']: resultMessage = setFouls(game, 0) game['play']['playResult'] = 'fouled' else: if play in globals.offPlays: utils.addStat(game,'possessions',1,startingPossessionHomeAway) if number == -1: log.debug("Trying to execute a normal play, but didn't have a number") resultMessage = numberMessage success = False else: numberResult, diffMessage = getNumberDiffForGame(game, number) log.debug("numberResult was {}".format(numberResult)) log.debug("Executing normal play: {}".format(play)) result = getPlayResult(game, play, numberResult) game['play']['result'] = result['result'] playResultName = result['result'].lower() log.debug('playResultName is {}'.format(playResultName)) ptf = re.search('2|3', playResultName) log.debug("ptf is {}".format(ptf)) if ptf: pointsTriedFor = int(ptf.group(0)) log.debug("this shot as an attempt for {} points".format(pointsTriedFor)) if playResultName.lower() in globals.pointResults : if 'points' not in result: log.warning("Result is a score, but I couldn't find any points") resultMessage = "Result of play is a number of points, but something went wrong and I couldn't find what number" success = False else: if playResultName in globals.foulPlays: ##After this play we will be waiting on the current devensive ##team since they will have to send a defensive number fouled = True points = result['points'] tempMessage = ["{}'s Basket is good for {} points.\n\n".format(game[game['status']['possession']]['name'],points)] if fouled: tempMessage.append('AND ONE. Player is fouled.\n\n') if points == 2: sub2Pt(game, True, fouled) game['play']['playDesc'] = '2' game['play']['playResult'] = 'made' game['status']['scored'] = True elif points == 3: sub3Pt(game, True, fouled) game['play']['playResult'] = 'made' game['play']['playDesc'] = '3' game['status']['scored'] = True log.debug("Result is a gain of {} points".format(points)) tempMessage.append("\nThe score is now **{}**: {}, **{}**: {}".format(game['away']['name'],game['score']['away'], game['home']['name'], game['score']['home'])) resultMessage = ''.join(tempMessage) elif playResultName in globals.foulMissPlays: log.debug("In foul Miss Plays") ##get numbers to see how many free thors we will shoot setFouls(game, pointsTriedFor) resultMessage = 'Fouled on a {0}pt shot. The shot is missed. Going to shoot {0} free throws.'.format(pointsTriedFor) game['play']['playResult'] = 'fouled' elif playResultName in globals.nonShootingFoul: ##This sets possession in the bonus check resultMessage = setFouls(game, 0) game['play']['playResult'] = 'fouled' elif playResultName in globals.missPlays: log.debug('In miss plays') game['play']['playResult'] = 'miss'##No need to change who we are waitingon here if pointsTriedFor == 2: sub2Pt(game, False, False) elif pointsTriedFor == 3: sub3Pt(game, False, False) else: return False, "Could not detect a number like we think it should. We must pay with our " resultMessage = "Missed a {} point shot.".format(pointsTriedFor) elif playResultName in globals.offRebounds: game['play']['playResult'] = 'offrebound' shotType = utils.coinToss() if shotType: log.debug('By random choice this was a 2 point shot') sub2Pt(game, False, False, True) else: log.debug('By random choice this was a 3 point shot') sub3Pt(game, False, False, True) resultMessage = "Missed a shot but got the offensive rebound" elif playResultName in globals.turnovers: game['play']['playResult'] = 'turnover' setTurnovers(game, playResultName.lower()) if playResultName == "Steal": resultMessage = "Hark, a steal" else: resultMessage = 'Turned the ball over' elif playResultName == 'block': resultMessage = "the shot was BLOCKED" game['play']['playResult'] = 'block' setBlock(game, 'block') elif playResultName == globals.stealDunk: tempMessage = ['The ball was stolen by {} and dunked for two points\n\n'.format(game[utils.reverseHomeAway(game['status']['possession'])]['name'])] setTurnovers(game, 'steal') utils.addStat(game, 'possessions',1, utils.reverseHomeAway(startingPossessionHomeAway)) game['status']['possession'] = utils.reverseHomeAway(startingPossessionHomeAway) log.debug('{} had the ball stolen and {} is about to score'.format(startingPossessionHomeAway, utils.reverseHomeAway(startingPossessionHomeAway))) sub2Pt(game, True, False) game['play']['playResult'] = 'made' game['waitingOn'] = utils.reverseHomeAway(startingPossessionHomeAway) tempMessage.append("\nThe score is now **{}**: {}, **{}**: {}".format(game['away']['name'],game['score']['away'], game['home']['name'], game['score']['home'])) resultMessage = ''.join(tempMessage) elif playResultName == globals.steal3Pt: tempMessage = ['The ball was stolen by {} and shot for a 3 PT.\n\n '.format(game[utils.reverseHomeAway(game['status']['possession'])]['name'])] setTurnovers(game, 'steal') utils.addStat(game, 'possessions',1, utils.reverseHomeAway(startingPossessionHomeAway)) game['status']['possession'] = utils.reverseHomeAway(startingPossessionHomeAway) log.debug('{} had the ball stolen and {} is about to score'.format(startingPossessionHomeAway, utils.reverseHomeAway(startingPossessionHomeAway))) sub3Pt(game, True, False) game['play']['playResult'] = 'made' game['waitingOn'] = utils.reverseHomeAway(startingPossessionHomeAway) tempMessage.append("\nThe score is now **{}**: {}, **{}**: {}".format(game['away']['name'],game['score']['away'], game['home']['name'], game['score']['home'])) resultMessage = ''.join(tempMessage) database.clearDefensiveNumber(game['dataID']) else: resultMessage = "{} isn't a valid play at the moment".format(play) success = False messages = [resultMessage] if resultMessage is not None: if success: if game['status']['ifoul']: game['status']['ifoul'] = False diffMessage = None result = None timeMessage = updateTime(game, play, result, startingPossessionHomeAway) if timeMessage is None: timeMessage = updateTime(game, play, result, startingPossessionHomeAway) messages.append(timeMessage) if diffMessage is not None: messages.append(diffMessage) log.debug("Finishing execution of play") log.debug("We will be waiting on {} for next number".format(game['waitingOn'])) log.debug("messages: resultMessage: {}, timeMessage:{}, diffMessage:{}".format(resultMessage, timeMessage, diffMessage)) ##determine here if we need to change possession changePossession(game) return success, '\n\n'.join(messages)
def scoreFieldGoal(game, homeAway): scoreForTeam(game, 3, homeAway) setStateTouchback(game, utils.reverseHomeAway(homeAway))
def processMessageOffensePlay(game, message, author): ##set some information for later. current = game['status']['possession'] other = utils.reverseHomeAway(current) game['play']['ocoach'] = game[current]['coaches'][0] game['play']['dcoach'] = game[other]['coaches'][0] game['play']['playMessage'] = message log.debug("Processing offense number message") if game['status']['ifoul']: numberMessage = '' number = 0 else: number, numberMessage = utils.extractPlayNumber(message) playOptions = ['chew', 'average', 'push', 'regular'] if not game['status']['ifoul']: playSelected = utils.findKeywordInMessage(playOptions, message) play = "default" if game['status']['free']: play = 'free' elif playSelected == "chew": play = "chew" elif playSelected == "average": play = "average" elif playSelected == "push": play = "push" elif playSelected == "mult": log.debug("Found multiple plays") return False, "I found multiple plays in your message. Please repost it with just the play and number." else: log.debug("Didn't find any plays") return False, "I couldn't find a play in your message. Please reply to this one with a play and a number." else: play = 'foul' numberMessage = 'intentional foul' playSelected = 'foul' game['play']['playType'] = play success, resultMessage = state.executePlay(game, play, number, numberMessage) result = [resultMessage] if playSelected != 'default' and success: state.setWaitingOn(game) game['dirty'] = True if game['waitingAction'] == 'play' and playSelected != 'default' and success: log.debug('going to set the play data up, save it, then remove it') utils.insertPlayData(game) game['status']['sendDef'] = True elif game['waitingAction'] == 'overtime': log.debug("Starting overtime, posting coin toss comment") message = "Overtime has started! {}, you're away, call **heads** or **tails** in the air.".format( utils.getCoachString(game, 'away')) comment = utils.sendGameComment(game, message, {'action': 'tip'}) game['waitingId'] = comment.fullname game['waitingAction'] = 'tip' return success, utils.embedTableInMessage('\n\n'.join(result), {'action': game['waitingAction']})
def scorePAT(game, homeAway): scoreForTeam(game, 1, homeAway) setStateTouchback(game, utils.reverseHomeAway(homeAway))
elif game['tip']['homeTip'] and not game['tip']['awayTip'] and game['waitingAction'] == 'tip': game['away']['playclockPenalties'] += 1 game['waitingOn'] = 'away' game['status']['possession'] = 'home' else: game[game['waitingOn']]['playclockPenalties'] += 1 penaltyMessage = "{} has not sent their number in over {} hours, playclock penalty. This is their {} penalty.".format( utils.getCoachString(game, game['waitingOn']),globals.delayHours, utils.getNthWord(game[game['waitingOn']]['playclockPenalties'])) if game['home']['playclockPenalties'] == 3 and game['away']['playclockPenalties'] == 3: ## This needs to be where we do something if both players hit 3 utils.endGameBothDelay(game,threadId) elif game[game['waitingOn']]['playclockPenalties'] >= 3: log.debug("3 penalties, game over") game['status']['halfType'] = 'end' game['waitingAction'] = 'end' resultMessage = "They forfeit the game. {} has won!".format(utils.flair(game[utils.reverseHomeAway(game['waitingOn'])])) utils.endGameDelayOfGame(game, threadId) elif techFoul: state.technicalFouls(game) else: utils.sendGameComment(game, penaltyMessage, {'action': 'death'}) pass database.setGamePlayed(game['dataID']) utils.updateGameThread(game) log.debug("Message processed after: %d", int(time.perf_counter() - startTime)) utils.clearLogGameID() if once:
def scoreSafety(game, homeAway): scoreForTeam(game, 2, homeAway) setStateTouchback(game, utils.reverseHomeAway(homeAway))
def processMessageOffensePlay(game, message, author): log.debug("Processing offense number message") number, numberMessage = utils.extractPlayNumber(message) timeoutMessageOffense = None timeoutMessageDefense = None if message.find("timeout") > 0: if game['status']['timeouts'][game['status']['possession']] > 0: game['status']['requestedTimeout'][game['status'] ['possession']] = 'requested' else: timeoutMessageOffense = "The offense requested a timeout, but they don't have any left" playOptions = [ 'run', 'pass', 'punt', 'field goal', 'kneel', 'spike', 'two point', 'pat' ] playSelected = utils.findKeywordInMessage(playOptions, message) play = "default" if playSelected == "run": play = "run" elif playSelected == "pass": play = "pass" elif playSelected == "punt": play = "punt" elif playSelected == "field goal": play = "fieldGoal" elif playSelected == "kneel": play = "kneel" elif playSelected == "spike": play = "spike" elif playSelected == "two point": play = "twoPoint" elif playSelected == "pat": play = "pat" elif playSelected == "mult": log.debug("Found multiple plays") return False, "I found multiple plays in your message. Please repost it with just the play and number." else: log.debug("Didn't find any plays") return False, "I couldn't find a play in your message" success, resultMessage = state.executePlay(game, play, number, numberMessage) if game['status']['requestedTimeout'][game['status'] ['possession']] == 'used': timeoutMessageOffense = "The offense is charged a timeout" elif game['status']['requestedTimeout'][game['status'] ['possession']] == 'requested': timeoutMessageOffense = "The offense requested a timeout, but it was not used" game['status']['requestedTimeout'][game['status']['possession']] = 'none' if game['status']['requestedTimeout'][utils.reverseHomeAway( game['status']['possession'])] == 'used': timeoutMessageDefense = "The defense is charged a timeout" elif game['status']['requestedTimeout'][utils.reverseHomeAway( game['status']['possession'])] == 'requested': timeoutMessageDefense = "The defense requested a timeout, but it was not used" game['status']['requestedTimeout'][utils.reverseHomeAway( game['status']['possession'])] = 'none' result = [resultMessage] if timeoutMessageOffense is not None: result.append(timeoutMessageOffense) if timeoutMessageDefense is not None: result.append(timeoutMessageDefense) game['waitingOn'] = utils.reverseHomeAway(game['waitingOn']) game['dirty'] = True if game['waitingAction'] == 'play': utils.sendDefensiveNumberMessage(game) return success, utils.embedTableInMessage( '\n\n'.join(result), {'action': game['waitingAction']})