def test_cards_of_same_suit_all_same_suit(self): from Game.Hand import Hand from Game.Card import Card hand = Hand() hand.append(Card(Card.Diamonds, Card.Jack)) hand.append(Card(Card.Diamonds, Card.Queen)) hand.append(Card(Card.Diamonds, Card.King)) self.assertEqual(len(hand.cards_of_same_suit(Card.Diamonds)), 3)
def test_cards_of_same_suit_no_mathces(self): from Game.Hand import Hand from Game.Card import Card hand = Hand() hand.append(Card(Card.Diamonds, Card.Jack)) hand.append(Card(Card.Diamonds, Card.Queen)) hand.append(Card(Card.Diamonds, Card.Queen)) self.assertEqual( hand.cards_of_same_suit(Card.Clubs, Card.Ace), [])
def test_cards_of_same_suit_1_greater_than(self): from Game.Hand import Hand from Game.Card import Card hand = Hand() hand.append(Card(Card.Diamonds, Card.Jack)) hand.append(Card(Card.Diamonds, Card.Queen)) card = Card(Card.Diamonds, Card.Ace) hand.append(card) self.assertEqual( hand.cards_of_same_suit(Card.Diamonds, Card.King)[0], card)
def __init__(self): super().__init__() for cardKey in Card.Values.keys(): for suitKey in Card.Suits.keys(): self.append(Card(suitKey, cardKey))
def testNonCardType(self): try: card = Card(1, 5) except: pass else: self.fail()
def __init__(self, game_controller, player): self.game = game_controller self.player = player self.opponent = self.game.get_other_player(self.player) self.window = Tk() self._player_cards = {} self._oppenent_cards = {} for i in range(5): self._player_cards[i] = GUICard() self._oppenent_cards[i] = GUICard() self._trump_card = GUICard() self._deck = GUICard() self._leader_card = GUICard() self._follower_card = GUICard() self._close_deck_button = None self._player_swap_trump_button = None self._player_points_label = None self._opponent_points_label = None self._trump_suit_label = None self._card_back = Card(Card.Back, 0) self.__build_play_space() # This feels hacky: self.game.on_event_callback_card_played = self.__callback_cards_played self._cheat_mode = False
def test_notinlist(self): try: card = Card("4", "5") except: pass else: self.fail()
def __init__(self): self.level_suit = ["Diamond", "Spade", "Heart", "Club"] self.level_value = [2, 3, 4, 5, 6, 7, 8, 9, 10, "Jack", "Queen", "King", "Ace"] self.lst_cards = [] for i in self.level_value: for z in self.level_suit: card = Card(i, z) self.lst_cards += [card]
def test_available_marriages_no_marriages(self): from Game.Deck import Card from Game.Hand import Hand hand = Hand() hand.append(Card(Card.Diamonds, Card.Ten)) hand.append(Card(Card.Diamonds, Card.King)) hand.append(Card(Card.Clubs, Card.Ace)) hand.append(Card(Card.Hearts, Card.King)) hand.append(Card(Card.Clubs, Card.King)) expected_marriage = [] result, marriage = hand.available_marriages() self.assertEqual(result, False) self.assertEqual(expected_marriage, marriage)
def test_available_marriages_out_of_order(self): from Game.Deck import Card from Game.Hand import Hand hand = Hand() hand.append(Card(Card.Diamonds, Card.Jack)) hand.append(Card(Card.Diamonds, Card.King)) hand.append(Card(Card.Diamonds, Card.Ace)) hand.append(Card(Card.Diamonds, Card.Ten)) hand.append(Card(Card.Diamonds, Card.Queen)) expected_marriage = [Card.Diamonds] result, marriage = hand.available_marriages() self.assertEqual(result, True) self.assertEqual(expected_marriage, marriage)
class TestCard(TestCase): def setUp(self): self.card = Card("4", "♠") self.other1 = Card("3", "♦") self.other3 = Card("5", "♣") self.other4 = Card("4", "♥") self.other2 = Card("4", "♦") #בודקת האם הוא מגדיר את הערכים נכון def testValue(self): self.assertTrue("4" == self.card.value) #בודק האם הוא מגדיר את הסוג נכון def testSuits(self): self.assertTrue("♠" == self.card.suit) #בודק שהוא מעלה value error כאשר הערכים הם לא ברשימת ערכים def testNonCardType(self): try: card = Card(1, 5) except: pass else: self.fail() #מתדוה הבודקת כאשר הtype הוא סטרינג והוא לא ברשימה def test_notinlist(self): try: card = Card("4", "5") except: pass else: self.fail() #בודק ש__ge__ מחזיק true כאשר הערך יותר גדול def testge1(self): self.assertTrue(self.card > (self.other2)) # בודק ש__ge__ מחזיר true כאשר הערך שווה והסוג גדול יותר def testge2(self): self.assertTrue(self.card > (self.other1)) # בודק ש__ge__ מחזיר false כאשר הערך יותר קטן def testge3(self): self.assertFalse(self.card > (self.other3)) # בודק ש__ge__ מחזיר true כאשר הערך יותר גדול def testge4(self): self.assertFalse(self.card > (self.other4)) #פונקציה הבודקת את הrepr def testRepr(self): self.assertTrue("4♠" == self.card.__repr__())
def test_set_Hand1(self): dcards = DeckOfCards() dcards.deckcards.clear() card = Card("4", "♣") for i in range(0, 4): dcards.deckcards.append(card) self.player.cards.clear() try: self.player.setHand(dcards) except: pass else: self.fail()
def encode_played(played: Card): m, i = played.get_raw() return (m - 1) * 4 + i
class IOHelpers: deck_closed_key = -1 my_points_to_victory_key = -2 my_unearned_points_key = -3 opponents_points_to_victory_key = -4 opponents_unearned_points_key = -5 match_points_on_offer_to_me_key = -6 match_points_on_offer_to_opponent_key = -7 # Make a static list of actions for performance. These should be used for reference only and not passed to the game engine d_marriage = Marriage(None, Card(Card.Diamonds, Card.Queen), Card(Card.Diamonds, Card.King)) s_marriage = Marriage(None, Card(Card.Spades, Card.Queen), Card(Card.Spades, Card.King)) h_marriage = Marriage(None, Card(Card.Hearts, Card.Queen), Card(Card.Hearts, Card.King)) c_marriage = Marriage(None, Card(Card.Clubs, Card.Queen), Card(Card.Clubs, Card.King)) output_actions = {} # Cards output_actions[0] = Action(card=Card(Card.Diamonds, Card.Jack), marriage=None, swap_trump=False, close_deck=False) output_actions[1] = Action(card=Card(Card.Diamonds, Card.Queen), marriage=None, swap_trump=False, close_deck=False) output_actions[2] = Action(card=Card(Card.Diamonds, Card.King), marriage=None, swap_trump=False, close_deck=False) output_actions[3] = Action(card=Card(Card.Diamonds, Card.Ten), marriage=None, swap_trump=False, close_deck=False) output_actions[4] = Action(card=Card(Card.Diamonds, Card.Ace), marriage=None, swap_trump=False, close_deck=False) output_actions[5] = Action(card=Card(Card.Spades, Card.Jack), marriage=None, swap_trump=False, close_deck=False) output_actions[6] = Action(card=Card(Card.Spades, Card.Queen), marriage=None, swap_trump=False, close_deck=False) output_actions[7] = Action(card=Card(Card.Spades, Card.King), marriage=None, swap_trump=False, close_deck=False) output_actions[8] = Action(card=Card(Card.Spades, Card.Ten), marriage=None, swap_trump=False, close_deck=False) output_actions[9] = Action(card=Card(Card.Spades, Card.Ace), marriage=None, swap_trump=False, close_deck=False) output_actions[10] = Action(card=Card(Card.Hearts, Card.Jack), marriage=None, swap_trump=False, close_deck=False) output_actions[11] = Action(card=Card(Card.Hearts, Card.Queen), marriage=None, swap_trump=False, close_deck=False) output_actions[12] = Action(card=Card(Card.Hearts, Card.King), marriage=None, swap_trump=False, close_deck=False) output_actions[13] = Action(card=Card(Card.Hearts, Card.Ten), marriage=None, swap_trump=False, close_deck=False) output_actions[14] = Action(card=Card(Card.Hearts, Card.Ace), marriage=None, swap_trump=False, close_deck=False) output_actions[15] = Action(card=Card(Card.Clubs, Card.Jack), marriage=None, swap_trump=False, close_deck=False) output_actions[16] = Action(card=Card(Card.Clubs, Card.Queen), marriage=None, swap_trump=False, close_deck=False) output_actions[17] = Action(card=Card(Card.Clubs, Card.King), marriage=None, swap_trump=False, close_deck=False) output_actions[18] = Action(card=Card(Card.Clubs, Card.Ten), marriage=None, swap_trump=False, close_deck=False) output_actions[19] = Action(card=Card(Card.Clubs, Card.Ace), marriage=None, swap_trump=False, close_deck=False) # Marriages output_actions[20] = Action(card=Card(Card.Diamonds, Card.Queen), marriage=d_marriage, swap_trump=False, close_deck=False) output_actions[21] = Action(card=Card(Card.Diamonds, Card.King), marriage=d_marriage, swap_trump=False, close_deck=False) output_actions[22] = Action(card=Card(Card.Spades, Card.Queen), marriage=s_marriage, swap_trump=False, close_deck=False) output_actions[23] = Action(card=Card(Card.Spades, Card.King), marriage=s_marriage, swap_trump=False, close_deck=False) output_actions[24] = Action(card=Card(Card.Hearts, Card.Queen), marriage=h_marriage, swap_trump=False, close_deck=False) output_actions[25] = Action(card=Card(Card.Hearts, Card.King), marriage=h_marriage, swap_trump=False, close_deck=False) output_actions[26] = Action(card=Card(Card.Clubs, Card.Queen), marriage=c_marriage, swap_trump=False, close_deck=False) output_actions[27] = Action(card=Card(Card.Clubs, Card.King), marriage=c_marriage, swap_trump=False, close_deck=False) #Special Actions output_actions[28] = Action(card=None, marriage=None, swap_trump=True, close_deck=False) output_actions[29] = Action(card=None, marriage=None, swap_trump=False, close_deck=True) @staticmethod def card_key(suit, value): # Build a unique int for quicker indexing (hopefully?)] # maybe build these upfront for performance? # e.g. 0 * 20 + 11 for Ace of spades # 1 * 20 + 2 = 22 for Jack of clubs return suit * 20 + value @staticmethod def create_input_from_game_state(game, player): # Make a flat vector of cards each with a state? # Make a convolution grd? # Make something else # # I have: # 20 cards # 1 trump card # up to 5 in a players hand # up to 18 won by a player # up to 5 that I know are in the opponents hand # Deck closed # Which marriages could be available # Un-beatable cards (?) # # Option 1: # Vector for each of the 20 cards: # Value (int) ?? # Suit (int) ?? # my hand (binary) # their hand (binary) # won by me (binary) # won by them (binary) # Is trump (binary) # # Trump suit (int) # Deck is closed (binary) # My pts to victory (int) # My unearned pts (int) # Opp pts to victory (int) # Opp unearned pts (int) # # 20 * 6 + 6 = 126 inputs. Not too bad inputs = {} for suit in [Card.Diamonds, Card.Clubs, Card.Spades, Card.Hearts]: for value in Card.Values.keys(): inputs[IOHelpers.card_key(suit, value)] = CardInput(suit, value) for card in player.hand: card_input = inputs[IOHelpers.card_key(card.suit, card.value)] card_input.in_my_hand = True # for card in game.get_other_player(player).hand - would be cheating!! Would be an interesting test, though! # As is, this handles cases where we know unequivocally that they have part of a marriage or the last 5 cards of the deck for card in player.opponent_hand: card_input = inputs[IOHelpers.card_key(card.suit, card.value)] card_input.in_opponent_hand = True for card in player.cards_won: card_input = inputs[IOHelpers.card_key(card.suit, card.value)] card_input.won_by_me = True for card in player.opponent_cards_won: card_input = inputs[IOHelpers.card_key(card.suit, card.value)] card_input.won_by_opponent = True lead_card = game.leading_card if lead_card is not None: inputs[IOHelpers.card_key(lead_card.suit, lead_card.value)].is_leading_card = True inputs[IOHelpers.deck_closed_key] = 1 if game.deck_closed else 0 inputs[ IOHelpers. my_points_to_victory_key] = game.match_point_limit - player.game_points inputs[IOHelpers.my_unearned_points_key] = 0 inputs[ IOHelpers. opponents_points_to_victory_key] = game.match_point_limit - player.opponent_game_points inputs[IOHelpers.opponents_unearned_points_key] = 0 inputs[IOHelpers.match_points_on_offer_to_me_key] = 0 inputs[IOHelpers.match_points_on_offer_to_opponent_key] = 0 # I now have all the data I need. Now to convert it into something useful. # Flat vector is simplest. Or do some clever CNN? # Simple flat vector to start with... return IOHelpers.__create_flat_tensor(inputs, game) @staticmethod def __create_flat_tensor(inputs, game): # (With performance in mind, it'd be better to create the tensor elements directly instead of using a list but hey...) input_vector = [] for item in inputs.values(): if type(item) is CardInput: input_vector.append(item.suit / 3) #Normalise suit value input_vector.append( item.value / game.game_point_limit ) #Normalise card value to fraction of a game input_vector.append(item.in_my_hand) input_vector.append(item.in_opponent_hand) input_vector.append(item.won_by_me) input_vector.append(item.won_by_opponent) input_vector.append(item.is_leading_card) input_vector.append(inputs[IOHelpers.deck_closed_key]) input_vector.append(inputs[IOHelpers.my_points_to_victory_key] / game.game_point_limit) input_vector.append(inputs[IOHelpers.opponents_points_to_victory_key] / game.game_point_limit) # input_vector.append(inputs[IOHelpers.my_unearned_points_key] / game.game_point_limit) # input_vector.append(inputs[IOHelpers.opponents_unearned_points_key] / game.game_point_limit) # input_vector.append(inputs[IOHelpers.match_points_on_offer_to_me_key]) # input_vector.append(inputs[IOHelpers.match_points_on_offer_to_opponent_key]) return torch.tensor(input_vector, dtype=torch.float) @staticmethod def check_action_legal(i, legal_actions): is_legal = False return_action = None output_action = IOHelpers.output_actions[i] for action in legal_actions: if output_action == action: is_legal = True return_action = action break return is_legal, return_action @staticmethod def get_index_for_action(action): for i, output_action in IOHelpers.output_actions.items(): if action == output_action: return i @staticmethod def get_random_legal_action(game, player): player.evaluate_legal_actions(game.leading_card) action = random.choice(player.legal_actions) i = IOHelpers.get_index_for_action(action) return torch.tensor([i], dtype=torch.long), action @staticmethod def get_legal_actions(game, player): player.evaluate_legal_actions(game.leading_card) legal_moves = [] legal_actions = [] for i, item in enumerate(IOHelpers.output_actions): is_legal, action = IOHelpers.check_action_legal( i, player.legal_actions) legal_moves.append(is_legal) legal_actions.append(action) return torch.tensor(legal_moves, dtype=torch.bool), legal_actions # Pick an action based on values. Ignore illegal moves # convert it into an actual action @staticmethod def policy(q_values, game, player): legal_mask, legal_actions = IOHelpers.get_legal_actions(game, player) # set all illegal moves to a quality value of -100 # this is more than a little hacky but in reality filters out illegal moves sufficiently q_values[~legal_mask] = -100 _, indices = q_values.max(0) selected_action = legal_actions[indices] selected_action_id = indices.unsqueeze(0) if selected_action is None: raise Exception('No valid action found') return selected_action_id, selected_action # 3D policy implementation @staticmethod def policy_batch(q_values, legal_mask): # this is hack as hell but works. q_values[~legal_mask] = -100 return q_values.max(1)[0].detach()
def __init__(self): self._cards = [] for m in Const.cards: for i in range(len(Const.cards[m])): self._cards.append(Card(m, i))
def play(player: Player, board: Board, my_score: Score, opp_score: Score): for card in player._cards: m, _ = card.get() if len(board._board[m]) > 0: index = player._cards.index(card) return player.play(index) cards = copy.deepcopy(player._cards) cards.sort() recurrent_score = [] my_jum = sum(Calculator.calculate(my_score)) opp_jum = sum(Calculator.calculate(opp_score)) appeared_card = [] for t in Const.types: appeared_card.extend(my_score.get(t)) appeared_card.extend(opp_score.get(t)) appeared_card.sort() for i, card in enumerate(cards): score = 0 if (i != 0 and cards[i]._month == cards[i - 1]._month) or ( i != len(cards) - 1 and cards[i]._month == cards[i + 1]._month): score += 100 if card._month in [5, 7, 10, 12]: score += 1 ms = copy.deepcopy(my_score) os = copy.deepcopy(opp_score) scored_cards = [] for idx in range(4): scored_cards.append(Card(card._month, idx)) os.add(cards) updated_opp_jum = sum(Calculator.calculate(os)) if opp_jum < Const.go_score <= updated_opp_jum: score -= 1000 elif updated_opp_jum > opp_jum: score -= 100 potential_score = [] for idx in range(4): potential_score.append(Card(card._month, idx)) ms.add(cards) updated_my_jum = sum(Calculator.calculate(ms)) if my_jum < updated_my_jum: score -= 10 * (21 - (2 * len(player._cards))) temp = 30 for appeared in appeared_card: m, _ = appeared.get() if m == card._month: temp = 0 score += temp recurrent_score.append(score) m = max(recurrent_score) selected = [i for i, v in enumerate(recurrent_score) if v == m] selected = selected[random.randint(0, len(selected) - 1)] card = cards[selected] index = player.find_index(card._month, card._index) return player.play(index)
def setUp(self): self.card = Card("4", "♠") self.other1 = Card("3", "♦") self.other3 = Card("5", "♣") self.other4 = Card("4", "♥") self.other2 = Card("4", "♦")
def __init__(self): self._cards = [ Card(rank, suit) for suit in self.SUITS for rank in self.RANKS ]
def test_add_card2(self): card = Card("4", "♣") amount = self.player.cardamount self.player.addCard(card) self.assertTrue(amount + 1 == self.player.cardamount) self.assertIn(card, self.player.cards)
def give_cards(self, musik): for card in musik: self.players[self.round.current_player].set_card_in_hand( Card(card["filename"].split('/').pop()[:-4], card["rank"], card["suit"], card["value"]))
def startCards(self): for i in self.values: for j in self.suits: card = Card(i, j) self.deckcards.append(card)
def getOptions(hand, piles, requiredPoints): options = [] typeOptions = [] # options.append([]) # we need to give the option of doing nothing inPiles = {} notInPiles = {} wilds = {} # first let's split the cards we have in our hand into two different parts, # the cards that are in piles on the table, and the cards that aren't for handPile in hand.getTypes(): # see if this is in piles if handPile == 'R' or handPile == '2': wilds[handPile] = hand.getCardCount(handPile) elif handPile in piles: inPiles[handPile] = hand.getCardCount(handPile) else: notInPiles[handPile] = hand.getCardCount(handPile) # now, have we already laid down the required amount? canLay = len(piles) > 0 if canLay == True: # there are piles already on the table, do we have any we can lay down? if(len(inPiles) > 0): # sweet, we have some cards in our hand that are on the table, we can lay them down # give the option to lay down only one type, or all if more than one # TODO: give all options (if three cardTypes can be laid down, give options: [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]) for cardType, count in inPiles.iteritems(): options.append([cardType]) typeOptions.append(cardType) # any clean stuff? for cardType,count in notInPiles.iteritems(): if count > 2: options.append([cardType]) typeOptions.append(cardType) # now dirty # if 'R' in notInPiles or '2' in notInPiles: # # find sets of two and add wilds to them. # for cardType,count in notInPiles.iteritems(): # if count == 2 # can we sprinkle the wilds in? for cardType,count in wilds.iteritems(): typeOptions.append(cardType) if len(typeOptions) >= 2: for i in range(2, len(typeOptions)+1): for x in itertools.combinations(typeOptions, i): option = list(x) if AIPlayer.isJustWilds(option): continue options.append(option) else: # we have to have enough points to lay down # first gather clean options cleanPoints = 0 cleanOptions = [] for cardType,count in notInPiles.iteritems(): if count > 2 and cardType != 'R' and cardType != '2': cleanPoints += Card.getPoints(cardType, count) cleanOptions.append(cardType) # now gather dirty options if cleanPoints >= requiredPoints: canLay = True # cool, so we can lay down cleanly, let's add these to the options for cardType in preOptions: options.append([cardType]) typeOptions.append(cardType) else: # still not enough points, do we have any wilds? if 'R' in notInPiles: points += Card.getPoints('R', notInPiles['R']) if '2' in notInPiles: points += Card.getPoints('2', notInPiles['R']) if points >= requiredPoints: canLay = True # can we lay now? # beforeLayOptions = [] # # get options and points # cleanPoints = 0 # cleanOptions = [] # for cardType,count in notInPiles.iteritems(): # if count > 2 and cardType != 'R' and cardType != '2': # cleanPoints += Card.getPoints(cardType, count) # cleanOptions.append(cardType) # if canLay == False: # if cleanPoints > requiredPoints: # # okay, so we haven't laid down, but we have enough cleanPoints to lay down # options.append(cleanOptions) # canLay = true # else: # # okay, we can't lay down cleanly, but do we have enough to lay down dirty? # if 'R' in notInPiles or '2' in notInPiles: # # we have wilds... iterate over cleanOptions # else: # # there are piles already on the table, we can put what we have into them # if(len(inPiles) > 0): # # yes, we have some cards in our hand that are on the table, we can lay them down # for cardType, count in inPiles.iteritems(): # options.append(cardType) options.append([]) # we need to give the option of doing nothing print "number of options", len(options) print options for i in range(0,len(options)): print "option " + `i+1` for card in options[i]: print card+": "+`hand.getCardCount(card)` print ""