コード例 #1
0
def is_one_hive(tiles: List[board.Tile]):
    tiles_count = len(tiles)
    main_hive = []
    if len(tiles) <= 1:
        return True

    main_tile = tiles.pop(0)
    main_hive.append(main_tile)
    stop = False
    actual_tiles = []
    while not stop:
        possible_tiles = hexutil.touching_hexagons(hexutil.Point(main_tile.x, main_tile.y))
        # check for above piece
        possible_tiles.append(hexutil.Point(main_tile.x, main_tile.y))
        for tile in possible_tiles:
            match = next((i for i in range(0, len(tiles)) if tiles[i].x == tile.x and tiles[i].y == tile.y), None)
            if match is not None:
                touching_tile = tiles.pop(match)
                actual_tiles.append(touching_tile)
                main_hive.append(touching_tile)
        if len(actual_tiles) != 0:
            main_tile = actual_tiles.pop(0)
        else:
            stop = True

    return tiles_count == len(main_hive)
コード例 #2
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
    def on_event(self, event):
        if event.type == pygame.QUIT:
            self._running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            clicked = pygame.mouse.get_pos()
            clicked = self.convert_to_play_area_coordinates(
                clicked[0], clicked[1])
            if clicked[0] > 0 and clicked[1] > 0:
                self.on_play_area_click(event)
            else:
                print(piece)
                # run player click

        elif event.type == pygame.MOUSEBUTTONUP:
            self.drag = False
            self.last_coord = None

        elif event.type == pygame.MOUSEMOTION:
            if self.drag:
                place = pygame.mouse.get_pos()
                coord = hexutil.Point(place[0], place[1])
                # don't need to convert so it can technically move offscreen correctly
                self.origin = hexutil.Point(
                    self.origin.x + (coord.x - self.last_coord.x),
                    self.origin.y + (coord.y - self.last_coord.y),
                )
                self.last_coord = coord
