Implement Mine
This commit is contained in:
parent
998d27764d
commit
d18942feda
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");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user