minegen.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import random
  2. FIELD_EMOJI_MAP = {
  3. -1: '🇧',
  4. 0: '0️⃣',
  5. 1: '1️⃣',
  6. 2: '2️⃣',
  7. 3: '3️⃣',
  8. 4: '4️⃣',
  9. 5: '5️⃣',
  10. 6: '6️⃣',
  11. 7: '7️⃣',
  12. 8: '8️⃣',
  13. 9: '9️⃣',
  14. }
  15. def _clamp(value: int, min_value: int, max_value: int) -> int:
  16. return max(min(value, max_value), min_value)
  17. class Field:
  18. def __init__(self, width: int, height: int, mine_count: int) -> None:
  19. if width <= 0 or height <= 0 or mine_count <= 0:
  20. raise ValueError('Supplied negative integers for mine field')
  21. self._width = width
  22. self._height = height
  23. self._mine_count = _clamp(mine_count, 1, self._width * self._height)
  24. self._field = self.generate()
  25. def generate(self) -> list[list[int]]:
  26. mine_field = [[0 for _ in range(self._height)] for _ in range(self._width)]
  27. mines_left = self._mine_count
  28. while mines_left > 0:
  29. x = random.randrange(self._width)
  30. y = random.randrange(self._height)
  31. if mine_field[x][y] == -1: continue
  32. mine_field[x][y] = -1
  33. mines_left -= 1
  34. for i in range(self._width):
  35. for j in range(self._height):
  36. if mine_field[i][j] == -1: continue
  37. mine_field[i][j] = self.check_surround(i, j, mine_field)
  38. return mine_field
  39. def check_surround(self, x: int, y: int, mine_field: list[list[int]]) -> int:
  40. neighbors = 0
  41. for i in range(-1, 2):
  42. for j in range(-1, 2):
  43. if i == 0 and j == 0: continue
  44. if x+i < 0 or y+j < 0 or x+i > self._width - 1 or y+j > self._height - 1: continue
  45. if mine_field[x+i][y+j] != -1: continue
  46. neighbors += 1
  47. return neighbors
  48. def __str__(self) -> str:
  49. out = ''
  50. for j in range(self._height):
  51. line = ''
  52. for i in range(self._width):
  53. cell = self._field[i][j]
  54. line += f'||{FIELD_EMOJI_MAP[cell]}||'
  55. out += line + '\n'
  56. return out
  57. if __name__ == '__main__':
  58. field = Field(9, 9, 13)
  59. print(field)