[pycon] warGame

Viewer

  1.  
  2. face = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
  3. suit = ["Clubs", "Diamonds", "Hearts", "Spades"]
  4.  
  5. import random
  6.  
  7. class Card:
  8.     # Constructor method for Card.
  9.     # Takes as input a face and suit value. 
  10.     # If they are not found in the global variables above, the card will be set to a 2 of clubs
  11.     def __init__(self, the_face, the_suit):
  12.         global face, suit
  13.         if (the_face in face and the_suit in suit):
  14.             self.face = the_face
  15.             self.suit = the_suit
  16.         else:
  17.             self.face = -1
  18.             self.suit = "ILLEGAL CARD"
  19.  
  20.     # Retuns the suit value of the calling card
  21.     def get_suit(self):
  22.         return self.suit
  23.  
  24.     # Returns the face value of the calling card
  25.     def get_face(self):
  26.         return self.face
  27.  
  28.     # Compares the face and suit attributes of other_card to those possessed by the calling card
  29.     def __eq__(self, other_card):
  30.         return (self.face == other_card.get_face()) and (self.suit == other_card.get_suit())
  31.  
  32.     # Returns the value of self > other_card
  33.     # The first comparison is on face value. If the faces are different, we return the result of
  34.     # self.face > other_card.get_face()
  35.     # If they are tied, we return the result of self.suit > other_card.get_suit()
  36.     def __gt__(self, other_card):
  37.         if self.face > other_card.get_face():
  38.             return True
  39.         elif (self.face == other_card.get_face()):
  40.             return self.suit > other_card.get_suit()
  41.         else:
  42.             return False
  43.  
  44.     # Card tostring. Will return the card in the format "Face of Suit"
  45.     def __str__(self):
  46.         return "%s of %s" % (self.face, self.suit)
  47.         
  48.         
  49. class Deck:
  50.     
  51.     # The constructor method for the Deck.
  52.     # It takes no parameters.
  53.     # It fills a deck with 52 unique card, and then uses random.shuffle to randomly order the deck
  54.     # The counter will be used to indicate which card is at the "top" of the deck
  55.     # i.e. all cards above counter will have been dealt
  56.     def __init__(self):
  57.         self.deck = []
  58.         self.counter = 0
  59.         global face
  60.         global suit
  61.         for the_face in face:
  62.             for the_suit in suit:
  63.                 self.deck.append(Card(the_face, the_suit))
  64.         for i in range(7):
  65.             random.shuffle(self.deck)
  66.  
  67.     # Returns the top card of the deck if it exists (if we have not previously dealt 52 cards)
  68.     # We could add in a method to automatically shuffle the deck if we reach this point
  69.     def deal(self):
  70.         if self.counter < 52:
  71.             result = self.deck[self.counter]
  72.             self.counter += 1
  73.             return result
  74.  
  75.     # Randomly shuffles the deck array seven times.
  76.     def shuffle(self):
  77.         self.counter = 0
  78.         for i in range(7):
  79.             random.shuffle(self.deck)
  80.  
  81.     # tostring method for deck class.
  82.     # Prints out all 52 cards in the deck, one per line.
  83.     # We indicate with an X cards that have been dealt
  84.     # << Current Top Card indicates which card is the current top of the deck.
  85.     def __str__(self):
  86.         result = ""
  87.         for i in range(52):
  88.             if i == self.counter:
  89.                 result += "%s << Current Top Card\n" % self.deck[i]
  90.             elif i < self.counter:
  91.                 result += "%s X\n" % self.deck[i]
  92.             else:
  93.                 result += "%s\n" % self.deck[i]
  94.         return result
  95.  
  96.  
  97. class Player_War:
  98.     
  99.     # For our Player, we need two attributes guaranteed, the current hand and the discard pile
  100.     # Depending on game design, we could have a data point to represent wins.
  101.     def __init__(self):
  102.         self.hand = []
  103.         self.discard = []
  104.         
  105.     # A method to allow cards to be added to the hand. Will be utilized by the game code
  106.     def add_card(self, card):
  107.         self.hand.append(card)
  108.         
  109.     # A method to allow cards to be added to the discard pile. Will be utilized by the game code
  110.     def add_discard(self, card):
  111.         self.discard.append(card)
  112.     
  113.     # Returns the number of cards currently in the player's hand
  114.     def hand_size(self):
  115.         return len(self.hand)
  116.        
  117.     # Returns the number of cards currently in the player's discard pile
  118.     def discard_size(self):
  119.         return len(self.discard)
  120.         
  121.     # Returns the top card of the player's hand. However, if the hand is empty, 
  122.     # we will shuffle the discard pile in with the helper method.
  123.     # We will post an error message if the hand is totally empty.
  124.     # NOTE: Perhaps in our gameplay loop we decide to remove the automatic shuffle
  125.     def play_card(self):
  126.         if len(self.hand) > 0:
  127.             return self.hand.pop()
  128.         elif len(self.discard) > 0:
  129.             self.shuffle_discard()
  130.             return self.hand.pop()
  131.         else:
  132.             return Card(-1, "HAND EMPTY")
  133.         
  134.     # Takes all cards from our discard pile and places them into the hand
  135.     def shuffle_discard(self):
  136.         while len(self.discard) > 0:
  137.             self.hand.append(self.discard.pop())
  138.         random.shuffle(self.hand)
  139.         
  140.     # Prints out both the hand and the discard pile for the current player
  141.     def __str__(self):
  142.         result = "Current Hand:"
  143.         for item in self.hand:
  144.             result += "\t%s" % item
  145.         result += "\nDiscard Pile:"
  146.         for item in self.discard:
  147.             result += "\t%s" % item
  148.         return result
  149.  
  150. # A class which defines the Game of War.
  151. # The rules of war are as follows:
  152.     # 2 Players
  153.     # 1 Deck of cards (52 unique cards)
  154.     # Could change/expand the base datapoints
  155.     # Deal the cards
  156.     # Cycle of Play
  157.         # Round by round/turn by turn
  158.         # Each player draws a card, and presents it (c1 and c2)
  159.         # If c1 > c2, P1 wins, and gets both cards into their discard
  160.         # If c2 > c1, P2 wins, ...
  161.         # There is no possibility of tie (This will change)
  162.         # Play continues until no cards are in the hand (at the start, 26 rounds/turns will go)
  163.         # shuffle the discard pile into the hand, and play continues
  164.     # Win Condition:
  165.         # Default is one of the players has all 52 cards
  166.         # We'll look at two possibilities:
  167.             # X Turns of have passed, the player with more cards wins
  168.             # Once a player has X number of cards total (hand + discard) (Look at this style next week)
  169. class War_Game:
  170.  
  171.     # The init method. It defines both players and the deck.
  172.     # We will be adding to this in the future, with the addition of win counters
  173.     def __init__(self):
  174.         self.player_one = Player_War()
  175.         self.player_two = Player_War()
  176.         self.player_three = Player_War()
  177.         self.player_four = Player_War()
  178.         self.p1_victories = 0
  179.         self.p2_victories = 0
  180.         self.p3_victories = 0
  181.         self.p4_victories = 0
  182.         self.deck = Deck()
  183.         
  184.     # Gives us the base setup for our War Game.
  185.     # Redeclares both players (perhaps we update Player_War to have a reset method)
  186.     # Shuffles the deck
  187.     # Deals the appropriate number of cards to each player
  188.     def start_game(self):
  189.         self.player_one = Player_War()
  190.         self.player_two = Player_War()
  191.         self.player_three = Player_War()
  192.         self.player_four = Player_War()
  193.         self.deck.shuffle()
  194.         for i in range(13):
  195.             self.player_one.add_card(self.deck.deal())
  196.             self.player_two.add_card(self.deck.deal())
  197.             self.player_three.add_card(self.deck.deal())
  198.             self.player_four.add_card(self.deck.deal())
  199.         
  200.  
  201.     def p1_win(self):
  202.         t1 = self.player_one.discard_size() + self.player_one.hand_size()
  203.         t2 = self.player_two.discard_size() + self.player_two.hand_size()
  204.         t3 = self.player_three.discard_size() + self.player_three.hand_size()
  205.         t4 = self.player_four.discard_size() + self.player_four.hand_size()
  206.         return ((t2 == 0 or t3 == 0 or t4 == 0) and (t1 > t2 and t1 > t3 and t1 > t4))
  207.     
  208.     def p2_win(self):
  209.         t1 = self.player_one.discard_size() + self.player_one.hand_size()
  210.         t2 = self.player_two.discard_size() + self.player_two.hand_size()
  211.         t3 = self.player_three.discard_size() + self.player_three.hand_size()
  212.         t4 = self.player_four.discard_size() + self.player_four.hand_size()
  213.         return ((t1 == 0 or t3 == 0 or t4 == 0) and (t2 > t1 and t2 > t3 and t2 > t4))  
  214.     def p3_win(self):
  215.         t1 = self.player_one.discard_size() + self.player_one.hand_size()
  216.         t2 = self.player_two.discard_size() + self.player_two.hand_size()
  217.         t3 = self.player_three.discard_size() + self.player_three.hand_size()
  218.         t4 = self.player_four.discard_size() + self.player_four.hand_size()
  219.         return ((t1 == 0 or t2 == 0 or t4 == 0) and (t3 > t1 and t3 > t2 and t3 > t4))    
  220.     
  221.     def p4_win(self):
  222.         t1 = self.player_one.discard_size() + self.player_one.hand_size()
  223.         t2 = self.player_two.discard_size() + self.player_two.hand_size()
  224.         t3 = self.player_three.discard_size() + self.player_three.hand_size()
  225.         t4 = self.player_four.discard_size() + self.player_four.hand_size()
  226.         return ((t1 == 0 or t2 == 0 or t3 == 0) and (t4 > t1 and t4 > t2 and t4 > t3))    
  227.     
  228.     def simulation(self, num_games):
  229.         # What exactly /is/ a simulation?
  230.         # We want to play a full game (and play it several times)
  231.         # Likely many calls to play round!
  232.         # What ends the game? What is the winning condition?
  233.         # Is it when no cards remain?
  234.         # X rounds have passed and whomever has most cards wins
  235.         # End when one player has X number of cards total <----
  236.         # Reset the game somewhere!
  237.         game_count = 1
  238.         while (game_count <= num_games):
  239.             # First thing is to reset the game state
  240.             self.start_game()
  241.             num_rounds = 0
  242.             game_won = False
  243.             while (not game_won):
  244.                 num_rounds += 1
  245.                 # Play a round
  246.                 self.play_round()
  247.                 # Check to see if the game is over
  248.                 if (self.p1_win()):
  249.                     print("Player 1 has won game #%s! It took %s rounds" % (game_count, num_rounds))
  250.                     game_won = True
  251.                     self.p1_victories += 1
  252.                 elif (self.p2_win()):
  253.                     print("Player 2 has won game #%s! It took %s rounds" % (game_count, num_rounds))
  254.                     game_won = True
  255.                     self.p2_victories += 1
  256.                 elif (self.p3_win()):
  257.                     print("Player 3 has won game #%s! It took %s rounds" % (game_count, num_rounds))
  258.                     game_won = True
  259.                     self.p3_victories += 1
  260.                 elif (self.p4_win()):
  261.                     print("Player 4 has won game #%s! It took %s rounds" % (game_count, num_rounds))
  262.                     game_won = True
  263.                     self.p4_victories += 1
  264.             game_count += 1
  265.     
  266.     
  267.     
  268.     # A method to play a singular round of War.
  269.     # Both players deal a card using the play_card method of Player_War
  270.     # The higher valued card wins the hand, and both cards are placed into the winning player's
  271.     # discard pile.
  272.     # Shuffling of discard into hand is handled by the Player_War object
  273.     def play_round(self):
  274.         
  275.         
  276.         
  277.         
  278.         c1 = self.player_one.play_card()
  279.         c2 = self.player_two.play_card()
  280.         c3 = self.player_three.play_card()
  281.         c4 = self.player_four.play_card()
  282.         
  283.        
  284.  
  285.         
  286.         if ((c1.get_face() < 0) or (c2.get_face() < 0) or (c3.get_face() < 0) or (c4.get_face() < 0 )):
  287.         
  288.             return False 
  289.             
  290.         t1 = self.player_one.discard_size() + self.player_one.hand_size()
  291.         t2 = self.player_two.discard_size() + self.player_two.hand_size()
  292.         t3 = self.player_three.discard_size() + self.player_three.hand_size()
  293.         t4 = self.player_four.discard_size() + self.player_four.hand_size()
  294.         
  295.         
  296.         if (t1 == 0):
  297.             if (t2 > t3 and t2 > t4):
  298.                 self.p2_win()
  299.             if (t3 > t2 and t3 > t4):
  300.                 self.p3_win()
  301.             if (t4 > t2 and t4 > t3):
  302.                 self.p4_win()   
  303.         elif (t2 == 0):
  304.             if (t1 > t3 and t1 > t4):
  305.                 self.p1_win()
  306.             if (t3 > t1 and t3 > t4):
  307.                 self.p3_win()
  308.             if (t4 > t1 and t4 > t3):
  309.                 self.p4_win()
  310.         elif (t3 == 0):
  311.             if (t1 > t2 and t1 > t4):
  312.                 self.p1_win()
  313.             if (t2 > t1 and t2 > t4):
  314.                 self.p2_win()
  315.             if (t4 > t2 and t4 > t1):
  316.                 self.p4_win()
  317.         elif (t4 == 0):
  318.             if (t2 > t3 and t2 > t1):
  319.                 self.p2_win()
  320.             if (t3 > t2 and t3 > t1):
  321.                 self.p3_win()
  322.             if (t1 > t2 and t1 > t3):
  323.                 self.p1_win()
  324.  
  325.         print("Player 1's Hand + Discard Count: %s" % t1)
  326.         print("Player 2's Hand + Discard Count: %s" % t2)
  327.         print("Player 3's Hand + Discard Count: %s" % t3)
  328.         print("Player 4's Hand + Discard Count: %s" % t4)
  329.         print("")
  330.         print("Playing %s vs %s vs %s vs %s" % (c1, c2, c3, c4))
  331.         
  332.         
  333.         if ((c1 > c2) and (c1 > c3) and (c1 > c4)):
  334.             # Player 1 won!
  335.             self.player_one.add_discard(c1)
  336.             self.player_one.add_discard(c2)
  337.             self.player_one.add_discard(c3)
  338.             self.player_one.add_discard(c4)
  339.             print( "Player One wins with %s!\n" % c1)
  340.             return True
  341.         elif((c2 > c1) and (c2 > c3) and (c2 > c4)):
  342.             # Player 2 won!
  343.             self.player_two.add_discard(c1)
  344.             self.player_two.add_discard(c2)
  345.             self.player_two.add_discard(c3)
  346.             self.player_two.add_discard(c4)
  347.             print( "Player Two wins with %s!\n" % c2)
  348.             return False
  349.         elif((c3 > c1) and (c3 > c2) and (c3 > c4)):
  350.             # Player 3 won!
  351.             self.player_three.add_discard(c1)
  352.             self.player_three.add_discard(c2)
  353.             self.player_three.add_discard(c3)
  354.             self.player_three.add_discard(c4)  
  355.             print( "Player Three wins with %s!\n" % c3)
  356.             return False
  357.         elif((c4 > c1) and (c4 > c2) and (c4 > c3)):
  358.             # Player 4 won!
  359.             self.player_four.add_discard(c1)
  360.             self.player_four.add_discard(c2)
  361.             self.player_four.add_discard(c3)
  362.             self.player_four.add_discard(c4)
  363.             print( "Player Four wins with %s!\n" % c4)
  364.             return False
  365.         
  366.         
  367.         
  368.     # Tostring for War_Game
  369.     # Currently it prints out both player objects, with a static number for wins.
  370.     def __str__(self):
  371.         result = "Player 1\tWins %s\n" % self.p1_victories
  372.         result += "%s\n" % self.player_one
  373.         result += "Player 2\tWins %s\n" % self.p2_victories
  374.         result += "%s\n" % self.player_two
  375.         result = "Player 3\tWins %s\n" % self.p3_victories
  376.         result += "%s\n" % self.player_three
  377.         result += "Player 4\tWins %s\n" % self.p4_victories
  378.         result += "%s\n" % self.player_four
  379.         return result
  380.  
  381.  
  382.  
  383.  
  384.  
  385. def main():
  386.     
  387.     print("Starting Game of War!\n")
  388.     my_game = War_Game()
  389.     my_game.simulation(1)
  390.     print("\nGame Over!")
  391.     
  392.     
  393.  
  394.  
  395. main()

Editor

You can edit this paste and save as new:


File Description
  • warGame
  • Paste Code
  • 06 May-2021
  • 15.34 Kb
You can Share it: