Skip to content

Commit

Permalink
Farmer points working.
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentbons committed May 19, 2020
1 parent 63d6430 commit 197c521
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 23 deletions.
33 changes: 18 additions & 15 deletions main/utils/city_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@

class CityUtil:

def __init__(self):
pass

def find_city(self, game_state: CarcassonneGameState, city_position: CoordinateWithSide) -> City:
cities: Set[CoordinateWithSide] = set(self.cities_for_position(game_state, city_position))
open_edges: Set[CoordinateWithSide] = set(map(lambda x: self.opposite_edge(x), cities))
@classmethod
def find_city(cls, game_state: CarcassonneGameState, city_position: CoordinateWithSide) -> City:
cities: Set[CoordinateWithSide] = set(cls.cities_for_position(game_state, city_position))
open_edges: Set[CoordinateWithSide] = set(map(lambda x: cls.opposite_edge(x), cities))
explored: Set[CoordinateWithSide] = cities.union(open_edges)
while len(open_edges) > 0:
open_edge: CoordinateWithSide = open_edges.pop()
new_cities = self.cities_for_position(game_state, open_edge)
new_cities = cls.cities_for_position(game_state, open_edge)
cities = cities.union(new_cities)
new_open_edges = set(map(lambda x: self.opposite_edge(x), new_cities))
new_open_edges = set(map(lambda x: cls.opposite_edge(x), new_cities))
explored = explored.union(new_cities)
new_open_edge: CoordinateWithSide
for new_open_edge in new_open_edges:
Expand All @@ -34,7 +32,8 @@ def find_city(self, game_state: CarcassonneGameState, city_position: CoordinateW
finished: bool = len(explored) == len(cities)
return City(city_positions=cities, finished=finished)

def opposite_edge(self, city_position: CoordinateWithSide):
@classmethod
def opposite_edge(cls, city_position: CoordinateWithSide):
if city_position.side == Side.TOP:
return CoordinateWithSide(Coordinate(city_position.coordinate.row - 1, city_position.coordinate.column),
Side.BOTTOM)
Expand All @@ -48,7 +47,8 @@ def opposite_edge(self, city_position: CoordinateWithSide):
return CoordinateWithSide(Coordinate(city_position.coordinate.row, city_position.coordinate.column - 1),
Side.RIGHT)

def cities_for_position(self, game_state: CarcassonneGameState, city_position: CoordinateWithSide):
@classmethod
def cities_for_position(cls, game_state: CarcassonneGameState, city_position: CoordinateWithSide):
tile: Tile = game_state.board[city_position.coordinate.row][city_position.coordinate.column]
cities = []
if tile is None:
Expand All @@ -61,14 +61,16 @@ def cities_for_position(self, game_state: CarcassonneGameState, city_position: C
cities.append(city_position)
return cities

def city_contains_meeples(self, game_state: CarcassonneGameState, city: City):
@classmethod
def city_contains_meeples(cls, game_state: CarcassonneGameState, city: City):
for city_position in city.city_positions:
for i in range(game_state.players):
if city_position in list(map(lambda x: x.coordinate_with_side, game_state.placed_meeples[i])):
return True
return False

def find_meeples(self, game_state: CarcassonneGameState, city: City) -> [[MeeplePosition]]:
@classmethod
def find_meeples(cls, game_state: CarcassonneGameState, city: City) -> [[MeeplePosition]]:
meeples: [[MeeplePosition]] = []

for i in range(game_state.players):
Expand All @@ -83,7 +85,8 @@ def find_meeples(self, game_state: CarcassonneGameState, city: City) -> [[Meeple

return meeples

def find_cities(self, game_state: CarcassonneGameState, coordinate: Coordinate):
@classmethod
def find_cities(cls, game_state: CarcassonneGameState, coordinate: Coordinate, sides: [Side] = (Side.TOP, Side.RIGHT, Side.BOTTOM, Side.LEFT)):
cities: Set[City] = set()

tile: Tile = game_state.board[coordinate.row][coordinate.column]
Expand All @@ -92,9 +95,9 @@ def find_cities(self, game_state: CarcassonneGameState, coordinate: Coordinate):
return cities

side: Side
for side in [Side.TOP, Side.RIGHT, Side.BOTTOM, Side.LEFT]:
for side in sides:
if tile.get_type(side) == TerrainType.CITY:
city: City = self.find_city(game_state=game_state,
city: City = cls.find_city(game_state=game_state,
city_position=CoordinateWithSide(coordinate=coordinate, side=side))
cities.add(city)

Expand Down
12 changes: 10 additions & 2 deletions main/utils/farm_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@
class FarmUtil:

@classmethod
def find_farm(cls, game_state: CarcassonneGameState, farmer_connection_with_coordinate: FarmerConnectionWithCoordinate) -> Farm:
def find_farm_by_coordinate(cls, game_state: CarcassonneGameState, position: CoordinateWithSide):
tile: Tile = game_state.get_tile(position.coordinate.row, position.coordinate.column)

farmer_connection: FarmerConnection
for farmer_connection in tile.farms:
if position.side in farmer_connection.farmer_positions:
return cls.find_farm(game_state, FarmerConnectionWithCoordinate(farmer_connection, position.coordinate))

@classmethod
def find_farm(cls, game_state: CarcassonneGameState, farmer_connection_with_coordinate: FarmerConnectionWithCoordinate) -> Farm:
farmer_connections_with_coordinate: [FarmerConnectionWithCoordinate] = {farmer_connection_with_coordinate}
open_sides: Set[CoordinateWithFarmerSide] = set(map(lambda x: CoordinateWithFarmerSide(farmer_connection_with_coordinate.coordinate, x), farmer_connection_with_coordinate.farmer_connection.tile_connections))
to_explore: Set[CoordinateWithFarmerSide] = set(map(lambda farmer_side: cls.opposite_edge(farmer_side), open_sides))
Expand Down Expand Up @@ -101,4 +109,4 @@ def find_meeples(cls, game_state: CarcassonneGameState, farm: Farm) -> [[MeepleP
if farmer_position == meeple_position.coordinate_with_side:
meeples[player].append(meeple_position)

return meeples
return meeples
53 changes: 47 additions & 6 deletions main/utils/points_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
from main.objects.city import City
from main.objects.coordinate import Coordinate
from main.objects.coordinate_with_side import CoordinateWithSide
from main.objects.farm import Farm
from main.objects.farmer_connection_with_coordinate import FarmerConnectionWithCoordinate
from main.objects.meeple_position import MeeplePosition
from main.objects.meeple_type import MeepleType
from main.objects.road import Road
from main.objects.side import Side
from main.objects.terrain_type import TerrainType
from main.objects.tile import Tile
from main.utils.city_util import CityUtil
from main.utils.farm_util import FarmUtil
from main.utils.meeple_util import MeepleUtil
from main.utils.road_util import RoadUtil

Expand All @@ -38,8 +41,9 @@ def remove_meeples_and_collect_points(self, game_state: CarcassonneGameState, co
continue
winning_player = PointsCollector.get_winning_player(meeple_counts_per_player)
if winning_player is not None:
game_state.scores[winning_player] += PointsCollector.count_city_points(game_state=game_state,
city=city)
points = PointsCollector.count_city_points(game_state=game_state, city=city)
print(points, "points for player", winning_player)
game_state.scores[winning_player] += points
self.meeple_util.remove_meeples(game_state=game_state, meeples=meeples)

# Points for finished roads
Expand All @@ -53,8 +57,9 @@ def remove_meeples_and_collect_points(self, game_state: CarcassonneGameState, co
continue
winning_player = PointsCollector.get_winning_player(meeple_counts_per_player)
if winning_player is not None:
game_state.scores[winning_player] += PointsCollector.count_road_points(game_state=game_state,
road=road)
points = PointsCollector.count_road_points(game_state=game_state, road=road)
print(points, "points for player", winning_player)
game_state.scores[winning_player] += points
self.meeple_util.remove_meeples(game_state=game_state, meeples=meeples)

# Points for finished chapels
Expand All @@ -73,6 +78,7 @@ def remove_meeples_and_collect_points(self, game_state: CarcassonneGameState, co
points = PointsCollector.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 = []
Expand Down Expand Up @@ -184,7 +190,9 @@ def count_final_scores(self, game_state: CarcassonneGameState):
print("Collecting points for unfinished city. Meeples:", json.dumps(meeple_counts_per_player))
winning_player = self.get_winning_player(meeple_counts_per_player)
if winning_player is not None:
game_state.scores[winning_player] += self.count_city_points(game_state=game_state, city=city)
points = self.count_city_points(game_state=game_state, city=city)
print(points, "points for player", player)
game_state.scores[winning_player] += points

self.meeple_util.remove_meeples(game_state=game_state, meeples=meeples)
continue
Expand All @@ -197,14 +205,17 @@ def count_final_scores(self, game_state: CarcassonneGameState):
print("Collecting points for unfinished road. Meeples:", json.dumps(meeple_counts_per_player))
winning_player = self.get_winning_player(meeple_counts_per_player)
if winning_player is not None:
game_state.scores[winning_player] += self.count_road_points(game_state=game_state, road=road)
points = self.count_road_points(game_state=game_state, road=road)
print(points, "points for player", player)
game_state.scores[winning_player] += points
self.meeple_util.remove_meeples(game_state=game_state, meeples=meeples)
continue

if terrrain_type == TerrainType.CHAPEL_OR_FLOWERS:
points = self.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 = []
Expand All @@ -215,6 +226,19 @@ def count_final_scores(self, game_state: CarcassonneGameState):
self.meeple_util.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 = self.get_meeple_counts_per_player(meeples)
print("Collecting points for farm. Meeples:", json.dumps(meeple_counts_per_player))
winning_player = self.get_winning_player(meeple_counts_per_player)
if winning_player is not None:
points = self.count_farm_points(game_state=game_state, farm=farm)
print(points, "points for player", winning_player)
game_state.scores[winning_player] += points
self.meeple_util.remove_meeples(game_state=game_state, meeples=meeples)
continue

print("Collecting points for unknown type", terrrain_type)

@staticmethod
Expand All @@ -229,3 +253,20 @@ def get_meeple_counts_per_player(meeples: [[MeeplePosition]]):
)
)
return meeple_counts_per_player

@classmethod
def count_farm_points(cls, game_state: CarcassonneGameState, farm: Farm):
cities: Set[City] = set()

points = 0

farmer_connection_with_coordinate: FarmerConnectionWithCoordinate
for farmer_connection_with_coordinate in farm.farmer_connections_with_coordinate:
cities = cities.union(CityUtil.find_cities(game_state=game_state, coordinate=farmer_connection_with_coordinate.coordinate, sides=farmer_connection_with_coordinate.farmer_connection.city_sides))

city: City
for city in cities:
if city.finished:
points += 3

return points

0 comments on commit 197c521

Please sign in to comment.