def test_find_meeples_in_donut_city(self): """ Find meeple positions for a donut shaped city """ # Given game_state: CarcassonneGameState = self.create_donut_city_board() game_state.placed_meeples = [[], [], []] game_state.placed_meeples[0].append( MeeplePosition(meeple_type=MeepleType.NORMAL, coordinate_with_side=CoordinateWithSide( Coordinate(2, 1), Side.RIGHT))) game_state.placed_meeples[0].append( MeeplePosition(meeple_type=MeepleType.NORMAL, coordinate_with_side=CoordinateWithSide( Coordinate(0, 1), Side.LEFT))) game_state.placed_meeples[1].append( MeeplePosition(meeple_type=MeepleType.BIG, coordinate_with_side=CoordinateWithSide( Coordinate(1, 2), Side.TOP))) game_state.players = 3 # When city: City = CityUtil.find_city(game_state=game_state, city_position=CoordinateWithSide( Coordinate(0, 0), Side.BOTTOM)) meeples: [[MeeplePosition]] = CityUtil.find_meeples(game_state, city) # Then self.assertEqual(3, len(meeples)) self.assertEqual(2, len(meeples[0])) self.assertEqual(1, len(meeples[1])) self.assertEqual(0, len(meeples[2])) self.assertIn( MeeplePosition(MeepleType.NORMAL, CoordinateWithSide(Coordinate(2, 1), Side.RIGHT)), meeples[0]) self.assertIn( MeeplePosition(MeepleType.NORMAL, CoordinateWithSide(Coordinate(0, 1), Side.LEFT)), meeples[0]) self.assertIn( MeeplePosition(MeepleType.BIG, CoordinateWithSide(Coordinate(1, 2), Side.TOP)), meeples[1])
def remove_meeples_and_collect_points(cls, game_state: CarcassonneGameState, coordinate: Coordinate): # Points for finished cities cities: [City] = CityUtil.find_cities(game_state=game_state, coordinate=coordinate) for city in cities: if city.finished: meeples: [[MeeplePosition] ] = CityUtil.find_meeples(game_state=game_state, city=city) meeple_counts_per_player = cls.get_meeple_counts_per_player( meeples) print("City finished. Meeples:", json.dumps(meeple_counts_per_player)) if sum(meeple_counts_per_player) == 0: continue winning_player = cls.get_winning_player( meeple_counts_per_player) if winning_player is not None: points = cls.count_city_points(game_state=game_state, city=city) print(points, "points for player", winning_player) game_state.scores[winning_player] += points MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples) # Points for finished roads roads: [Road] = RoadUtil.find_roads(game_state=game_state, coordinate=coordinate) for road in roads: if road.finished: meeples: [[MeeplePosition] ] = RoadUtil.find_meeples(game_state=game_state, road=road) meeple_counts_per_player = cls.get_meeple_counts_per_player( meeples) print("Road finished. Meeples:", json.dumps(meeple_counts_per_player)) if sum(meeple_counts_per_player) == 0: continue winning_player = cls.get_winning_player( meeple_counts_per_player) if winning_player is not None: points = cls.count_road_points(game_state=game_state, road=road) print(points, "points for player", winning_player) game_state.scores[winning_player] += points MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples) # Points for finished chapels for row in range(coordinate.row - 1, coordinate.row + 2): for column in range(coordinate.column - 1, coordinate.column + 2): tile: Tile = game_state.get_tile(row, column) if tile is None: continue coordinate = Coordinate(row=row, column=column) coordinate_with_side = CoordinateWithSide( coordinate=coordinate, side=Side.CENTER) meeple_of_player = MeepleUtil.position_contains_meeple( game_state=game_state, coordinate_with_side=coordinate_with_side) if (tile.chapel or tile.flowers) and meeple_of_player is not None: points = cls.chapel_or_flowers_points( game_state=game_state, coordinate=coordinate) if points == 9: print("Chapel or flowers finished for player", str(meeple_of_player)) print(points, "points for player", meeple_of_player) game_state.scores[meeple_of_player] += points meeples_per_player = [] for _ in range(game_state.players): meeples_per_player.append([]) meeples_per_player[meeple_of_player].append( coordinate_with_side) MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples_per_player)
def count_final_scores(cls, game_state: CarcassonneGameState): for player, placed_meeples in enumerate(game_state.placed_meeples): # TODO also remove meeples from meeples_to_remove, when there are multiple meeples_to_remove: Set[MeeplePosition] = set(placed_meeples) while len(meeples_to_remove) > 0: meeple_position: MeeplePosition = meeples_to_remove.pop() tile: Tile = game_state.board[ meeple_position.coordinate_with_side.coordinate.row][ meeple_position.coordinate_with_side.coordinate.column] terrrain_type: TerrainType = tile.get_type( meeple_position.coordinate_with_side.side) if terrrain_type == TerrainType.CITY: city: City = CityUtil.find_city( game_state=game_state, city_position=meeple_position.coordinate_with_side) meeples: [CoordinateWithSide ] = CityUtil.find_meeples(game_state=game_state, city=city) meeple_counts_per_player = cls.get_meeple_counts_per_player( meeples) print("Collecting points for unfinished city. Meeples:", json.dumps(meeple_counts_per_player)) winning_player = cls.get_winning_player( meeple_counts_per_player) if winning_player is not None: points = cls.count_city_points(game_state=game_state, city=city) print(points, "points for player", player) game_state.scores[winning_player] += points MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples) continue if terrrain_type == TerrainType.ROAD: road: [Road] = RoadUtil.find_road( game_state=game_state, road_position=meeple_position.coordinate_with_side) meeples: [CoordinateWithSide ] = RoadUtil.find_meeples(game_state=game_state, road=road) meeple_counts_per_player = cls.get_meeple_counts_per_player( meeples) print("Collecting points for unfinished road. Meeples:", json.dumps(meeple_counts_per_player)) winning_player = cls.get_winning_player( meeple_counts_per_player) if winning_player is not None: points = cls.count_road_points(game_state=game_state, road=road) print(points, "points for player", player) game_state.scores[winning_player] += points MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples) continue if terrrain_type == TerrainType.CHAPEL or terrrain_type == TerrainType.FLOWERS: points = cls.chapel_or_flowers_points( game_state=game_state, coordinate=meeple_position.coordinate_with_side. coordinate) print( "Collecting points for unfinished chapel or flowers for player", str(player)) print(points, "points for player", player) game_state.scores[player] += points meeples_per_player = [] for _ in range(game_state.players): meeples_per_player.append([]) meeples_per_player[player].append(meeple_position) MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples_per_player) continue if meeple_position.meeple_type == MeepleType.FARMER or meeple_position.meeple_type == MeepleType.BIG_FARMER: farm: Farm = FarmUtil.find_farm_by_coordinate( game_state=game_state, position=meeple_position.coordinate_with_side) meeples: [[MeeplePosition] ] = FarmUtil.find_meeples(game_state=game_state, farm=farm) meeple_counts_per_player = cls.get_meeple_counts_per_player( meeples) print("Collecting points for farm. Meeples:", json.dumps(meeple_counts_per_player)) winning_player = cls.get_winning_player( meeple_counts_per_player) if winning_player is not None: points = cls.count_farm_points(game_state=game_state, farm=farm) print(points, "points for player", winning_player) game_state.scores[winning_player] += points MeepleUtil.remove_meeples(game_state=game_state, meeples=meeples) continue print("Collecting points for unknown type", terrrain_type)