Add effect for Merchant

This commit is contained in:
Markus Wagner 2021-01-12 20:55:36 +01:00
parent 83d5062a84
commit b30cc02306
2 changed files with 83 additions and 13 deletions

View File

@ -86,6 +86,7 @@ macro_rules! coin {
pub enum CardType { pub enum CardType {
Action(fn(&mut Game)), Action(fn(&mut Game)),
Curse, Curse,
Reaction(fn(&mut Game)),
Treasure(u32), Treasure(u32),
Victory(u32), Victory(u32),
} }

View File

@ -165,7 +165,13 @@ impl Default for GameSetup {
} }
} }
#[derive(Clone)]
enum Effect {
OnCardPlayed(fn(&mut Game, &Card) -> bool),
}
pub struct Game { pub struct Game {
effects: Vec<Effect>,
players: Vec<Player>, players: Vec<Player>,
state: GameState, state: GameState,
setup: GameSetup, setup: GameSetup,
@ -179,6 +185,7 @@ pub struct Game {
impl Game { impl Game {
fn new(player: Player) -> Self { fn new(player: Player) -> Self {
Self { Self {
effects: vec![],
players: vec![player], players: vec![player],
state: GameState::Setup, state: GameState::Setup,
setup: GameSetup::default(), setup: GameSetup::default(),
@ -227,7 +234,12 @@ impl Game {
Card { Card {
name: "Moat".into(), name: "Moat".into(),
cost: 2, cost: 2,
types: vec![CardType::Action(|game| draw!(game, 2))], types: vec![
CardType::Action(|game| {
draw!(game, 2);
}),
CardType::Reaction(|_| {}),
],
}, },
10, 10,
), ),
@ -249,6 +261,14 @@ impl Game {
types: vec![CardType::Action(|game| { types: vec![CardType::Action(|game| {
draw!(game, 1); draw!(game, 1);
action!(game, 1); action!(game, 1);
game.add_effect(Effect::OnCardPlayed(|game, card| {
if card.name.as_str() == "Silver" {
coin!(game, 1);
true
} else {
false
}
}));
})], })],
}, },
10, 10,
@ -257,7 +277,7 @@ impl Game {
Card { Card {
name: "Workshop".into(), name: "Workshop".into(),
cost: 3, cost: 3,
types: vec![CardType::Action(|game| {})], types: vec![CardType::Action(|_| {})],
}, },
10, 10,
), ),
@ -273,7 +293,7 @@ impl Game {
Card { Card {
name: "Remodel".into(), name: "Remodel".into(),
cost: 4, cost: 4,
types: vec![CardType::Action(|game| {})], types: vec![CardType::Action(|_| {})],
}, },
10, 10,
), ),
@ -304,7 +324,7 @@ impl Game {
Card { Card {
name: "Mine".into(), name: "Mine".into(),
cost: 5, cost: 5,
types: vec![CardType::Action(|game| {})], types: vec![CardType::Action(|_| {})],
}, },
10, 10,
), ),
@ -330,6 +350,8 @@ impl Game {
self.active_player += 1; self.active_player += 1;
self.active_player %= self.players.len(); self.active_player %= self.players.len();
self.turn_state = TurnState::default(); self.turn_state = TurnState::default();
self.effects.clear();
} }
// Check if the end game condition is reached and finish the game if so, // Check if the end game condition is reached and finish the game if so,
@ -368,7 +390,32 @@ impl Game {
.push(self.players[player_number].hand.remove(index)); .push(self.players[player_number].hand.remove(index));
} }
pub fn play_card(&mut self, player_number: usize, index: usize) { pub fn can_play(&self, player_number: usize, index: usize) -> bool {
let card = self.players[player_number].hand.get(index).unwrap();
match card.action() {
Some(_) => {
if self.turn_state.actions > 0 {
return true;
}
}
None => (),
}
match card.treasure() {
Some(_) => {
return true;
}
None => (),
}
false
}
pub fn play_card(&mut self, player_number: usize, index: usize) -> bool {
if !self.can_play(player_number, index) {
return false;
}
let card = self.players[player_number].hand.remove(index); let card = self.players[player_number].hand.remove(index);
if let Some(coin) = card.treasure() { if let Some(coin) = card.treasure() {
@ -381,7 +428,22 @@ impl Game {
effect(self); effect(self);
} }
let mut effects = self.effects.clone();
effects.retain(|effect| {
match effect {
Effect::OnCardPlayed(effect) => {
if effect(self, &card) {
return false;
}
}
}
true
});
self.effects = effects;
self.players[player_number].played_cards.push(card); self.players[player_number].played_cards.push(card);
true
} }
pub fn buy_card(&mut self, player_number: usize, index: usize) -> bool /*-> Result<(), &'static str>*/ pub fn buy_card(&mut self, player_number: usize, index: usize) -> bool /*-> Result<(), &'static str>*/
@ -409,6 +471,10 @@ impl Game {
//Err("Not enough coin"); //Err("Not enough coin");
false false
} }
fn add_effect(&mut self, effect: Effect) {
self.effects.push(effect);
}
} }
#[derive(Clone, Default)] #[derive(Clone, Default)]
@ -683,14 +749,17 @@ async fn main() -> Result<(), std::io::Error> {
let game = games.get_mut(&game_id).unwrap(); let game = games.get_mut(&game_id).unwrap();
let card_name = game.players[player_number].hand[index].name.clone(); let card_name = game.players[player_number].hand[index].name.clone();
game.play_card(player_number, index); if game.play_card(player_number, index) {
notify_players(
notify_players( &game,
&game, format!(
format!("{} spielt {}", game.players[player_number].name, card_name), "{} spielt {}",
) game.players[player_number].name, card_name
.await; ),
broadcast_state(&game).await; )
.await;
broadcast_state(&game).await;
}
} }
ClientMessage::BuyCard { index } => { ClientMessage::BuyCard { index } => {