Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
191de2d
Add small assertion
bcollazo Oct 13, 2024
db1a88b
cargo new catanatron_rust
bcollazo Oct 13, 2024
0d6abc7
Example tests
bcollazo Oct 13, 2024
8db9a8a
Sample enums and decks (bitfield) implementation
bcollazo Oct 13, 2024
9671f84
Fixup Deck
bcollazo Oct 13, 2024
c9a3e9a
Copy benchmark
bcollazo Oct 13, 2024
ff86757
initialize_state_vector
bcollazo Oct 13, 2024
85d0685
Note on Player State
bcollazo Oct 13, 2024
76d69d6
Fix Python Benchmark
bcollazo Oct 13, 2024
e90f64d
Copy Benchmark Update
bcollazo Oct 14, 2024
7946660
More Example Benchmark on Main
bcollazo Oct 14, 2024
a8dd52d
Python deck Benchmark
bcollazo Oct 14, 2024
7f54510
Update state.py documentation
bcollazo Oct 15, 2024
310020b
Simple Vector State
bcollazo Oct 16, 2024
a912a7a
README.md Update
bcollazo Oct 16, 2024
6431d4c
Py: Create map_template.py
bcollazo Oct 16, 2024
1ce7911
map_template.rs
bcollazo Oct 16, 2024
f8beb2e
State Fixup
bcollazo Oct 16, 2024
53c5637
Global State that inits Base and Mini Templates
bcollazo Oct 16, 2024
97bdbcf
Use Global State in main.rs
bcollazo Oct 16, 2024
6154ea8
Rename CatanMap to MapInstance
bcollazo Oct 16, 2024
1cc30e3
Rename map.py to map_instance.py
bcollazo Oct 16, 2024
7cd50f1
OrderedHashMap and TileSlot fix
bcollazo Oct 17, 2024
8566708
Initial Map Instance
bcollazo Oct 18, 2024
075b842
Make MapInstance immutable
bcollazo Oct 18, 2024
42287a6
Initial Attempt at Rust CI
bcollazo Oct 19, 2024
6b507fa
Attempt 2 at GH Actions
bcollazo Oct 19, 2024
0d4c7b9
Initial state_functions and game structure
bcollazo Oct 20, 2024
0cdeb5e
Add clippy to CI
bcollazo Oct 20, 2024
7454f5d
Apply some clippy suggestions
bcollazo Oct 20, 2024
1b8cae9
Apply clippy suggestions
bcollazo Oct 20, 2024
887e94b
Move generation structure
bcollazo Oct 20, 2024
5782d4f
Rename State to StateVector
bcollazo Oct 20, 2024
ca49067
Rename state.rs to state_vector.rs
bcollazo Oct 20, 2024
8404fd3
Bug Fix
bcollazo Oct 20, 2024
bfd4a8b
Dynamic state_vector
bcollazo Oct 20, 2024
7aba25d
Deprecation Notice
bcollazo Oct 20, 2024
62326d4
Further MapInstance
bcollazo Oct 20, 2024
b51a923
Introduce State.rs
bcollazo Oct 20, 2024
a965a97
Fix clippy
bcollazo Oct 20, 2024
b4d433a
Object oriented State instead of state_functions
bcollazo Oct 23, 2024
317b315
Double down on OOP State and Action enum
bcollazo Oct 23, 2024
d7c589a
mutations.rs, 2 turns running
bcollazo Oct 26, 2024
adc0be4
Clippy fixes
bcollazo Oct 26, 2024
b818f8a
Improve Testing
bcollazo Oct 26, 2024
92cbeb7
Add Test
bcollazo Oct 27, 2024
a92b1e6
Create State::new_base to share in tests
bcollazo Oct 27, 2024
de503c7
Progress on Initial Building Phase
bcollazo Oct 27, 2024
07a13c5
max_ticks in favor of max_turns
bcollazo Oct 27, 2024
376b101
Test 4 player initial build phase (just building sequence)
bcollazo Oct 27, 2024
9da7b77
Test initial build phase (sequence only) for 2 player catan
bcollazo Oct 27, 2024
9f9dc06
Python refactor: Create play_turn_possibilities
bcollazo Oct 27, 2024
dcce77e
Initial Build Phase
bcollazo Nov 23, 2024
5f09779
Fix some warnings
bcollazo Nov 23, 2024
9c9216f
Clippy Fix
bcollazo Nov 23, 2024
4307065
Merge branch 'master' into feature/catanatron-rust
bcollazo Nov 23, 2024
581429c
Rename mutations.rs into move_application.rs
bcollazo Nov 23, 2024
59d1550
Reorder methods in State.move_application
bcollazo Nov 23, 2024
6ae93a0
Add TODO's
bcollazo Nov 23, 2024
b646f59
Settlement possibilities
zarns Dec 28, 2024
c22b422
Fix player_hand_slice
zarns Dec 29, 2024
20e960f
Maintain longest road
zarns Jan 4, 2025
d954062
Buy Dev Cards
zarns Jan 5, 2025
6cc44c1
Merge pull request #298 from zarns/feature/zarns/catanatron-rust
bcollazo Jan 9, 2025
d0893e4
cargo fmt
zarns Jan 12, 2025
640fe4e
roll_dice yields
zarns Jan 19, 2025
8523bc3
Dice yields with insufficient bank
zarns Jan 20, 2025
df6efea
Discard
zarns Jan 20, 2025
042bcd5
Unused var
zarns Jan 20, 2025
bc679dd
Play Dev Cards
zarns Jan 20, 2025
15fe2fb
Maritime trade
zarns Jan 20, 2025
6ce7c12
End Turn
zarns Jan 21, 2025
454a908
Merge pull request #301 from zarns/feature/zarns/catanatron_rust
bcollazo Jan 23, 2025
f1e5eca
Refactor struct enums
zarns Jan 25, 2025
a1cfe13
Rename signature
zarns Jan 25, 2025
2cbece6
Clarify state_vector
zarns Jan 25, 2025
e13903a
Robber Possibilities
zarns Jan 25, 2025
42b13bb
Year of Plenty Possibilities
zarns Jan 26, 2025
b61bdfc
Node production
zarns Jan 26, 2025
67df809
Mark dead code to satisfy clippy
zarns Jan 26, 2025
e5046bb
Maritime trade possibilities
zarns Feb 9, 2025
f88ad0a
Merge pull request #302 from zarns/feature/zarns/catanatron_rust
bcollazo Feb 10, 2025
bf6542f
initial pyo3 testing
zarns Feb 23, 2025
40a2a62
debug logs
zarns Mar 1, 2025
7dfbba6
debug logs and bugfixes
zarns Mar 1, 2025
a6a93ea
Update maturin consumer
zarns Mar 1, 2025
6962369
Fix maintain connected components
zarns Mar 1, 2025
7decbfa
Merge pull request #303 from zarns/feature/zarns/catanatron_rust
bcollazo Mar 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,41 @@ jobs:
working-directory: ./ui
- run: npm run build
working-directory: ./ui

