game.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. WALL_NONE = 0
  2. WALL_TOP = 1
  3. WALL_RIGHT = 2
  4. WALL_BOTTOM = 4
  5. WALL_LEFT = 8
  6. WALL_ALL = WALL_TOP | WALL_RIGHT | WALL_BOTTOM | WALL_LEFT
  7. class Game:
  8. def __init__(self, w, h):
  9. assert w > 1 and h > 1
  10. self.w = w
  11. self.h = h
  12. self.rooms = [[None] * w for _ in xrange(h)]
  13. self.walls = [[WALL_NONE] * w for _ in xrange(h)]
  14. for col in xrange(w):
  15. self.walls[0][col] |= WALL_TOP
  16. self.walls[-1][col] |= WALL_BOTTOM
  17. for row in self.walls:
  18. row[0] |= WALL_LEFT
  19. row[-1] |= WALL_RIGHT
  20. def click_wall(self, x, y, direction, player):
  21. def try_click(x, y, d):
  22. if 0 <= x < self.w and 0 <= y < self.h:
  23. if self.walls[y][x] & d:
  24. raise ValueError('dir %d already set on %d,%d' % (d, x, y))
  25. self.walls[y][x] |= d
  26. if self.walls[y][x] == WALL_ALL:
  27. self.rooms[y][x] = player
  28. rooms.append((x, y))
  29. rooms = []
  30. try_click(x, y, direction)
  31. if direction == WALL_TOP:
  32. try_click(x, y - 1, WALL_BOTTOM)
  33. elif direction == WALL_RIGHT:
  34. try_click(x + 1, y, WALL_LEFT)
  35. elif direction == WALL_BOTTOM:
  36. try_click(x, y + 1, WALL_TOP)
  37. elif direction == WALL_LEFT:
  38. try_click(x - 1, y, WALL_RIGHT)
  39. return rooms
  40. def __str__(self):
  41. roomwidth = 3
  42. s = ('+' + '-' * roomwidth) * self.w + '+\n'
  43. for y, (rrow, wrow) in enumerate(zip(self.rooms, self.walls)):
  44. for x, (p, wall) in enumerate(zip(rrow, wrow)):
  45. s += '|' if wall & WALL_LEFT else ' '
  46. s += ('%%-%dd' % roomwidth) % p if p else ' ' * roomwidth
  47. s += '|\n'
  48. for wall in wrow:
  49. s += '+'
  50. s += ('-' if wall & WALL_BOTTOM else ' ') * roomwidth
  51. s += '+'
  52. if y != self.h - 1:
  53. s += '\n'
  54. return s
  55. def is_finished(self):
  56. return all(all(row) for row in self.rooms)
  57. def scores(self):
  58. indexed = {}
  59. for row in self.rooms:
  60. for player in row:
  61. if player:
  62. indexed[player] = indexed.get(player, 0) + 1
  63. return indexed
  64. def sorted_scores(self):
  65. scores = self.scores().items()
  66. scores.sort(key=lambda (player, score): score, reverse=True)
  67. return scores