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