def create_ships(self): ships = (4, 3, 3, 2, 2, 2, 1, 1, 1, 1) board = Field(size=self.size) a = 0 for i in ships: while True: a += 1 if a > 2000: return None ship = Ship(Dot(randint(0, self.size), randint(0, self.size)), randint(1, 2), i) try: board.add_ship(ship) break except CannotPlaceShip: pass board.check() return board
class Player(object): def __init__(self, name, size): self.name = name self.ships = [] self.field_size = size self.my_field = Field(size, is_enemy=False) self.enemy_field = Field(size, is_enemy=True) self.verbose = True def __str__(self): return self.name def print_for_player(self, message): if self.verbose: print(message) def place_ships(self): self.print_for_player("Now it's time for "+self.name+' to place ships!') for length, count in SHIPS_SET: for _ in range(count): while True: try: ship = self.__class__.ship_input(length, self.field_size) if not ship.valid_ship_position(self.field_size): self.print_for_player('Ship is out of field.') continue for other_ship in self.ships: if other_ship.intersects(ship): raise IndexError self.ships.append(ship) self.print_for_player('Ship is added!') self.my_field.add_ship(ship) if self.verbose: self.my_field.draw_field() except ValueError: self.print_for_player('Bad input.') continue except IndexError: self.print_for_player('Ship is intersecting with other ship') continue else: break @staticmethod def ship_input(length, field_size): print('Place ship with length '+str(length)) orientation = '-' if length != 1: orientation = get_input('Enter orientation, | or - :') if orientation not in ['|', '-']: raise ValueError() cords = get_input('Enter coordinates of upper-left corner of ship (F7 for example):') x = letter_to_int(cords[0]) y = int(cords[1:])-1 if (x not in range(0, field_size)) or (y not in range(0, field_size)): raise ValueError() ship = Ship(x, y, length, orientation) return ship def draw_fields(self): print('Your field:') self.my_field.draw_field() print('Your shots:') self.enemy_field.draw_field() def make_move(self): while True: try: cords = get_input(self.name+', take a shot! Enter shot coordinates (A1 for example):') x = letter_to_int(cords[0]) y = int(cords[1:])-1 if (x not in range(0, self.field_size)) or (y not in range(0, self.field_size)): raise ValueError() except ValueError: print('Bad input.') continue else: break return x, y
class Player: def __init__(self, name: str, window: Window = None): self.name = name self.field = Field(10, 10) self.window = window self.score = 0 def setup(self, screen: Any, max_y: int, max_x: int, min_y: int, min_x: int): ship_size = 5 i = 0 ship_pts = [] vert = True f_x = round((max_x + min_x) / 2) - 5 f_y = round((max_y + min_y) / 2) - 5 while True: if len(ship_pts) == ship_size: xs = [pt.x for pt in ship_pts] ys = [pt.y for pt in ship_pts] self.field.add_ship( Ship(Point(min(xs), min(ys)), Point(max(xs), max(ys)))) ship_pts = [] i += 1 if i == 5: break elif i == 5 + 1 - ship_size: ship_size -= 1 i = 0 e = screen.getch() if e == ord('q'): break if e == curses.KEY_MOUSE: _, mx, my, _, _ = curses.getmouse() if min_x <= mx <= max_x and min_y <= my <= max_y: if len(ship_pts) == 0: screen.addstr(my, mx, "x") ship_pts.append(Point(int(mx - f_x), int(my - f_y))) elif len(ship_pts) == 1 and \ ((abs(ship_pts[0].x + f_x - mx) == 1 and ship_pts[0].y + f_y == my) or (abs(ship_pts[0].y + f_y - my) == 1 and ship_pts[0].x + f_x == mx)): vert = (abs(ship_pts[0].x + f_x - mx) == 1 and ship_pts[0].y + f_y == my) screen.addstr(my, mx, "x") ship_pts.append(Point(int(mx - f_x), int(my - f_y))) elif len(ship_pts) > 1: for pt in ship_pts: if (vert and (abs(pt.x + f_x - mx) == 1 and pt.y + f_y == my)) or \ (not vert and (abs(pt.y + f_y - my) == 1 and pt.x + f_x == mx)): screen.addstr(my, mx, "x") ship_pts.append( Point(int(mx - f_x), int(my - f_y))) break def launch(self, point: Point, player): gotcha = player.field.launch(point) if gotcha: self.score += 1