Skip to content

Commit

Permalink
start to use effects for scoring
Browse files Browse the repository at this point in the history
  • Loading branch information
evanofslack committed Dec 8, 2024
1 parent 4393306 commit cfda694
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 39 deletions.
11 changes: 1 addition & 10 deletions src/core/deck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,13 @@ impl Deck {
pub fn new() -> Self {
Self { cards: Vec::new() }
}
pub(crate) fn contains(&self, c: &Card) -> bool {
self.cards.contains(c)
}
pub(crate) fn remove(&mut self, c: &Card) -> bool {
pub fn remove(&mut self, c: &Card) -> bool {
if let Some(pos) = self.cards.iter().position(|x| x == c) {
self.cards.remove(pos);
return true;
}
return false;
}
pub(crate) fn push(&mut self, c: Card) {
self.cards.push(c)
}
pub(crate) fn draw(&mut self, n: usize) -> Option<Vec<Card>> {
if self.cards.len() < n {
return None;
Expand All @@ -33,9 +27,6 @@ impl Deck {
pub(crate) fn len(&self) -> usize {
self.cards.len()
}
pub(crate) fn is_empty(&self) -> bool {
self.cards.is_empty()
}

pub(crate) fn shuffle(&mut self) {
self.cards.shuffle(&mut thread_rng());
Expand Down
53 changes: 53 additions & 0 deletions src/core/effect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::core::game::Game;
use crate::core::joker::{Joker, Jokers};
use std::sync::Arc;

#[derive(Debug, Clone)]
pub struct EffectRegistry {
pub on_play: Vec<Effects>,
pub on_discard: Vec<Effects>,
pub on_score: Vec<Effects>,
pub on_handrank: Vec<Effects>,
}

impl EffectRegistry {
pub fn new() -> Self {
return Self {
on_play: Vec::new(),
on_discard: Vec::new(),
on_score: Vec::new(),
on_handrank: Vec::new(),
};
}
pub fn register_jokers(&mut self, jokers: Vec<Jokers>, game: &Game) {
for j in jokers.clone() {
for e in j.effects(game) {
match e {
Effects::OnPlay(_) => self.on_play.push(e),
Effects::OnDiscard(_) => self.on_discard.push(e),
Effects::OnScore(_) => self.on_score.push(e),
Effects::OnHandRank(_) => self.on_handrank.push(e),
}
}
}
}
}

#[derive(Clone)]
pub enum Effects {
OnPlay(Arc<dyn Fn(&mut Game)>),
OnDiscard(Arc<dyn Fn(&mut Game)>),
OnScore(Arc<dyn Fn(&mut Game)>),
OnHandRank(Arc<dyn Fn(&mut Game)>),
}

impl std::fmt::Debug for Effects {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::OnPlay(_) => write!(f, "OnPlay"),
Self::OnDiscard(_) => write!(f, "OnDiscard"),
Self::OnScore(_) => write!(f, "OnScore"),
Self::OnHandRank(_) => write!(f, "OnHandRank"),
}
}
}
49 changes: 38 additions & 11 deletions src/core/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::core::action::{Action, MoveDirection};
use crate::core::ante::Ante;
use crate::core::card::Card;
use crate::core::deck::Deck;
use crate::core::effect::EffectRegistry;
use crate::core::error::GameError;
use crate::core::hand::{MadeHand, SelectHand};
use crate::core::joker::Jokers;
Expand All @@ -12,6 +13,8 @@ use std::fmt;

use itertools::Itertools;

use super::effect::Effects;

const DEFAULT_ROUND_START: usize = 0;
const DEFAULT_PLAYS: usize = 4;
const DEFAULT_DISCARDS: usize = 4;
Expand All @@ -21,24 +24,26 @@ const DEFAULT_MONEY_PER_HAND: usize = 1;
const DEFAULT_INTEREST_RATE: f32 = 0.2;
const DEFAULT_INTEREST_MAX: usize = 5;
const HAND_SIZE: usize = 8;
const BASE_MULT: usize = 1;
const BASE_MULT: usize = 0;
const BASE_CHIPS: usize = 0;
const BASE_SCORE: usize = 0;

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct Game {
pub shop: Shop,
pub deck: Deck,
pub available: Vec<Card>,
pub discarded: Vec<Card>,
pub jokers: Vec<Jokers>,
pub blind: Option<Blind>,
pub stage: Stage,
pub ante: Ante,
pub action_history: Vec<Action>,
pub round: usize,

// jokers and their effects
pub jokers: Vec<Jokers>,
pub effect_registry: EffectRegistry,

// playing
pub plays: usize,
pub discards: usize,
Expand All @@ -58,12 +63,13 @@ impl Game {
deck: Deck::default(),
available: Vec::new(),
discarded: Vec::new(),
jokers: Vec::new(),
blind: None,
stage: Stage::PreBlind,
ante: Ante::One,
action_history: Vec::new(),
round: DEFAULT_ROUND_START,
jokers: Vec::new(),
effect_registry: EffectRegistry::new(),
plays: DEFAULT_PLAYS,
discards: DEFAULT_DISCARDS,
reward: DEFAULT_REWARD,
Expand Down Expand Up @@ -165,11 +171,30 @@ impl Game {
}
}

pub fn calc_score(&self, hand: MadeHand) -> usize {
let base_mult = hand.rank.level().mult;
let base_chips = hand.rank.level().chips;
let hand_chips: usize = hand.hand.cards().iter().map(|c| c.chips()).sum();
return (hand_chips + base_chips) * base_mult;
pub fn calc_score(&mut self, hand: MadeHand) -> usize {
// compute chips and mult from hand level
self.chips += hand.rank.level().chips;
self.mult += hand.rank.level().mult;

// add chips for each played card
let card_chips: usize = hand.hand.cards().iter().map(|c| c.chips()).sum();
self.chips += card_chips;

// Apply effects that modify game.chips and game.mult
for e in self.effect_registry.on_score.clone() {
match e {
Effects::OnScore(f) => f(self),
_ => (),
}
}

// compute score
let score = self.chips * self.mult;

// reset chips and mult
self.mult = BASE_MULT;
self.chips = BASE_CHIPS;
return score;
}

pub fn required_score(&self) -> Result<usize, GameError> {
Expand Down Expand Up @@ -204,6 +229,8 @@ impl Game {

pub fn buy_joker(&mut self, joker: Jokers) -> Result<(), GameError> {
self.jokers.push(joker);
self.effect_registry
.register_jokers(self.jokers.clone(), &self.clone());
return Ok(());
}

Expand Down Expand Up @@ -507,7 +534,7 @@ mod tests {
let g = Game::new();
assert_eq!(g.available.len(), 0);
assert_eq!(g.deck.len(), 52);
assert_eq!(g.mult, 1);
assert_eq!(g.mult, 0);
}

#[test]
Expand Down Expand Up @@ -548,7 +575,7 @@ mod tests {

#[test]
fn test_score() {
let g = Game::new();
let g = &mut Game::new();
let ace = Card::new(Value::Ace, Suit::Heart);
let king = Card::new(Value::King, Suit::Diamond);
let jack = Card::new(Value::Jack, Suit::Club);
Expand Down
27 changes: 9 additions & 18 deletions src/core/joker.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
use crate::core::effect::Effects;
use crate::core::game::Game;
use std::sync::Arc;
use strum::{EnumIter, IntoEnumIterator};

pub trait Effect {
fn apply(&self, game: &mut Game);
}

pub enum Effects {
OnPlay(Box<dyn FnOnce(&mut Game)>),
OnDiscard(Box<dyn FnOnce(&mut Game)>),
OnScore(Box<dyn FnOnce(&mut Game)>),
OnHandRank(Box<dyn FnOnce(&mut Game)>),
}

pub trait Joker: std::fmt::Debug + Clone {
fn name(&self) -> String;
fn desc(&self) -> String;
fn rarity(&self) -> Rarity;
fn categories(&self) -> Vec<Categories>;
fn effects(&self, game: Game) -> Vec<Effects>;
fn effects(&self, game: &Game) -> Vec<Effects>;
}

#[derive(Debug, Clone, Eq, PartialEq)]
Expand All @@ -30,7 +21,7 @@ pub enum Categories {
Effect,
}

#[derive(Debug, Clone, Eq, PartialEq, EnumIter)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Rarity {
Common,
Uncommon,
Expand Down Expand Up @@ -76,7 +67,7 @@ impl Joker for Jokers {
Self::LustyJoker(j) => j.categories(),
}
}
fn effects(&self, game: Game) -> Vec<Effects> {
fn effects(&self, game: &Game) -> Vec<Effects> {
match self {
Self::TheJoker(j) => j.effects(game),
Self::LustyJoker(j) => j.effects(game),
Expand All @@ -100,11 +91,11 @@ impl Joker for TheJoker {
fn categories(&self) -> Vec<Categories> {
vec![Categories::MultPlus]
}
fn effects(&self, _in: Game) -> Vec<Effects> {
fn effects(&self, _in: &Game) -> Vec<Effects> {
fn apply(g: &mut Game) {
g.mult += 4;
}
vec![Effects::OnScore(Box::new(apply))]
vec![Effects::OnScore(Arc::new(apply))]
}
}

Expand All @@ -124,10 +115,10 @@ impl Joker for LustyJoker {
fn categories(&self) -> Vec<Categories> {
vec![Categories::MultPlus]
}
fn effects(&self, _in: Game) -> Vec<Effects> {
fn effects(&self, _in: &Game) -> Vec<Effects> {
fn apply(g: &mut Game) {
g.mult += 4;
}
vec![Effects::OnScore(Box::new(apply))]
vec![Effects::OnScore(Arc::new(apply))]
}
}
1 change: 1 addition & 0 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod action;
pub mod ante;
pub mod card;
pub mod deck;
pub mod effect;
pub mod error;
pub mod game;
pub mod hand;
Expand Down

0 comments on commit cfda694

Please sign in to comment.