Card Game with Dominoes using python Number of players 2 or
Card Game with Dominoes using python
Number of players: 2 or 6
Purpose: The players try to achieve to see who can get the most doubles, fives, or all cards.
Also try to take a double five or even (take all) from the desk.
Card deck: total of 28 cards with dominoes
Deal: 3 cards are given to a player if there are two players. If there are six players then its 2 cards. After that place 4 cards faced up on the desk and the rest of the cards put on the side for later use.
How to play:
First players starts by playing one card, and if the player has a card that has same one number on one or more cards on the desk and the summation of those other numbers on the player\'s card and the card or cards on the desk equals a multiple of 5, this means these cards could be taken and placed face-down on the player’s side. Example of this is shown on the figure, so if a player has the 4:1 in his hand and the cards with 4:4, 4:5 and 4:0 was on the desk, these cards can be taken because the card has the number 4\'s they are same and also the sum of the other numbers such as 1+4+0+5=10, this is a multiple of 5. Now for taking doubles, it is similar. For example using the figure, suppose the player has the 5:5 card that player can take the 0:0 card also the summation of those cards will be 5+0=5, which is a multiple of 5. Now what If the player took all the cards on the desk, this is called (take all), the player would face up one of his cards and mark it. Also, the next player would also lay a card on the desk. Now if any of the players cannot see either a same or take any cards, then the player must place a card face up on the desk. These cards that are being placed on the desk can be taken by other players too. After performing the first deal of each hand, so suppose the face up cards as a group of 4 or are as two pairs have one number in common/similarity and the summation of those other numbers is a multiple of 5, the dealer takes all of the cards and scores a point for a sweep. When all the players are do not have any cards, the dealer will give 3 more cards will be given to each player from the card deck. On the final round there could only be 2 cards left.
Special Instructions:
How to score--after having no cards on hand, 1 point is given to the players with the max amount doubles, five\'s, and cards itself.
1 point is given to players who did per (take all) and also 1 point for any double five.
How do you know who won the game: The players who gets to 10 or 15 points wins the game
If there are 5 players playing: Put only 3 cards on the desk during beginning of the game.
Actions: Finished(This part is finished you can check in the def actions(self, agent):) So the below instructions are just to give an idea for the next part.
Define Actions: when beginning to create a adversarial search would be to generate all correct actions or in our case plays. And then do a heuristic to order all the explorations. So given in the python code below
Using the actions() function, we need it so that it returns a list of lists, where each embedded list represents a legal action (a play the agent can make) and the set of all of those lists is complete (it includes every possible action that is legal according to the rules of the game; the list should not just be the single best play – that will be selected as part of the implementation of the Minimax algorithm in a subsequent part of this homework). The key data structures required for this task are the agent’s (player’s) hand and the desk (the dominos face-up on the desk). Each of these is represented as a list of tuples (specifically, pairs), where a pair represents a single domino (or card) by indicating the two pip counts of the domino, ranging from zero to six. See the code for details. Each action list should start with the pair representing the domino from the player’s hand that is to be played. When the action is a discard, this will be the only pair in the list. When the domino is being used to take other dominos from the desk, the card from the hand should be followed in the list by n pairs representing the n dominos to be taken from the desk.
Code: need to implement the def minimax, min_play, max_play
import random
from random import shuffle
import itertools
import sys
import ast
def count_fives(lst):
count = 0
for l in lst:
if 5 in l:
count += 1
return count
def is_pair_match(t1, t2):
x, y = t1
Flag = False
if x not in t2 and y not in t2:
return False
else:
if x in t2:
e = t2[0] if t2.index(x) == 1 else t2[1]
Flag = True if (e + y) % 5 == 0 else False
else:
e = t2[0] if t2.index(y) == 1 else t2[1]
Flag = True if (e + x) % 5 == 0 else False
return Flag
def check_all_sum(table):
x, y = table[0]
flag = False if x == y else True
sum1, sum2 = y, x
xc, yc = 1, 1
for i in range(1, len(table)):
if x in table[i]:
xc += 1
elem = table[i][0] if table[i].index(x) == 1 else table[i][1]
sum1 = sum1 + elem
if not flag and table[i][0] == table[i][1]:
xc += 1
yc += 1
sum1 = sum1 + table[i][0]
sum2 = sum2 + table[i][0]
if flag and y in table[i]:
yc += 1
elem = table[i][0] if table[i].index(y) == 1 else table[i][1]
sum2 = sum2 + elem
if xc == len(table) and sum1 % 5 == 0:
return True
elif yc == len(table) and sum2 % 5 == 0:
return True
else:
return False
def check_pairs(table):
pairs_list = []
no_pair_list = []
for j in range(1, len(table)):
if is_pair_match(table[0], table[j]):
pairs_list.append(table[j])
else:
no_pair_list.append(table[j])
if len(pairs_list) == 0:
return False
elif len(pairs_list) == 1:
return is_pair_match(no_pair_list[0], no_pair_list[1])
elif len(pairs_list) == 3:
if is_pair_match(pairs_list[0], pairs_list[2]):
return True
else:
return is_pair_match(pairs_list[0], pairs_list[2])
else:
if is_pair_match(no_pair_list[0], pairs_list[0]):
return True
elif is_pair_match(no_pair_list[0], pairs_list[1]):
return True
else:
return False
class Agent:
def __init__(self, hand, role):
self.hand = hand
self.collected = []
self.role = role
class Game:
def __init__(self, size):
hand = []
for i in range(0, size + 1):
for j in (s for s in range(0, size + 1) if s >= i):
hand.append((i, j))
shuffle(hand)
self.table = hand[:4]
self.player = Agent(hand[4:7], \'player\')
self.computer = Agent(hand[7:10], \'computer\')
self.player_sweep = 0
self.computer_sweep = 0
self.picked_last=\"\"
def checkInitalTable(self, dealer):
sweep = check_pairs(self.table)
if not sweep:
sweep = check_all_sum(self.table)
if sweep:
if dealer.role == \'player\':
self.player_sweep += 1
else:
self.computer_sweep += 1
dealer.collected.extend(self.table)
self.table = []
if len(self.table) == 0:
return True
return False
def actions(self, agent):
finallist = []
for pcard in agent.hand:
xlist = []
ylist = []
doubles = []
x, y = pcard
for i in self.table:
if x in i:
xlist.append(i)
elif not x == y and y in i:
ylist.append(i)
elif x == y and i[0] == i[1]:
doubles.append(i)
finalxlist = []
finalylist = []
finaldoubleslist = []
for L in range(0, len(doubles) + 1):
for subset in itertools.combinations(doubles, L):
if not len(subset) == 0:
# print subset
sum = x
for curr in list(subset):
sum += curr[0]
if sum % 5 == 0:
finaldoubleslist.append([pcard] + list(subset))
for L in range(0, len(xlist) + 1):
for subset in itertools.combinations(xlist, L):
if not len(subset) == 0:
sum = y
for curr in list(subset):
# print list(subset)
e = curr[0] if curr.index(x) == 1 else curr[1]
sum += e
if sum % 5 == 0:
finalxlist.append([pcard] + list(subset))
for L in range(0, len(ylist) + 1):
for subset in itertools.combinations(ylist, L):
if not len(subset) == 0:
sum = x
for curr in list(subset):
e = curr[0] if curr.index(y) == 1 else curr[1]
sum += e
if sum % 5 == 0:
finalylist.append([pcard] + list(subset))
finallist = finallist + finalylist + finalxlist + finaldoubleslist
finallist.append([pcard])
return finallist
def minimax(self, agent):
best_action = []
\'\'\'
minimax has to return an action: a list with tuples
Table: [(4, 4), (1, 5)]
Hand: [(5, 5), (1, 2), (1, 1)]
Eg: best_action = [(1,1),(4,4)] - This is a take action. Agent picks (4,4) domino from the table
with (1,1) domino in the hand (order is important - hand domino followed by table dominos)
best_action = [(1,1)] - This action is to discard (1,1) domino
\'\'\'
\'\'\'
Your Code Goes Here
\'\'\'
return best_action
def min_play(self,agent):
#print \"this is minplay\"
\'\'\'
Your Code Goes Here
\'\'\'
def max_play(self,agent):
#print \"this is maxplay\"
\'\'\'
Your Code Goes Here
\'\'\'
def isValidAction(self, card, to_collect, agent):
# print \"card: \"+str(card)+\",plan: \"+str(to_collect)
# print \"table: \"+str(self.table) +\",hand: \"+str(agent.hand)
# print str([card]+ to_collect)
if not card in agent.hand:
print \"Card %s is not available with the player\" % (str(card))
print \"************************************************\"
print \"GAME OVER\"
exit(1)
else:
if len(to_collect) == 0:
return True
else:
if not len(set(to_collect).intersection(set(self.table))) == len(to_collect):
print \"Cards you wish to collect are not on table\"
print \"************************************************\"
print \"GAME OVER\"
exit(1)
else:
if not check_all_sum([card] + to_collect):
print \"Cannot collect these cards: Sum of all cards is not a multiple of 5 \"
print \"************************************************\"
print \"GAME OVER\"
exit(1)
else:
return True
def makeMove(self, card, to_collect, agent):
if self.isValidAction(card, to_collect, agent):
if len(to_collect) == 0:
self.table.append(card)
if agent.role == \'player\':
self.player.hand.remove(card)
else:
self.computer.hand.remove(card)
else:
if agent.role == \'player\':
self.player.collected.extend([card] + to_collect)
self.player.hand.remove(card)
else:
self.computer.collected.extend([card] + to_collect)
self.computer.hand.remove(card)
for t in to_collect:
self.table.remove(t)
if len(self.table) == 0:
if agent.role == \'player\':
self.player_sweep += 1
else:
self.computer_sweep += 1
def isGameOver(self):
if len(self.computer.hand) == 0 and len(self.player.hand) == 0:
return True
return False
def whoGoesFirst(self):
# Randomly choose the player who goes first.
if random.randint(0, 1) == 0:
return self.computer
else:
return self.player
def computeScore(self,agent):
play_score,comp_score = 0,0
if not len(self.table) == 0:
if self.picked_last == \'player\':
self.player.collected += self.table
self.table = []
else:
self.computer.collected += self.table
self.table = []
if len(self.player.collected)>len(self.computer.collected):
play_score = play_score + 1
elif len(self.player.collected)
comp_score = comp_score + 1
play_score += count_fives(self.player.collected) + self.player_sweep
comp_score += count_fives(self.computer.collected) + self.computer_sweep
#print \"computer_score = \"+ str(comp_score)
#print \"player_score= \" + str(play_score)+\"\ \"
if agent.role == \'player\':
return play_score-comp_score
else:
return comp_score-play_score
def get_enemy(self, agent):
if agent.role == \"player\":
return self.computer
else:
return self.player
def print_board(self, agent):
opponent = self.get_enemy(agent)
print \"After \" + str(agent.role) + \"\'s action ---------- \"
print \"Table: \" + str(self.table)
print \"Computer_sweeps: \" + str(self.computer_sweep) + \" and Player_sweeps: \" + str(self.player_sweep)
print str(agent.role) + \"\'s hand: \" + str(agent.hand)
print \"Cards \" + str(agent.role) + \" collected: \" + str(agent.collected)
print str(opponent.role) + \"\'s hand: \" + str(opponent.hand)
print \"Cards \" + str(opponent.role) + \" collected: \" + str(opponent.collected) + \"\ \ \"
def run(self, agent):
sequence_of_actions = []
test = str(self.table) + \"##\" + str(self.player.hand) + \"##\" + str(
self.computer.hand) + \"##\" + agent.role + \"##\"
print agent.role
opponent = self.get_enemy(agent)
print \"*********************************\ Initial Table: \" + str(self.table)
print str(agent.role) + \" is playing first\"
print str(agent.role) + \"\'s hand: \" + str(agent.hand)
print \"Cards \" + str(agent.role) + \" collected: \" + str(agent.collected)
print str(opponent.role) + \"\'s hand: \" + str(opponent.hand)
print \"Cards \" + str(opponent.role) + \" collected: \" + str(opponent.collected)
print \"*********************************\ \ \"
# print \"current_hand\" + str(agent.hand)
# print \"opponent_hand\" + str(opponent.hand)
while not self.isGameOver():
# print game.actions(agent)
action = self.minimax(agent)
if len(action) > 1:
self.picked_last = agent.role
self.makeMove(action[0], action[1:], agent)
self.print_board(agent)
sequence_of_actions.append(action)
if not self.isGameOver():
print self.actions(opponent)
action = self.minimax(opponent)
if len(action) > 1:
self.picked_last = agent.role
self.makeMove(action[0], action[1:], opponent)
self.print_board(opponent)
sequence_of_actions.append(action)
else:
break
print \"Score of the Max at the end:\" + str(self.computeScore(agent))
print \"sequence of actions played:\" + str(sequence_of_actions)
return sequence_of_actions
def main(test):
res = True
while res:
game = Game(6)
agent = game.whoGoesFirst()
dealer = game.computer if agent.role == \'player\' else game.player
if game.checkInitalTable(dealer):
game.picked_last = \"computer\" if game.computer_sweep > game.player_sweep else \"player\"
actions = game.actions(agent)
# print agent.hand
for action in actions:
# print action
if len(action) > 1:
res = False
break
if res:
# print game.get_enemy(agent).hand
game.table.extend(agent.hand)
# print \"table after extending\"+ str(game.table)
actions = game.actions(game.get_enemy(agent))
game.table = [x for x in game.table if x not in agent.hand]
for action in actions:
# print action
if len(action) > 1:
res = False
break
if test:
F = open(\"test.txt\",
\"r\") # leave this file in the folder where you run the code from or modify the path accordingly
correct = 0
for line in F:
finallist = []
split = line.split(\"##\")
split[0] = ast.literal_eval(split[0])
split[1] = ast.literal_eval(split[1])
split[2] = ast.literal_eval(split[2])
split[4] = ast.literal_eval(split[4])
game.table = split[0]
game.player.hand = split[1]
game.computer.hand = split[2]
agent = game.player if split[3] == \'player\' else game.computer
game.player.collected = []
game.computer.collected = []
game.computer_sweep = 0
game.player_sweep = 0
finallist = game.run(agent)
if finallist == split[4]:
correct += 1
else:
\"This test case failed: \" + line
print \"FinalScore: \" + str(correct)
else:
game.run(agent)
if __name__ == \"__main__\":
if len(sys.argv)>1:
if sys.argv[1]==\"-t\":
main(True)
else:
print \"The argument\" + sys.argv[1] + \"is not valid\"
else:
main(False)
Test file for Minimax: Put in like test.txt
00-0 0 00-0 0 t-o 00 oolo o olo 00 40Solution
import itertools
import random
class :
def __init__(self):
self.suits = [\'Spades\',\'Hearts\',\'Diamonds\',\'Clubs\']
self.values = range(1,14)
self.ActualCards = [] #Empty List to Append
for Card in itertools.product(self.suits,self.values):
self.ActualCards.append(Card) #Cartesian Product to Create Deck
def GetRandomCard(self):
RandomNumber = random.randint(0,53)
CardToBeReturned = self.ActualCards[RandomNumber] #Generates Random Card
return(CardToBeReturned)
class Player:
def __init__(self,ID,Card):
self.PlayerID = ID
self.CardForPlayer = Card
class Game:
def __init__(self,NameOfGame):
self.name = NameOfGame
class SimpleWar(Game):
def __init__(self,NumberOfPlayers):
self.NumberOfPlayers = NumberOfPlayers
self.PlayerList = []
def StartGame(self):
DeckOfCards = Cards()
for playerID in range(0,self.NumberOfPlayers):
CardForPlayer = DeckOfCards.GetRandomCard()
NewPlayer = Player(playerID,CardForPlayer) #Save Player ID and Card
self.PlayerList.append(NewPlayer)
self.DecideWinner()
def DecideWinner(self):
WinningID = self.PlayerList[0]
for playerID in self.PlayerList:
if(playerID.CardForPlayer[1]>WinningID.CardForPlayer[1]):
WinningID = playerID #Find the Player with Highest Card
print \"Winner is Player \"+str(WinningID.PlayerID)
print \"Her Card was \"+ str(WinningID.CardForPlayer[1]) + \" of \" + str(WinningID.CardForPlayer[0])
if __name__==\"__main__\":
NewGame = SimpleWar(2)
NewGame.StartGame()