コード例 #3
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
    def render_piece_in_play(self, surface, tile, scale):
        font = self.font()
        text = font.render(tile.piece.species, True,
                           self.species_color_map[tile.piece.species])
        offset = 0
        if tile.z > 0:
            offset = 5 * tile.z
        text_rect: pygame.rect = text.get_rect()
        # set the center of the rectangular object.
        center = hexutil.hexagon_to_pixel(self.origin,
                                          hexutil.Point(tile.x, tile.y), scale)
        text_rect.center = (center.x + offset, center.y + offset)

        corners = hexutil.polygon_corners(self.origin,
                                          hexutil.Point(tile.x, tile.y), scale)
        corners = [hexutil.Point(i.x + offset, i.y + offset) for i in corners]
        pygame.draw.polygon(surface,
                            ((50, 50, 50), (222, 220,
                                            193))[tile.piece.color == 'W'],
                            corners, 0)
        if tile.piece is self.selected_piece:
            pygame.draw.polygon(surface, (55, 250, 250), corners, scale // 8)
        else:
            pygame.draw.polygon(surface,
                                ((90, 90, 90), (235, 233,
                                                209))[tile.piece.color == 'W'],
                                corners, scale // 12)
        surface.blit(text, text_rect)
コード例 #4
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
    def on_play_area_click(self, event):
        clicked = pygame.mouse.get_pos()
        clicked = self.convert_to_play_area_coordinates(clicked[0], clicked[1])

        if event.button == 4:
            # prevents getting trapped at small scales
            self.scale = int(self.scale * 1.15) + 1
            return
        elif event.button == 5:
            self.scale = max(int(self.scale * .85), 2)
            return
        elif event.button == 3:
            self.drag = True
            self.last_coord = hexutil.Point(clicked[0], clicked[1])
            return

        elif event.button == 1:
            est = hexutil.pixel_to_closest_hexagon(
                self.origin, hexutil.Point(clicked[0], clicked[1]), self.scale)
            if est is not None:
                # todo: figure out z axis here
                if self.board.space_occupied(est.x, est.y):
                    if self.selected_piece is not None:
                        self.selected_piece = None
                        return
                    z = 0
                    while self.board.space_occupied(est.x, est.y, z) and z < 7:
                        z = z + 1
                    self.selected_piece = self.board.piece_at(
                        est.x, est.y, z - 1)

                else:
                    self.selected_piece = None
                    return
コード例 #5
0
 def test_can_slide_two(self):
     t = [
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W'))
     ]
     first = t.pop(0)
     self.assertTrue(hiveutil.can_slide_to(hexutil.Point(first.x, first.y), hexutil.Point(3, 0), t, first.z))
コード例 #6
0
 def test_can_not_hop_hopper_space(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W')),
         board.Tile(3, 1, 0, piece.create_ladybug('W')),
         board.Tile(4, 0, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_hopper('B'))
     self.assertFalse(hiveutil.space_hopable(p, hexutil.Point(5, 0), t, hiveutil.generate_hive_movement_cloud(t, p)))
     self.assertTrue(hiveutil.space_hopable(p, hexutil.Point(3, 0), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #7
0
 def test_can_not_slide_ring(self):
     t = [
         board.Tile(1, 1, 0, piece.create_ladybug('W')),
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W')),
         board.Tile(2, 2, 0, piece.create_ladybug('W')),
         board.Tile(1, 2, 0, piece.create_ladybug('W')),
         board.Tile(0, 1, 0, piece.create_ladybug('W')),
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     first = t.pop(0)
     self.assertFalse(hiveutil.can_slide_to(hexutil.Point(first.x, first.y), hexutil.Point(3, 1), t, first.z))
コード例 #8
0
def space_crawable(start: board.Tile, end: hexutil.Point, tiles: List[board.Tile], movement_cloud):
    # todo: need to be able to work in 3d space
    possible_paths = [deque()]
    # todo: add z axis to Move object
    possible_paths[0].append(Move(hexutil.Point(start.x, start.y), 0))

    temp = tiles[:]
    if start in temp:
        temp.remove(start)

    current_path = possible_paths[0]
    spots = start.piece.crawl_spaces or 20
    for i in range(1, spots + 1):
        paths_to_extend = possible_paths[:]
        p: deque[Move]
        for p in paths_to_extend:
            path_to_be_removed = p
            neighbors = hexutil.touching_hexagons(p[-1].position)
            for n in neighbors:
                # todo: add z axis in can_slide check
                if n in movement_cloud and can_slide_to(p[-1].position, n, temp, start.z):
                    # not (dir != p[-1]dir and not p[-2].hex == n)
                    if len(p) >= 2 and p[-2].position == n:
                        continue
                    elif n == end and start.piece.crawl_spaces is None:
                        return True
                    # todo: add in z axis when adding new move (axis of start z, cannot change)
                    possible_paths.append(p + deque([Move(n, direction_of_crawl(p[-1].position, n, temp))]))
                    # at end and cannot be moved to
                elif n == end:
                    return False

            possible_paths.remove(path_to_be_removed)

    return any(move[-1].position == end for move in possible_paths)
コード例 #9
0
 def test_can_not_crawl_to_spider_back_and_forth(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_spider('W'))
     self.assertFalse(hiveutil.space_crawable(p,
                                              hexutil.Point(0, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #10
0
 def test_can_crawl_to_spider(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_spider('W'))
     self.assertTrue(hiveutil.space_crawable(p,
                                             hexutil.Point(2, 0), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #11
0
 def test_valid_moves_single_ant(self):
     t = [
         board.Tile(0, 0, 0, piece.create_ant('W')),
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     moves = hexutil.touching_hexagons(hexutil.Point(1, 0))
     self.assertCountEqual(hiveutil.generate_valid_moves(t[0], t), moves)
コード例 #12
0
    def test_can_not_crawl_to_beetle_out_of_range(self):
        t = [

            board.Tile(1, 0, 0, piece.create_ladybug('W')),
        ]
        p = board.Tile(0, 0, 0, piece.create_beetle('W'))
        self.assertFalse(hiveutil.space_crawable(p,
                                                 hexutil.Point(1, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #13
0
 def test_can_crawl_to_beetle_on_top(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
         board.Tile(1, 1, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(1, 0, 1, piece.create_beetle('W'))
     self.assertTrue(hiveutil.space_crawable(p,
                                             hexutil.Point(1, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #14
0
def space_hopable(start: board.Tile, end: hexutil.Point, tiles: List[board.Tile], movement_cloud):
    # determine if start and end are in the same line
    x_dist = hexutil.relative_distance_x(hexutil.Point(start.x, start.y), end)
    y_dist = hexutil.relative_distance_y(hexutil.Point(start.x, start.y), end)
    angle = angle_of_vector(x_dist, y_dist)
    if angle % 60 != 0:
        return False
    # determine if there are spaces open in that line
    match = -1
    space = start
    while end != space:
        n = hexutil.touching_hexagons(space)[int(angle / 60)]
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y), None)
        if match is None and end != n:
            return False
        space = n
    return True
コード例 #15
0
 def get_occupied_tiles(self):
     tiles = []
     for p in self.play_space.items():
         point = hexutil.Point(p[0][0], p[0][1])
         if self.space_occupied(point.x, point.y, 0):
             for z in range(0, len(p[1])):
                 tiles.append(Tile(point.x, point.y, z, self.piece_at(point.x, point.y, z)))
     tiles.sort(key=lambda tile: (tile.z, tile.x, tile.y))
     return tiles
コード例 #16
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
    def render_player_space(self):
        line_start = self.convert_to_play_area_coordinates(0, self.height)
        pygame.draw.line(self._player_surface, (100, 100, 100),
                         (line_start[0] - 1, 0),
                         (line_start[0] - 1, self.height))
        font = pygame.font.SysFont(None, 36)
        labels = []
        tile: piece.Piece
        last_tile: piece.Piece = piece.Piece("", "")
        offset = 0
        for tile in self.board.player_1.piece_reserve + self.board.player_2.piece_reserve:

            if tile.color == last_tile.color and tile.species == last_tile.species:
                offset += 5
                labels.pop()
            else:
                offset = 0
            text = font.render(tile.species, True, (255, 0, 0))
            text_rect = text.get_rect()
            center = hexutil.hexagon_to_pixel(
                self.player_piece_layout[tile.color][tile.species],
                hexutil.Point(0, 0),
                self.player_piece_offset(1) * .9)
            text_rect.center = (center.x + offset, center.y + offset)
            labels.append((text, text_rect))
            corners = hexutil.polygon_corners(
                self.player_piece_layout[tile.color][tile.species],
                hexutil.Point(0, 0),
                self.player_piece_offset(1) * .9)
            corners = [
                hexutil.Point(i.x + offset, i.y + offset) for i in corners
            ]
            pygame.draw.polygon(self._player_surface,
                                ((50, 50, 50),
                                 (255, 254, 242))[tile.color == 'W'], corners,
                                0)
            pygame.draw.polygon(self._player_surface, (0, 0, 0), corners, 2)
            last_tile = tile

        self._display_surface.blit(self._player_surface, (0, 0))
        for label in labels:
            self._display_surface.blit(label[0], label[1])
コード例 #17
0
 def test_can_not_crawl_to_ant_gates(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W')),
         board.Tile(2, 2, 0, piece.create_ladybug('W')),
         board.Tile(1, 2, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_ant('W'))
     self.assertFalse(hiveutil.space_crawable(p,
                                              hexutil.Point(1, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #18
0
 def test_can_crawl_to_spider_strange_case(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W')),
         board.Tile(2, 2, 0, piece.create_ladybug('W')),
         board.Tile(1, 3, 0, piece.create_ladybug('W')),
         board.Tile(0, 3, 0, piece.create_ladybug('W')),
         board.Tile(0, 2, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_spider('W'))
     cloud = hiveutil.generate_hive_movement_cloud(t, p)
     self.assertTrue(hiveutil.space_crawable(p
                                             , hexutil.Point(1, 2), t, cloud))
     self.assertTrue(hiveutil.space_crawable(p,
                                             hexutil.Point(1, 1), t, cloud))
     self.assertTrue(hiveutil.space_crawable(p,
                                             hexutil.Point(2, -1), t, cloud))
     self.assertTrue(hiveutil.space_crawable(p,
                                             hexutil.Point(-1, 2), t, cloud))
コード例 #19
0
def generate_hive_movement_cloud(tiles: List[board.Tile], mover):
    possible_spots = []
    for tile in tiles:
        neighbors = hexutil.touching_hexagons(hexutil.Point(tile.x, tile.y))
        for n in neighbors:
            if n in possible_spots:
                continue
            match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y
                          and tiles[i].z == mover.z), None)
            # if tile not occupied
            if match is None:
                possible_spots.append(n)
    return possible_spots
コード例 #20
0
 def test_can_crawl_to_ant_gates_in_big_ring(self):
     t = [
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(3, 0, 0, piece.create_ladybug('W')),
         board.Tile(4, 0, 0, piece.create_ladybug('W')),
         board.Tile(4, 1, 0, piece.create_ladybug('W')),
         board.Tile(4, 2, 0, piece.create_ladybug('W')),
         board.Tile(3, 3, 0, piece.create_ladybug('W')),
         board.Tile(2, 3, 0, piece.create_ladybug('W')),
         board.Tile(1, 3, 0, piece.create_ladybug('W')),
         board.Tile(1, 2, 0, piece.create_ladybug('W'))
     ]
     p = board.Tile(1, 0, 0, piece.create_ant('W'))
     self.assertTrue(hiveutil.space_crawable(p
                                             , hexutil.Point(3, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #21
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
 def on_init(self):
     pygame.init()
     self._display_surface = pygame.display.set_mode(
         self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
     self._running = True
     self._sys_font = pygame.font.get_default_font()
     self._background = pygame.Surface(self._display_surface.get_size())
     self._background.fill((219, 210, 127))
     self._board_surface = pygame.Surface(
         (int(self.width * self.board_x_split_percentage), self.height))
     self.origin = hexutil.Point(
         self.width * self.board_x_split_percentage // 2, self.height // 2)
     self._board_surface.fill((219, 210, 127))
     self._player_surface = pygame.Surface(
         (self.width - int(self.width * self.board_x_split_percentage),
          self.height))
     self._player_surface.fill((200, 200, 200))
     return True
コード例 #22
0
 def test_movement_cloud_one_piece(self):
     t = [
         board.Tile(1, 1, 0, piece.create_ladybug('W'))
     ]
     cloud = [
         hexutil.Point(2, 0),
         hexutil.Point(2, 1),
         hexutil.Point(2, 2),
         hexutil.Point(1, 2),
         hexutil.Point(0, 1),
         hexutil.Point(1, 0),
     ]
     self.assertCountEqual(hiveutil.generate_hive_movement_cloud(t, t[0]), cloud)
コード例 #23
0
def can_start_hop(start: hexutil.Point, tiles: List[board.Tile], z):
    neighbors = hexutil.touching_hexagons(hexutil.Point(start.x, start.y))
    touches = 0
    max_continuous_touches = 0
    continuous_touches = 0
    for n in neighbors:
        match = next((i for i in range(0, len(tiles)) if tiles[i].x == n.x and tiles[i].y == n.y
                      and tiles[i].z == z), None)
        if match is not None:
            touches += 1
            continuous_touches += 1
            max_continuous_touches = max(max_continuous_touches, continuous_touches)
        else:
            continuous_touches = 0

    if touches == max_continuous_touches:
        return True
    else:
        return False
コード例 #24
0
 def test_movement_cloud_six_piece_ring(self):
     t = [
         board.Tile(2, 0, 0, piece.create_ladybug('W')),
         board.Tile(2, 1, 0, piece.create_ladybug('W')),
         board.Tile(2, 2, 0, piece.create_ladybug('W')),
         board.Tile(1, 2, 0, piece.create_ladybug('W')),
         board.Tile(0, 1, 0, piece.create_ladybug('W')),
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     cloud = [
         hexutil.Point(1, 1),
         hexutil.Point(3, 1),
         hexutil.Point(3, 2),
         hexutil.Point(2, 3),
         hexutil.Point(1, 3),
         hexutil.Point(0, 3),
         hexutil.Point(0, 2),
         hexutil.Point(-1, 1),
         hexutil.Point(0, 0),
         hexutil.Point(0, -1),
         hexutil.Point(1, -1),
         hexutil.Point(2, -1),
         hexutil.Point(3, 0),
     ]
     self.assertCountEqual(hiveutil.generate_hive_movement_cloud(t, t[0]), cloud)
コード例 #25
0
 def test_can_not_hop_hopper_simple_off_direction(self):
     t = [
         board.Tile(1, 0, 0, piece.create_ladybug('W')),
     ]
     p = board.Tile(0, 0, 0, piece.create_hopper('B'))
     self.assertFalse(hiveutil.space_hopable(p, hexutil.Point(1, 1), t, hiveutil.generate_hive_movement_cloud(t, p)))
コード例 #26
0
ファイル: game.py プロジェクト: Rpifer/BoardGameArenaHive
 def __init__(self):
     self._running = True
     self._display_surface = None
     self._sys_font = None
     self._background = None
     self._board_surface = None
     self.board_x_split_percentage = 0.8
     self._player_surface = None
     self.board = board.Board()
     self.size = self.width, self.height = 900, 600
     self.origin = hexutil.Point(self.width // 2, self.height // 2)
     self.scale = 50
     self.selected_piece = None
     self.drag = False
     self.last_coord = None
     self.player_piece_layout = dict(
         W={
             'Q':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(1)),
             'A':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(2)),
             'S':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(3)),
             'H':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(4)),
             'B':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(5)),
             'M':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(6)),
             'L':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(7)),
             'P':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(8))
         },
         B={
             'Q':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(9)),
             'A':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(10)),
             'S':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(11)),
             'H':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(12)),
             'B':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(13)),
             'M':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(14)),
             'L':
             hexutil.Point(self.player_piece_offset(1),
                           self.player_piece_offset(15)),
             'P':
             hexutil.Point(
                 self.player_piece_offset(1) * 3,
                 self.player_piece_offset(16))
         })
     self.species_color_map = {
         "A": (17, 99, 207),
         "B": (182, 20, 196),
         "H": (45, 153, 41),
         "L": (179, 13, 7),
         "M": (156, 156, 156),
         "P": (86, 219, 184),
         "Q": (227, 219, 59),
         "S": (115, 85, 46),
     }