Add effect for Merchant
This commit is contained in:
parent
83d5062a84
commit
b30cc02306
@ -86,6 +86,7 @@ macro_rules! coin {
|
||||
pub enum CardType {
|
||||
Action(fn(&mut Game)),
|
||||
Curse,
|
||||
Reaction(fn(&mut Game)),
|
||||
Treasure(u32),
|
||||
Victory(u32),
|
||||
}
|
||||
|
85
src/main.rs
85
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,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;
|
||||
|
Loading…
Reference in New Issue
Block a user