remove separate trait
This commit is contained in:
+5
-20
@@ -16,6 +16,7 @@ pub trait Game: Clone {
|
|||||||
config: &Self::Config,
|
config: &Self::Config,
|
||||||
) -> impl Iterator<Item = Self::Instruction> + use<Self>;
|
) -> impl Iterator<Item = Self::Instruction> + use<Self>;
|
||||||
fn is_instruction_valid(&self, config: &Self::Config, instruction: &Self::Instruction) -> bool;
|
fn is_instruction_valid(&self, config: &Self::Config, instruction: &Self::Instruction) -> bool;
|
||||||
|
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>);
|
||||||
fn is_win(&self) -> bool;
|
fn is_win(&self) -> bool;
|
||||||
/// Validate an instruction to prepare to run it.
|
/// Validate an instruction to prepare to run it.
|
||||||
fn stage_instruction<'a>(
|
fn stage_instruction<'a>(
|
||||||
@@ -54,21 +55,13 @@ impl<'a, G: Game> StagedInstruction<'a, G> {
|
|||||||
(game, stats, config, instruction)
|
(game, stats, config, instruction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<G: Game> StagedInstruction<'_, G>
|
impl<G: Game> StagedInstruction<'_, G> {
|
||||||
where
|
|
||||||
G: InstructionConsumer,
|
|
||||||
{
|
|
||||||
/// Process the staged instruction.
|
/// Process the staged instruction.
|
||||||
pub fn commit(self) {
|
pub fn commit(self) {
|
||||||
G::process_instruction(self);
|
G::process_instruction(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply an atomic state update
|
|
||||||
pub trait InstructionConsumer: Game {
|
|
||||||
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// card_game supports up to 4 identifiably separate decks.
|
/// card_game supports up to 4 identifiably separate decks.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub enum Deck {
|
pub enum Deck {
|
||||||
@@ -558,7 +551,6 @@ where
|
|||||||
G: Eq + core::hash::Hash,
|
G: Eq + core::hash::Hash,
|
||||||
G::Stats: Default,
|
G::Stats: Default,
|
||||||
G::Instruction: Eq + core::hash::Hash,
|
G::Instruction: Eq + core::hash::Hash,
|
||||||
G: InstructionConsumer,
|
|
||||||
{
|
{
|
||||||
pub fn new(state: G, config: SessionConfig<G::Config>) -> Self {
|
pub fn new(state: G, config: SessionConfig<G::Config>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -678,15 +670,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn is_win(&self) -> bool {
|
|
||||||
self.state.is_win()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<G> InstructionConsumer for SessionState<G>
|
|
||||||
where
|
|
||||||
G: Game<Score = i32, Stats: Default>,
|
|
||||||
G: InstructionConsumer,
|
|
||||||
{
|
|
||||||
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>) {
|
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>) {
|
||||||
let (game, stats, config, instruction) = valid_instruction.consume();
|
let (game, stats, config, instruction) = valid_instruction.consume();
|
||||||
match instruction {
|
match instruction {
|
||||||
@@ -711,6 +694,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn is_win(&self) -> bool {
|
||||||
|
self.state.is_win()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
@@ -719,7 +705,6 @@ where
|
|||||||
G: serde::Deserialize<'de> + Clone + Eq + core::hash::Hash,
|
G: serde::Deserialize<'de> + Clone + Eq + core::hash::Hash,
|
||||||
G::Stats: Default,
|
G::Stats: Default,
|
||||||
G::Instruction: serde::Deserialize<'de> + Eq + core::hash::Hash,
|
G::Instruction: serde::Deserialize<'de> + Eq + core::hash::Hash,
|
||||||
G: InstructionConsumer,
|
|
||||||
SessionConfig<G::Config>: serde::Deserialize<'de>,
|
SessionConfig<G::Config>: serde::Deserialize<'de>,
|
||||||
Vec<G::Instruction>: serde::Deserialize<'de>,
|
Vec<G::Instruction>: serde::Deserialize<'de>,
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-13
@@ -1,6 +1,6 @@
|
|||||||
pub type Rng = rand::rngs::StdRng;
|
pub type Rng = rand::rngs::StdRng;
|
||||||
|
|
||||||
use card_game::{Card, Game, InstructionConsumer, Pile, Rank, Stack, StagedInstruction};
|
use card_game::{Card, Game, Pile, Rank, Stack, StagedInstruction};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
@@ -835,18 +835,6 @@ impl Game for Klondike {
|
|||||||
fn is_instruction_valid(&self, config: &Self::Config, instruction: &Self::Instruction) -> bool {
|
fn is_instruction_valid(&self, config: &Self::Config, instruction: &Self::Instruction) -> bool {
|
||||||
self.state.is_instruction_valid(config, instruction)
|
self.state.is_instruction_valid(config, instruction)
|
||||||
}
|
}
|
||||||
fn is_win(&self) -> bool {
|
|
||||||
// all foundations contain all ranks
|
|
||||||
self.state.foundations.iter().all(|foundation| {
|
|
||||||
foundation.len() == Rank::RANKS.len()
|
|
||||||
&& foundation
|
|
||||||
.iter()
|
|
||||||
.zip(Rank::RANKS)
|
|
||||||
.all(|(card, rank)| card.rank() == rank)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl InstructionConsumer for Klondike {
|
|
||||||
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>) {
|
fn process_instruction(valid_instruction: StagedInstruction<'_, Self>) {
|
||||||
let (game, stats, config, instruction) = valid_instruction.consume();
|
let (game, stats, config, instruction) = valid_instruction.consume();
|
||||||
stats.increment_moves();
|
stats.increment_moves();
|
||||||
@@ -886,6 +874,16 @@ impl InstructionConsumer for Klondike {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn is_win(&self) -> bool {
|
||||||
|
// all foundations contain all ranks
|
||||||
|
self.state.foundations.iter().all(|foundation| {
|
||||||
|
foundation.len() == Rank::RANKS.len()
|
||||||
|
&& foundation
|
||||||
|
.iter()
|
||||||
|
.zip(Rank::RANKS)
|
||||||
|
.all(|(card, rank)| card.rank() == rank)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
|
|||||||
Reference in New Issue
Block a user