コード例 #1
0
    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])
コード例 #2
0
    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)
コード例 #3
0
    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)