def __init__(self): self.model = Model() self.view = View() # create selection matrix for filter # create top row of card ranks top_row = [SelectionItem('', is_top_left=True)] + [ SelectionItem(Card.ranks[rank], is_card=False, is_top_row=True) for rank in range(1, RANKS + 1) ] # create selection item for each card self.model.selection_matrix = [top_row] + [[ SelectionItem(str(Card(rank, suit)), card=Card(rank, suit)) for rank in range(1, RANKS + 1) ] for suit in range(1, SUITS + 1)] # add leftmost column for suits for i in range(1, len(self.model.selection_matrix)): self.model.selection_matrix[i] = [ SelectionItem(Card.suits[i], is_card=False) ] + self.model.selection_matrix[i] # deselect all for row in self.model.selection_matrix: for item in row: item.is_selected = False # initialize game state self.model.deck = Deck() self.model.player_hand = Hand() self.model.dealer_hand = Hand() self.model.drawn_cards = []
def save_turn_one_game_state(game, deck, player_one_hand): """Save the state of the game after player one has made a move. Args: game: current game the player is playing in. deck: the deck state after the player has drawn cards for the card_id exchange phase. hand: the final hand the player has after the desired cards have been replaced. """ # Save player one's final hand hand = Poker.serialize_hand(player_one_hand) final_hand = Hand( player=game.player_one, game=game.key, hand=hand, state=str(HandState.ENDING) ) final_hand.put() game.active_player = game.player_two game.deck = deck.serialize() game.put() taskqueue.add( url='/tasks/send_move_email', params={ 'game_key': game.key.urlsafe(), 'user_key': game.active_player.urlsafe() }, transactional=True )
def get_game_history(self, request): """Get player game history.""" player = User.query(User.name == request.player).get() if not player: raise endpoints.NotFoundException( '{0} does not exist!'.format(request.player) ) games = Game.query( ndb.AND( Game.game_over == True, # noqa ndb.OR( Game.player_one == player.key, Game.player_two == player.key ) ) ) game_histories = [] for game in games: player_one = game.player_one.get() player_two = game.player_two.get() if game.is_forfeit: game_histories.append( GameHistoryForm( game_urlsafe_key=game.key.urlsafe(), player_one=player_one.name, player_two=player_two.name, is_forfeit=game.is_forfeit, winner=game.winner.get().name ) ) else: p1_hands = Hand.query( Hand.game == game.key, Hand.player == player_one.key ) p1_hands = Poker.get_player_start_end_hands(p1_hands) p2_hands = Hand.query( Hand.game == game.key, Hand.player == player_two.key ) p2_hands = Poker.get_player_start_end_hands(p2_hands) game_histories.append( GameHistoryForm( game_urlsafe_key=game.key.urlsafe(), player_one=player_one.name, player_one_start_hand=repr(p1_hands[0]), player_one_end_hand=repr(p1_hands[1]), player_two=player_two.name, player_two_start_hand=repr(p2_hands[0]), player_two_end_hand=repr(p2_hands[1]), is_forfeit=game.is_forfeit, winner=game.winner.get().name ) ) return GameHistoryForms( games=game_histories )
def test_init_invalid(self): with self.assertRaises(Exception): Hand('akqjt98765432') # missing suit with self.assertRaises(Exception): Hand('sakqjt98765432a') # too many cards with self.assertRaises(Exception): Hand('sakqjt987d765432') # too many cards
def test_parse_with_gaps(self): md = VugraphMD.parse('3SQH269D347QKC34QK,S68KAH37QD2JAC27A,S2357H8JAD568C69J,') self.assertEqual(md.dealer, 3) self.assertEqual(len(md.hands), 4) self.assertEqual(md.hands[0], Hand.parse('SQH269D347QKC34QK')) self.assertEqual(md.hands[1], Hand.parse('S68KAH37QD2JAC27A')) self.assertEqual(md.hands[2], Hand.parse('S2357H8JAD568C69J')) self.assertEqual(md.hands[3], Hand.parse('s49tjh45tkd9tc58t'))
def test_parse_none_missing(self): md = VugraphMD.parse('3SQJHQT9632D82CK98,S8743HK854DK76CQ2,SAT2HAJ7DAJ543CJ5,SK965HDQT9CAT7643') self.assertEqual(md.dealer, 3) self.assertEqual(len(md.hands), 4) self.assertEqual(md.hands[0], Hand.parse('SQJHQT9632D82CK98')) self.assertEqual(md.hands[1], Hand.parse('S8743HK854DK76CQ2')) self.assertEqual(md.hands[2], Hand.parse('SAT2HAJ7DAJ543CJ5')) self.assertEqual(md.hands[3], Hand.parse('SK965HDQT9CAT7643'))
def test_init(self): hands = [ Hand.parse('SQJHQT9632D82CK98'), Hand.parse('S8743HK854DK76CQ2'), Hand.parse('SAT2HAJ7DAJ543CJ5'), Hand.parse('SK965HDQT9CAT7643') ] md = VugraphMD(3, hands) self.assertEqual(md.dealer, 3) self.assertEqual(md.hands, hands)
def make_move(game, player, card_ids): """Record and respond to player's move. Record player card exchanges if any requeted. An empty card_ids means the player does not want to exchange any of his/her cards. Args: game: An entity representing the game state. player: An entity representing the active player. card_ids: A list with the cards the player wants to exchange. Returns: The player's final hand. Raises: ForbiddenException: Player is trying to exchange more than the max hand size; 5 cards. """ final_hand = Hand.query( ndb.AND(Hand.game == game.key, Hand.player == player.key) ).get() final_hand = Poker.load_player_hand(final_hand.hand) deck = Deck.construct_json_deck(game.deck) if len(card_ids) > 0: if len(card_ids) < 6: final_hand = Poker.get_new_cards(deck, final_hand, card_ids) else: raise endpoints.ForbiddenException( '''It is not possible to exchange more cards than your hand size''' ) if game.active_player == game.player_one: Poker.save_turn_one_game_state(game, deck, final_hand) else: player_one_hand = Hand.query( ndb.AND(Hand.game == game.key, Hand.player == game.player_one) ).get() player_one_hand = Poker.load_player_hand(player_one_hand.hand) Poker.save_turn_two_game_state( game, deck, final_hand, player_one_hand ) Poker.update_player_stats(game) return final_hand
def initRound(self): self.deck = Deck() self.activePlayers = [0 for i in range(MAX_PLAYERS)] self.playersHands = [Hand([]) for i in range(MAX_PLAYERS)] self.activeBets = [0 for i in range(MAX_PLAYERS)] self.actedThisRound = [0 for i in range(MAX_PLAYERS)] self.money = [0 for i in range(MAX_PLAYERS)] for i in range(MAX_PLAYERS): self.players[i].holeCards = [] # calculate the remaining players and deal them the hole cards for i in range(MAX_PLAYERS): if self.players[i].stack != 0: self.activePlayers[i] = 1 self.blindIndex = int(self.roundsPlayed / HANDS_PER_ROUND) if self.blindIndex > len(BIG_BLINDS) - 1: self.blindIndex = len(BIG_BLINDS) - 1 if ( self.dealer == -1 ): self.dealer = 0 else: self.dealer = self.findNext(self.dealer) self.smallBlind = self.findNext(self.dealer) self.bigBlind = self.findNext(self.smallBlind) self.pots = [] self.pots.append(Pot(0, self.activePlayers.copy())) self.communityCards = [] self.flop = [] self.turn = [] self.river = []
def parse(md): dealer = int(md[0:1]) if dealer < 1 or dealer > 4: raise Exception('Unexpected dealer: ' + md) hands = [] remaining_cards = Deck.cards() for hand_str in md[1:].split(','): if '' == hand_str: hands.append(Hand(remaining_cards)) else: hand = Hand.parse(hand_str) hands.append(hand) for card in hand.cards: remaining_cards.remove(card) if len(hands) != 4: raise Exception('Unexpected number of hands: ' + md) return VugraphMD(dealer, hands)
def save_turn_two_game_state(game, deck, player_two_hand, player_one_hand): """Save the state of the game after player two has made a move. This should signal the end of the game. Args: game: current game the player is playing in. deck: the deck state after the player has drawn cards for the card_id exchange phase. player_two_hand: the final hand player two has after the desired cards have been replaced. player_one_hand: player one's final hand. """ # Save player two's final hand hand = Poker.serialize_hand(player_two_hand) final_hand = Hand( player=game.player_two, game=game.key, hand=hand, state=str(HandState.ENDING) ) final_hand.put() # Check game outcome and send email to players with results. game_outcome = Poker.game_outcome(player_one_hand, player_two_hand) game.game_over = True game.active_player = None if game_outcome == 0: game.winner = None elif game_outcome == 1: game.winner = game.player_one else: game.winner = game.player_two game.deck = deck.serialize() game.put() taskqueue.add( url='/tasks/send_game_result_email', params={ 'game_key': game.key.urlsafe() }, transactional=True )
def post(self): """Send an email to a User that it is their turn.""" user = get_by_urlsafe(self.request.get('user_key'), User) game = get_by_urlsafe(self.request.get('game_key'), Game) player_hand = Hand.query( ndb.AND( Hand.player == user.key, Hand.game == game.key, Hand.state == HandState.STARTING.name ) ).get() if not player_hand: raise endpoints.NotFoundException( 'Hand not found for player key {0} and game key {1}'.format( user.key, game.key ) ) hand = json.loads(player_hand.hand) cards = [Card(name=card['name'], suit=card['suit']) for card in hand] hand_information = '' for card in cards: hand_information += 'Card: {0}\nCard Id: {1}\n\n'.format( repr(card), card.id ) subject = 'Your Turn!' body = ''' Hi {0}! It's your turn current turn to play five card poker! Choose the cards you want to replace, if any, and respond to us. After your move, we will reveal your new hand. After each player makes their move, the game will notify each player the winner by email. May the player with the best hand win! The game key is: {2} Here is your hand: {1} Notice, below each listed card is a "Card Id"; this is what you will use to identify to the server which cards you want to exchange when you make your next move to the server. '''.format(user.name, hand_information, game.key.urlsafe()) print body mail.send_mail( 'noreply@{}.appspotmail.com'.format( app_identity.get_application_id() ), user.email, subject, body )
def new_game(player_one, player_two, game_id): """Creates and returns a new game. Args: player_one: A key representing player one. player_two: A key representing player two. game_id: A string representing a game_id for generating a Game.key. Returns: A game detailing the players, the active player, and the deck. """ game_key = ndb.Key(Game, game_id) game = Game( key=game_key, player_one=player_one, player_two=player_two, active_player=player_one, game_over=False ) deck = Deck() deck.shuffle() # Deal out each player's starting hand player_one_hand = Poker.serialize_hand(deck.draw(5)) hand = Hand( player=player_one, game=game.key, hand=player_one_hand, state=str(HandState.STARTING) ) hand.put() player_two_hand = Poker.serialize_hand(deck.draw(5)) hand = Hand( player=player_two, game=game.key, hand=player_two_hand, state=str(HandState.STARTING) ) hand.put() game.deck = deck.serialize() game.put() # Send email to active player signaling the start of the game taskqueue.add( url='/tasks/send_move_email', params={ 'game_key': game.key.urlsafe(), 'user_key': game.active_player.urlsafe() }, transactional=True ) return game
def test_parse_valid(self): self.assertEqual(str(Hand.parse('sakqjt98765432')), 's23456789tjqka') self.assertEqual(str(Hand.parse('s23456789tjqka')), 's23456789tjqka') self.assertEqual(str(Hand.parse('sqh269d347qkc34qk')), 'c34qkd347qkh269sq') self.assertEqual(str(Hand.parse('SAKQJT98765432')), 's23456789tjqka') self.assertEqual(str(Hand.parse('SQH269D347QKC34QK')), 'c34qkd347qkh269sq') self.assertEqual(str(Hand.parse('saskhqhjdtd9d8c7c6c5s4s3h2')), 'c567d89th2jqs34ka')
def get_user_hand(self, request): """Get player's most recent hand state for a given game.""" game = get_by_urlsafe(request.game_urlsafe_key, Game) player = User.query(User.name == request.player).get() if not player: raise endpoints.NotFoundException( '{0} does not exist!'.format(request.player) ) if game.player_one != player.key and game.player_two != player.key: raise endpoints.ForbiddenException( '{0} is not part of this game!'.format(request.player) ) def get_card_form(hand): card_forms = [] hand = Poker.load_player_hand(hand.hand) for card in hand: card_forms.append( CardForm(name=card.name, suit=card.suit, card_id=card.id) ) return card_forms cards = [] state = 'STARTING' hands = Hand.query( Hand.game == game.key, Hand.player == player.key ).fetch() if len(hands) == 1: cards = get_card_form(hands[0]) else: state = 'ENDING' for hand in hands: if hand.state == HandState.ENDING.name: cards = get_card_form(hand) return PlayerHandForm( name=player.name, cards=cards, state=state )
def test_init(self): cards = [ Card('s', '7'), Card('s', '6'), Card('s', '4'), Card('s', '3'), Card('h', 'a'), Card('h', 'k'), Card('h', 't'), Card('d', 'q'), Card('d', 'j'), Card('d', '8'), Card('c', 't'), Card('c', '5'), Card('c', '2') ] hand = Hand(cards) self.assertEqual(len(hand.cards), 13) # cards are re-ordered from lowest to highest self.assertEqual(hand.cards[0], Card('c', '2')) self.assertEqual(hand.cards[-1], Card('s', '7')) # cards are sorted into suits in the dict self.assertEqual(len(hand.card_dict['c']), 3) self.assertEqual(Card('c', '2'), hand.card_dict['c'][0]) self.assertEqual(Card('c', '5'), hand.card_dict['c'][1]) self.assertEqual(Card('c', 't'), hand.card_dict['c'][2]) self.assertEqual(len(hand.card_dict['d']), 3) self.assertEqual(Card('d', '8'), hand.card_dict['d'][0]) self.assertEqual(Card('d', 'j'), hand.card_dict['d'][1]) self.assertEqual(Card('d', 'q'), hand.card_dict['d'][2]) self.assertEqual(len(hand.card_dict['h']), 3) self.assertEqual(Card('h', 't'), hand.card_dict['h'][0]) self.assertEqual(Card('h', 'k'), hand.card_dict['h'][1]) self.assertEqual(Card('h', 'a'), hand.card_dict['h'][2]) self.assertEqual(len(hand.card_dict['s']), 4) self.assertEqual(Card('s', '3'), hand.card_dict['s'][0]) self.assertEqual(Card('s', '4'), hand.card_dict['s'][1]) self.assertEqual(Card('s', '6'), hand.card_dict['s'][2]) self.assertEqual(Card('s', '7'), hand.card_dict['s'][3])
def post(self): """Send an email to the players to notify them the game results.""" game = get_by_urlsafe(self.request.get('game_key'), Game) player_one_hand = Hand.query( ndb.AND( Hand.player == game.player_one, Hand.game == game.key, Hand.state == HandState.ENDING.name ) ).get() if not player_one_hand: raise endpoints.NotFoundException( 'Hand not found for player key {0} and game key {1}'.format( game.player_one, game.key ) ) player_two_hand = Hand.query( ndb.AND( Hand.player == game.player_two, Hand.game == game.key, Hand.state == HandState.ENDING.name ) ).get() if not player_two_hand: raise endpoints.NotFoundException( 'Hand not found for player key {0} and game key {1}'.format( game.player_two, game.key ) ) player_one = game.player_one.get() hand = json.loads(player_one_hand.hand) cards = [Card(name=card['name'], suit=card['suit']) for card in hand] p1_hand_information = '' for card in cards: p1_hand_information += 'Card: {0}\n'.format(repr(card)) player_two = game.player_two.get() hand = json.loads(player_two_hand.hand) cards = [Card(name=card['name'], suit=card['suit']) for card in hand] p2_hand_information = '' for card in cards: p2_hand_information += 'Card: {0}\n'.format(repr(card)) subject = 'It''s a tie!' if game.winner == game.player_one: subject = '{0} Wins'.format(player_one.name) elif game.winner == game.player_two: subject = '{0} Wins!'.format(player_two.name) body = ''' Game finished! {0} {1}'s hand: {2} {3}'s hand: {4} '''.format( subject, player_one.name, p1_hand_information, player_two.name, p2_hand_information ) print body mail.send_mail( 'noreply@{}.appspotmail.com'.format( app_identity.get_application_id() ), player_one.email, subject, body ) mail.send_mail( 'noreply@{}.appspotmail.com'.format( app_identity.get_application_id() ), player_two.email, subject, body )