daily pastebin goal
79%
SHARE
TWEET

Untitled

a guest Dec 7th, 2017 40 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Import
  2.  
  3. from random import randint, sample, shuffle
  4.  
  5. class uno:
  6.     def __init__(self):
  7.         self.pile = []
  8.         self.stack = self.deck()
  9.         self.playerHands = {}                # A dictionary containing each player's hand
  10.         self.gameOrder = []                  # A list containing each player's name, which are also the keys for the dictionary above
  11.         self.numberOfPlayers = 0
  12.         self.counter = 0
  13.         self.lastPlayedCard = None
  14.         self.clockwise = True
  15.         self.endGame = False
  16.  
  17.         # Main Program
  18.  
  19.         self.initGame()
  20.  
  21.         while True:
  22.             self.gameRound()
  23.             if self.endGame:
  24.                 break
  25.  
  26.             if self.clockwise:
  27.                 self.counter += 1
  28.             elif not self.clockwise:
  29.                 self.counter -= 1
  30.  
  31.             self.whoIsPlayingNextRound()
  32.  
  33.  
  34.     # ███    ███  █████  ██ ███    ██     ███████ ██    ██ ███    ██  ██████ ████████ ██  ██████  ███    ██ ███████
  35.     # ████  ████ ██   ██ ██ ████   ██     ██      ██    ██ ████   ██ ██         ██    ██ ██    ██ ████   ██ ██
  36.     # ██ ████ ██ ███████ ██ ██ ██  ██     █████   ██    ██ ██ ██  ██ ██         ██    ██ ██    ██ ██ ██  ██ ███████
  37.     # ██  ██  ██ ██   ██ ██ ██  ██ ██     ██      ██    ██ ██  ██ ██ ██         ██    ██ ██    ██ ██  ██ ██      ██
  38.     # ██      ██ ██   ██ ██ ██   ████     ██       ██████  ██   ████  ██████    ██    ██  ██████  ██   ████ ███████
  39.  
  40.  
  41.  
  42.     def initGame(self):
  43.         """ Initialise the game """
  44.         self.numberOfPlayers = int(input('Please input the number of players in your game : '))
  45.         while (10 < self.numberOfPlayers) or (self.numberOfPlayers < 2):
  46.             self.numberOfPlayers = int(input('Please input the number of players in your game (2 min|10 max) : '))
  47.         maxNumberCards = int(108 / self.numberOfPlayers)
  48.         numberCardsHands = int(input("Input the number of cards you want in each player's hand at the begining of the game (< {}) : ".format(maxNumberCards)))
  49.         while (maxNumberCards <= numberCardsHands) or (numberCardsHands <= 1):
  50.             numberCardsHands = int(input("Input the number of cards you want in each player's hand at the begining of the game (< {}) : ".format(maxNumberCards)))
  51.  
  52.         playerNames = []
  53.         for i in range(self.numberOfPlayers):
  54.             names = input("Input the name of the player {} : ".format(i))
  55.             while names in playerNames:
  56.                 names = input("Input the name of the player {} (You can't use the same name twice) : ".format(i))
  57.             playerNames.append(names)
  58.  
  59.         for j in playerNames:
  60.             self.playerHands[j] = []
  61.  
  62.         for k in range(self.numberOfPlayers):
  63.             self.currentPlayer = playerNames[k]
  64.             self.draw(numberCardsHands)
  65.  
  66.         ans = ['y', 'Y', 'n', 'N']
  67.         keepOrder = input('The current direction of rotation is defined by the order in which you entered the name of the players, do you want to randomize it? [Y/N] ')
  68.         while keepOrder not in ans:
  69.             keepOrder = input('The current direction of rotation is defined by the order in which you entered the name of the players, do you want to randomize it? [Y/N] ')
  70.         self.gameOrder = list(playerNames)
  71.         if keepOrder in ['y', 'Y']:
  72.             shuffle(self.gameOrder)
  73.         self.currentPlayer = self.gameOrder[0]
  74.  
  75.         self.draw(1, True) # Put a random card of the deck on top of the pile
  76.         self.lastPlayedCard = self.pile[0]
  77.  
  78.     def deck(self):
  79.         """ Create an already shuffled deck of cards """
  80.         deck = sample(range(1, 109), 108)
  81.         return deck
  82.  
  83.     def draw(self, numCard, init=False):
  84.         """ Draw X cards and append them in the hand of the player """
  85.         for i in range(numCard):
  86.             r = randint(0, len(self.stack) - 1)
  87.             drawnCard = self.stack[r]
  88.             self.stack.pop(self.stack.index(drawnCard))
  89.             if not init:
  90.                 self.playerHands[self.currentPlayer].append(drawnCard)
  91.             elif init:
  92.                 self.pile.append(drawnCard)
  93.                 return
  94.         return drawnCard
  95.  
  96.     def automaticallyDraw(self):
  97.         print("You don't have any card to match the one on the pile.")
  98.         print('The game will automatically draw cards until you can play.')
  99.         counter = 0
  100.         while True:
  101.             if not self.stack:
  102.                 self.refillStack()
  103.             dc = self.draw(1)
  104.             canPlayThisCard = self.setDownVerification(dc)
  105.             counter += 1
  106.             if canPlayThisCard:
  107.                 self.pile.append(dc)
  108.                 self.playerHands[self.currentPlayer].remove(dc)
  109.                 self.lastPlayedCard = dc
  110.                 print('You drew {} cards before being able to play. The last one has been played for you automatically.')
  111.                 break
  112.  
  113.     def refillStack(self):
  114.         """ Refill the stack with the cards in the pile (Called when the stack becomes empty) """
  115.         lastCard = self.pile[-1]
  116.         self.pile.pop(self.pile.index(lastCard))
  117.         self.stack += list(self.pile)
  118.         shuffle(self.stack)
  119.         self.pile = [lastCard]
  120.  
  121.  
  122.     def showPlayerHand(self, victory=False):
  123.         """ Display the hand of the player in the console """
  124.         if not victory:
  125.             handText = list(self.playerHands[self.currentPlayer])
  126.             handTitle = "---- {}'s hand ----".format(self.currentPlayer)
  127.             print(handTitle)
  128.             for i in range(len(handText)):
  129.                 handText[i] = '[{}]  {}'.format(i, self.convertToText(handText[i]))
  130.             print ('\n'.join(handText))
  131.             print('-' * len(handTitle))
  132.         elif victory:
  133.             self.gameOrder.remove(self.playerHands[self.currentPlayer])
  134.             for e in self.gameOrder:
  135.                 handText = list(self.playerHands[e])
  136.                 print("{}'s hand:'")
  137.                 for i in range(len(handText)):
  138.                     handText[i] = '[{}]  {}'.format(i, self.convertToText(handText[i]))
  139.                 print ('\n'.join(handText))
  140.  
  141.     def countCardsToDraw(self):
  142.         """ Count the number of 'Draw Two' and 'Wild Draw Four' cards that follow each other
  143.            to determine the number of cards that the player needs to draw               """
  144.         i = -1
  145.         drawTwo = 0
  146.         wildDrawFour = 0
  147.         while True:
  148.             x = self.convertToNumber(self.pile[i])
  149.             if x == 10:
  150.                 drawTwo += 1
  151.                 i -= 1
  152.             elif x == 14:
  153.                 wildDrawFour += 1
  154.                 i -= 1
  155.             elif i+1 == -len(self.pile):
  156.                 break
  157.             else:
  158.                 break
  159.         total = (drawTwo * 2) + (wildDrawFour * 4)
  160.         return total
  161.         print('countCardsToDraw total =',total)
  162.  
  163.     def playableCards(self):
  164.         """ Return a list of index of playable cards (-> pc) in the player's hand """
  165.         pc = []
  166.         for i in range(len(self.playerHands[self.currentPlayer])):
  167.             x = self.setDownVerification(self.playerHands[self.currentPlayer][i])
  168.             if x:
  169.                 pc.append(i)
  170.         return pc
  171.  
  172.     def chooseCard(self):
  173.         """ Ask the player which card he wants to play """
  174.         self.showPlayerHand()
  175.         pc = self.playableCards()
  176.         playingCard = self.convertToText(self.lastPlayedCard)
  177.         print('The last card in the pile is [{}]'.format(playingCard))
  178.         x = int(input("Please choose a valid card to play: "))
  179.         while True:
  180.             if x in pc:
  181.                 break
  182.             else:
  183.                 x = int(input("This card isn't valid, please choose a valid card to play: "))
  184.         return self.playerHands[self.currentPlayer][x]
  185.  
  186.     def whoIsPlayingNextRound(self):
  187.         """ Save in an instance variable the name / key of the player that is playing the current round """
  188.         index = self.counter % self.numberOfPlayers
  189.         self.currentPlayer = self.gameOrder[index]
  190.  
  191.     #  ██████  ██████  ███    ██ ██    ██ ███████ ██████  ███████ ██  ██████  ███    ██     ███████ ██    ██ ███    ██  ██████ ████████ ██  ██████  ███    ██ ███████
  192.     # ██      ██    ██ ████   ██ ██    ██ ██      ██   ██ ██      ██ ██    ██ ████   ██     ██      ██    ██ ████   ██ ██         ██    ██ ██    ██ ████   ██ ██
  193.     # ██      ██    ██ ██ ██  ██ ██    ██ █████   ██████  ███████ ██ ██    ██ ██ ██  ██     █████   ██    ██ ██ ██  ██ ██         ██    ██ ██    ██ ██ ██  ██ ███████
  194.     # ██      ██    ██ ██  ██ ██  ██  ██  ██      ██   ██      ██ ██ ██    ██ ██  ██ ██     ██      ██    ██ ██  ██ ██ ██         ██    ██ ██    ██ ██  ██ ██      ██
  195.     #  ██████  ██████  ██   ████   ████   ███████ ██   ██ ███████ ██  ██████  ██   ████     ██       ██████  ██   ████  ██████    ██    ██  ██████  ██   ████ ███████
  196.  
  197.  
  198.  
  199.     def convertToColor(self, i):
  200.         """ Return the color of a card based on her position in the deck """
  201.         if (1 <= i <= 25):
  202.             return 'Yellow'
  203.         elif (26 <= i <= 50):
  204.             return 'Blue'
  205.         elif (51 <= i <= 75):
  206.             return 'Green'
  207.         elif (76 <= i <= 100):
  208.             return 'Red'
  209.  
  210.     def convertToNumber(self, i):
  211.         """ Return the number / function of a card based on her position in the deck """
  212.         if i > 100:
  213.             if (100 < i <= 104):
  214.                 return 13
  215.             if (104 < i <= 108):
  216.                 return 14
  217.         else:
  218.             mod = i % 25
  219.             if mod not in [0, 24]:
  220.                 return (mod // 2)
  221.             else:
  222.                 return 12
  223.  
  224.     def convertToText(self, ind, returnText=True):
  225.         """ Return the color and number / function of a card """
  226.         color = self.convertToColor(ind)
  227.         number = self.convertToNumber(ind)
  228.  
  229.         if number >= 10:
  230.             if number == 10:
  231.                 number = 'Draw Two'
  232.             elif number == 11:
  233.                 number = 'Reverse'
  234.             elif number == 12:
  235.                 number = 'Skip'
  236.             elif not returnText:
  237.                 return None, None
  238.             elif number == 13:
  239.                 return 'Wild'
  240.             elif number == 14:
  241.                 return 'Wild Draw Four'
  242.         if (returnText):
  243.             # Formated to be printed in the console
  244.             text = '{} - {}'.format(number, color)
  245.             return text
  246.         else:
  247.             # Return separately the color and the number / function of a card
  248.             return color, number
  249.  
  250.  
  251.     # ██    ██ ███████ ██████  ██ ███████ ██  ██████  █████  ████████ ██  ██████  ███    ██     ███████ ██    ██ ███    ██  ██████ ████████ ██  ██████  ███    ██ ███████
  252.     # ██    ██ ██      ██   ██ ██ ██      ██ ██      ██   ██    ██    ██ ██    ██ ████   ██     ██      ██    ██ ████   ██ ██         ██    ██ ██    ██ ████   ██ ██
  253.     # ██    ██ █████   ██████  ██ █████   ██ ██      ███████    ██    ██ ██    ██ ██ ██  ██     █████   ██    ██ ██ ██  ██ ██         ██    ██ ██    ██ ██ ██  ██ ███████
  254.     #  ██  ██  ██      ██   ██ ██ ██      ██ ██      ██   ██    ██    ██ ██    ██ ██  ██ ██     ██      ██    ██ ██  ██ ██ ██         ██    ██ ██    ██ ██  ██ ██      ██
  255.     #   ████   ███████ ██   ██ ██ ██      ██  ██████ ██   ██    ██    ██  ██████  ██   ████     ██       ██████  ██   ████  ██████    ██    ██  ██████  ██   ████ ███████
  256.  
  257.  
  258.  
  259.     def setDownVerification(self, card):
  260.         """ Verify, for a given card, if it can be played or not based on the rules """
  261.         lastCard = self.pile[-1]
  262.         numLastCard = self.convertToNumber(lastCard)
  263.         numCard = self.convertToNumber(card)
  264.         lastCardColor, lastCardNumber = self.convertToText(lastCard, False)
  265.         cardColor, cardNumber = self.convertToText(card, False)
  266.         # Case 1 -> card = Wild Draw Four
  267.         if numCard == 14:
  268.             return True
  269.         # Case 2 -> card = Wild
  270.         elif (numCard == 13) and (numLastCard not in [10, 14]):
  271.             return True
  272.         # Case 3 -> Same color
  273.         elif (lastCardColor == cardColor) and (lastCardColor is not None) and (cardColor is not None) and (numLastCard is not 10):
  274.             return True
  275.         # Case 4 -> Same number or 'function'
  276.         elif (cardNumber == lastCardNumber) and (lastCardNumber is not None) and (cardNumber is not None):
  277.             return True
  278.         # Case 5 -> The last card is a 'Draw Two' or a 'Wild Draw Four' and the player don't have one of these cards
  279.         elif numLastCard in [10, 14]:
  280.             return 'forcedDraw'
  281.         # Case 6 -> The player cannot play
  282.         else:
  283.             return False
  284.  
  285.     def playOrDraw(self):
  286.         """ Verify that the player has at least one playable card in his hand """
  287.         forcedDrawList = []
  288.         for i in range(len(self.playerHands[self.currentPlayer])):
  289.             x = self.setDownVerification(self.playerHands[self.currentPlayer][i])
  290.             forcedDrawList.append(x)
  291.             if x:
  292.                 # The player can play
  293.                 pc = self.playableCards()
  294.                 return True, pc
  295.         # The player is forced to draw because of a 'Draw Two' or a 'Wild Draw Four'
  296.         if all(e == 'forcedDraw' for e in forcedDrawList):
  297.             cardsToDraw = self.countCardsToDraw()
  298.             return False, cardsToDraw
  299.         else:
  300.             # The player needs to draw
  301.             return False, -1
  302.  
  303.     def victory(self):
  304.         """ Check if the hand of a player is empty (Which also means that he won) """
  305.         if not self.playerHands[self.currentPlayer]:
  306.             return True
  307.             self.endGame = True
  308.         return False
  309.  
  310.     def gameRound(self):
  311.         play, cards = self.playOrDraw()
  312.         print(play, cards)
  313.         if play:
  314.             c = self.chooseCard()
  315.             self.pile.append(c)
  316.             self.playerHands[self.currentPlayer].remove(c)
  317.             self.lastPlayedCard = c
  318.             win = self.victory()
  319.             if win:
  320.                 print('{} won this game! Congratulation :)'.format(self.currentPlayer))
  321.                 print('The hands of the remaining players will be displayed below')
  322.                 self.showPlayerHand(True)
  323.                 return
  324.  
  325.         elif not play:
  326.             if cards != -1:
  327.                 print("Because there's one or multiple Draw Two / Wild Draw Four cards on the pile, you need to draw {} cards.".format(cards))
  328.                 self.draw(cards)
  329.                 print('The cards have been drawn for you automatically')
  330.                 play, cards = self.playOrDraw()
  331.                 if (not play) and (cards == -1):
  332.                     self.automaticallyDraw()
  333.  
  334.             elif cards == -1:
  335.                 self.automaticallyDraw()
  336.  
  337. uno = uno();
RAW Paste Data
Top