def end_game(self): super().end_game() """In case a user wants to end the game if they want to :return: message that the user quit the game """ current_game = self.ddb.current_game_state(self.channel_id) if 'Item' not in current_game or current_game['Item'][ 'game_status'] == 'challenged': return RMB.respond(None, game_response_type='end_no_game', values=[]) current_game = current_game['Item'] if self.requester == current_game[ 'challenger_name'] or self.requester == current_game[ 'opponent_name']: self.ddb.delete_game(self.channel_id) return RMB.respond(None, game_response_type='end_game', values=[self.requester], slack_response_type='in_channel') else: return RMB.respond(None, game_response_type='end_wrong_player', values=[])
def game_help(self): super().game_help() """Help handler which provides information about the game and how to play it. :return: """ return RMB.respond(None, game_response_type='help_text', values=[])
def accept_game(self): super().accept_game() """Accept request handler is called when the user accepts a challenge Conditions: The game can be only accepted by the opponent whom it was challenged to Once the challenge is accepted the game a notification is publicly sent to the channel :return: """ current_game = self.ddb.current_game_state(self.channel_id) # Use cases # trying to accept a challenge with no game if not 'Item' in current_game or current_game['Item'][ 'game_status'] == 'in_progress': return RMB.respond(None, game_response_type='accept_no_challenge', values=[]) current_game = current_game['Item'] # Wrong opponent trying to accept the challenge if current_game['opponent_name'] != self.requester: return RMB.respond(None, game_response_type='accept_wrong_player', values=[current_game['opponent_name']]) # right opponent trying to accept the challenge self.ddb.update_game(channel_id=self.channel_id, game_status='in_progress') response = '`{0}` has accepted the challenge by `{1}` to play tic-tact-toe\n' \ .format(current_game['opponent_name'], current_game['challenger_name']) response += '{0} ( `{1}` ) vs {2} ( `{3}` )\n ' \ .format(current_game['challenger_name'], current_game['challenger_action'], current_game['opponent_name'], current_game['opponent_action']) response += '\n> next turn `{0}`\n\n'.format( current_game['current_turn_player']) response += self.draw_board() response += '\n> Play next move using command like eg. `/ttt-move b3` where `b` is row `3` is column in the grid' return RMB.respond(None, game_response_type='', values=[], slack_response_type='in_channel', response=response)
def lambda_handler(event, context): resource = event["resource"] params = parse_qs(event['body']) token = params['token'][0] expected_token = util.decrypt(KMS_ENCRYPTED_TOKEN) if token != expected_token: return RMB.respond(err=Exception('Invalid request token'), game_response_type='', values=[]) rh = RequestHandler(params) return rh.route(resource)
def display_board(self, response_type='Ephemeral'): """Board request handler displays the current status of the board to the user. :return: current view of the board """ current_game = self.ddb.current_game_state(channel_id=self.channel_id) # if no game is being played if 'Item' not in current_game or current_game['Item'][ 'game_status'] == 'challenged': return RMB.respond(None, game_response_type='board_no_game', values=[]) current_game = current_game['Item'] response = 'Current Status of the game: `{0}` ( `{1}` ) vs `{2}` ( `{3}` )'\ .format(current_game['challenger_name'], current_game['challenger_action'], current_game['opponent_name'], current_game['opponent_action']) response += '\n> Next turn `{0}` \n\n'.format( current_game['current_turn_player']) response += self.draw_board( current_game['loc_a1'], current_game['loc_a2'], current_game['loc_a3'], current_game['loc_b1'], current_game['loc_b2'], current_game['loc_b3'], current_game['loc_c1'], current_game['loc_c2'], current_game['loc_c3'], ) return RMB.respond(None, game_response_type='', values=[], slack_response_type=response_type, response=response)
def decline_game(self): super().decline_game() """Decline request handler is called when the user declines a challenge :return: """ current_game = self.ddb.current_game_state(self.channel_id) if "Item" not in current_game: return RMB.respond(None, game_response_type='decline_no_game', values=[]) if current_game['Item']['game_status'] == 'in_progress': return RMB.respond(None, game_response_type='decline_game_in_progress', values=[]) current_game = current_game['Item'] cg_challenger = current_game['challenger_name'] cg_opponent = current_game['opponent_name'] cg_status = current_game['game_status'] # only game opponent can decline if cg_status == 'challenged': if cg_opponent == self.requester: self.ddb.delete_game(self.channel_id) return RMB.respond(None, game_response_type='decline_right_player', values=[cg_opponent, cg_challenger], slack_response_type='in_channel') else: return RMB.respond(None, game_response_type='decline_wrong_player', values=[cg_opponent]) else: return RMB.respond(None, game_response_type='err_response', values=[])
def new_game(self): super().new_game() if self.command is None: return RMB.respond(None, game_response_type='new_game_no_opponent', values=[]) if self.command == self.requester: return RMB.respond(None, game_response_type='new_game_challenge_self', values=[]) current_game = self.ddb.current_game_state(self.channel_id) if 'Item' in current_game and current_game['Item'][ 'game_status'] == 'in_progress': return RMB.respond(None, game_response_type='new_game_in_progress', values=[self.requester, self.command]) # make sure new challenge is not made when there is a challenge pending from 30 mins if "Item" in current_game: current_game = current_game['Item'] created_at = datetime.strptime(current_game['created_at'], "%Y-%m-%d %H:%M:%S") now = datetime.now() created_at_ts = time.mktime(created_at.timetuple()) now_ts = time.mktime(now.timetuple()) if ((now_ts - created_at_ts) / 60) < 5: return RMB.respond(None, game_response_type='new_game_new_challenge', values=[ current_game['challenger_name'], current_game['opponent_name'] ]) # start game new_game = self.ddb.create_new_game(self.channel_id, self.requester, self.command) if new_game is not None: return RMB.respond( None, game_response_type='new_valid_game', values=[self.requester, self.command, self.command], slack_response_type='in_channel') else: print( 'Something went wrong when challenging for a game of tic-tac-toe' ) return RMB.respond(None, game_response_type='err_response', values=[])
def __generate_response(self, response_map): print('*** RESPONSE: ',response_map); game_response_type = response_map['game_response_type'] values = response_map['values'].split(',') slack_response_type = None if "slack_response_type" in response_map: slack_response_type = response_map["slack_response_type"] else: slack_response_type = 'Ephemeral' response = None if 'response' in response_map: response = response_map['response'] return RMB.respond(None, game_response_type=game_response_type, values=values, slack_response_type=slack_response_type, response=response)
def play_move(self): super().play_move() """Move handler handles the next move by the player. :param position: position where user wants to put X or O to :return: current view of the board after the move """ # if there is no command if self.command is None: return RMB.respond(None, game_response_type='move_no_position', values=[]) current_game = self.ddb.current_game_state(self.channel_id) if 'Item' not in current_game or current_game['Item'][ 'game_status'] == 'challenged': return RMB.respond(None, game_response_type='move_no_game', values=[]) current_game = current_game['Item'] if current_game['current_turn_player'] != self.requester: return RMB.respond(None, game_response_type='move_wrong_player', values=[current_game['current_turn_player']]) # check valid move if self.__check_valid_move(self.command, current_game): current_player = self.requester move = None next_player = current_player if current_player == current_game['challenger_name']: move = current_game['challenger_action'] next_player = current_game['opponent_name'] else: move = current_game['opponent_action'] next_player = current_game['challenger_name'] self.__update_db_with_move(self.command, move, next_player) # check if the last move won the game current_game = self.ddb.current_game_state(self.channel_id) current_game = current_game['Item'] board = self.draw_board( current_game['loc_a1'], current_game['loc_a2'], current_game['loc_a3'], current_game['loc_b1'], current_game['loc_b2'], current_game['loc_b3'], current_game['loc_c1'], current_game['loc_c2'], current_game['loc_c3']) if self.__check_winner(current_game): response = RMB.response('game_won', [self.requester]) # check if the last move was a tie elif self.__check_game_tie(current_game): response = RMB.response('game_tie', [ current_game['challenger_name'], current_game['opponent_name'] ]) else: return self.display_board(response_type='in_channel') self.ddb.delete_game(self.channel_id) response += '`The final status of the board`\n\n' response += board return RMB.respond(None, game_response_type='', slack_response_type='in_channel', values=[], response=response) else: return RMB.respond(None, game_response_type='move_invalid', values=[])