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 {
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user