-
Notifications
You must be signed in to change notification settings - Fork 14
/
carcassonne_game_state.py
99 lines (81 loc) · 3.75 KB
/
carcassonne_game_state.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import random
from typing import Optional
from main.objects.actions.tile_action import TileAction
from main.objects.coordinate import Coordinate
from main.objects.game_phase import GamePhase
from main.tile_sets.base_deck import base_tile_counts, base_tiles
from main.tile_sets.inns_and_cathedrals_deck import inns_and_cathedrals_tile_counts, inns_and_cathedrals_tiles
from main.tile_sets.supplementary_rules import SupplementaryRule
from main.tile_sets.the_river_deck import the_river_tiles, the_river_tile_counts
from main.objects.rotation import Rotation
from main.objects.tile import Tile
from main.tile_sets.tile_sets import TileSet
class CarcassonneGameState:
def __init__(
self,
tile_sets: [TileSet] = (TileSet.BASE, TileSet.THE_RIVER, TileSet.INNS_AND_CATHEDRALS),
supplementary_rules: [SupplementaryRule] = (SupplementaryRule.FARMERS, SupplementaryRule.ABBOTS),
players: int = 2,
board_size: (int, int) = (35, 35),
starting_position: Coordinate = Coordinate(6, 15)
):
self.deck = self.initialize_deck(tile_sets=tile_sets)
self.supplementary_rules: [SupplementaryRule] = supplementary_rules
self.board: [[Tile]] = [[None for column in range(board_size[1])] for row in range(board_size[0])]
self.starting_position: Coordinate = starting_position
self.next_tile = self.deck.pop(0)
self.players = players
self.meeples = [7 for _ in range(players + 1)]
self.abbots = [1 if SupplementaryRule.ABBOTS in supplementary_rules else 0 for _ in range(players + 1)]
self.big_meeples = [1 if TileSet.INNS_AND_CATHEDRALS in tile_sets else 0 for _ in range(players + 1)]
self.placed_meeples = [[] for _ in range(players + 1)]
self.scores: [int] = [0 for _ in range(players + 1)]
self.current_player = 0
self.phase = GamePhase.TILES
self.last_tile_action: Optional[TileAction] = None
self.last_river_rotation: Rotation = Rotation.NONE
def get_tile(self, row: int, column: int):
if row < 0 or column < 0:
return None
elif row >= len(self.board) or column >= len(self.board[0]):
return None
else:
return self.board[row][column]
def empty_board(self):
for row in self.board:
for column in row:
if column is not None:
return False
return True
def is_terminated(self) -> bool:
return self.next_tile is None
def initialize_deck(self, tile_sets: [TileSet]):
deck: [Tile] = []
# The river
if TileSet.THE_RIVER in tile_sets:
deck.append(the_river_tiles["river_start"])
new_tiles = []
for card_name, count in the_river_tile_counts.items():
if card_name == "river_start":
continue
if card_name == "river_end":
continue
for i in range(count):
new_tiles.append(the_river_tiles[card_name])
random.shuffle(new_tiles)
for tile in new_tiles:
deck.append(tile)
deck.append(the_river_tiles["river_end"])
new_tiles = []
if TileSet.BASE in tile_sets:
for card_name, count in base_tile_counts.items():
for i in range(count):
new_tiles.append(base_tiles[card_name])
if TileSet.INNS_AND_CATHEDRALS in tile_sets:
for card_name, count in inns_and_cathedrals_tile_counts.items():
for i in range(count):
new_tiles.append(inns_and_cathedrals_tiles[card_name])
random.shuffle(new_tiles)
for tile in new_tiles:
deck.append(tile)
return deck