build-rust:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true

- name: Run `cargo fmt`
run: cargo fmt -- --check
working-directory: catanatron_rust
- name: Run `cargo clippy`
run: cargo clippy -- -D warnings
working-directory: catanatron_rust

- name: Run `cargo run`
run: cargo run
working-directory: catanatron_rust
- name: Run `cargo run --release`
run: cargo run --release
working-directory: catanatron_rust

- name: Run `cargo test`
run: cargo test --verbose
working-directory: catanatron_rust
- name: Run `cargo test --release`
run: cargo test --release --verbose
working-directory: catanatron_rust

- name: Run `cargo bench`
run: cargo bench
working-directory: catanatron_rust
8 changes: 4 additions & 4 deletions catanatron_core/catanatron/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from catanatron.models.enums import Action, ActionPrompt, ActionType
from catanatron.state import State, apply_action
from catanatron.state_functions import player_key, player_has_rolled
from catanatron.models.map import CatanMap
from catanatron.models.map_instance import MapInstance
from catanatron.models.player import Color, Player

# To timeout RandomRobots from getting stuck...
Expand Down Expand Up @@ -92,7 +92,7 @@ def __init__(
seed: Optional[int] = None,
discard_limit: int = 7,
vps_to_win: int = 10,
catan_map: Optional[CatanMap] = None,
map_instance: Optional[MapInstance] = None,
initialize: bool = True,
):
"""Creates a game (doesn't run it).
Expand All @@ -102,7 +102,7 @@ def __init__(
seed (int, optional): Random seed to use (for reproducing games). Defaults to None.
discard_limit (int, optional): Discard limit to use. Defaults to 7.
vps_to_win (int, optional): Victory Points needed to win. Defaults to 10.
catan_map (CatanMap, optional): Map to use. Defaults to None.
map_instance (MapInstance, optional): Map to use. Defaults to None.
initialize (bool, optional): Whether to initialize. Defaults to True.
"""
if initialize:
Expand All @@ -111,7 +111,7 @@ def __init__(

self.id = str(uuid.uuid4())
self.vps_to_win = vps_to_win
self.state = State(players, catan_map, discard_limit=discard_limit)
self.state = State(players, map_instance, discard_limit=discard_limit)

def play(self, accumulators=[], decide_fn=None):
"""Executes game until a player wins or exceeded TURNS_LIMIT.
Expand Down
2 changes: 1 addition & 1 deletion catanatron_core/catanatron/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import json
from enum import Enum

from catanatron.models.map import Water, Port, LandTile
from catanatron.models.map_instance import Water, Port, LandTile
from catanatron.game import Game
from catanatron.models.player import Color
from catanatron.models.enums import RESOURCES, Action, ActionType
Expand Down
71 changes: 38 additions & 33 deletions catanatron_core/catanatron/models/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Move-generation functions (these return a list of actions that can be taken
by current player). Main function is generate_playable_actions.
"""

import operator as op
from functools import reduce
from typing import Any, Dict, List, Set, Tuple, Union
Expand Down Expand Up @@ -51,39 +52,7 @@ def generate_playable_actions(state) -> List[Action]:
elif action_prompt == ActionPrompt.MOVE_ROBBER:
return robber_possibilities(state, color)
elif action_prompt == ActionPrompt.PLAY_TURN:
if state.is_road_building:
return road_building_possibilities(state, color, False)
actions = []
# Allow playing dev cards before and after rolling
if player_can_play_dev(state, color, "YEAR_OF_PLENTY"):
actions.extend(year_of_plenty_possibilities(color, state.resource_freqdeck))
if player_can_play_dev(state, color, "MONOPOLY"):
actions.extend(monopoly_possibilities(color))
if player_can_play_dev(state, color, "KNIGHT"):
actions.append(Action(color, ActionType.PLAY_KNIGHT_CARD, None))
if (
player_can_play_dev(state, color, "ROAD_BUILDING")
and len(road_building_possibilities(state, color, False)) > 0
):
actions.append(Action(color, ActionType.PLAY_ROAD_BUILDING, None))
if not player_has_rolled(state, color):
actions.append(Action(color, ActionType.ROLL, None))
else:
actions.append(Action(color, ActionType.END_TURN, None))
actions.extend(road_building_possibilities(state, color))
actions.extend(settlement_possibilities(state, color))
actions.extend(city_possibilities(state, color))

can_buy_dev_card = (
player_can_afford_dev_card(state, color)
and len(state.development_listdeck) > 0
)
if can_buy_dev_card:
actions.append(Action(color, ActionType.BUY_DEVELOPMENT_CARD, None))

# Trade
actions.extend(maritime_trade_possibilities(state, color))
return actions
return play_turn_possibilities(state, color)
elif action_prompt == ActionPrompt.DISCARD:
return discard_possibilities(color)
elif action_prompt == ActionPrompt.DECIDE_TRADE:
Expand Down Expand Up @@ -236,6 +205,42 @@ def robber_possibilities(state, color) -> List[Action]:
return actions


def play_turn_possibilities(state, color) -> List[Action]:
if state.is_road_building:
return road_building_possibilities(state, color, False)
actions = []
# Allow playing dev cards before and after rolling
if player_can_play_dev(state, color, "YEAR_OF_PLENTY"):
actions.extend(year_of_plenty_possibilities(color, state.resource_freqdeck))
if player_can_play_dev(state, color, "MONOPOLY"):
actions.extend(monopoly_possibilities(color))
if player_can_play_dev(state, color, "KNIGHT"):
actions.append(Action(color, ActionType.PLAY_KNIGHT_CARD, None))
if (
player_can_play_dev(state, color, "ROAD_BUILDING")
and len(road_building_possibilities(state, color, False)) > 0
):
actions.append(Action(color, ActionType.PLAY_ROAD_BUILDING, None))
if not player_has_rolled(state, color):
actions.append(Action(color, ActionType.ROLL, None))
else:
actions.append(Action(color, ActionType.END_TURN, None))
actions.extend(road_building_possibilities(state, color))
actions.extend(settlement_possibilities(state, color))
actions.extend(city_possibilities(state, color))

can_buy_dev_card = (
player_can_afford_dev_card(state, color)
and len(state.development_listdeck) > 0
)
if can_buy_dev_card:
actions.append(Action(color, ActionType.BUY_DEVELOPMENT_CARD, None))

# Trade
actions.extend(maritime_trade_possibilities(state, color))
return actions


def initial_road_possibilities(state, color) -> List[Action]:
# Must be connected to last settlement
last_settlement_node_id = state.buildings_by_color[color][SETTLEMENT][-1]
Expand Down
12 changes: 6 additions & 6 deletions catanatron_core/catanatron/models/board.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import networkx as nx # type: ignore

from catanatron.models.player import Color
from catanatron.models.map import (
from catanatron.models.map_instance import (
BASE_MAP_TEMPLATE,
MINI_MAP_TEMPLATE,
NUM_NODES,
CatanMap,
MapInstance,
NodeId,
)
from catanatron.models.enums import FastBuildingType, SETTLEMENT, CITY


# Used to find relationships between nodes and edges
base_map = CatanMap.from_template(BASE_MAP_TEMPLATE)
mini_map = CatanMap.from_template(MINI_MAP_TEMPLATE)
base_map = MapInstance.from_template(BASE_MAP_TEMPLATE)
mini_map = MapInstance.from_template(MINI_MAP_TEMPLATE)
STATIC_GRAPH = nx.Graph()
for tile in base_map.tiles.values():
STATIC_GRAPH.add_nodes_from(tile.nodes.values())
Expand Down Expand Up @@ -54,12 +54,12 @@ class Board:
robber_coordinate (Coordinate): Coordinate where robber is.
"""

def __init__(self, catan_map=None, initialize=True):
def __init__(self, map_instance=None, initialize=True):
self.buildable_subgraph: Any = None
self.buildable_edges_cache = {}
self.player_port_resources_cache = {}
if initialize:
self.map: CatanMap = catan_map or CatanMap.from_template(
self.map: MapInstance = map_instance or MapInstance.from_template(
BASE_MAP_TEMPLATE
) # Static State (no need to copy)

Expand Down
Loading