def _get_piece_center(self, piece_coord, piece, terrain_centers): """Takes a piece's hex coordinate, the piece itself, and the terrain_centers dictionary which maps tile_id->(x,y) Returns the piece's center, as an (x,y) pair. Also returns the angle the piece should be rotated at, if any """ if piece.type == PieceType.road: # these pieces are on edges tile_id = hexgrid.nearest_tile_to_edge(piece_coord) tile_coord = hexgrid.tile_id_to_coord(tile_id) direction = hexgrid.tile_edge_offset_to_direction(piece_coord - tile_coord) terrain_x, terrain_y = terrain_centers[tile_id] angle = 60*self._edge_angle_order.index(direction) dx = math.cos(math.radians(angle)) * self.distance_tile_to_edge() dy = math.sin(math.radians(angle)) * self.distance_tile_to_edge() return terrain_x + dx, terrain_y + dy, angle + 90 elif piece.type in [PieceType.settlement, PieceType.city]: # these pieces are on nodes tile_id = hexgrid.nearest_tile_to_node(piece_coord) tile_coord = hexgrid.tile_id_to_coord(tile_id) direction = hexgrid.tile_node_offset_to_direction(piece_coord - tile_coord) terrain_x, terrain_y = terrain_centers[tile_id] angle = 30 + 60*self._node_angle_order.index(direction) dx = math.cos(math.radians(angle)) * self._tile_radius dy = math.sin(math.radians(angle)) * self._tile_radius return terrain_x + dx, terrain_y + dy, 0 elif piece.type == PieceType.robber: # these pieces are on tiles tile_id = hexgrid.tile_id_from_coord(piece_coord) terrain_x, terrain_y = terrain_centers[tile_id] return terrain_x, terrain_y, 0 else: logging.warning('Unknown piece={}'.format(piece))
def _draw_piece_shadows(self, piece_type, board, terrain_centers): logging.debug('Drawing piece shadows of type={}'.format( piece_type.value)) piece = Piece(piece_type, self.game.get_cur_player()) if piece_type == PieceType.road: edges = hexgrid.legal_edge_coords() count = 0 for edge in edges: if (hexgrid.EDGE, edge) in board.pieces: logging.debug( 'Not drawing shadow road at coord={}'.format(edge)) continue count += 1 self._draw_piece(edge, piece, terrain_centers, ghost=True) logging.debug('Road shadows drawn: {}'.format(count)) elif piece_type == PieceType.settlement: nodes = hexgrid.legal_node_coords() for node in nodes: if (hexgrid.NODE, node) in board.pieces: continue self._draw_piece(node, piece, terrain_centers, ghost=True) elif piece_type == PieceType.city: for (_, node), p in board.pieces.items(): if p.type == PieceType.settlement and p.owner.color == piece.owner.color: self._draw_piece(node, piece, terrain_centers, ghost=True) elif piece_type == PieceType.robber: for coord in hexgrid.legal_tile_coords(): if hexgrid.tile_id_from_coord(coord) != self.game.robber_tile: self._draw_piece(coord, piece, terrain_centers, ghost=True) else: logging.warning( 'Attempted to draw piece shadows for nonexistent type={}'. format(piece_type))
def _draw_piece_shadows(self, piece_type, board, terrain_centers): logging.debug('Drawing piece shadows of type={}'.format(piece_type.value)) piece = Piece(piece_type, self.game.get_cur_player()) if piece_type == PieceType.road: edges = hexgrid.legal_edge_coords() count = 0 for edge in edges: if (hexgrid.EDGE, edge) in board.pieces: logging.debug('Not drawing shadow road at coord={}'.format(edge)) continue count += 1 self._draw_piece(edge, piece, terrain_centers, ghost=True) logging.debug('Road shadows drawn: {}'.format(count)) elif piece_type == PieceType.settlement: nodes = hexgrid.legal_node_coords() for node in nodes: if (hexgrid.NODE, node) in board.pieces: continue self._draw_piece(node, piece, terrain_centers, ghost=True) elif piece_type == PieceType.city: for (_, node), p in board.pieces.items(): if p.type == PieceType.settlement and p.owner.color == piece.owner.color: self._draw_piece(node, piece, terrain_centers, ghost=True) elif piece_type == PieceType.robber: for coord in hexgrid.legal_tile_coords(): if hexgrid.tile_id_from_coord(coord) != self.game.robber_tile: self._draw_piece(coord, piece, terrain_centers, ghost=True) else: logging.warning('Attempted to draw piece shadows for nonexistent type={}'.format(piece_type))
def get_adj_tile_ids_to_node(location: int) -> List[int]: if location not in hexgrid.legal_node_coords(): raise ValueError(f'tried to access node {location}') if location % 2 == 0: tile_coords = [location - 0x1, location + 0x1, location - 0x21] else: tile_coords = [location + 0x10, location - 0x10, location - 0x12] return [hexgrid.tile_id_from_coord(coord) - 1 for coord in tile_coords if coord in hexgrid.legal_tile_coords()]
def start(self, players): """ Start the game. The value of option 'pregame' determines whether the pregame will occur or not. - Resets the board - Sets the players - Sets the game state to the appropriate first turn of the game - Finds the robber on the board, sets the robber_tile appropriately - Logs the catanlog header :param players: players to start the game with """ # print('game\'s start method called') from .boardbuilder import Opt # print('-calling reset()') self.reset() if self.board.opts.get('players') == Opt.debug: # print('-using debug players={}'.format(Game.get_debug_players())) players = Game.get_debug_players() # print('-calling set_players({})'.format(players)) self.set_players(players) if self.options.get('pregame') is None or self.options.get( 'pregame') == 'on': # logging.debug('Entering pregame, game options={}'.format(self.options)) # print('-call set_state(catan.states.GameStatePreGamePlacingPiece(self, catan.pieces.PieceType.settlement))') self.set_state( catan.states.GameStatePreGamePlacingPiece( self, catan.pieces.PieceType.settlement)) elif self.options.get('pregame') == 'off': # logging.debug('Skipping pregame, game options={}'.format(self.options)) self.set_state(catan.states.GameStateBeginTurn(self)) terrain = list() numbers = list() for tile in self.board.tiles: terrain.append(tile.terrain) numbers.append(tile.number) # print('-populated terrain={0} and numbers={1} from tiles={2}' # .format(terrain, numbers, self.board.tiles)) for (_, coord), piece in self.board.pieces.items(): if piece.type == catan.pieces.PieceType.robber: self.robber_tile = hexgrid.tile_id_from_coord(coord) # logging.debug('Found robber at coord={}, set robber_tile={}'.format(coord, self.robber_tile)) self.catanlog.log_game_start(self.players, terrain, numbers, self.board.ports) self.notify_observers()
def piece_click(self, piece_type, event): tags = self._board_canvas.gettags(event.widget.find_closest(event.x, event.y)) # avoid processing tile clicks tag = None for t in tags: if 'tile' not in t: tag = t break logging.debug('Piece clicked with tag={}'.format(tag)) if piece_type == PieceType.road: self.game.place_road(self._coord_from_road_tag(tag)) elif piece_type == PieceType.settlement: self.game.place_settlement(self._coord_from_settlement_tag(tag)) elif piece_type == PieceType.city: self.game.place_city(self._coord_from_city_tag(tag)) elif piece_type == PieceType.robber: self.game.move_robber(hexgrid.tile_id_from_coord(self._coord_from_robber_tag(tag))) self.redraw()
def piece_click(self, piece_type, event): tags = self._board_canvas.gettags( event.widget.find_closest(event.x, event.y)) # avoid processing tile clicks tag = None for t in tags: if 'tile' not in t: tag = t break logging.debug('Piece clicked with tag={}'.format(tag)) if piece_type == PieceType.road: self.game.place_road(self._coord_from_road_tag(tag)) elif piece_type == PieceType.settlement: self.game.place_settlement(self._coord_from_settlement_tag(tag)) elif piece_type == PieceType.city: self.game.place_city(self._coord_from_city_tag(tag)) elif piece_type == PieceType.robber: self.game.move_robber( hexgrid.tile_id_from_coord(self._coord_from_robber_tag(tag))) self.redraw()
def start(self, players): """ Start the game. The value of option 'pregame' determines whether the pregame will occur or not. - Resets the board - Sets the players - Sets the game state to the appropriate first turn of the game - Finds the robber on the board, sets the robber_tile appropriately - Logs the catanlog header :param players: players to start the game with """ from .boardbuilder import Opt self.reset() if self.board.opts.get("players") == Opt.debug: players = Game.get_debug_players() self.set_players(players) if self.options.get("pregame") is None or self.options.get("pregame") == "on": logging.debug("Entering pregame, game options={}".format(self.options)) self.set_state(catan.states.GameStatePreGamePlacingPiece(self, catan.pieces.PieceType.settlement)) elif self.options.get("pregame") == "off": logging.debug("Skipping pregame, game options={}".format(self.options)) self.set_state(catan.states.GameStateBeginTurn(self)) terrain = list() numbers = list() for tile in self.board.tiles: terrain.append(tile.terrain) numbers.append(tile.number) for (_, coord), piece in self.board.pieces.items(): if piece.type == catan.pieces.PieceType.robber: self.robber_tile = hexgrid.tile_id_from_coord(coord) logging.debug("Found robber at coord={}, set robber_tile={}".format(coord, self.robber_tile)) self.catanlog.log_game_start(self.players, terrain, numbers, self.board.ports) self.notify_observers()
def _get_piece_center(self, piece_coord, piece, terrain_centers): """Takes a piece's hex coordinate, the piece itself, and the terrain_centers dictionary which maps tile_id->(x,y) Returns the piece's center, as an (x,y) pair. Also returns the angle the piece should be rotated at, if any """ if piece.type == PieceType.road: # these pieces are on edges tile_id = hexgrid.nearest_tile_to_edge(piece_coord) tile_coord = hexgrid.tile_id_to_coord(tile_id) direction = hexgrid.tile_edge_offset_to_direction(piece_coord - tile_coord) terrain_x, terrain_y = terrain_centers[tile_id] angle = 60 * self._edge_angle_order.index(direction) dx = math.cos(math.radians(angle)) * self.distance_tile_to_edge() dy = math.sin(math.radians(angle)) * self.distance_tile_to_edge() return terrain_x + dx, terrain_y + dy, angle + 90 elif piece.type in [PieceType.settlement, PieceType.city]: # these pieces are on nodes tile_id = hexgrid.nearest_tile_to_node(piece_coord) tile_coord = hexgrid.tile_id_to_coord(tile_id) direction = hexgrid.tile_node_offset_to_direction(piece_coord - tile_coord) terrain_x, terrain_y = terrain_centers[tile_id] angle = 30 + 60 * self._node_angle_order.index(direction) dx = math.cos(math.radians(angle)) * self._tile_radius dy = math.sin(math.radians(angle)) * self._tile_radius return terrain_x + dx, terrain_y + dy, 0 elif piece.type == PieceType.robber: # these pieces are on tiles tile_id = hexgrid.tile_id_from_coord(piece_coord) terrain_x, terrain_y = terrain_centers[tile_id] return terrain_x, terrain_y, 0 else: logging.warning('Unknown piece={}'.format(piece))