def _possibilities_of_bomb(self, hand_cards, target_cards): result = [] if len(target_cards) == 4 and target_cards[0].rank == target_cards[1].rank == target_cards[2].rank == \ target_cards[3].rank: result += self._possibilities_of_same_rank(hand_cards, target_cards[0], 4) else: result += self._possibilities_of_same_rank(hand_cards, Card(rank=-1), 4) if Card('Uu') in hand_cards and Card('Vv') in hand_cards: result.append({Card('Uu'), Card('Vv')}) return result
def test_player_should_skip(): game = Game(OrderedDict({ 'player1': Player([Card('4d')]), 'player2': Player([Card('2h')]), 'player3': Player([Card('9d')]), }), desk_pool=[Card('9s'), Card('Kc'), Card('Ks'), Card('Kh')]) game.start() assert game.winner == 'player3'
def test_simple_game(): game = Game(OrderedDict({ 'player1': Player([Card('4d'), Card('5c'), Card('5s'), Card('Ah')]), 'player2': Player([Card('2h'), Card('2d')]), 'player3': Player([Card('9d')]), }), desk_pool=[]) game.start() assert game.winner == 'player2'
def test_only_straight_win(): game = Game(OrderedDict({ 'player1': Player([Card('4d'), Card('5c'), Card('6s'), Card('7h'), Card('8d')]), 'player2': Player([Card('2h'), Card('2d')]), 'player3': Player([Card('9d')]), }), desk_pool=[]) game.start() if game.winner == 'player1': # The winning way is the straight assert len(game.history[0][1]) == 5 else: assert game.winner == 'player2'
def possibilities(self, desk_cards, hand_cards): """ List possibilities according to the cards in desk and cards in hands :param desk: a list of Card :param hand: a list of Card :return: a list of set of Card """ desk_cards.sort() hand_cards.sort() # No one is higher than the super bomb if Card('Vv') in desk_cards and Card('Uu') in desk_cards: return [] result = self._possibilities_of_bomb(hand_cards, desk_cards) if len(desk_cards) == 1: for card in hand_cards: if self.higher(card, desk_cards[0]): result.append({card}) elif len(desk_cards) == 2: assert desk_cards[0].rank == desk_cards[1].rank result += self._possibilities_of_same_rank(hand_cards, desk_cards[0], 2) elif len(desk_cards) == 3: assert desk_cards[0].rank == desk_cards[1].rank == desk_cards[ 2].rank result += self._possibilities_of_same_rank(hand_cards, desk_cards[0], 3) elif len(desk_cards) == 4: if desk_cards[0].rank == desk_cards[1].rank == desk_cards[ 2].rank == desk_cards[3].rank: # This is a bomb, we have got all the possible bombs, so we just do nothing here pass else: # Three same cards with one single card # Pick the second card as target card, as the type could be AAAB or ABBB three_same = self._possibilities_of_same_rank( hand_cards, desk_cards[1], 3) for possibility in three_same: for card in hand_cards: if card not in possibility: result.append({*possibility, card}) elif len(desk_cards) == 5: if desk_cards[0].rank == desk_cards[1].rank: # Full house # Pick the third card as target card, as the type could be AABBB or AAABB three_same = self._possibilities_of_same_rank( hand_cards, desk_cards[2], 3) two_same = self._possibilities_of_same_rank( hand_cards, Card(rank=-1), 2) for p in three_same: for q in two_same: if next(iter(p)).rank != next(iter(q)).rank: result.append({*p, *q}) else: # Straight result += self._possibilities_of_straight(hand_cards, desk_cards[0], length=5) else: result += self._possibilities_of_straight(hand_cards, desk_cards[0], length=len(desk_cards)) return result
win_rate_frequency, float(ai_win) / float(win_rate_frequency))) ai_win = 0 # end of game print('game over') if __name__ == "__main__": scenario = 2 if scenario == 1: players = OrderedDict({ 'player1': AIPlayer( [Card('2s'), Card('3d'), Card('3h'), Card('3c'), Card('4d')]), 'player2': Player([Card('As'), Card('2d'), Card('5h')]), 'player3': Player([Card('Ks'), Card('6d'), Card('6h'), Card('6s')]), }) train(players, desk_pool=[]) elif scenario == 2: p1 = '3s,3d,5s,5h,6s,6d,6h,2s,2d,2h,4s' p2 = 'Ks,Kd,Kc,9s,9d,Vv' p3 = 'Jc,Jd,Jh,2c'
if replay_game: game.replay() if (episode + 1) % win_rate_frequency == 0: print('AI win rate for last {0} rounds: {1}'.format(win_rate_frequency, float(ai_win) / float(win_rate_frequency))) ai_win = 0 if __name__ == "__main__": scenario = 2 if scenario == 1: players = OrderedDict({ 'player1': AIPlayer([Card('2s'), Card('3d'), Card('3h'), Card('3c'), Card('4d')]), 'player2': Player([Card('As'), Card('2d'), Card('5h')]), 'player3': Player([Card('Ks'), Card('6d'), Card('6h'), Card('6s')]), }) train(players, desk_pool=[]) elif scenario == 2: p1 = '3s,3d,5s,5h,6s,6d,6h,2s,2d,2h,4s' p2 = 'Ks,Kd,Kc,9s,9d,Vv' p3 = 'Jc,Jd,Jh,2c' # train(OrderedDict({ # 'p1': AIPlayer([Card(s) for s in p1.split(',')]), # 'p2': Player([Card(s) for s in p2.split(',')]), # 'p3': Player([Card(s) for s in p3.split(',')]), # }), desk_pool=[], rounds=5000, win_rate_frequency=20, replay_game=False) play(OrderedDict({ 'p1': DQNPlayer([Card(s) for s in p1.split(',')], model_name='ai-01'),
def test_four_same_card_in_hand(): desk = [Card('As'), Card('Ah'), Card('Ac'), Card('2d'), Card('2c')] hand = [ Card('9d'), Card('9h'), Card('9c'), Card('Uu'), Card('Ad'), Card('9s'), Card('2h') ] assert [{Card('9d'), Card('9h'), Card('9c'), Card('9s')}] == LandlordRule().possibilities(desk, hand)
def test_single_card_in_desk(): assert LandlordRule().possibilities( [Card('Uu')], [Card('Vv'), Card('5c')]) == [{Card('Vv')}] assert LandlordRule().possibilities( [Card('Ks')], [Card('2h'), Card('5c')]) == [{Card('2h')}] assert LandlordRule().possibilities([Card('2s')], [Card('2h'), Card('5c')]) == [] assert LandlordRule().possibilities([Card('Ks')], [Card('Jh'), Card('5c')]) == []
def test_four_same_card_aka_bomb_in_desk(): desk = [Card('Js'), Card('Jh'), Card('Jc'), Card('Jd')] hand = [ Card('2s'), Card('Uu'), Card('5c'), Card('2c'), Card('2d'), Card('2h') ] assert {Card('2s'), Card('2c'), Card('2d'), Card('2h')} in LandlordRule().possibilities(desk, hand) desk = [Card('Js'), Card('Jh'), Card('Jc'), Card('Jd')] hand = [ Card('2s'), Card('Uu'), Card('5c'), Card('Ac'), Card('2d'), Card('2h') ] assert [] == LandlordRule().possibilities(desk, hand)
def test_three_same_card_and_one_single_card_in_desk(): # todo: can the single card be joker? desk = [Card('Js'), Card('Jh'), Card('Jc'), Card('As')] hand = [Card('Ks'), Card('Kd'), Card('3c'), Card('Kc'), Card('2d')] assert {Card('Ks'), Card('Kd'), Card('Kc'), Card('3c')} in LandlordRule().possibilities(desk, hand) assert {Card('Ks'), Card('Kd'), Card('Kc'), Card('2d')} in LandlordRule().possibilities(desk, hand) desk = [Card('7d'), Card('Kh'), Card('Kd'), Card('Ks')] hand = [Card('9s'), Card('Ad'), Card('9h'), Card('9c'), Card('Jd')] assert [] == LandlordRule().possibilities(desk, hand)
def test_three_same_card_in_desk(): desk = [Card('Js'), Card('Jh'), Card('Jc')] hand = [Card('2s'), Card('Uu'), Card('5c'), Card('2c'), Card('2d')] assert {Card('2s'), Card('2c'), Card('2d')} in LandlordRule().possibilities(desk, hand)
def test_two_same_card_in_desk(): desk = [Card('Ks'), Card('Kh')] hand = [Card('As'), Card('Uu'), Card('5c'), Card('Ac')] assert {Card('As'), Card('Ac')} in LandlordRule().possibilities(desk, hand)
def test_all_possibilities(): hand = [ Card('As'), Card('Uu'), Card('5c'), Card('Ac'), Card('Ad'), Card('2h'), Card('5h') ] assert {Card('As'), Card('Ac'), Card('Ad'), Card('2h')} in LandlordRule().all_possibilities(hand)
def test_super_bomb_in_hand(): desk = [Card('As'), Card('Ah'), Card('Ac'), Card('Ad')] hand = [ Card('Vv'), Card('Tc'), Card('9c'), Card('Uu'), Card('Ad'), Card('Kh'), Card('2h') ] assert [{Card('Vv'), Card('Uu')}] == LandlordRule().possibilities(desk, hand)
def test_full_house_in_desk(): desk = [Card('Js'), Card('Jh'), Card('Jc'), Card('Kd'), Card('Ks')] hand = [ Card('As'), Card('Uu'), Card('5c'), Card('Ac'), Card('Ad'), Card('2h'), Card('5h') ] assert {Card('As'), Card('Ac'), Card('Ad'), Card('5h'), Card('5c')} in LandlordRule().possibilities(desk, hand) desk = [Card('Js'), Card('Jh'), Card('Jc'), Card('Kd'), Card('Ks')] hand = [ Card('5s'), Card('Uu'), Card('5c'), Card('Ac'), Card('Ad'), Card('2h'), Card('5h') ] assert [] == LandlordRule().possibilities(desk, hand)
def all_possibilities(self, hand_cards): """ List all the possibilities according the cards in hands (assuming the desk is empty). :param hand_cards: a list of Card :return: a list of set of Card """ result = [] # Todo: add more kinds of desk cards # Possibilities without straight assume_desk_cards = [ [Card(rank=-1)], [Card(rank=-1), Card(rank=-1)], [Card(rank=-1), Card(rank=-1), Card(rank=-1)], [Card(rank=-1), Card(rank=-1), Card(rank=-1), Card(rank=-1)], [Card(rank=-1), Card(rank=-1), Card(rank=-1), Card(rank=-2)], [ Card(rank=-1), Card(rank=-1), Card(rank=-1), Card(rank=-2), Card(rank=-2) ], ] for desk_cards in assume_desk_cards: result += self.possibilities(desk_cards, hand_cards) # Possibilities with straight has_straight = True length = 5 while has_straight and length <= len(hand_cards): straight_result = self._possibilities_of_straight(hand_cards, Card(rank=-1), length=length) if not straight_result: break result += straight_result length += 1 return result
def test_five_card_straight_in_desk(): desk = [Card('5s'), Card('6h'), Card('7c'), Card('8d'), Card('9s')] hand = [ Card('Js'), Card('Tc'), Card('Qd'), Card('9c'), Card('Qc'), Card('Ad'), Card('Kh'), Card('2h') ] assert ({ Card('Tc'), Card('Js'), Card('Qc'), Card('Kh'), Card('Ad') } in LandlordRule().possibilities(desk, hand) or { Card('Tc'), Card('Js'), Card('Qd'), Card('Kh'), Card('Ad') } in LandlordRule().possibilities(desk, hand))