board.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import numpy as np
  2. class Board:
  3. MAX_BLOB = 255.0
  4. MIN_BLOB = 0.0
  5. MIN_FOOD_BLOB = 50
  6. DECREASE_BLOB = 0.1
  7. INIT_FOOD = 100
  8. def __init__(self, width, height):
  9. self.width = width
  10. self.height = height
  11. self.dropped_blob = np.zeros(shape=(width, height), dtype=float)
  12. self.foods = np.zeros(shape=(width, height), dtype=float)
  13. self.touched = np.zeros(shape=(width, height), dtype=bool)
  14. def save(self):
  15. stream = str(self.width) + ' ' + str(self.height) + '\n'
  16. for y in range(self.height):
  17. for x in range(self.width):
  18. # TODO change food savings
  19. saved_node = "{:d},{:d},{} ".format(self.touched[x, y], self.foods[x, y] != 0, self.dropped_blob[x, y])
  20. stream += saved_node
  21. stream = stream.rstrip(' ')
  22. stream += '\n'
  23. return stream.rstrip('\n')
  24. def load(self, filename):
  25. with open(filename, 'r') as file:
  26. dim = file.readline()
  27. dims = dim.split(' ')
  28. if dims[0] != self.width and dims[1] != self.height:
  29. self.__init__(int(dims[0]), int(dims[1]))
  30. y = 0
  31. for line in file:
  32. nodes = line.split(' ')
  33. if len(nodes) != self.width:
  34. print("Error with given height !" + str(len(nodes)))
  35. x = 0
  36. for node in nodes:
  37. values = node.split(',')
  38. if len(values) != 3:
  39. print("Error with packaged values !")
  40. self.touched[x, y] = values[0] == '1'
  41. # TODO Adapt loadings
  42. if values[1] == '1':
  43. self.foods[x, y] = Board.INIT_FOOD
  44. self.dropped_blob[x, y] = float(values[2])
  45. x += 1
  46. y += 1
  47. def has_food(self, x, y):
  48. return self.inside(x, y) and self.foods[x, y] > 0
  49. def set_food(self, x, y):
  50. if not self.foods[x, y] > 0:
  51. self.foods[x, y] = Board.INIT_FOOD
  52. def remove_food(self, x, y):
  53. if self.foods[x, y] > 0:
  54. self.foods[x, y] = 0
  55. def update_blob(self, x, y, change_value):
  56. if self.inside(x, y):
  57. self.touched[x, y] = True
  58. self.dropped_blob[x, y] = max(0, min(self.dropped_blob[x, y] + change_value, Board.MAX_BLOB))
  59. return True
  60. else:
  61. return False
  62. def eat_food(self, x, y, change_value):
  63. if self.foods[x, y] > 0:
  64. if self.foods[x, y] - change_value >= 0:
  65. self.foods[x, y] -= change_value
  66. else:
  67. change_value = self.foods[x, y]
  68. self.foods[x, y] = 0
  69. else:
  70. change_value = 0
  71. return change_value, self.foods[x, y] <= 0
  72. def get_blob(self, x, y):
  73. if self.inside(x, y):
  74. return self.dropped_blob[x, y]
  75. else:
  76. return None
  77. def inside(self, x, y):
  78. return 0 <= x < self.width and 0 <= y < self.height
  79. def is_touched(self, x, y):
  80. if self.inside(x, y):
  81. return self.touched[x, y]
  82. else:
  83. return False
  84. def get_cover(self, half_board=0):
  85. if half_board == 1:
  86. val = np.sum(self.touched[:, 0:int(self.height/2)]) * 2
  87. elif half_board == 2:
  88. val = np.sum(self.touched[:, int(self.height/2):self.height]) * 2
  89. else:
  90. val = np.sum(self.touched)
  91. return val / self.height / self.width * 100
  92. def get_blob_total(self):
  93. total = 0
  94. for x in range(self.width):
  95. for y in range(self.height):
  96. total += self.dropped_blob[x, y]
  97. return total / self.height / self.width / self.MAX_BLOB * 100
  98. def next_turn(self, food_lock=True):
  99. for x in range(self.width):
  100. for y in range(self.height):
  101. if self.touched[x, y]:
  102. if not (food_lock and self.foods[x, y] > 0 and self.dropped_blob[x, y] <= Board.MIN_FOOD_BLOB):
  103. self.update_blob(x, y, -Board.DECREASE_BLOB)
  104. def reset(self, x, y):
  105. if self.inside(x, y):
  106. self.touched[x, y] = False
  107. self.dropped_blob[x, y] = 0
  108. self.foods[x, y] = 0
  109. def compare(self, board):
  110. if board.height != self.height and board.width != self.width:
  111. print("Size don't match !")
  112. return None
  113. board_comp = Board(self.width, self.height)
  114. for x in range(self.width):
  115. for y in range(self.height):
  116. board_comp.foods[x, y] = board.foods[x, y] - self.foods[x, y]
  117. board_comp.touched[x, y] = self.touched[x, y] == board.touched[x, y]
  118. board_comp.dropped_blob[x, y] = board.dropped_blob[x, y] - self.dropped_blob[x, y]
  119. return board_comp