Implement Mine
This commit is contained in:
		
							
								
								
									
										11
									
								
								src/cards.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/cards.rs
									
									
									
									
									
								
							@@ -82,10 +82,19 @@ macro_rules! coin {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
fn serialize_card_type<S>(_: &fn(&mut super::Game), serializer: S) -> Result<S::Ok, S::Error>
 | 
			
		||||
where
 | 
			
		||||
    S: Serializer,
 | 
			
		||||
{
 | 
			
		||||
    serializer.serialize_str("ActionSer")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Serialize)]
 | 
			
		||||
pub enum CardType {
 | 
			
		||||
    #[serde(serialize_with = "serialize_card_type")]
 | 
			
		||||
    Action(fn(&mut Game)),
 | 
			
		||||
    Curse,
 | 
			
		||||
    #[serde(serialize_with = "serialize_card_type")]
 | 
			
		||||
    Reaction(fn(&mut Game)),
 | 
			
		||||
    Treasure(u32),
 | 
			
		||||
    Victory(u32),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -4,7 +4,7 @@ mod cards;
 | 
			
		||||
use async_std::{prelude::*, sync::RwLock};
 | 
			
		||||
use cards::*;
 | 
			
		||||
use itertools::Itertools;
 | 
			
		||||
use rand::{seq::SliceRandom, Rng, thread_rng};
 | 
			
		||||
use rand::{seq::SliceRandom, thread_rng, Rng};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use std::{collections::HashMap, sync::Arc};
 | 
			
		||||
use tide::{Body, Redirect, Request, Response};
 | 
			
