fork download
  1. #!/usr/bin/env python3
  2.  
  3. from functools import reduce
  4. from itertools import groupby, zip_longest
  5. from random import randint, sample
  6. from sys import argv, exit
  7.  
  8. class Card(object):
  9. '''トランプのオブジェクト'''
  10. def __init__(self, suit, number):
  11. self.suit = suit
  12. self.number = number
  13.  
  14. # Card クラスのインスタンスの表示形式を調整する
  15. def __repr__(self):
  16. return f"[{self.suit}:{self.number}]"
  17.  
  18. class Player(object):
  19. '''プレイヤーオブジェクト'''
  20. def __init__(self, cards):
  21. self.cards = cards
  22. self.card = False
  23. self.discarded = []
  24. self.message = Message()
  25.  
  26. def drawCard(self, player2, pos):
  27. '''カードを引く'''
  28. self.card = player2.cards[pos]
  29. self.cards += [self.card]
  30. player2.cards = player2.cards[:pos] + player2.cards[pos + 1:]
  31. return player2
  32.  
  33. def discardPair(self):
  34. '''カードを捨てる'''
  35. p = [j[0] for j in [list(i) for key, i in \
  36. groupby(sorted(self.cards, key = lambda x: x.number), \
  37. key = lambda x: x.number)] if len(j) != 2]
  38. self.discarded = list(set(self.cards) - set(p))
  39. self.cards = p
  40. return self
  41.  
  42. def showCards(self, id):
  43. return self.message.showCards(id, self.cards)
  44.  
  45. def showDiscardCards(self, id):
  46. return self.message.showDiscardCards(id, self.discarded)
  47.  
  48. def selectCard(num):
  49. '''num枚のカードから引くカードを決める'''
  50. return randint(0, num - 1)
  51.  
  52. def dealCards(deck, n):
  53. '''カードを配る'''
  54. i = len(deck) // n
  55. acc = [deck[x:x + i] for x in range(0, len(deck), i)]
  56. # ここで Player クラスのインスタンスを生成する
  57. return [Player(i[0] + [i[1]] if i[1] != None else i[0]) for i in \
  58. zip_longest(acc[:-1], acc[-1])]
  59.  
  60. def shuffle_list(lst, n):
  61. '''カードシャッフルする'''
  62. return reduce(lambda x, y: sample(x, len(lst)), range(n), lst)
  63.  
  64. class Message(object):
  65. '''メッセージ'''
  66. def __init__(self):
  67. self.message = {
  68. "inputSelectCard" : "何枚目のカードを引きますか? (0 〜 {0})\n",
  69. "showNumCard" : "プレイヤー{0}のカード: {1}枚\n",
  70. "showCards" : "プレイヤー{0}のカード: {1}\n",
  71. "showDiscardCards" : "プレイヤー{0}が捨てたカード: {1}\n",
  72. "showDrawCard" : "プレイヤー{0} -> プレイヤー{1} : {2}\n",
  73. "showResult" : "プレイヤー{0}の負けです...\n"
  74. }
  75.  
  76. def showCards(self, id, cards):
  77. '''手持ちのカードを表示する'''
  78. if id == 0:
  79. return self.message["showCards"].format(id, self.getCardsStr(cards))
  80. else:
  81. return self.message["showNumCard"].format(id, len(cards))
  82.  
  83. def showDiscardCards(self, id, cards):
  84. '''捨てられたカードを表示する文字列'''
  85. if cards == []:
  86. return ""
  87. else:
  88. return self.message["showDiscardCards"].format(id, \
  89. self.getCardsStr(cards))
  90.  
  91. def showDrawCard(self, id1, id2, card):
  92. '''カードの交換状況を表示する文字列'''
  93. return self.message["showDrawCard"].format(id1, id2, \
  94. self.getCardStr(card))
  95.  
  96. def showResult(self, id):
  97. '''ゲームの結果を表示する文字列'''
  98. return self.message["showResult"].format(id)
  99.  
  100. def getCardsStr(self, cards):
  101. '''Cardオブジェクトのリストを文字列に変換'''
  102. return "".join([self.getCardStr(i) for i in cards])
  103.  
  104. def getCardStr(self, card):
  105. '''Cardオブジェクトを文字列に変換'''
  106. return "{0}".format(card)
  107.  
  108. def make_deck():
  109. '''トランプのカードを作成する'''
  110. return [Card("J", "0")] + [Card(i, "A" if j == 1 else "J" if j == 11 \
  111. else "Q" if j == 12 else "K" if j == 13 \
  112. else str(j)) for i in \
  113. ("D", "H", "S", "C") for j in \
  114. range(1, 14)]
  115.  
  116. class World(object):
  117. '''環境'''
  118. def __init__(self, clist, pair, id1, id2, players):
  119. self.clist = clist
  120. self.pair = pair
  121. self.id1 = id1
  122. self.id2 = id2
  123. self.players = players
  124.  
  125. def insert(self, i, j, player1, player2):
  126. self.players[i] = player1
  127. self.players[j] = player2
  128. return self
  129.  
  130. def next_id(self):
  131. self.pair = [self.id1, self.id2]
  132. self.id1 = next_id(self.clist, self.id1 + 1, self.players)
  133. self.id2 = next_id(self.clist, self.id1 + 1, self.players)
  134. return self
  135.  
  136. def next_id(clist, i, players):
  137. while True:
  138. pos = clist[i % len(clist)]
  139. cards = players[pos].cards
  140. if cards != []:
  141. return pos
  142. i += 1
  143.  
  144. # read
  145.  
  146. def read(w):
  147. id1, id2, players = w.id1, w.id2, w.players
  148. k = len(players[id2].cards)
  149. m = Message()
  150. if id1 == 0:
  151. return int(input(m.message["inputSelectCard"].format(k - 1)))
  152. else:
  153. return selectCard(k)
  154.  
  155. # eval
  156.  
  157. def world_go(exp, w):
  158. id1, id2, players = w.id1, w.id2, w.players
  159. player1, player2 = players[id1], players[id2]
  160. player2 = player1.drawCard(player2, exp)
  161. return w.insert(id1, id2, player1.discardPair(), player2).next_id()
  162.  
  163. # print
  164.  
  165. def display(w):
  166. pair, players = w.pair, w.players
  167. head, tail = pair[0], pair[1]
  168. player = players[head]
  169. m = Message()
  170. print(m.showDrawCard(tail, head, player.card) + \
  171. player.showDiscardCards(head) + \
  172. "".join([j.showCards(i) for i, j in enumerate(players)]), end ="")
  173. return w
  174.  
  175. def is_game_ends(w):
  176. '''ゲーム終了判定'''
  177. return w.id1 == w.id2
  178.  
  179. # 初期化
  180.  
  181. def initialize(n):
  182. players = dealCards(shuffle_list(make_deck(), 7), n)
  183. [print(j.showCards(i), end = "") for i, j in enumerate(players)]
  184. [p.discardPair() for p in players]
  185. [print(j.showDiscardCards(i), end = "") for i, j in enumerate(players)]
  186. [print(j.showCards(i), end = "") for i, j in enumerate(players)]
  187. return World(list(range(n)), [], 0, 1, players)
  188.  
  189. if __name__ == '__main__':
  190. '''REPL'''
  191. w = initialize(int(argv[1]))
  192. m = Message()
  193. while True:
  194. if is_game_ends(w):
  195. print(m.showResult(w.id1))
  196. exit()
  197. try:
  198. w = display(world_go(read(w), w))
  199. except IndexError:
  200. print("不正な入力です")
  201. except ValueError:
  202. print("不正な入力です")
  203. finally:
  204. w
  205.  
Runtime error #stdin #stdout #stderr 0.19s 23476KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Traceback (most recent call last):
  File "./prog.py", line 191, in <module>
IndexError: list index out of range