from ShootResult import ShootResult from ShipDirection import ShipDirection from ShipMode import ShipMode class ShipField: def __init__(self): self.field = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '] self.ships = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1] self.field_size = 10 self.field_mode = ShipMode.PUT self.ship_size = 4 self.ship_direction = ShipDirection.VERTICAL def __getitem__(self, item): if item is None: return None if type(item) is not int and item.isnumeric(): item = int(item) if type(item) is int and 0 <= item <= len(self.field): return self.field[item] return None def action(self, row, col): self.clear_marker() if self.field_mode == ShipMode.PUT: #if self.check_ship(row, col): # self.get_ship(row, col) #elif if self.ship_size in self.ships and self.check_possible(row, col): self.set_ship(row, col) elif self.field_mode == ShipMode.SHOOT: self.shoot(row, col) def target(self, row, col): self.clear_marker() if self.field_mode == ShipMode.PUT: if self.check_possible(row, col): if self.ship_direction == ShipDirection.VERTICAL: for r in range(row, row + self.ship_size): if self.ship_size in self.ships: self.field[r * self.field_size + col] = 'p' else: self.field[r * self.field_size + col] = 'r' if self.ship_direction == ShipDirection.HORIZONTAL: for c in range(col, col + self.ship_size): if self.field_size in self.ships: self.field[row * self.field_size + c] = 'p' else: self.field[row * self.field_size + c] = 'r' else: self.field[row * self.field_size + col] = '+' def clear_marker(self): for i in range(0, len(self.field)): if self.field[i] == 'p' or self.field[i] == 'r': self.field[i] = '' if '+' in self.field[i]: self.field[i] = self.field[i].replace('+', '') def set_ship(self, row, col): if row < 0 or row > self.field_size: return if col < 0 or col > self.field_size: return index = row * self.field_size + col if self.ship_direction == ShipDirection.VERTICAL: if self.field_size - row < self.ship_size: return for r in range(row, row + self.ship_size): index = r * self.field_size + col self.field[index] = "1" if self.ship_direction == ShipDirection.HORIZONTAL: if self.field_size - col < self.ship_size: return for c in range(col, col + self.ship_size): index = row * self.field_size + c self.field[index] = "1" if self.ship_size in self.ships: self.ships.remove(self.ship_size) def shoot(self, row, col): if row < 0 or row > self.field_size - 1: return ShootResult.UNDEFINED if col < 0 or col > self.field_size - 1: return ShootResult.UNDEFINED index = row * self.field_size + col if (self.field[index]).strip() == "": self.field[index] = "0" return ShootResult.EMPTY elif (self.field[index]).strip() == "1": self.field[index] = "\\" return ShootResult.DAMAGED else: return ShootResult.UNDEFINED def check_possible(self, row, col): if self.ship_direction == ShipDirection.VERTICAL: if self.field_size - row >= self.ship_size: for r in range(row, row + self.ship_size): if not self.check_blocked(r, col): return False return True if self.ship_direction == ShipDirection.HORIZONTAL: if self.field_size - col >= self.ship_size: for c in range(col, col + self.ship_size): if not self.check_blocked(row, c): return False return True return False def check_blocked(self, row, col): for r in range(row - 1, row + 2): for c in range(col - 1, col + 2): if 0 <= r < self.field_size and 0 <= c < self.field_size: cell = (self.field[r * self.field_size + c]).strip() if cell != '' and cell != 'p': return False return True def set_ship_size(self, value): if value is None: return if type(value) is str and value.isnumeric(): value = int(value) if type(value) is int and 1 <= value <= 4: self.ship_size = value def set_ship_direction(self, value): if value is None: return if value != ShipDirection.UNKNOWN: self.ship_direction = value def toggle_ship_direction(self): if self.ship_direction == ShipDirection.VERTICAL: self.ship_direction = ShipDirection.HORIZONTAL else: self.ship_direction = ShipDirection.VERTICAL def toggle_field_mode(self): if self.field_mode == ShipMode.PUT: self.field_mode = ShipMode.SHOOT else: self.field_mode = ShipMode.PUT def print_field(self): print(self.ships) for r in range(0, self.field_size): blocked_string = '' ship_string = '' for c in range(0, self.field_size): blocked_string += str(self.check_blocked(r, c))[0] + ', ' ship_string += self.field[r * self.field_size + c] + ', ' print(ship_string[: -2]) print('********************************************************') @staticmethod def convert_to_json(obj): if isinstance(obj, ShipField): result = obj.__dict__ result['field_mode'] = obj.field_mode.value result['ship_direction'] = obj.ship_direction.value return result