		||||
@@ -192,6 +192,7 @@ enum ResolveReply {
 | 
			
		||||
enum ResolveRequest {
 | 
			
		||||
    ChooseHandCardsToDiscard {
 | 
			
		||||
        player: ResolvingPlayer,
 | 
			
		||||
        filter: CardFilter,
 | 
			
		||||
    },
 | 
			
		||||
    GainCard {
 | 
			
		||||
        player: ResolvingPlayer,
 | 
			
		||||
@@ -214,6 +215,7 @@ enum Effect {
 | 
			
		||||
enum CardFilter {
 | 
			
		||||
    Any,
 | 
			
		||||
    MaxCost(u32),
 | 
			
		||||
    Type(CardType),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ResolvingEffect = fn(&mut Game, &ResolveReply);
 | 
			
		||||
@@ -287,12 +289,14 @@ impl Game {
 | 
			
		||||
                                    "Cellar".into(),
 | 
			
		||||
                                    ResolveRequest::ChooseHandCardsToDiscard {
 | 
			
		||||
                                        player: ResolvingPlayer::ActivePlayer,
 | 
			
		||||
                                        filter: CardFilter::Any,
 | 
			
		||||
                                    },
 | 
			
		||||
                                    |game, message| {
 | 
			
		||||
                                        if let ResolveReply::HandCardsChosen { choice } = message {
 | 
			
		||||
                                            let mut discarded = 0;
 | 
			
		||||
                                            for c in choice.iter().sorted_by(|a, b| b.cmp(a)) {
 | 
			
		||||
                                                game.players[game.active_player].discard(*c);
 | 
			
		||||
                                                game.get_active_player().discard(*c);
 | 
			
		||||
                                                //game.players[game.active_player].discard(*c);
 | 
			
		||||
                                                discarded += 1;
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
@@ -402,6 +406,7 @@ impl Game {
 | 
			
		||||
                                    "Remodel".into(),
 | 
			
		||||
                                    ResolveRequest::ChooseHandCardsToDiscard {
 | 
			
		||||
                                        player: ResolvingPlayer::ActivePlayer,
 | 
			
		||||
                                        filter: CardFilter::Any,
 | 
			
		||||
                                    },
 | 
			
		||||
                                    |game, message| {
 | 
			
		||||
                                        if let ResolveReply::HandCardsChosen { choice } = message {
 | 
			
		||||
@@ -503,7 +508,95 @@ impl Game {
 | 
			
		||||
                        Card {
 | 
			
		||||
                            name: "Mine".into(),
 | 
			
		||||
                            cost: 5,
 | 
			
		||||
                            types: vec![CardType::Action(|_| {})],
 | 
			
		||||
                            types: vec![CardType::Action(|game| {
 | 
			
		||||
                                game.add_effect(Effect::Resolving(
 | 
			
		||||
                                    "Mine".into(),
 | 
			
		||||
                                    ResolveRequest::ChooseHandCardsToDiscard {
 | 
			
		||||
                                        player: ResolvingPlayer::ActivePlayer,
 | 
			
		||||
                                        filter: CardFilter::Type(CardType::Treasure(0)),
 | 
			
		||||
                                    },
 | 
			
		||||
                                    |game, message| {
 | 
			
		||||
                                        if let ResolveReply::HandCardsChosen { choice } = message {
 | 
			
		||||
                                            if choice.len() != 1 {
 | 
			
		||||
                                                return;
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            if let Some(card) =
 | 
			
		||||
                                                game.get_active_player().hand.get(choice[0])
 | 
			
		||||
                                            {
 | 
			
		||||
                                                if let None = card.treasure() {
 | 
			
		||||
                                                    return;
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            let card = game.players[game.active_player]
 | 
			
		||||
                                                .hand
 | 
			
		||||
                                                .remove(choice[0]);
 | 
			
		||||
                                            let cost = card.cost;
 | 
			
		||||
 | 
			
		||||
                                            game.trash.push(card);
 | 
			
		||||
 | 
			
		||||
                                            game.add_effect(Effect::Resolving(
 | 
			
		||||
                                                "Mine".into(),
 | 
			
		||||
                                                ResolveRequest::GainCard {
 | 
			
		||||
                                                    player: ResolvingPlayer::ActivePlayer,
 | 
			
		||||
                                                    filter: CardFilter::MaxCost(cost + 3),
 | 
			
		||||
                                                },
 | 
			
		||||
                                                |game, message| {
 | 
			
		||||
                                                    if let ResolveReply::SupplyCardChosen {
 | 
			
		||||
                                                        choice,
 | 
			
		||||
                                                    } = message
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        if let Some((card, count)) =
 | 
			
		||||
                                                            game.supply.get(*choice)
 | 
			
		||||
                                                        {
 | 
			
		||||
                                                            if *count < 1 {
 | 
			
		||||
                                                                return;
 | 
			
		||||
                                                            }
 | 
			
		||||
 | 
			
		||||
                                                            if let Some((
 | 
			
		||||
                                                                _,
 | 
			
		||||
                                                                ResolveRequest::GainCard {
 | 
			
		||||
                                                                    filter:
 | 
			
		||||
                                                                        CardFilter::MaxCost(cost),
 | 
			
		||||
                                                                    ..
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                                _,
 | 
			
		||||
                                                            )) = game.resolving_effect
 | 
			
		||||
                                                            {
 | 
			
		||||
                                                                if card.cost > cost {
 | 
			
		||||
                                                                    return;
 | 
			
		||||
                                                                }
 | 
			
		||||
 | 
			
		||||
                                                                if let None = card.treasure() {
 | 
			
		||||
                                                                    return;
 | 
			
		||||
                                                                }
 | 
			
		||||
 | 
			
		||||
                                                                game.supply
 | 
			
		||||
                                                                    .get_mut(*choice)
 | 
			
		||||
                                                                    .unwrap()
 | 
			
		||||
                                                                    .1 = game
 | 
			
		||||
                                                                    .supply
 | 
			
		||||
                                                                    .get(*choice)
 | 
			
		||||
                                                                    .unwrap()
 | 
			
		||||
                                                                    .1
 | 
			
		||||
                                                                    - 1;
 | 
			
		||||
                                                                let card =
 | 
			
		||||
                                                                    game.supply[*choice].0.clone();
 | 
			
		||||
 | 
			
		||||
                                                                game.players[game.active_player]
 | 
			
		||||
                                                                    .discard_pile
 | 
			
		||||
                                                                    .push(card.clone());
 | 
			
		||||
                                                                game.resolving_effect = None;
 | 
			
		||||
                                                            }
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                },
 | 
			
		||||
                                            ));
 | 
			
		||||
                                        }
 | 
			
		||||
                                    },
 | 
			
		||||
                                ));
 | 
			
		||||
                            })],
 | 
			
		||||
                        },
 | 
			
		||||
                        10,
 | 
			
		||||
                    ),
 | 
			
		||||
@@ -515,6 +608,10 @@ impl Game {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn end_turn(&mut self) {
 | 
			
		||||
        if let Some(_) = self.resolving_effect {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        match self.players.get_mut(self.active_player) {
 | 
			
		||||
            None => {}
 | 
			
		||||
            Some(p) => {
 | 
			
		||||
@@ -560,16 +657,24 @@ impl Game {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_active_player(&mut self) -> &Player {
 | 
			
		||||
        return &self.players[self.active_player];
 | 
			
		||||
    fn get_active_player(&mut self) -> &mut Player {
 | 
			
		||||
        return &mut self.players[self.active_player];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn trash_hand(&mut self, player_number: usize, index: usize) {
 | 
			
		||||
        if let Some(_) = self.resolving_effect {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.trash
 | 
			
		||||
            .push(self.players[player_number].hand.remove(index));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn can_play(&self, player_number: usize, index: usize) -> bool {
 | 
			
		||||
        if let Some(_) = self.resolving_effect {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let card = self.players[player_number].hand.get(index).unwrap();
 | 
			
		||||
 | 
			
		||||
        match card.action() {
 | 
			
		||||
@@ -630,6 +735,10 @@ impl Game {
 | 
			
		||||
 | 
			
		||||
    pub fn buy_card(&mut self, player_number: usize, index: usize) -> bool /*-> Result<(), &'static str>*/
 | 
			
		||||
    {
 | 
			
		||||
        if let Some(_) = self.resolving_effect {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if player_number != self.active_player {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -748,7 +857,7 @@ async fn broadcast_state(game: &Game) {
 | 
			
		||||
 | 
			
		||||
    if let Some((card_name, request, _)) = &game.resolving_effect {
 | 
			
		||||
        match request {
 | 
			
		||||
            ResolveRequest::ChooseHandCardsToDiscard { ref player } => match player {
 | 
			
		||||
            ResolveRequest::ChooseHandCardsToDiscard { ref player, .. } => match player {
 | 
			
		||||
                ResolvingPlayer::ActivePlayer => {
 | 
			
		||||
                    let p = game.players.get(game.active_player).unwrap();
 | 
			
		||||
                    let sm = ServerMessage::ResolveRequest {
 | 
			
		||||
 
 | 
			
		||||
@@ -443,7 +443,7 @@ img.card:hover {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dialog.hand {
 | 
			
		||||
    top: 50%;
 | 
			
		||||
    top: 20%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dialog img {
 | 
			
		||||
@@ -482,6 +482,9 @@ img.card:hover {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var toggle_supply_selection = function(index) {
 | 
			
		||||
            document.querySelectorAll(".supply-area .supply-pile").forEach((c) => {
 | 
			
		||||
                c.classList.remove("selected");
 | 
			
		||||
            });
 | 
			
		||||
            document.querySelectorAll(".supply-area .supply-pile")[index].classList.toggle("selected");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user