Add effect for Merchant
This commit is contained in:
		@@ -86,6 +86,7 @@ macro_rules! coin {
 | 
			
		||||
pub enum CardType {
 | 
			
		||||
    Action(fn(&mut Game)),
 | 
			
		||||
    Curse,
 | 
			
		||||
    Reaction(fn(&mut Game)),
 | 
			
		||||
    Treasure(u32),
 | 
			
		||||
    Victory(u32),
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -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,14 +749,17 @@ 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);
 | 
			
		||||
 | 
			
		||||
                        notify_players(
 | 
			
		||||
                            &game,
 | 
			
		||||
                            format!("{} spielt {}", game.players[player_number].name, card_name),
 | 
			
		||||
                        )
 | 
			
		||||
                        .await;
 | 
			
		||||
                        broadcast_state(&game).await;
 | 
			
		||||
                        if game.play_card(player_number, index) {
 | 
			
		||||
                            notify_players(
 | 
			
		||||
                                &game,
 | 
			
		||||
                                format!(
 | 
			
		||||
                                    "{} spielt {}",
 | 
			
		||||
                                    game.players[player_number].name, card_name
 | 
			
		||||
                                ),
 | 
			
		||||
                            )
 | 
			
		||||
                            .await;
 | 
			
		||||
                            broadcast_state(&game).await;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    ClientMessage::BuyCard { index } => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user