Skip to content

Commit

Permalink
Name change turn -> rules/step
Browse files Browse the repository at this point in the history
  • Loading branch information
walkie committed Jun 1, 2024
1 parent df9bd80 commit cccb9cc
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 99 deletions.
4 changes: 2 additions & 2 deletions t4t-games/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ keywords = ["game-theory", "economics", "evolution"]

[dependencies]
log = "0.4.21"
t4t = "0.1.0"
# t4t = { path = "../t4t" }
# t4t = "0.1.0"
t4t = { path = "../t4t" }

[dev-dependencies]
env_logger = "0.11.3"
Expand Down
4 changes: 2 additions & 2 deletions t4t-games/src/dilemma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ impl Game<2> for Dilemma {
type State = ();
type View = ();

fn first_turn(&self) -> Turn<(), Move, SimultaneousOutcome<Move, i64, 2>, 2> {
self.as_normal().first_turn()
fn rules(&self) -> Rules<(), Move, SimultaneousOutcome<Move, i64, 2>, 2> {
self.as_normal().rules()
}

fn state_view(&self, _state: &(), _player: PlayerIndex<2>) {}
Expand Down
32 changes: 16 additions & 16 deletions t4t/src/game.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fmt::Debug;

use crate::{Action, Context, Error, Matchup, Move, Outcome, PlayerIndex, Turn, Utility};
use crate::rules::Rules;
use crate::{Action, Context, Error, Matchup, Move, Outcome, PlayerIndex, Utility};

/// A trait that collects the trait requirements of a game state.
///
Expand Down Expand Up @@ -36,12 +37,11 @@ pub trait Game<const P: usize>: Clone + Sized + Send + Sync {
/// state that are not visible to players while making strategic decisions.
type View: State;

/// A specification of how this game is executed.
/// A step-by-step executable description of how this game is played.
///
/// This method returns the first turn in the specification of the game's execution, from which
/// the rest of the specification is reachable through each action's `next` method, if
/// applicable.
fn first_turn(&self) -> Turn<Self::State, Self::Move, Self::Outcome, P>;
/// This method returns the first step in the game's rules, from which subsequent steps can be
/// reached through each action's `next` method, if applicable.
fn rules(&self) -> Rules<Self::State, Self::Move, Self::Outcome, P>;

/// Produce a view of the game state for the given player.
fn state_view(&self, state: &Self::State, player: PlayerIndex<P>) -> Self::View;
Expand All @@ -62,36 +62,36 @@ pub trait Game<const P: usize>: Clone + Sized + Send + Sync {
/// Play this game with the given players, producing a value of the game's outcome type on
/// success.
fn play(&self, matchup: &Matchup<Self, P>) -> PlayResult<Self, P> {
let mut turn = self.first_turn();
let mut step = self.rules();
let mut strategies = matchup.strategies();

loop {
match turn.action {
Action::Players { to_move, next } => {
match step.action {
Action::Turn { to_move, next } => {
let moves = to_move
.iter()
.map(|&index| {
let view = self.state_view(&turn.state, index);
let view = self.state_view(&step.state, index);
let context = Context::new(index, view);
strategies[index].next_move(&context)
})
.collect();

match next(turn.state.clone(), moves) {
Ok(next_turn) => turn = next_turn,
match next(step.state.clone(), moves) {
Ok(next_step) => step = next_step,
Err(kind) => {
return Err(Error::new(turn.state, kind));
return Err(Error::new(step.state, kind));
}
}
}

Action::Chance { distribution, next } => {
let the_move = distribution.sample();

match next(turn.state.clone(), *the_move) {
Ok(next_turn) => turn = next_turn,
match next(step.state.clone(), *the_move) {
Ok(next_step) => step = next_step,
Err(kind) => {
return Err(Error::new(turn.state, kind));
return Err(Error::new(step.state, kind));
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions t4t/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//!
//! A subtler but more extreme case of this tradeoff is how games are executed. The [`Game`] trait
//! is quite generic, and implementers of this trait do not implement the execution of their game
//! directly, but rather produce a [*description*](crate::Turn) of how the game is executed. This
//! directly, but rather produce a [*description*](crate::Step) of how the game is executed. This
//! is much less efficient, but enables generically transforming the execution of a game, for
//! example, defining new games that modify the behavior of existing games.
//!
Expand Down Expand Up @@ -156,13 +156,13 @@ pub(crate) mod possible_profiles;
pub(crate) mod profile;
pub(crate) mod record;
pub(crate) mod repeated;
pub(crate) mod rules;
pub(crate) mod score;
pub(crate) mod simultaneous;
pub(crate) mod strategy;
pub(crate) mod summary;
pub(crate) mod tournament;
pub(crate) mod transcript;
pub(crate) mod turn;
// pub(crate) mod tree;

pub use distribution::*;
Expand All @@ -183,11 +183,11 @@ pub use possible_profiles::*;
pub use profile::*;
pub use record::*;
pub use repeated::*;
pub use rules::*;
pub use score::*;
pub use simultaneous::*;
pub use strategy::*;
pub use summary::*;
pub use tournament::*;
pub use transcript::*;
pub use turn::*;
// pub use tree::*;
8 changes: 4 additions & 4 deletions t4t/src/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::sync::Arc;

use crate::{
Dominated, ErrorKind, Game, Move, Outcome, Payoff, PerPlayer, PlayerIndex, PossibleMoves,
PossibleOutcomes, PossibleProfiles, Profile, Record, Simultaneous, SimultaneousOutcome, Turn,
PossibleOutcomes, PossibleProfiles, Profile, Record, Simultaneous, SimultaneousOutcome, Step,
Utility,
};

Expand Down Expand Up @@ -65,16 +65,16 @@ impl<M: Move, U: Utility, const P: usize> Game<P> for Normal<M, U, P> {
type State = ();
type View = ();

fn first_turn(&self) -> Turn<(), M, SimultaneousOutcome<M, U, P>, P> {
fn rules(&self) -> Step<(), M, SimultaneousOutcome<M, U, P>, P> {
let state = Arc::new(());
Turn::all_players(state.clone(), move |_, profile| {
Step::all_players(state.clone(), move |_, profile| {
for ply in profile.plies() {
let player = ply.player.unwrap();
if !self.is_valid_move_for_player(player, ply.the_move) {
return Err(ErrorKind::InvalidMove(player, ply.the_move));
}
}
Ok(Turn::end(
Ok(Step::end(
state,
SimultaneousOutcome::new(profile, self.payoff(profile)),
))
Expand Down
44 changes: 22 additions & 22 deletions t4t/src/repeated.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;
use std::sync::Arc;

use crate::{Action, Game, History, PlayerIndex, Turn};
use crate::{Action, Game, History, PlayerIndex, Step};

/// A finitely [repeated](https://en.wikipedia.org/wiki/Repeated_game) or iterated version of game
/// `G`.
Expand Down Expand Up @@ -46,7 +46,7 @@ impl<G: Game<P> + 'static, const P: usize> Repeated<G, P> {
impl<G: Game<P>, const P: usize> RepeatedState<G, P> {
/// Construct a new repeated game state.
pub fn new(stage_game: Arc<G>, remaining: usize) -> Self {
let stage_state = stage_game.first_turn().state.clone();
let stage_state = stage_game.rules().state.clone();
RepeatedState {
stage_game,
stage_state,
Expand All @@ -72,68 +72,68 @@ impl<G: Game<P>, const P: usize> RepeatedState<G, P> {
}
}

fn lift_turn<'g, G: Game<P> + 'g, const P: usize>(
fn lift_step<'g, G: Game<P> + 'g, const P: usize>(
stage_game: &'g G,
state: Arc<RepeatedState<G, P>>,
turn: Turn<'g, G::State, G::Move, G::Outcome, P>,
) -> Turn<'g, RepeatedState<G, P>, G::Move, History<G, P>, P> {
match turn.action {
Action::Players {
step: Step<'g, G::State, G::Move, G::Outcome, P>,
) -> Step<'g, RepeatedState<G, P>, G::Move, History<G, P>, P> {
match step.action {
Action::Turn {
to_move: players,
next,
} => Turn::players(
} => Step::players(
state.clone(),
players,
move |repeated_state: Arc<RepeatedState<G, P>>, moves: Vec<G::Move>| match next(
repeated_state.stage_state.clone(),
moves,
) {
Ok(stage_turn) => {
Ok(stage_step) => {
let mut next_state = (*state).clone();
next_state.stage_state = stage_turn.state.clone();
next_state.stage_state = stage_step.state.clone();

Ok(lift_turn(stage_game, Arc::new(next_state), stage_turn))
Ok(lift_step(stage_game, Arc::new(next_state), stage_step))
}

Err(kind) => Err(kind),
},
),

Action::Chance { distribution, next } => Turn::chance(
Action::Chance { distribution, next } => Step::chance(
state.clone(),
distribution,
move |repeated_state: Arc<RepeatedState<G, P>>, the_move: G::Move| match next(
repeated_state.stage_state.clone(),
the_move,
) {
Ok(stage_turn) => {
Ok(stage_step) => {
let mut next_state = (*state).clone();
next_state.stage_state = stage_turn.state.clone();
next_state.stage_state = stage_step.state.clone();

Ok(lift_turn(stage_game, Arc::new(next_state), stage_turn))
Ok(lift_step(stage_game, Arc::new(next_state), stage_step))
}

Err(kind) => Err(kind),
},
),

Action::End { outcome } if state.remaining > 0 => {
let stage_turn = stage_game.first_turn();
let stage_step = stage_game.rules();

let mut next_state = (*state).clone();
next_state.stage_state = stage_turn.state.clone();
next_state.stage_state = stage_step.state.clone();

next_state.completed.add(outcome);
next_state.remaining -= 1;

lift_turn(stage_game, Arc::new(next_state), stage_turn)
lift_step(stage_game, Arc::new(next_state), stage_step)
}

Action::End { outcome } => {
let mut history = state.completed.clone(); // TODO avoid this clone
history.add(outcome);

Turn::end(state, history)
Step::end(state, history)
}
}
}
Expand All @@ -145,16 +145,16 @@ impl<G: Game<P> + 'static, const P: usize> Game<P> for Repeated<G, P> {
type State = RepeatedState<G, P>;
type View = RepeatedState<G, P>; // TODO add RepeatedStateView or some other solution

fn first_turn(&self) -> Turn<RepeatedState<G, P>, G::Move, History<G, P>, P> {
fn rules(&self) -> Step<RepeatedState<G, P>, G::Move, History<G, P>, P> {
let init_state = Arc::new(RepeatedState::new(
self.stage_game.clone(),
self.repetitions - 1,
));

lift_turn(
lift_step(
self.stage_game.as_ref(),
init_state,
self.stage_game.first_turn(),
self.stage_game.rules(),
)
}

Expand Down
Loading

0 comments on commit cccb9cc

Please sign in to comment.