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 {
Action(fn(&mut Game)),
Curse,
Reaction(fn(&mut Game)),
Treasure(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 {
effects: Vec<Effect>,
players: Vec<Player>,
state: GameState,
setup: GameSetup,
@ -179,6 +185,7 @@ pub struct Game {
impl Game {
fn new(player: Player) -> Self {
Self {
effects: vec![],
players: vec![player],
state: GameState::Setup,
setup: GameSetup::default(),
@ -227,7 +234,12 @@ impl Game {
Card {
name: "Moat".into(),
cost: 2,
types: vec![CardType::Action(|game| draw!(game, 2))],
types: vec![
CardType::Action(|game| {
draw!(game, 2);
}),
CardType::Reaction(|_| {}),
],
},
10,
),
@ -249,6 +261,14 @@ impl Game {
types: vec![CardType::Action(|game| {
draw!(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,
@ -257,7 +277,7 @@ impl Game {
Card {
name: "Workshop".into(),
cost: 3,
types: vec![CardType::Action(|game| {})],
types: vec![CardType::Action(|_| {})],
},
10,
),
@ -273,7 +293,7 @@ impl Game {
Card {
name: "Remodel".into(),
cost: 4,
types: vec![CardType::Action(|game| {})],
types: vec![CardType::Action(|_| {})],
},
10,
),
@ -304,7 +324,7 @@ impl Game {
Card {
name: "Mine".into(),
cost: 5,
types: vec![CardType::Action(|game| {})],
types: vec![CardType::Action(|_| {})],
},
10,
),
@ -330,6 +350,8 @@ impl Game {
self.active_player += 1;
self.active_player %= self.players.len();
self.turn_state = TurnState::default();
self.effects.clear();
}
// 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));
}
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);
if let Some(coin) = card.treasure() {
@ -381,7 +428,22 @@ impl Game {
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);
true
}
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");
false
}
fn add_effect(&mut self, effect: Effect) {
self.effects.push(effect);
}
}
#[derive(Clone, Default)]
@ -683,15 +749,18 @@ async fn main() -> Result<(), std::io::Error> {
let game = games.get_mut(&game_id).unwrap();
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(
&game,
format!("{} spielt {}", game.players[player_number].name, card_name),
format!(
"{} spielt {}",
game.players[player_number].name, card_name
),
)
.await;
broadcast_state(&game).await;
}
}
ClientMessage::BuyCard { index } => {
let mut games = req.state().games.write().await;