Advertisement
Lydss

UNO PYTHON PROTO

Jul 3rd, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 67.02 KB | None | 0 0
  1. import os
  2. import sys
  3. import random
  4. import math
  5. import time
  6.  
  7. class BadInputError(Exception):
  8. pass
  9.  
  10. class Player():
  11.  
  12. def __init__(self, name):
  13. self.id = None
  14. self.name = name
  15. self.type = 'Human'
  16. self.hand = Hand()
  17. self.legalCards = []
  18. self.wildCards = []
  19. self.valueChangeCards = []
  20. self.zeroCards = []
  21. self.canSkip = False
  22. self.canReverse = False
  23. self.canDrawTwo = False
  24. self.canDrawFour = False
  25. self.canValueChange = False
  26. self.drew = False
  27. self.scrollMax = 0
  28. self.points = 0
  29. self.forceDraw = 0
  30.  
  31. def addCard(self, card):
  32. self.drew = True
  33. if self.forceDraw > 0:
  34. self.forceDraw -= 1
  35. self.drew = False
  36. self.hand.addCard(card)
  37.  
  38. def beginTurn(self):
  39. self.drew = False
  40.  
  41. def didDraw(self):
  42. return self.drew
  43.  
  44. def getLegalCards(self, color, value, zeroChange=False):
  45. self.canSkip = False
  46. self.canReverse = False
  47. self.canDrawTwo = False
  48. self.canDrawFour = False
  49. self.canValueChange = False
  50. self.canZeroChange = False
  51. self.legalCards = []
  52. self.wildCards = []
  53. self.valueChangeCards = []
  54. self.zeroCards = []
  55. plusFours = []
  56. for card in self.hand:
  57. if card.isWild():
  58. if card.getValue() == '+4':
  59. plusFours.append(card)
  60. else:
  61. self.wildCards.append(card)
  62. elif zeroChange and card.isZero():
  63. self.canZero = True
  64. self.zeroCards.append(card)
  65. elif card.getColor() == color or card.getValue() == value:
  66. if card.getColor() != color:
  67. self.canValueChange = True
  68. self.valueChangeCards.append(card)
  69. if card.getValue() == "+2":
  70. self.canDrawTwo = True
  71. elif card.getValue() == 'R':
  72. self.canReverse = True
  73. elif card.getValue() == 'X':
  74. self.canSkip = True
  75. self.legalCards.append(card)
  76. if len(self.legalCards) == 0 and len(plusFours) > 0:
  77. self.canDrawFour = True
  78. self.wildCards += plusFours
  79.  
  80. def getValidCards(self):
  81. return self.legalCards
  82.  
  83. def getAllValidCards(self):
  84. return self.legalCards + self.wildCards + self.zeroCards
  85.  
  86. def hasLegalCard(self):
  87. return len(self.legalCards) > 0
  88.  
  89. def addPoints(self, amount):
  90. if (self.points + amount) <= 999999999999999999999:
  91. self.points += amount
  92.  
  93. def removeCard(self, index):
  94. return self.hand.removeCard(index)
  95.  
  96. def assignID(self, identity):
  97. self.id = identity
  98.  
  99. def getName(self):
  100. return self.name
  101.  
  102. def getID(self):
  103. return self.id
  104.  
  105. def getPoints(self):
  106. return self.points
  107.  
  108. def getType(self):
  109. return self.type
  110.  
  111. def getCardNum(self):
  112. return len(self.hand)
  113.  
  114. def getHand(self, scrollNum=0, hide=False):
  115. return self.hand.show(scrollNum, hide)
  116.  
  117. def getForceDraws(self):
  118. return self.forceDraw
  119.  
  120. def addForceDraw(self, num):
  121. self.forceDraw += num
  122.  
  123. def decreaseForceDraw(self):
  124. self.forceDraw -= 1
  125.  
  126. def removeForceDraw(self):
  127. self.forceDraw = 0
  128.  
  129. def checkCard(self, index):
  130. return self.hand.getCard(int(index))
  131.  
  132. def discardHand(self):
  133. self.hand.discard()
  134.  
  135. def __str__(self):
  136. return self.name
  137.  
  138. def __repr__(self):
  139. return '({},{})'.format(self.name, self.points)
  140.  
  141. class Hand():
  142. ''''deck' (Deck) : Card's Color (rgby)
  143. 'numberOfCards' (int) : Card's Value (0-9, R, X, W, +2, +4)'''
  144.  
  145. def __init__(self, deck=None,numberOfCards=0):
  146. self.hand = []
  147. if deck != None:
  148. self.draw(deck,numberOfCards)
  149.  
  150. def __iter__(self):
  151. return iter(self.hand)
  152.  
  153. def __len__(self):
  154. return len(self.hand)
  155.  
  156. def __getitem__(self, item):
  157. try:
  158. return self.hand[item]
  159. except:
  160. return ''
  161.  
  162. def addCard(self, card):
  163. self.hand.append(card)
  164.  
  165. def removeCard(self, index):
  166. index = int(index)
  167. if (0 <= index < len(self)):
  168. return self.hand.pop(index)
  169.  
  170. def discard(self):
  171. self.hand = []
  172.  
  173. def show(self, scrollNum=0, hide=False):
  174. if scrollNum == -1:
  175. scrollNum = 0
  176. output = ''
  177. num = 0
  178. header, footer, upper, lower = '', '', '', ''
  179. header += ('\033[97m\u2666--\u2666\033[0m ')
  180. upper += ('\033[97m|<-|\033[0m ')
  181. lower += ('\033[97m|<-|\033[0m ')
  182. footer += ('\033[97m\u2666--\u2666\033[0m ')
  183. for i in range(10):
  184. indexNum = i+(10*scrollNum)
  185. if indexNum < len(self):
  186. header += (self[indexNum].getRow(0,hide)+' ')
  187. upper += (self[indexNum].getRow(1,hide)+' ')
  188. lower += (self[indexNum].getRow(2,hide)+' ')
  189. footer += (self[indexNum].getRow(3,hide)+' ')
  190. num += 1
  191. for j in range(10-num):
  192. j #unused
  193. header += (' ')
  194. footer += (' ')
  195. upper += (' ')
  196. lower += (' ')
  197. header += ('\033[97m\u2666--\u2666\033[0m ')
  198. upper += ('\033[97m|->|\033[0m ')
  199. lower += ('\033[97m|->|\033[0m ')
  200. footer += ('\033[97m\u2666--\u2666\033[0m ')
  201. output += (' '+header+'\n '+upper+'\n '+lower+'\n '+footer+'\n\033[97m|-(<)--')
  202. for k in range(num):
  203. output += '({})'.format(k)
  204. output += '--'
  205. for l in range(10-num):
  206. l #unused
  207. output += '-----'
  208. output += '(>)--|\033[0m\n'
  209. return output
  210.  
  211. def getCard(self, index):
  212. return self.hand[index]
  213.  
  214. def indexCard(self, card):
  215. return self.hand.index(card)
  216.  
  217. class GameSettings():
  218.  
  219. playerIdentities = ('play1','play2','play3','play4')
  220. computerNames = ('Watson','SkyNet','Hal','Metal Gear')
  221.  
  222. def __init__(self):
  223. self.playerStaging = [] # Where Player Objs Are Stored Before Game Starts
  224. self.players = {} # ID : Player Obj
  225. self.numPlayers = 0
  226. self.useColor = True
  227. self.displayEffects = True
  228. self.hideComputerHands = True
  229. self.zeroChange = False
  230. self.computerSimulation = False
  231. self.mainMenuError = ''
  232. self.computerSpeed = 'normal'
  233.  
  234. def canAddPlayer(self):
  235. return (self.numPlayers < 4)
  236.  
  237. def canRemovePlayer(self):
  238. return (self.numPlayers > 0)
  239.  
  240. def canBegin(self):
  241. return (self.numPlayers > 1)
  242.  
  243. def addPlayer(self, player):
  244. self.playerStaging.append(player)
  245. self.numPlayers += 1
  246.  
  247. def removePlayer(self, number):
  248. number -= 1
  249. del self.playerStaging[number]
  250. self.numPlayers -= 1
  251.  
  252. def clearStaging(self):
  253. self.numPlayers = 0
  254. self.playerStaging = []
  255.  
  256. def finalizePlayers(self):
  257. self.players.clear()
  258. identity = 0
  259. for player in self.playerStaging:
  260. playerID = self.playerIdentities[identity]
  261. player.assignID(playerID)
  262. self.players[playerID] = player
  263. identity += 1
  264.  
  265. def getPlayerNum(self):
  266. return self.numPlayers
  267.  
  268. def getComputerName(self):
  269. complete = False
  270. index = self.numPlayers
  271. while not complete:
  272. name = self.computerNames[index]
  273. complete = True
  274. for player in self.playerStaging:
  275. if player.getName() == name:
  276. index += 1
  277. if index >= len(self.computerNames):
  278. index = 0
  279. complete = False
  280.  
  281. return self.computerNames[index]
  282.  
  283. def getRandomIdentity(self):
  284. '''For Getting a Random Player for First Turn.'''
  285. return random.choice(self.players.keys())
  286.  
  287. def compileMainMenuElements(self):
  288. def getBlankSpace(word, total):
  289. return " "*(total-len(word))
  290.  
  291. def getPlayerBox(playerNum, rowNum):
  292. if rowNum == 1:
  293. name = self.playerStaging[playerNum-1].getName()
  294. return '{}{}'.format(name, getBlankSpace(name, 29))
  295. elif rowNum == 2:
  296. points = self.playerStaging[playerNum-1].getPoints()
  297. return 'Points: {}{}'.format(points, getBlankSpace(str(points), 21))
  298.  
  299. self.mainMenuElements= {'play1row1':'No Player ','play1row2':' ',
  300. 'play2row1':'No Player ',
  301. 'play2row2':' ',
  302. 'play3row1':'No Player ','play3row2':' ',
  303. 'play4row1':'No Player ',
  304. 'play4row2':' ',
  305. 'play1box':'\033[90m','play2box':'\033[90m','play3box':'\033[90m','play4box':'\033[90m',
  306. 'beginBox':'\033[90m','addBox':'\033[97m','removeBox':'\033[90m'
  307. }
  308. playerBoxKey = 'play{}box'
  309. playerRowKey = 'play{}row{}'
  310. i = 1
  311. for j in self.playerStaging:
  312. j
  313. colorCode = ['\033[91m','\033[94m','\033[92m','\033[93m']
  314. key = playerBoxKey.format(i)
  315. self.mainMenuElements[key] = colorCode[i-1]
  316. self.mainMenuElements[playerRowKey.format(i,1)] = getPlayerBox(i, 1)
  317. self.mainMenuElements[playerRowKey.format(i,2)] = getPlayerBox(i, 2)
  318. i+=1
  319. if self.canBegin():
  320. self.mainMenuElements['beginBox'] = '\033[95m'
  321. if not self.canAddPlayer():
  322. self.mainMenuElements['addBox'] = '\033[90m'
  323. if self.canRemovePlayer():
  324. self.mainMenuElements['removeBox'] = '\033[97m'
  325.  
  326. def changeComputerSpeed(self):
  327. if self.computerSpeed == 'slow':
  328. self.computerSpeed = 'normal'
  329. elif self.computerSpeed == 'normal':
  330. self.computerSpeed = 'fast'
  331. elif self.computerSpeed == 'fast':
  332. self.computerSpeed = 'slow'
  333.  
  334. def getMainMenuElements(self):
  335. return self.mainMenuElements
  336.  
  337. class Deck():
  338. ''''shuffle' (bool) : shuffle deck.'''
  339.  
  340. colors = ('red','yellow','green','blue')
  341. values = ('0','1','2','3','4','5','6','7','8','9','X','R','+2')
  342.  
  343. def __init__(self, populate):
  344. '''Initializes proper deck of 108 Uno Cards.'''
  345. self.deck = []
  346. if populate:
  347. self.populate(True)
  348.  
  349. def __getitem__(self, index):
  350. return self.deck[index]
  351.  
  352. def populate(self, shuffle=True):
  353. for color in self.colors:
  354. for value in self.values:
  355. self.deck.append(Card(color, value))
  356. if value != '0':
  357. self.deck.append(Card(color, value))
  358. for i in range(4):
  359. i #unused
  360. self.deck.append(Card('wild', '+4'))
  361. self.deck.append(Card('wild', 'W'))
  362. if shuffle:
  363. self.shuffle()
  364.  
  365. def __iter__(self):
  366. return iter(self.deck)
  367.  
  368. def __len__(self):
  369. return len(self.deck)
  370.  
  371. def draw(self):
  372. return self.deck.pop()
  373.  
  374. def place(self, card):
  375. return self.deck.append(card)
  376.  
  377. def insert(self, card):
  378. self.deck.insert(0, card)
  379.  
  380. def shuffle(self):
  381. random.shuffle(self.deck)
  382.  
  383. class ComputerPlayer(Player):
  384.  
  385. def __init__(self, name):
  386. super().__init__(name)
  387. self.type = 'Computer'
  388. self.begun = False
  389. self.colorsInHand = {'red':0, 'blue':0, 'green':0, 'yellow':0, 'wild':0}
  390. self.colorsOutHand = {}
  391. self.currentColor = ""
  392.  
  393. def addCard(self, card):
  394. Player.addCard(self, card)
  395. color = card.getColor()
  396. self.colorsInHand[color] += 1
  397.  
  398. def indexCard(self, cardColor, cardValue):
  399. for card in self.hand:
  400. if card.getValue() == cardValue:
  401. if cardValue in ('+4', 'W'):
  402. return self.hand.indexCard(card)
  403. else:
  404. if card.getColor() == cardColor:
  405. return self.hand.indexCard(card)
  406. raise ValueError("Card Cannot Be Found")
  407.  
  408. def think(self, match):
  409. card = None
  410. self.currentColor = match.currentColor
  411. currentValue = match.currentValue
  412. zeroChangeRule = match.zeroChange
  413. twoPlayers = False
  414. previousTurnID = match.getNextTurn(True)
  415. nextTurnID = match.getNextTurn(False)
  416. previousPlayer = match.getPlayer(previousTurnID)
  417. #nextPlayer = match.getPlayer(nextTurnID)
  418. if previousTurnID == nextTurnID:
  419. twoPlayers = True
  420. if self.canSkip == False and self.canReverse == True:
  421. self.canSkip = True
  422. self.canReverse = False
  423.  
  424. self.getLegalCards(self.currentColor, currentValue, zeroChangeRule)
  425.  
  426. ### DRAW CASE ###
  427.  
  428. if len(self.legalCards) == 0 and len(self.wildCards) == 0:
  429. return "d"
  430.  
  431. else:
  432.  
  433. ### NO LEGAL CARD, USE WILD CARD ###
  434.  
  435. if len(self.legalCards) == 0:
  436.  
  437. if zeroChangeRule and self.canZeroChange:
  438. bestZeroColor = self.getBestColor(self.zeroCards)
  439. card = self.getCardByColor(self.zeroCards, bestZeroColor)
  440.  
  441. else:
  442.  
  443. if self.canDrawFour:
  444. card = self.getCardByValue(self.wildCards, "+4")
  445. print(card)
  446.  
  447. else:
  448. card = random.choice(self.wildCards)
  449.  
  450. else:
  451.  
  452. ### HAS LEGAL CARD ###
  453.  
  454. if twoPlayers and self.canSkip: #Always play a skip card in a two player game
  455. #print("Shed Skip Strategy")
  456. card = self.getCardByValue(self.legalCards,"R", "X")
  457.  
  458. if self.canReverse and previousPlayer.didDraw():
  459. #print("Reverse Strategy")
  460. reverseCards = self.getAllCardsByValue(self.legalCards, "R")
  461. for reverseCard in reverseCards:
  462. if reverseCard.getColor() == self.currentColor:
  463. card = reverseCard
  464.  
  465. if self.canValueChange:
  466. # Computer Can Value Change, However, Should it?
  467. # Computer Checks to See if Value Change Color is Better Than Current
  468. currentColorNum = self.colorsInHand[self.currentColor]
  469. bestValueChangeColor = self.getBestColor(self.valueChangeCards)
  470. if self.colorsInHand[bestValueChangeColor] > currentColorNum or len(self.valueChangeCards) == len(self.legalCards):
  471. card = self.getCardByColor(self.valueChangeCards, bestValueChangeColor)
  472.  
  473.  
  474. if card == None:
  475. #print("Random Strategy")
  476. card = random.choice(list(set(self.legalCards) - set(self.valueChangeCards)))
  477.  
  478. color = card.getColor()
  479. self.colorsInHand[color] -= 1
  480. return str(self.indexCard(card.getColor(), card.getValue()))
  481.  
  482. def getWildColor(self):
  483. maxKey = max(self.colorsInHand, key=self.colorsInHand.get)
  484. if maxKey == 'wild':
  485. return random.choice(('r','g','b','y'))
  486. else:
  487. return maxKey
  488.  
  489. def getCardByValue(self, cardList, *values):
  490. for card in cardList:
  491. if card.getValue() in values:
  492. return card
  493.  
  494. def getAllCardsByValue(self, cardList, *values):
  495. cards = []
  496. for card in cardList:
  497. if card.getValue() in values:
  498. cards.append(card)
  499. return cards
  500.  
  501. def getCardByColor(self, cardList, *colors):
  502. for card in cardList:
  503. if card.getColor() in colors:
  504. return card
  505.  
  506. def getBestColor(self, cardList):
  507. bestColor = None
  508. bestColorNum = 0
  509. for card in cardList:
  510. color = card.getColor()
  511. if self.colorsInHand[color] > bestColorNum:
  512. bestColor = color
  513. bestColorNum = self.colorsInHand[color]
  514. return bestColor
  515.  
  516. class Card():
  517. '''
  518. 'suit' (string) : Card's Color (rgby)
  519. 'rank' (string) : Card's Value (0-9, R, X, W, +2, +4)
  520. '''
  521.  
  522. colors = {
  523. 'red' : '\033[91m',
  524. 'green' : '\033[92m',
  525. 'yellow' : '\033[93m',
  526. 'blue' : '\033[94m',
  527. 'purple' : '\033[95m',
  528. 'cyan' : '\033[96m',
  529. 'white' : '\033[97m',
  530. 'wild' : '',
  531. 'dwild' : '',
  532. 'dred' : '\033[31m',
  533. 'dgreen' : '\033[32m',
  534. 'dyellow' : '\033[33m',
  535. 'dblue' : '\033[34m',
  536. 'dpurple' : '\033[35m',
  537. 'dcyan' : '\033[36m',
  538. 'dwhite' : '\033[37m',
  539. }
  540.  
  541. idMap = {
  542. 'red':'R','blue':'B','green':'G','yellow':'Y','wild':'W',
  543. '0':'0','1':'1','2':'2','3':'3','4':'4','5':'5','6':'6','7':'7','8':'8','9':'9',
  544. '+2':'+','R':'R','W':'W','+4':'$','X':'X'
  545. }
  546.  
  547. bigNums = {
  548. "0" : [" .d888b. ","d88P Y88b","888 888","888 888","888 888","888 888","d88P Y88b"," \"Y888P\" "],
  549. "1" : [" d888 "," d8888 "," 888 "," 888 "," 888 "," 888 "," 888 "," 8888888 "],
  550. "2" : [".d8888b. ","d88P Y88","d8 888"," .d88P",".od888P\" ","d88P\" ","888\" ","888888888"],
  551. "3" : [" .d8888b.","d88P Y88"," .d88"," 8888\" "," \"Y8b","888 88","Y88b d88"," \"Y8888P\""],
  552. "4" : [" d88b "," d8P88 "," d8 88 "," d8 88 ","d8 88 ","888888888"," 88 "," 88 "],
  553. "5" : ["888888888","888 ","888 ","8888888b "," \"Y88b "," 888","Y88b d88P","\"Y8888P\" "],
  554. "6" : [" .d888b. ","d88P Y88b","888 ","888d888b ","888P \"Y8b","888 888","Y88b d88b"," \"Y888P\" "],
  555. "7" : ["888888888"," d8P"," d8P "," d8P "," 8888888 "," d8P "," d8P ","d8P "],
  556. "8" : [" .d888b. ","d8P Y8b","Y8b. d8P"," \"Y8888\" "," .dP\"Yb. ","888 888","Y88b d88P"," \"Y888P\" "],
  557. "9" : [" .d888b. ","d8P Y8b","88 88","Y8b. d88"," \"Y88P888"," 888","Y88b d88P"," \"Y888P\" "],
  558. "X" : ["Y8b d8P"," Y8b d8P "," Y8o8P "," Y8P "," d8b "," d888b "," d8P Y8b ","d8P Y8b"],
  559. "W" : ["88 88","88 88","88 o 88","88 d8b 88","88d888b88","88P Y88","8P Y8","P Y"],
  560. "+2" : [" db "," 88 ","C8888D "," 88 8888"," VP 8"," 8888"," 8 "," 8888"],
  561. "+4" : [" db "," 88 ","C8888D "," 88 d "," VP d8 "," d 8 "," d8888"," 8 "],
  562. "R9" : [" d88P "," d88P "," d88P "," d88P "," Y88b "," Y88b "," Y88b "," Y88b "],
  563. "R8" : [" d88P "," d88P "," d88P ","d88P ","Y88b "," Y88b "," Y88b "," Y88b "],
  564. "R7" : [" d88P Y"," d88P ","d88P ","88P ","88b ","Y88b "," Y88b "," Y88b d"],
  565. "R6" : [" d88P Y8","d88P Y","88P ","8P ","8b ","88b ","Y88b d"," Y88b d8"],
  566. "R5" : ["d88P Y88","88P Y8","8P Y","P ","b ","8b d","88b d8","Y88b d88"],
  567. "R4" : ["88P Y88b","8P Y88","P Y8"," Y"," d","b d8","8b d88","88b d88P"],
  568. "R3" : ["8P Y88b ","P Y88b"," Y88"," Y8"," d8"," d88","b d88P","8b d88P "],
  569. "R2" : ["P Y88b "," Y88b "," Y88b"," Y88"," d88"," d88P"," d88P ","b d88P "],
  570. "R1" : [" Y88b "," Y88b "," Y88b "," Y88b"," d88P"," d88P "," d88P "," d88P "],
  571. "R0" : [" Y88b "," Y88b "," Y88b "," Y88b "," d88P "," d88P "," d88P "," d88P "],
  572. }
  573.  
  574.  
  575. def __init__(self, color, value):
  576. '''Initializes Uno Card w/ Color and Value.'''
  577. self.wild = False #Is wild card?
  578. self.zero = False
  579. self.cardID = '{}{}'.format(self.idMap[color],self.idMap[value])
  580. self.setColor(color)
  581. self.setValue(value)
  582. self.setPoints(value)
  583.  
  584.  
  585. #############################################
  586.  
  587. ### -\/- Retrieve Card Information -\/- ###
  588.  
  589. def __repr__(self):
  590. return "{},{}".format(self.color, self.value)
  591.  
  592. def getBigNum(self, reverse, reverseSeed=0):
  593. '''Returns list of strings to draw card's value on the pile.'''
  594. bigNums = []
  595. colorCode = self.colorCode
  596. colorCodeDark = self.colorCodeDark
  597. value = self.value
  598. if value == 'R':
  599. if not reverse:
  600. value += str(reverseSeed)
  601. else:
  602. value += str(9-reverseSeed)
  603. for mid in self.bigNums[value]:
  604. bigNums += ['{}| |{}'.format(colorCode,colorCodeDark)+mid+'{}| |\033[0m\t'.format(colorCode)]
  605.  
  606. return bigNums
  607.  
  608. def getColor(self):
  609. '''Returns card's color.'''
  610. return self.color
  611.  
  612. def getColorCode(self):
  613. '''Returns card's color code.'''
  614. return self.colorCode
  615.  
  616. def getValue(self):
  617. '''Returns card's value.'''
  618. return self.value
  619.  
  620. def getPoints(self):
  621. '''Returns card's point value.'''
  622. return self.points
  623.  
  624. def getRow(self,rowNum,hide=False):
  625. value = self.value
  626. displaySpace = self.displaySpace
  627. if hide:
  628. colorCode = '\033[97m'
  629. value = '?'
  630. displaySpace = ' '
  631. else:
  632. colorCode = self.colorCode
  633. if self.isWild():
  634. if rowNum == 0:
  635. colorCode = '\033[91m'
  636. elif rowNum == 1:
  637. colorCode = '\033[93m'
  638. elif rowNum == 2:
  639. colorCode = '\033[92m'
  640. elif rowNum == 3:
  641. colorCode = '\033[94m'
  642.  
  643. if rowNum == 0:
  644. return '{}\u2666--\u2666\033[0m'.format(colorCode)
  645. elif rowNum == 1:
  646. return '{}|{}{}|\033[0m'.format(colorCode, displaySpace, value)
  647. elif rowNum == 2:
  648. if hide:
  649. return '{}|? |\033[0m'.format(colorCode)
  650. else:
  651. return '{}| |\033[0m'.format(colorCode)
  652. elif rowNum == 3:
  653. return '{}\u2666--\u2666\033[0m'.format(colorCode)
  654.  
  655. #############################################
  656.  
  657. ### -\/- Set Card Information -\/- ###
  658.  
  659. def setColor(self, color):
  660. '''Sets Card's color and escape code.'''
  661. if color == 'blue':
  662. self.color = 'blue'
  663. self.colorCode = self.colors['blue']
  664. self.colorCodeDark = self.colors['dblue']
  665. elif color == 'red':
  666. self.color = 'red'
  667. self.colorCode = self.colors['red']
  668. self.colorCodeDark = self.colors['dred']
  669. elif color == 'yellow':
  670. self.color = 'yellow'
  671. self.colorCode = self.colors['yellow']
  672. self.colorCodeDark = self.colors['dyellow']
  673. elif color == 'green':
  674. self.color = 'green'
  675. self.colorCode = self.colors['green']
  676. self.colorCodeDark = self.colors['dgreen']
  677. elif color == 'wild': #No color modification
  678. self.wild = True
  679. self.color = 'wild'
  680. self.colorCodeDark = self.colors['dwild']
  681. self.colorCode = self.colors['wild']
  682.  
  683. def setValue(self, value):
  684. if value in ('0','1','2','3','4','5','6','7','8','9','X','R','+2','+4','W'):
  685. self.value = value
  686. self.displaySpace = ' '
  687. if len(value) == 2:
  688. self.displaySpace = ''
  689. if value == '0':
  690. self.zero = True
  691.  
  692. def setPoints(self, value):
  693. if value in ('0','1','2','3','4','5','6','7','8','9'):
  694. self.points = int(value)
  695. elif value in ("W", "+4"):
  696. self.points = 50
  697. else:
  698. self.points = 20
  699.  
  700.  
  701. #############################################
  702.  
  703. ### -\/- Wild Card Methods -\/- ###
  704.  
  705. def changeColor(self, color):
  706. '''Changes Card's Color, Intended for Wild Cards.'''
  707. self.setColor(color)
  708.  
  709. def isWild(self):
  710. '''Returns if card is a wild card.'''
  711. return self.wild
  712.  
  713. def isZero(self):
  714. return self.zero
  715.  
  716. class Match():
  717.  
  718. elementsInit = {
  719. ### Names (final) ###
  720. 'P1Name':' ', 'P2Name':' ', 'P3Name':' ', 'P4Name':' ',
  721. ### Card Values ###
  722. 'P1Cards':' ', 'P2Cards':' ', 'P3Cards':' ', 'P4Cards':' ',
  723. ### Turn Colors / Hand###
  724. 'P1Turn':'', 'P2Turn':'', 'P3Turn':'', 'P4Turn':'',
  725. 'HName':'\t\t', 'HVisual':'' ,'Hand':'',
  726. ### Deck ###
  727. 'DNum':'', 'Deck':['','','','','','','','',''],
  728. 'PostDNum':'',
  729. ### Pile ###
  730. 'uHeader':'\t\t\t\t', 'uMiddle':' ', 'uLower':' ',
  731. 'oHeader':'\t\t\t', 'oMiddle':['\t\t\t','\t\t\t','\t\t\t','\t\t\t','\t\t\t','\t\t\t','\t\t\t','\t\t\t'],
  732. ### Messages ###
  733. 'Console':'', 'Error':''
  734. }
  735.  
  736. speeds = {'slow':2,'normal':1,'fast':0}
  737.  
  738.  
  739. def __init__(self, gs):
  740. ### Decks ###
  741. self.deck = Deck(True)
  742. self.pile = Deck(False)
  743.  
  744. ### Player Information ###
  745. self.players = gs.players
  746. self.turnList = []
  747. self.handTitles = {'play1':'','play2':'','play3':'','play4':''}
  748.  
  749. ### Carry Information ###
  750. self.displayEffects = gs.displayEffects
  751. self.hideComputerHands = gs.hideComputerHands
  752. self.zeroChange = gs.zeroChange
  753. self.computerSpeed = self.speeds[gs.computerSpeed]
  754. self.simulation = gs.computerSimulation
  755.  
  756. ### Data ###
  757. self.handPosition = 0 # For hand displays
  758. self.drawAmount = 0 # Used for force draws
  759. self.passes = 0 # Keep track of consecutive passes for emergency color change
  760. self.passMax = 0 # Max passes before color change
  761. self.turn = '' # Current turn
  762. self.event = '' # Wild, Reverse, Skip, etc
  763. self.wildColorChange = '' # Specifies color to change wild card to
  764. self.currentColor = '' # Current color
  765. self.currentValue = '' # Current value
  766. self.winnerID = '' # ID of Player who Won
  767. self.reverse = False # Is turn order reversed
  768. self.turnComplete = False # Is turn complete
  769. self.matchComplete = False # Is the Game over?
  770. self.matchAbort = False # Did the match conclude without a winner?
  771. self.forcedWild = False # Force change wild
  772.  
  773. ### Initialize Names / Cards / Deck (Assuming New Game) ###
  774. self.elements = dict(self.elementsInit)
  775.  
  776. keyStringName = 'P{}Name'
  777. keyStringCards = 'P{}Cards'
  778.  
  779. for i in self.players:
  780. self.elements[keyStringName.format(i[-1])] = self.players[i].getName()+(' '*(11-len(self.players[i].getName())))
  781. self.elements[keyStringCards.format(i[-1])] = ' '+(' '*(3-len(str(self.players[i].getCardNum()))))+str(self.players[i].getCardNum())+' Cards'
  782.  
  783. self.elements['DNum'] = len(self.deck)
  784.  
  785. if len(str(len(self.deck))) < 2:
  786. self.elements['PostDNum'] = '\t'
  787.  
  788. j = 8
  789. for i in range(int(math.ceil(len(self.deck)/12))):
  790. self.elements['Deck'][j] = '='
  791. j -= 1
  792.  
  793. for key in GameSettings.playerIdentities:
  794. try:
  795. self.buildHandString(key)
  796. self.turnList += [key]
  797. except KeyError:
  798. pass
  799.  
  800. self.passMax = len(self.turnList)
  801.  
  802. def clearShell(self):
  803. os.system('cls' if os.name == 'nt' else 'clear')
  804.  
  805. def begin(self):
  806. self.elements['Console'] = 'Beginning Game, Press Enter.'
  807. print(self.drawScreen())
  808. self.enterBreak()
  809. self.eventDealCards()
  810. self.turn = random.choice(self.turnList)
  811. self.elements['Console'] = 'First turn will be {}. Press Enter.'.format(self.players[self.turn].getName())
  812. print(self.drawScreen(True))
  813. self.enterBreak()
  814. self.placeCard()
  815. self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
  816. if self.event == 'wild':
  817. self.eventWildCard()
  818. elif self.event == 'reverse':
  819. self.eventReverse()
  820.  
  821. def end(self, gs):
  822. if not self.matchAbort:
  823. points = 0
  824. self.elements['P{}Turn'.format(self.turn[-1])] = ''
  825. self.elements['Console'] = '{} Wins! Press Enter to Begin Point Tally'.format(self.players[self.winnerID].getName())
  826. print(self.drawScreen())
  827. self.enterBreak()
  828.  
  829. for identity in self.turnList:
  830. if identity != self.winnerID:
  831. self.turn = identity
  832. self.elements['HName'] = self.handTitles[self.turn]
  833. self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
  834. while self.players[identity].getCardNum() > 0:
  835. card = self.players[identity].removeCard(0)
  836. points += card.getPoints()
  837. self.elements['Console'] = '{} Won {} Points!'.format(self.players[self.winnerID].getName(),points)
  838.  
  839. keyStringCards = 'P{}Cards'
  840. self.elements[keyStringCards.format(identity[-1])] = ' '+(' '*(3-len(str(self.players[identity].getCardNum()))))+str(self.players[identity].getCardNum())+' Cards'
  841. self.players[identity].maxScroll = math.ceil((self.players[identity].getCardNum() / 10)-1)
  842. if self.handPosition > self.players[identity].maxScroll:
  843. self.handPosition -= 1
  844. self.buildHandVisual(identity)
  845.  
  846. if self.displayEffects and not self.simulation:
  847. print(self.drawScreen())
  848. time.sleep(.1)
  849. self.elements['P{}Turn'.format(self.turn[-1])] = ''
  850.  
  851. self.players[self.winnerID].addPoints(points)
  852. self.elements['Console'] = '{} Won {} Points! Press Enter'.format(self.players[self.winnerID].getName(),points)
  853. print(self.drawScreen())
  854. self.enterBreak()
  855.  
  856. gs.clearStaging()
  857. for identity in self.turnList:
  858. self.players[identity].discardHand()
  859. gs.addPlayer(self.players[identity])
  860. return gs
  861.  
  862. def adjustCardAmount(self, playerID):
  863. keyStringCards = 'P{}Cards'
  864. self.elements[keyStringCards.format(playerID[-1])] = ' '+(' '*(3-len(str(self.players[playerID].getCardNum()))))+str(self.players[playerID].getCardNum())+' Cards'
  865. self.players[playerID].maxScroll = math.ceil((self.players[playerID].getCardNum() / 10)-1)
  866. if self.handPosition > self.players[playerID].maxScroll:
  867. self.handPosition -= 1
  868. self.buildHandVisual(playerID)
  869.  
  870. def buildHandString(self, playerID):
  871. playerName = self.players[playerID].getName()
  872. if len(playerName) < 9:
  873. self.handTitles[playerID] = "{}'s Hand\t".format(self.players[playerID].getName())
  874. else:
  875. self.handTitles[playerID] = "{}'s Hand".format(self.players[playerID].getName())
  876.  
  877. def buildHandVisual(self, playerID):
  878. string = '['
  879. for i in range(self.players[playerID].maxScroll+1):
  880. if i == self.handPosition:
  881. string += '|'
  882. else:
  883. string += '-'
  884. string += ']'
  885. self.elements['HVisual'] = string
  886.  
  887. def checkInput(self, playerInput):
  888. if playerInput == '':
  889. return {'valid':False,'entry':playerInput}
  890. if playerInput.isnumeric():
  891. if int(playerInput)+(10*self.handPosition) < self.players[self.turn].getCardNum():
  892. return {'valid':True,'entry':str(int(playerInput)+(10*self.handPosition)),'type':'card'}
  893. else:
  894. self.elements['Error'] = '{} is not a card.'.format(playerInput)
  895. return {'valid':False,'entry':playerInput}
  896. else:
  897. playerInput = playerInput.lower()[0]
  898. if playerInput in ['<','>','u','d','p','q','s']:
  899. return {'valid':True,'entry':playerInput}
  900. else:
  901. self.elements['Error'] = '{} is not a valid selection.'.format(playerInput)
  902. return {'valid':False,'entry':playerInput}
  903.  
  904. def checkColorInput(self, playerInput):
  905. if playerInput == '':
  906. return {'valid':False,'entry':playerInput}
  907. playerInput = str(playerInput).lower()[0]
  908. if playerInput[0] == 'b':
  909. return {'valid':True,'entry':'blue'}
  910. elif playerInput[0] == 'r':
  911. return {'valid':True,'entry':'red'}
  912. elif playerInput[0] == 'g':
  913. return {'valid':True,'entry':'green'}
  914. elif playerInput[0] == 'y':
  915. return {'valid':True,'entry':'yellow'}
  916. return {'valid':False,'entry':playerInput}
  917.  
  918. def eventDealCards(self):
  919. if self.displayEffects and not self.simulation:
  920. self.elements['Console'] = 'Dealing Cards...'
  921. for i in ('play1','play2','play3','play4'):
  922. if i in self.players:
  923. for j in range(7):
  924. j #unused
  925. self.dealCard(i)
  926. if self.displayEffects and not self.simulation:
  927. print(self.drawScreen(True))
  928. time.sleep(.1)
  929.  
  930. def eventReverse(self):
  931. if self.displayEffects and not self.simulation:
  932. hide = False
  933. if self.players[self.turn].getType() == "Computer":
  934. hide = self.hideComputerHands
  935. self.elements['Console'] = "Reverse Card Played! Reversing Turn Order.".format(self.players[self.turn].getName())
  936. print(self.drawScreen(hide))
  937. time.sleep(1)
  938. for i in range(10):
  939. cardBigNums = self.pile[0].getBigNum(self.reverse,i)
  940. self.elements['oMiddle'] = cardBigNums
  941. print(self.drawScreen(hide))
  942. if self.displayEffects and not self.simulation:
  943. time.sleep(.1)
  944. cardBigNums = self.pile[0].getBigNum(self.reverse,9)
  945. self.elements['oMiddle'] = cardBigNums
  946. self.reverse = not self.reverse
  947. self.event = ''
  948.  
  949. def eventSkip(self):
  950. if self.displayEffects and not self.simulation:
  951. hide = False
  952. if self.players[self.turn].getType() == "Computer":
  953. hide = self.hideComputerHands
  954. self.elements['Console'] = "Skip Card Placed! Skipping {}'s Turn.".format(self.players[self.turn].getName())
  955. print(self.drawScreen(hide))
  956. time.sleep(1)
  957. for i in range(2):
  958. i #unused
  959. self.elements['P{}Turn'.format(self.turn[-1])] = '\033[91m'
  960. print(self.drawScreen(hide))
  961. time.sleep(.3)
  962. self.elements['P{}Turn'.format(self.turn[-1])] = ''
  963. print(self.drawScreen(hide))
  964. time.sleep(.3)
  965. self.turnComplete = True
  966. self.event = ''
  967.  
  968. def eventWildCard(self):
  969. hide = False
  970. if not self.forcedWild:
  971. if self.players[self.turn].getType() == 'Human':
  972. self.elements['Console'] = 'Wild Card! Specifiy a Color: (B)lue, (R)ed, (G)reen, (Y)ellow'
  973. self.elements['Error'] = 'Specifiy A Color'
  974. print(self.drawScreen())
  975. playerInput = str(input("Color Change: "))
  976. checked = self.checkColorInput(playerInput)
  977. while not checked['valid']:
  978. if checked['entry'] == '<':
  979. self.handPosition -= 1
  980. if self.handPosition == -1:
  981. self.handPosition = self.players[self.turn].maxScroll
  982. self.buildHandVisual(self.turn)
  983. elif checked['entry'] == '>':
  984. self.handPosition += 1
  985. if self.handPosition > self.players[self.turn].maxScroll:
  986. self.handPosition = 0
  987. self.buildHandVisual(self.turn)
  988. print(self.drawScreen())
  989. playerInput = str(input("Color Change: "))
  990. checked = self.checkColorInput(playerInput)
  991. else:
  992. hide = self.hideComputerHands
  993. checked = self.checkColorInput(self.players[self.turn].getWildColor())
  994. self.wildColorChange = checked['entry']
  995. else:
  996. self.wildColorChange = self.checkColorInput(random.choice(('r','b','g','y')))['entry']
  997. self.forcedWild = False
  998. self.currentColor = self.wildColorChange
  999. self.elements['Error'] = ""
  1000. if self.displayEffects and not self.simulation:
  1001. self.elements['Console'] = 'Wild Card! Changing Color.'
  1002. seed = 1
  1003. for i in range(10):
  1004. i #unused
  1005. if seed > 4:
  1006. seed = 1
  1007. print(self.drawScreen(hide,wildSeed=seed))
  1008. time.sleep(.1)
  1009. seed += 1
  1010. self.pile[0].changeColor(self.wildColorChange)
  1011. self.wildColorChange = ''
  1012. cardBigNums = self.pile[0].getBigNum(self.reverse)
  1013. self.elements['oHeader'] = '{}\u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t'.format(self.pile[0].getColorCode())
  1014. self.elements['oMiddle'] = cardBigNums
  1015. self.event = ''
  1016.  
  1017. def eventDraw(self):
  1018. self.players[self.turn].addForceDraw(self.drawAmount)
  1019. self.drawAmount = 0
  1020. self.event = ''
  1021.  
  1022. def dealCard(self, playerID):
  1023.  
  1024. card = self.deck.draw()
  1025. self.players[playerID].addCard(card)
  1026.  
  1027. ### Adjust Hand Visual ###
  1028. self.players[playerID].maxScroll = math.ceil((self.players[playerID].getCardNum() / 10)-1)
  1029. self.handPosition = self.players[playerID].maxScroll
  1030. self.buildHandVisual(playerID)
  1031.  
  1032. ### Adjust Player Tile ###
  1033. keyStringCards = 'P{}Cards'
  1034. self.elements[keyStringCards.format(playerID[-1])] = ' '+(' '*(3-len(str(self.players[playerID].getCardNum()))))+str(self.players[playerID].getCardNum())+' Cards'
  1035.  
  1036. ### Adjust Deck ###
  1037. self.elements['DNum'] = len(self.deck)
  1038. if len(str(len(self.deck))) < 2:
  1039. self.elements['PostDNum'] = '\t'
  1040. j = 8
  1041. self.elements['Deck'] = [' ',' ',' ',' ',' ',' ',' ',' ', ' ']
  1042. for i in range(math.ceil(len(self.deck)/12)):
  1043. i #unused
  1044. self.elements['Deck'][j] = '='
  1045. j -= 1
  1046.  
  1047. def placeCard(self, card=None):
  1048. if card == None:
  1049. ### Used At Beginning For First Card ###
  1050. card = self.deck.draw()
  1051. self.elements['DNum'] = len(self.deck)
  1052.  
  1053. cardColor = card.getColorCode()
  1054. cardBigNums = card.getBigNum(self.reverse)
  1055.  
  1056. self.currentColor = card.getColor()
  1057. self.currentValue = card.getValue()
  1058.  
  1059. self.pile.insert(card)
  1060. self.elements['oHeader'] = '{}\u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t'.format(cardColor)
  1061. self.elements['oMiddle'] = cardBigNums
  1062.  
  1063. if len(self.pile) > 1:
  1064. previousCard = self.pile[1]
  1065. previousCardColor = previousCard.getColorCode()
  1066. self.elements['uHeader'] = '{} \u2666\u2666\u2666=========\u2666\u2666\u2666\033[0m\t\t'.format(previousCardColor)
  1067. self.elements['uMiddle'] = '{}| |\033[0m'.format(previousCardColor)
  1068. self.elements['uLower'] = '{}\u2666\u2666\u2666\033[0m'.format(previousCardColor)
  1069.  
  1070. if self.currentColor == 'wild':
  1071. self.event = 'wild'
  1072.  
  1073. if self.currentValue == 'X':
  1074. self.event = 'skip'
  1075. elif self.currentValue == 'R':
  1076. if len(self.players) > 2:
  1077. self.event = 'reverse'
  1078. else:
  1079. self.event = 'skip'
  1080. elif self.currentValue == '+4':
  1081. self.drawAmount = 4
  1082. elif self.currentValue == '+2':
  1083. self.drawAmount = 2
  1084. self.passes = 0
  1085.  
  1086. def extractCard(self, playerID, index):
  1087. card = self.players[playerID].removeCard(index)
  1088. if self.players[playerID].getCardNum() == 0:
  1089. self.matchComplete = True
  1090. self.winnerID = self.turn
  1091. self.adjustCardAmount(playerID)
  1092. return card
  1093.  
  1094. def enterBreak(self):
  1095. if not self.simulation:
  1096. str(input())
  1097. return
  1098.  
  1099. def nextTurn(self):
  1100. self.turnComplete = False
  1101. self.handPosition = 0
  1102. turnType = self.players[self.turn].getType()
  1103. self.players[self.turn].beginTurn()
  1104. ### Prepare Hand Visuals ###
  1105.  
  1106. self.elements['HName'] = self.handTitles[self.turn]
  1107. self.buildHandVisual(self.turn)
  1108.  
  1109. if self.event == 'skip':
  1110. self.eventSkip()
  1111. elif self.drawAmount > 0:
  1112. self.eventDraw()
  1113.  
  1114. while not self.turnComplete:
  1115. if turnType == 'Human':
  1116. self.players[self.turn].getLegalCards(self.currentColor, self.currentValue, self.zeroChange)
  1117. if len(self.deck) > 0:
  1118. self.elements['Console'] = 'Select a card, (D)raw, or (P)ause.'
  1119. else:
  1120. self.players[self.turn].removeForceDraw()
  1121. self.elements['Console'] = 'Select a card, (D)raw, (P)ause, or Pas(s).'
  1122. if self.players[self.turn].getForceDraws() > 0:
  1123. self.elements['Error'] = 'Draw Card Played! Draw {} cards.'.format(self.players[self.turn].getForceDraws())
  1124. print(self.drawScreen())
  1125. playerInput = str(input("\033[97mSelection: \033[92m"))
  1126. checked = self.checkInput(playerInput)
  1127. while not checked['valid']:
  1128. print(self.drawScreen())
  1129. playerInput = str(input("\033[97mSelection: \033[92m"))
  1130. checked = self.checkInput(playerInput)
  1131.  
  1132. playerInput = checked['entry']
  1133.  
  1134. if playerInput == '<':
  1135. self.handPosition -= 1
  1136. if self.handPosition == -1:
  1137. self.handPosition = self.players[self.turn].maxScroll
  1138. self.buildHandVisual(self.turn)
  1139. elif playerInput == '>':
  1140. self.handPosition += 1
  1141. if self.handPosition > self.players[self.turn].maxScroll:
  1142. self.handPosition = 0
  1143. self.buildHandVisual(self.turn)
  1144. elif playerInput == 'd':
  1145. if len(self.deck) > 0:
  1146. self.elements['Error'] = ''
  1147. self.dealCard(self.turn)
  1148. else:
  1149. self.elements['Error'] = "Cannot Draw. Deck is Empty"
  1150. elif playerInput == 'p':
  1151. pauseOutput = self.pauseScreen()
  1152. if pauseOutput == 'quit':
  1153. self.matchComplete = True
  1154. self.turnComplete = True
  1155. self.winnerID = 'play1'
  1156. self.matchAbort = True
  1157. elif playerInput == 's':
  1158. if len(self.deck) > 0:
  1159. self.elements['Error'] = "Cannot pass until Deck is empty."
  1160. elif len(self.players[self.turn].getAllValidCards()) > 0:
  1161. self.elements['Error'] = "Cannot pass while having playable cards."
  1162. else:
  1163. self.turnComplete = True
  1164. self.passes += 1
  1165. if self.passes == self.passMax:
  1166. self.forcedWild = True
  1167. self.event = 'wild'
  1168. self.passes = 0
  1169. elif playerInput.isnumeric():
  1170. if self.players[self.turn].getForceDraws() == 0:
  1171. cardCheck = self.players[self.turn].checkCard(playerInput)
  1172. if cardCheck in self.players[self.turn].getAllValidCards():
  1173. card = self.extractCard(self.turn, playerInput)
  1174. self.placeCard(card)
  1175. self.elements['Error'] = ""
  1176. self.turnComplete = True
  1177. else:
  1178. self.elements['Error'] = "Card Doesn't Match The Color {} or Value {}!".format(self.currentColor, self.currentValue)
  1179. else:
  1180. pass
  1181.  
  1182. elif turnType == 'Computer':
  1183. self.elements['Console'] = '{}\'s Turn'.format(self.players[self.turn].getName())
  1184. print(self.drawScreen(self.hideComputerHands))
  1185. if not self.simulation:
  1186. time.sleep(self.computerSpeed)
  1187. #str(input())
  1188. while (True):
  1189. if self.displayEffects and not self.simulation:
  1190. time.sleep(.2)
  1191. if self.players[self.turn].getForceDraws() > 0 and len(self.deck) > 0:
  1192. cardIndex = 'd'
  1193. else:
  1194. cardIndex = self.players[self.turn].think(self)
  1195. if cardIndex.isnumeric():
  1196. card = self.extractCard(self.turn, int(cardIndex))
  1197. if card.getColor() != self.currentColor:
  1198. self.resetDrawBool()
  1199. self.placeCard(card)
  1200. self.turnComplete = True
  1201. break
  1202. else:
  1203. if cardIndex == 'd':
  1204. if len(self.deck) > 0:
  1205. self.dealCard(self.turn)
  1206. print(self.drawScreen(self.hideComputerHands))
  1207. else:
  1208. self.turnComplete = True
  1209. self.players[self.turn].removeForceDraw()
  1210. self.passes += 1
  1211. if self.passes == self.passMax:
  1212. self.forcedWild = True
  1213. self.event = 'wild'
  1214. self.passes = 0
  1215. break
  1216.  
  1217. ### DECODE INPUT ###
  1218.  
  1219. if self.event == 'reverse':
  1220. self.eventReverse()
  1221. elif self.event == 'wild':
  1222. self.eventWildCard()
  1223.  
  1224. # Clear Current Turn
  1225. self.elements['P{}Turn'.format(self.turn[-1])] = ''
  1226. # Prepare Next Turn
  1227. self.turn = self.getNextTurn()
  1228. self.elements['P{}Turn'.format(self.turn[-1])] = '\033[93m'
  1229.  
  1230. def drawScreen(self, hide=False, wildSeed=0):
  1231. if self.simulation:
  1232. return ''
  1233. colorCombos = {
  1234. 1 : ['\033[91m','\033[93m','\033[92m','\033[94m'],
  1235. 2 : ['\033[94m','\033[91m','\033[93m','\033[92m'],
  1236. 3 : ['\033[92m','\033[94m','\033[91m','\033[93m'],
  1237. 4 : ['\033[93m','\033[92m','\033[94m','\033[91m'] }
  1238. currentTurn = self.turn
  1239. if currentTurn == '':
  1240. currentTurn = self.turnList[-1]
  1241. hide = True
  1242. if wildSeed != 0:
  1243. colorMod = colorCombos[wildSeed]
  1244. else:
  1245. colorMod = ['','','','']
  1246.  
  1247. self.clearShell()
  1248. screenout = ''
  1249. screenout += '\t\t\033[94m || ||\033[92m ||\ || \033[91m// \\\\\n\033[0m'
  1250. screenout += '\t\t\033[94m || ||\033[92m ||\\\|| \033[91m(( ))\n\033[0m'
  1251. screenout += '\t\t\033[94m \\\ //\033[92m || \|| \033[91m \\\ //\n\033[0m'
  1252. screenout += '\033[97m===============================================================\n'
  1253. screenout += '\033[93m{}\033[0m\n'.format(self.elements['Console'])
  1254. screenout += '\033[97m===============================================================\n'
  1255. screenout += '\t\t\t\t\t\t' + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P1Turn'])
  1256. screenout += '\033[97mDeck:\t\t' + '{}'.format(self.elements['uHeader']) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P1Turn'],self.elements['P1Name'])
  1257. screenout += '\033[97m{} Cards'.format(self.elements['DNum']) + '{}'.format(self.elements['PostDNum'])+'\t' + '{}'.format(self.elements['uHeader']) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P1Turn'],self.elements['P1Cards'])
  1258. screenout += '\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[0],self.elements['oHeader']) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P1Turn'])
  1259. screenout += '\033[97m _+_ \t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[1],self.elements['oHeader']) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P2Turn'])
  1260. screenout += '\033[97m | ' + '\033[92m{}\033[0m'.format(self.elements['Deck'][0]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[2],self.elements['oMiddle'][0]) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P2Turn'],self.elements['P2Name'])
  1261. screenout += '\033[97m | ' + '\033[92m{}\033[0m'.format(self.elements['Deck'][1]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[3],self.elements['oMiddle'][1]) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P2Turn'],self.elements['P2Cards'])
  1262. screenout += '\033[97m | ' + '\033[92m{}\033[0m'.format(self.elements['Deck'][2]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[0],self.elements['oMiddle'][2]) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P2Turn'])
  1263. screenout += '\033[97m | ' + '\033[93m{}\033[0m'.format(self.elements['Deck'][3]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[1],self.elements['oMiddle'][3]) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P3Turn'])
  1264. screenout += '\033[97m | ' + '\033[93m{}\033[0m'.format(self.elements['Deck'][4]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[2],self.elements['oMiddle'][4]) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P3Turn'],self.elements['P3Name'])
  1265. screenout += '\033[97m | ' + '\033[93m{}\033[0m'.format(self.elements['Deck'][5]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uMiddle']) + '\033[97m{}{}'.format(colorMod[3],self.elements['oMiddle'][5]) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P3Turn'],self.elements['P3Cards'])
  1266. screenout += '\033[97m | ' + '\033[91m{}\033[0m'.format(self.elements['Deck'][6]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uLower']) + '\033[97m{}{}'.format(colorMod[0],self.elements['oMiddle'][6]) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P3Turn'])
  1267. screenout += '\033[97m | ' + '\033[91m{}\033[0m'.format(self.elements['Deck'][7]) + '\033[97m |\t\t ' + '{}'.format(self.elements['uLower']) + '\033[97m{}{}'.format(colorMod[1],self.elements['oMiddle'][7]) + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P4Turn'])
  1268. screenout += '\033[97m |_' + '\033[91m{}\033[0m'.format(self.elements['Deck'][8]) + '\033[97m_|\t\t ' + '\033[97m{}{}'.format(colorMod[2],self.elements['oHeader']) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P4Turn'],self.elements['P4Name'])
  1269. screenout += '\033[97m\t\t ' + '\033[97m{}{}'.format(colorMod[3],self.elements['oHeader']) + ' \033[97m{}|{}|\033[0m\n'.format(self.elements['P4Turn'],self.elements['P4Cards'])
  1270. screenout += '\t\t\t\t\t\t' + ' \033[97m{}\u2666-----------\u2666\033[0m\n'.format(self.elements['P4Turn'])
  1271. screenout += "\033[97m{}".format(self.elements['HName']) + "\t\t\t\t {}\n".format(self.elements['HVisual'])
  1272. screenout += '\033[97m===============================================================\n'
  1273. screenout += self.players[currentTurn].getHand(self.handPosition,hide)
  1274. screenout += '\033[91m{}\033[0m'.format(self.elements['Error'])
  1275. return screenout
  1276.  
  1277. def pauseScreen(self):
  1278. while True:
  1279. self.clearShell()
  1280. print('\n\t\t\tPause')
  1281. print('\n\t\t1. Resume')
  1282. print('\t\t2. Quit')
  1283.  
  1284. selection = str(input('\nSelection: ')).upper()
  1285. while selection not in ['1', '2']:
  1286. print('\nSelection Invalid')
  1287. selection = str(input('\nSelection: ')).upper()
  1288.  
  1289. if selection == '1' or "":
  1290. return ""
  1291.  
  1292. elif selection == '2':
  1293. return "quit"
  1294.  
  1295.  
  1296. def isComplete(self):
  1297. return self.matchComplete
  1298.  
  1299. def next(self):
  1300. self.turn = self.getNextTurn()
  1301.  
  1302. def getNextTurn(self, forceReverse=False):
  1303. if forceReverse:
  1304. reverse = not self.reverse
  1305. else:
  1306. reverse = self.reverse
  1307. currentIndex = self.turnList.index(self.turn)
  1308. if not reverse:
  1309. if (currentIndex + 1) == len(self.turnList):
  1310. return self.turnList[0]
  1311. else:
  1312. return self.turnList[currentIndex+1]
  1313. else:
  1314. if currentIndex == 0:
  1315. return self.turnList[len(self.turnList) - 1]
  1316. else:
  1317. return self.turnList[currentIndex-1]
  1318.  
  1319. def getPlayer(self, playerID):
  1320. return self.players[playerID]
  1321.  
  1322. def resetDrawBool(self):
  1323. for identity in self.players:
  1324. self.players[identity].drew = False
  1325.  
  1326. def Uno(debugging=False):
  1327.  
  1328. ###MENUS###
  1329.  
  1330. def clearShell():
  1331. os.system('cls' if os.name == 'nt' else 'clear')
  1332.  
  1333. def mainMenu():
  1334. sys.stdout.write("\x1b[8;32;63t")
  1335. sys.stdout.flush()
  1336. gs = GameSettings()
  1337.  
  1338. while True:
  1339.  
  1340. print(drawMainMenu(gs))
  1341.  
  1342. selection = str(input('\033[97mSelection: \033[92m'))
  1343. while selection not in ['1', '2', '3', '4', '5']:
  1344. gs.mainMenuError = "Invalid Selection"
  1345. print(drawMainMenu(gs))
  1346. selection = str(input('\033[97mSelection: \033[92m'))
  1347.  
  1348. if selection == '1':
  1349. if gs.canBegin():
  1350. gs.mainMenuError = ""
  1351. gs.finalizePlayers()
  1352. gs = playMatch(gs)
  1353. else:
  1354. gs.mainMenuError = "Two Players Required to Begin"
  1355.  
  1356. elif selection == '2':
  1357. if gs.canAddPlayer():
  1358. gs.mainMenuError = ""
  1359. gs = addPlayer(gs)
  1360. else:
  1361. gs.mainMenuError = "Max Number of Players Reached"
  1362.  
  1363. elif selection == '3':
  1364. if gs.canAddPlayer():
  1365. gs.mainMenuError = ""
  1366. gs = addComputer(gs)
  1367. else:
  1368. gs.mainMenuError = "Max Number of Players Reached"
  1369.  
  1370. elif selection == '4':
  1371. if gs.canRemovePlayer():
  1372. gs.mainMenuError = ""
  1373. gs = removePlayer(gs)
  1374. else:
  1375. gs.mainMenuError = "No Players to Remove"
  1376.  
  1377. elif selection == '5':
  1378. gs.mainMenuError = ""
  1379. gs = settingsMenu(gs)
  1380.  
  1381. else:
  1382. raise BadInputError('Data Provided Has No Function')
  1383.  
  1384. def playMatch(gs):
  1385. for i in range(1):
  1386. i
  1387. m = Match(gs)
  1388. m.begin()
  1389. while (not m.isComplete()):
  1390. m.nextTurn()
  1391. gs = m.end(gs)
  1392. return gs
  1393.  
  1394. def addPlayer(gs):
  1395. colors = ['\033[91m','\033[94m', '\033[92m', '\033[93m']
  1396. nameOkay = False
  1397. playerNum = gs.getPlayerNum() + 1
  1398. colorIndex = playerNum - 1
  1399. message = "\033[97mPlease Enter Player {}'s Name: {}".format(playerNum, colors[colorIndex])
  1400.  
  1401. while not nameOkay:
  1402. print(drawMainMenu(gs))
  1403. name = str(input(message)).title()
  1404. if len(name) > 11:
  1405. gs.mainMenuError = "Name Must Be 11 Characters or Less!"
  1406. elif len(name) == 0:
  1407. gs.mainMenuError = ""
  1408. return gs
  1409. else:
  1410. nameOkay = True
  1411. for player in gs.playerStaging:
  1412. if player.getName() == name:
  1413. nameOkay = False
  1414. if nameOkay == False or name in GameSettings.computerNames:
  1415. gs.mainMenuError = "Name Cannot Match Another Player's Name!"
  1416.  
  1417. p = Player(name)
  1418. gs.addPlayer(p)
  1419. gs.mainMenuError = ""
  1420.  
  1421. return gs
  1422.  
  1423. def addComputer(gs):
  1424. name = gs.getComputerName()
  1425. c = ComputerPlayer(name)
  1426. gs.addPlayer(c)
  1427.  
  1428. return gs
  1429.  
  1430. def removePlayer(gs):
  1431. sys.stdout.write("\x1b[8;{rows};{cols}t".format(rows=32, cols=63))
  1432. sys.stdout.flush()
  1433. clearShell()
  1434.  
  1435. complete = False
  1436. playerNum = gs.getPlayerNum()
  1437. message = "\033[97mPlease Enter Player Number to Remove: \033[91m".format(playerNum)
  1438.  
  1439. while (not complete):
  1440. print(drawMainMenu(gs))
  1441. number = str(input(message))
  1442. if len(number) == 0:
  1443. gs.mainMenuError = ""
  1444. return gs
  1445. try:
  1446. number = int(number)
  1447. if 0 < number <= playerNum:
  1448. complete = True
  1449. else:
  1450. gs.mainMenuError = "Invalid Player Number!"
  1451. except:
  1452. gs.mainMenuError = "Please Enter the Player Number, not Name!"
  1453.  
  1454. gs.mainMenuError = ""
  1455. gs.removePlayer(number)
  1456. return gs
  1457.  
  1458. def settingsMenu(gs):
  1459. while True:
  1460. sys.stdout.write("\x1b[8;32;63t")
  1461. sys.stdout.flush()
  1462. clearShell()
  1463. print('\n\t\tSettings')
  1464. print('\n\t1. Draw Effects\t\t\t{}'.format(gs.displayEffects))
  1465. print('\t2. Hide Computer Hands\t\t{}'.format(gs.hideComputerHands))
  1466. print('\t3. Computer Speed\t\t{}'.format(gs.computerSpeed.title()))
  1467. #print('\t4. Zero Card Changes Color\t{}'.format(gs.zeroChange))
  1468. #print('\t5. Run Simulations\t\t{}'.format(gs.computerSimulation))
  1469. print('\n\tA. Exit')
  1470.  
  1471. selection = str(input('\nSelection: ')).upper()
  1472. while selection not in ('1', '2', '3', '4', '5', 'A', ''):
  1473. print('\nSelection Invalid')
  1474. selection = str(input('\nSelection: ')).upper()
  1475.  
  1476. if selection == '1':
  1477. gs.displayEffects = not gs.displayEffects
  1478.  
  1479. elif selection == '2':
  1480. gs.hideComputerHands = not gs.hideComputerHands
  1481.  
  1482. elif selection == '3':
  1483. gs.changeComputerSpeed()
  1484. '''
  1485. elif selection == '4':
  1486. gs.zeroChange = not gs.zeroChange
  1487.  
  1488. elif selection == '5':
  1489. gs.computerSimulation = not gs.computerSimulation
  1490. '''
  1491. elif selection == 'A' or selection == '' or selection in ('4','5'):
  1492. return gs
  1493.  
  1494. def drawMainMenu(gs):
  1495. clearShell()
  1496. gs.compileMainMenuElements()
  1497. menuElements = gs.getMainMenuElements()
  1498. screenout = ''
  1499. screenout += '\t\t\033[94m || ||\033[92m ||\ || \033[91m// \\\\\n\033[0m'
  1500. screenout += '\t\t\033[94m || ||\033[92m ||\\\|| \033[91m(( ))\n\033[0m'
  1501. screenout += '\t\t\033[94m \\\ //\033[92m || \|| \033[91m \\\ //\n\033[0m'
  1502. screenout += '\033[97m===============================================================\033[0m\n'
  1503. screenout += "{}1-----------------------------1\033[0m {}2-----------------------------2\033[0m\n".format(menuElements['play1box'],menuElements['play2box'])
  1504. screenout += "{}|{}|\033[0m {}|{}|\033[0m\n".format(menuElements['play1box'],menuElements['play1row1'],menuElements['play2box'],menuElements['play2row1'])
  1505. screenout += "{}|{}|\033[0m {}|{}|\033[0m\n".format(menuElements['play1box'],menuElements['play1row2'],menuElements['play2box'],menuElements['play2row2'])
  1506. screenout += "{}1-----------------------------1\033[0m {}2-----------------------------2\033[0m\n".format(menuElements['play1box'],menuElements['play2box'])
  1507. screenout += "{}3-----------------------------3\033[0m {}4-----------------------------4\033[0m\n".format(menuElements['play3box'],menuElements['play4box'])
  1508. screenout += "{}|{}|\033[0m {}|{}|\033[0m\n".format(menuElements['play3box'],menuElements['play3row1'],menuElements['play4box'],menuElements['play4row1'])
  1509. screenout += "{}|{}|\033[0m {}|{}|\033[0m\n".format(menuElements['play3box'],menuElements['play3row2'],menuElements['play4box'],menuElements['play4row2'])
  1510. screenout += "{}3-----------------------------3\033[0m {}4-----------------------------4\033[0m\n".format(menuElements['play3box'],menuElements['play4box'])
  1511. screenout += "\033[97m===============================================================\033[0m\n"
  1512. screenout += " {}\u2666---------------------------\u2666\033[0m \u2666===========================\u2666\n".format(menuElements['beginBox'])
  1513. screenout += " {}|1. Begin Match |\033[0m | High Scores |\n".format(menuElements['beginBox'])
  1514. screenout += " {}\u2666---------------------------\u2666\033[0m \u2666---------------------------\u2666\n".format(menuElements['beginBox'])
  1515. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['addBox'])
  1516. screenout += " {}|2. Add Player |\033[0m | |\n".format(menuElements['addBox'])
  1517. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['addBox'])
  1518. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['addBox'])
  1519. screenout += " {}|3. Add Computer |\033[0m | |\n".format(menuElements['addBox'])
  1520. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['addBox'])
  1521. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['removeBox'])
  1522. screenout += " {}|4. Remove Player |\033[0m | |\n".format(menuElements['removeBox'])
  1523. screenout += " {}\u2666---------------------------\u2666\033[0m | |\n".format(menuElements['removeBox'])
  1524. screenout += " \033[97m\u2666---------------------------\u2666\033[0m | |\n"
  1525. screenout += " \033[97m|5. Settings |\033[0m | |\n"
  1526. screenout += " \033[97m\u2666---------------------------\u2666\033[0m \u2666===========================\u2666\n"
  1527. screenout += "\033[97m===============================================================\033[0m\n"
  1528. screenout += '\033[91m{}\033[0m'.format(gs.mainMenuError)
  1529. return screenout
  1530.  
  1531. mainMenu()
  1532.  
  1533. if __name__ == "__main__":
  1534. Uno()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement