Compare commits
No commits in common. "ea94aa523086d7757a1938da108cc1dfc6decb6d" and "9ab7d7fcfb252a985c9d8228b67f243f61dca2d6" have entirely different histories.
ea94aa5230
...
9ab7d7fcfb
130
src/cards.rs
130
src/cards.rs
@ -1,130 +0,0 @@
|
|||||||
use serde::{Serialize, Serializer};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
pub fn copper() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Copper".into(),
|
|
||||||
cost: 0,
|
|
||||||
types: vec![CardType::Treasure(1)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn silver() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Silver".into(),
|
|
||||||
cost: 3,
|
|
||||||
types: vec![CardType::Treasure(2)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gold() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Gold".into(),
|
|
||||||
cost: 6,
|
|
||||||
types: vec![CardType::Treasure(3)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn estate() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Estate".into(),
|
|
||||||
cost: 2,
|
|
||||||
types: vec![CardType::Victory(1)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn duchy() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Duchy".into(),
|
|
||||||
cost: 5,
|
|
||||||
types: vec![CardType::Victory(3)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn province() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Province".into(),
|
|
||||||
cost: 8,
|
|
||||||
types: vec![CardType::Victory(6)],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn curse() -> Card {
|
|
||||||
Card {
|
|
||||||
name: "Curse".into(),
|
|
||||||
cost: 0,
|
|
||||||
types: vec![CardType::Curse],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum CardType {
|
|
||||||
Action(fn()),
|
|
||||||
Curse,
|
|
||||||
Treasure(u32),
|
|
||||||
Victory(u32),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Card {
|
|
||||||
pub name: String,
|
|
||||||
pub cost: u32,
|
|
||||||
pub types: Vec<CardType>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Card {
|
|
||||||
pub fn action(&self) -> Option<()> {
|
|
||||||
for t in &self.types {
|
|
||||||
match t {
|
|
||||||
CardType::Action(_) => return Some(()),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn curse(&self) -> Option<()> {
|
|
||||||
for t in &self.types {
|
|
||||||
match t {
|
|
||||||
CardType::Curse => return Some(()),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn treasure(&self) -> Option<u32> {
|
|
||||||
for t in &self.types {
|
|
||||||
match t {
|
|
||||||
CardType::Treasure(coin) => return Some(*coin),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn victory(&self) -> Option<u32> {
|
|
||||||
for t in &self.types {
|
|
||||||
match t {
|
|
||||||
CardType::Victory(points) => return Some(*points),
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for Card {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
serializer.serialize_str(&self.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Card {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.name)
|
|
||||||
}
|
|
||||||
}
|
|
83
src/main.rs
83
src/main.rs
@ -20,7 +20,6 @@ enum ClientMessage {
|
|||||||
EndTurn,
|
EndTurn,
|
||||||
PlayCard { name: String, index: usize },
|
PlayCard { name: String, index: usize },
|
||||||
GainCard { name: String, index: usize },
|
GainCard { name: String, index: usize },
|
||||||
BuyCard { index: usize },
|
|
||||||
DrawCard,
|
DrawCard,
|
||||||
Discard { index: usize },
|
Discard { index: usize },
|
||||||
TrashHand { index: usize },
|
TrashHand { index: usize },
|
||||||
@ -211,12 +210,19 @@ impl Game {
|
|||||||
(estate(), victory_qty),
|
(estate(), victory_qty),
|
||||||
(duchy(), victory_qty),
|
(duchy(), victory_qty),
|
||||||
(province(), victory_qty),
|
(province(), victory_qty),
|
||||||
(curse(), 10),
|
(
|
||||||
|
Card {
|
||||||
|
name: "Curse".into(),
|
||||||
|
cost: 0,
|
||||||
|
types: vec![],
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
Card {
|
Card {
|
||||||
name: "Cellar".into(),
|
name: "Cellar".into(),
|
||||||
cost: 2,
|
cost: 2,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -224,7 +230,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Moat".into(),
|
name: "Moat".into(),
|
||||||
cost: 2,
|
cost: 2,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -232,7 +238,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Village".into(),
|
name: "Village".into(),
|
||||||
cost: 3,
|
cost: 3,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -240,7 +246,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Merchant".into(),
|
name: "Merchant".into(),
|
||||||
cost: 3,
|
cost: 3,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -248,7 +254,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Workshop".into(),
|
name: "Workshop".into(),
|
||||||
cost: 3,
|
cost: 3,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -256,7 +262,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Smithy".into(),
|
name: "Smithy".into(),
|
||||||
cost: 4,
|
cost: 4,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -264,7 +270,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Remodel".into(),
|
name: "Remodel".into(),
|
||||||
cost: 4,
|
cost: 4,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -272,7 +278,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Militia".into(),
|
name: "Militia".into(),
|
||||||
cost: 4,
|
cost: 4,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -280,7 +286,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Market".into(),
|
name: "Market".into(),
|
||||||
cost: 5,
|
cost: 5,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -288,7 +294,7 @@ impl Game {
|
|||||||
Card {
|
Card {
|
||||||
name: "Mine".into(),
|
name: "Mine".into(),
|
||||||
cost: 5,
|
cost: 5,
|
||||||
types: vec![CardType::Action(|| {})],
|
types: vec![],
|
||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
@ -356,38 +362,8 @@ impl Game {
|
|||||||
self.turn_state.coin += coin;
|
self.turn_state.coin += coin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(_) = card.action() {
|
|
||||||
self.turn_state.actions -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.played_cards.push(card);
|
player.played_cards.push(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buy_card(&mut self, player_number: usize, index: usize) -> bool /*-> Result<(), &'static str>*/
|
|
||||||
{
|
|
||||||
if player_number != self.active_player {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.turn_state.buys < 1 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(card) = self.supply.get(index).as_deref() {
|
|
||||||
if card.0.cost <= self.turn_state.coin {
|
|
||||||
let card = card.0.clone();
|
|
||||||
|
|
||||||
self.supply.get_mut(index).unwrap().1 = self.supply.get(index).unwrap().1 - 1;
|
|
||||||
self.turn_state.coin -= card.cost;
|
|
||||||
self.turn_state.buys -= 1;
|
|
||||||
self.players[player_number].discard_pile.push(card);
|
|
||||||
return true;
|
|
||||||
//return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Err("Not enough coin");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -455,8 +431,6 @@ async fn broadcast_state(game: &Game) {
|
|||||||
let score = p.draw_pile.iter().fold(0, |acc, card| {
|
let score = p.draw_pile.iter().fold(0, |acc, card| {
|
||||||
if let Some(points) = card.victory() {
|
if let Some(points) = card.victory() {
|
||||||
acc + points
|
acc + points
|
||||||
} else if let Some(_) = card.curse() {
|
|
||||||
acc - 1
|
|
||||||
} else {
|
} else {
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
@ -672,27 +646,6 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
broadcast_state(&game).await;
|
broadcast_state(&game).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientMessage::BuyCard { index } => {
|
|
||||||
let mut games = req.state().games.write().await;
|
|
||||||
let game = games.get_mut(&game_id).unwrap();
|
|
||||||
|
|
||||||
if game.buy_card(player_number, index) {
|
|
||||||
if let Some(card) =
|
|
||||||
game.players[player_number].discard_pile.last().as_deref()
|
|
||||||
{
|
|
||||||
notify_players(
|
|
||||||
&game,
|
|
||||||
format!(
|
|
||||||
"{} kauft {}",
|
|
||||||
game.players[player_number].name, card.name
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
broadcast_state(&game).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientMessage::GainCard { name: _, index } => {
|
ClientMessage::GainCard { name: _, index } => {
|
||||||
let mut games = req.state().games.write().await;
|
let mut games = req.state().games.write().await;
|
||||||
let game = games.get_mut(&game_id).unwrap();
|
let game = games.get_mut(&game_id).unwrap();
|
||||||
|
@ -481,6 +481,7 @@ img.card:hover {
|
|||||||
|
|
||||||
function SupplyPile(initialVnode) {
|
function SupplyPile(initialVnode) {
|
||||||
var dragStart = function(ev) {
|
var dragStart = function(ev) {
|
||||||
|
console.log(ev);
|
||||||
let data = {
|
let data = {
|
||||||
source: "Supply",
|
source: "Supply",
|
||||||
name: ev.target.dataset.name,
|
name: ev.target.dataset.name,
|
||||||
@ -489,16 +490,7 @@ img.card:hover {
|
|||||||
ev.dataTransfer.setData("text", JSON.stringify(data));
|
ev.dataTransfer.setData("text", JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
var doubleclick = function(ev) {
|
return {
|
||||||
let msg = {
|
|
||||||
type: "BuyCard",
|
|
||||||
index: parseInt(ev.srcElement.parentElement.dataset.index),
|
|
||||||
}
|
|
||||||
|
|
||||||
webSocket.send(JSON.stringify(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
view: function(vnode) {
|
view: function(vnode) {
|
||||||
return m(".supply-pile",
|
return m(".supply-pile",
|
||||||
{
|
{
|
||||||
@ -507,7 +499,6 @@ img.card:hover {
|
|||||||
"data-index": vnode.attrs.index,
|
"data-index": vnode.attrs.index,
|
||||||
ondragstart: dragStart,
|
ondragstart: dragStart,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
ondblclick: doubleclick,
|
|
||||||
},
|
},
|
||||||
m("img", {
|
m("img", {
|
||||||
class: "card",
|
class: "card",
|
||||||
|
BIN
static/images/cards/duchy.jpg
(Stored with Git LFS)
BIN
static/images/cards/duchy.jpg
(Stored with Git LFS)
Binary file not shown.
@ -1,21 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>DnD</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<p>
|
|
||||||
<div>
|
|
||||||
<form id="login_form" method="post">
|
|
||||||
Your name: <input type="text" name="name"> <br />
|
|
||||||
<input type="hidden" name="type" value="JoinGame">
|
|
||||||
<input type="submit" value="Join game">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user