board.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import enum
  2. import random
  3. class CANDIDATE(enum.Enum):
  4. TOO_LOW = 0
  5. PENALTY = 1
  6. PUT = 2
  7. class Board:
  8. PENALTIES = [(55, 7), (11, 5), (10, 3), (5, 2)]
  9. def __init__(self, nrows = 4, deck_size = 104, max_row_len = 5):
  10. self.ncards = deck_size
  11. self.deck = list(range(1, deck_size + 1))
  12. random.shuffle(self.deck)
  13. #print(self.deck)
  14. self.rows = [[c] for c in self.draw(nrows)]
  15. #print(self.rows)
  16. self.max_row_len = max_row_len
  17. @classmethod
  18. def card_value(cls, card):
  19. for divider, penalty in Board.PENALTIES:
  20. if (card % divider) == 0:
  21. return penalty
  22. return 1
  23. @classmethod
  24. def calc_penalty(cls, row):
  25. return sum(map(Board.card_value, row))
  26. def draw(self, n = 1):
  27. print(len(self.deck), n)
  28. assert len(self.deck) >= n, 'draw: not that many cards in the deck'
  29. top_n = self.deck[:n]
  30. self.deck = self.deck[n:]
  31. return top_n
  32. def reset_row(self, row_ind, card):
  33. assert 0 <= row_ind < len(self.rows), 'reset_row: index is out of the range'
  34. assert 0 < card <= self.ncards, 'reset_row: invalid card'
  35. penalty = self.calc_penalty(self.rows[row_ind])
  36. self.rows[row_ind] = [card]
  37. return penalty
  38. def place_card(self, card):
  39. mindiff = self.ncards
  40. candidate_row = None
  41. minind = -1
  42. for i, row in enumerate(self.rows):
  43. diff = card - row[-1]
  44. if 0 < diff < mindiff:
  45. mindiff = diff
  46. minind = i
  47. candidate_row = row
  48. if not candidate_row:
  49. return (CANDIDATE.TOO_LOW, None) #TODO
  50. elif len(candidate_row) == self.max_row_len:
  51. penalty = self.calc_penalty(candidate_row)
  52. self.rows[minind] = [card]
  53. print(self.rows)
  54. return (CANDIDATE.PENALTY, penalty)
  55. else:
  56. candidate_row.append(card)
  57. return (CANDIDATE.PUT, None) #TODO