More implemented.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
Rocket.toml
|
||||||
|
|||||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1105,6 +1105,7 @@ dependencies = [
|
|||||||
"rocket_codegen",
|
"rocket_codegen",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"state",
|
"state",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"time",
|
"time",
|
||||||
|
|||||||
@ -13,7 +13,7 @@ features = [ "serde" ]
|
|||||||
|
|
||||||
[dependencies.rocket]
|
[dependencies.rocket]
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
features = [ "uuid" ]
|
features = [ "uuid", "json" ]
|
||||||
|
|
||||||
[dependencies.uuid]
|
[dependencies.uuid]
|
||||||
version = "1.13.1"
|
version = "1.13.1"
|
||||||
|
|||||||
75
src/game.rs
75
src/game.rs
@ -1,7 +1,6 @@
|
|||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rand::{random_bool, rng};
|
use rand::{random_bool, rng};
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ struct CardInfo {
|
|||||||
count: usize,
|
count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone, Copy)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
pub enum Player {
|
pub enum Player {
|
||||||
A,
|
A,
|
||||||
@ -46,7 +45,15 @@ struct Hand {
|
|||||||
enum Event {
|
enum Event {
|
||||||
Shuffle(Player),
|
Shuffle(Player),
|
||||||
Draw(Player, usize),
|
Draw(Player, usize),
|
||||||
Pass,
|
Pass(Player, Player),
|
||||||
|
ChangeLifeTotal(Player, i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Clone)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
struct CountedEvent {
|
||||||
|
id: usize,
|
||||||
|
event: Event,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -56,9 +63,10 @@ pub struct GameState {
|
|||||||
shadow_realm: Vec<Uuid>,
|
shadow_realm: Vec<Uuid>,
|
||||||
play: Vec<InPlay>,
|
play: Vec<InPlay>,
|
||||||
hands: Vec<Hand>,
|
hands: Vec<Hand>,
|
||||||
|
life_totals: Vec<i32>,
|
||||||
turn_player: Player,
|
turn_player: Player,
|
||||||
card_map: HashMap<Uuid, CardInfo>,
|
//card_map: HashMap<Uuid, CardInfo>,
|
||||||
events: Vec<Event>,
|
events: Vec<CountedEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -68,13 +76,14 @@ pub struct OnePlayerGameState {
|
|||||||
shadow_realm: Vec<Uuid>,
|
shadow_realm: Vec<Uuid>,
|
||||||
play: Vec<InPlay>,
|
play: Vec<InPlay>,
|
||||||
hand: Vec<Uuid>,
|
hand: Vec<Uuid>,
|
||||||
|
life_totals: Vec<i32>,
|
||||||
turn_player: Player,
|
turn_player: Player,
|
||||||
opponent_cards_in_hand: usize,
|
opponent_cards_in_hand: usize,
|
||||||
you: Player,
|
you: Player,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameState {
|
impl GameState {
|
||||||
pub fn as_one_player(&self, player: Player) -> OnePlayerGameState {
|
fn as_one_player(&self, player: Player) -> OnePlayerGameState {
|
||||||
OnePlayerGameState {
|
OnePlayerGameState {
|
||||||
discard_pile: self.discard_pile.clone(),
|
discard_pile: self.discard_pile.clone(),
|
||||||
shadow_realm: self.shadow_realm.clone(),
|
shadow_realm: self.shadow_realm.clone(),
|
||||||
@ -83,6 +92,7 @@ impl GameState {
|
|||||||
Player::A => self.hands[0].cards.clone(),
|
Player::A => self.hands[0].cards.clone(),
|
||||||
_ => self.hands[1].cards.clone(),
|
_ => self.hands[1].cards.clone(),
|
||||||
},
|
},
|
||||||
|
life_totals: self.life_totals.clone(),
|
||||||
turn_player: self.turn_player.clone(),
|
turn_player: self.turn_player.clone(),
|
||||||
opponent_cards_in_hand: match player {
|
opponent_cards_in_hand: match player {
|
||||||
Player::A => self.hands[1].cards.len(),
|
Player::A => self.hands[1].cards.len(),
|
||||||
@ -97,17 +107,17 @@ const CARD_DATA_JSON: &str = include_str!("cards.json");
|
|||||||
|
|
||||||
pub fn new() -> GameState {
|
pub fn new() -> GameState {
|
||||||
let parsed_cards: Vec<CardInfo> = serde_json::from_str(CARD_DATA_JSON).unwrap();
|
let parsed_cards: Vec<CardInfo> = serde_json::from_str(CARD_DATA_JSON).unwrap();
|
||||||
let card_map = parsed_cards
|
/*let card_map = parsed_cards
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|card| (card.scryfall_id, card))
|
.map(|card| (card.scryfall_id, card))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<HashMap<_, _>>();*/
|
||||||
let starting_player = match random_bool(0.5) {
|
let starting_player = match random_bool(0.5) {
|
||||||
true => Player::A,
|
true => Player::A,
|
||||||
_ => Player::B,
|
_ => Player::B,
|
||||||
};
|
};
|
||||||
let mut deck: Vec<Uuid> = card_map
|
let mut deck: Vec<Uuid> = parsed_cards
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(move |(id, card)| vec![id.clone(); card.count])
|
.flat_map(move |card| vec![card.scryfall_id.clone(); card.count])
|
||||||
.collect();
|
.collect();
|
||||||
deck.shuffle(&mut rng());
|
deck.shuffle(&mut rng());
|
||||||
GameState {
|
GameState {
|
||||||
@ -125,8 +135,9 @@ pub fn new() -> GameState {
|
|||||||
owner: Player::B,
|
owner: Player::B,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
life_totals: vec![20; 2],
|
||||||
turn_player: starting_player,
|
turn_player: starting_player,
|
||||||
card_map,
|
//card_map,
|
||||||
events: vec![],
|
events: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,9 +147,10 @@ pub fn draw(game_state: &mut GameState, count: usize, player: Player) {
|
|||||||
Player::A => &mut game_state.hands[0],
|
Player::A => &mut game_state.hands[0],
|
||||||
_ => &mut game_state.hands[1],
|
_ => &mut game_state.hands[1],
|
||||||
};
|
};
|
||||||
game_state
|
game_state.events.push(CountedEvent {
|
||||||
.events
|
id: game_state.events.len(),
|
||||||
.push(Event::Draw(player.clone(), count.clone()));
|
event: Event::Draw(player.clone(), count.clone()),
|
||||||
|
});
|
||||||
player_hand.cards.extend_from_slice(
|
player_hand.cards.extend_from_slice(
|
||||||
game_state
|
game_state
|
||||||
.deck
|
.deck
|
||||||
@ -148,7 +160,10 @@ pub fn draw(game_state: &mut GameState, count: usize, player: Player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn shuffle(game_state: &mut GameState, player: Player) {
|
pub fn shuffle(game_state: &mut GameState, player: Player) {
|
||||||
game_state.events.push(Event::Shuffle(player));
|
game_state.events.push(CountedEvent {
|
||||||
|
id: game_state.events.len(),
|
||||||
|
event: Event::Shuffle(player),
|
||||||
|
});
|
||||||
game_state.deck.shuffle(&mut rng());
|
game_state.deck.shuffle(&mut rng());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,3 +174,33 @@ pub fn get_game_one_player(game_state: &GameState, player: Player) -> String {
|
|||||||
pub fn get_events(game_state: &GameState) -> String {
|
pub fn get_events(game_state: &GameState) -> String {
|
||||||
serde_json::to_string(&game_state.events).unwrap()
|
serde_json::to_string(&game_state.events).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pass(game_state: &mut GameState) {
|
||||||
|
let current_player = &game_state.turn_player;
|
||||||
|
let new_player = match current_player {
|
||||||
|
Player::A => Player::B,
|
||||||
|
_ => Player::A,
|
||||||
|
};
|
||||||
|
game_state.events.push(CountedEvent {
|
||||||
|
id: game_state.events.len(),
|
||||||
|
event: Event::Pass(*current_player, new_player.clone()),
|
||||||
|
});
|
||||||
|
game_state.turn_player = new_player;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn change_life(game_state: &mut GameState, diff: i32, player: Player) {
|
||||||
|
let mut player_life = match player {
|
||||||
|
Player::A => game_state.life_totals[0].clone(),
|
||||||
|
_ => game_state.life_totals[1].clone(),
|
||||||
|
};
|
||||||
|
//let diffed_player = player_life.clone() + diff;
|
||||||
|
game_state.events.push(CountedEvent {
|
||||||
|
id: game_state.events.len(),
|
||||||
|
event: Event::ChangeLifeTotal(player, player_life.clone(), player_life.clone() + diff),
|
||||||
|
});
|
||||||
|
player_life += diff;
|
||||||
|
match player {
|
||||||
|
Player::A => game_state.life_totals[0] = player_life,
|
||||||
|
_ => game_state.life_totals[1] = player_life,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
172
src/main.rs
172
src/main.rs
@ -1,32 +1,21 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate rocket;
|
||||||
mod game;
|
mod game;
|
||||||
use game::GameState;
|
use game::GameState;
|
||||||
use game::Player;
|
use game::Player;
|
||||||
|
use rocket::fs::{relative, FileServer};
|
||||||
use rocket::response::status::BadRequest;
|
use rocket::response::status::BadRequest;
|
||||||
use rocket::State;
|
use rocket::State;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use uuid::Uuid;
|
||||||
#[macro_use]
|
|
||||||
extern crate rocket;
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn index() -> &'static str {
|
fn index(player_uuids: &State<PlayerUuids>) -> String {
|
||||||
"Hello, world!"
|
format!(
|
||||||
}
|
"a: localhost:8000/{}/\nb: localhost:8000/{}/",
|
||||||
|
player_uuids.a, player_uuids.b
|
||||||
#[get("/shuffle/<player_id>")]
|
)
|
||||||
fn shuffle(
|
|
||||||
player_id: &str,
|
|
||||||
game_state_arc: &State<ArcMutexGameState>,
|
|
||||||
) -> Result<String, BadRequest<String>> {
|
|
||||||
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
|
||||||
let mut game_state = game_state_mutex.lock().unwrap();
|
|
||||||
let player = match player_id {
|
|
||||||
"a" => Player::A,
|
|
||||||
"b" => Player::B,
|
|
||||||
_ => return Err(BadRequest(format!("Invalid player {}.", player_id))),
|
|
||||||
};
|
|
||||||
game::shuffle(&mut game_state, player);
|
|
||||||
Ok(format!("Deck Shuffled!"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/get_events")]
|
#[get("/get_events")]
|
||||||
@ -36,41 +25,93 @@ fn get_events(game_state_arc: &State<ArcMutexGameState>) -> String {
|
|||||||
format!("{}", game::get_events(&game_state))
|
format!("{}", game::get_events(&game_state))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/get_state/<player_id>")]
|
#[post("/<uuid>/shuffle")]
|
||||||
fn get_state(
|
fn shuffle(
|
||||||
player_id: &str,
|
uuid: Uuid,
|
||||||
game_state_arc: &State<ArcMutexGameState>,
|
|
||||||
) -> Result<String, BadRequest<String>> {
|
|
||||||
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
|
||||||
let game_state = game_state_mutex.lock().unwrap();
|
|
||||||
let player = match player_id {
|
|
||||||
"a" => Player::A,
|
|
||||||
"b" => Player::B,
|
|
||||||
_ => return Err(BadRequest(format!("Invalid player {}.", player_id))),
|
|
||||||
};
|
|
||||||
Ok(format!(
|
|
||||||
"{}",
|
|
||||||
game::get_game_one_player(&game_state, player)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/draw/<player_id>/<count>")]
|
|
||||||
fn draw(
|
|
||||||
player_id: &str,
|
|
||||||
count: usize,
|
|
||||||
game_state_arc: &State<ArcMutexGameState>,
|
game_state_arc: &State<ArcMutexGameState>,
|
||||||
|
player_uuids: &State<PlayerUuids>,
|
||||||
) -> Result<String, BadRequest<String>> {
|
) -> Result<String, BadRequest<String>> {
|
||||||
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
||||||
let mut game_state = game_state_mutex.lock().unwrap();
|
let mut game_state = game_state_mutex.lock().unwrap();
|
||||||
let player = match player_id {
|
let player = match player_uuids.map.get(&uuid) {
|
||||||
"a" => Player::A,
|
Some(player) => player,
|
||||||
"b" => Player::B,
|
None => return Err(BadRequest(format!("Invalid player {}.", uuid))),
|
||||||
_ => return Err(BadRequest(format!("Invalid player {}.", player_id))),
|
};
|
||||||
|
game::shuffle(&mut game_state, player.clone());
|
||||||
|
Ok(format!("Deck Shuffled!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<uuid>/pass")]
|
||||||
|
fn pass(
|
||||||
|
uuid: Uuid,
|
||||||
|
game_state_arc: &State<ArcMutexGameState>,
|
||||||
|
player_uuids: &State<PlayerUuids>,
|
||||||
|
) -> Result<String, BadRequest<String>> {
|
||||||
|
match player_uuids.map.get(&uuid) {
|
||||||
|
Some(_) => (),
|
||||||
|
None => return Err(BadRequest(format!("Invalid player {}.", uuid))),
|
||||||
|
};
|
||||||
|
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
||||||
|
let mut game_state = game_state_mutex.lock().unwrap();
|
||||||
|
game::pass(&mut game_state);
|
||||||
|
Ok(format!("{}", game::get_events(&game_state)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<uuid>/get_state")]
|
||||||
|
fn get_state(
|
||||||
|
uuid: Uuid,
|
||||||
|
game_state_arc: &State<ArcMutexGameState>,
|
||||||
|
player_uuids: &State<PlayerUuids>,
|
||||||
|
) -> Result<String, BadRequest<String>> {
|
||||||
|
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
||||||
|
let game_state = game_state_mutex.lock().unwrap();
|
||||||
|
let player = match player_uuids.map.get(&uuid) {
|
||||||
|
Some(player) => player,
|
||||||
|
None => return Err(BadRequest(format!("Invalid player {}.", uuid))),
|
||||||
|
};
|
||||||
|
Ok(format!(
|
||||||
|
"{}",
|
||||||
|
game::get_game_one_player(&game_state, player.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<uuid>/draw/<count>")]
|
||||||
|
fn draw(
|
||||||
|
uuid: Uuid,
|
||||||
|
count: usize,
|
||||||
|
game_state_arc: &State<ArcMutexGameState>,
|
||||||
|
player_uuids: &State<PlayerUuids>,
|
||||||
|
) -> Result<String, BadRequest<String>> {
|
||||||
|
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
||||||
|
let mut game_state = game_state_mutex.lock().unwrap();
|
||||||
|
let player = match player_uuids.map.get(&uuid) {
|
||||||
|
Some(player) => player,
|
||||||
|
None => return Err(BadRequest(format!("Invalid player {}.", uuid))),
|
||||||
};
|
};
|
||||||
game::draw(&mut game_state, count, player.clone());
|
game::draw(&mut game_state, count, player.clone());
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"{}",
|
"{}",
|
||||||
game::get_game_one_player(&game_state, player)
|
game::get_game_one_player(&game_state, player.clone())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<uuid>/life/<count>")]
|
||||||
|
fn life(
|
||||||
|
uuid: Uuid,
|
||||||
|
count: i32,
|
||||||
|
game_state_arc: &State<ArcMutexGameState>,
|
||||||
|
player_uuids: &State<PlayerUuids>,
|
||||||
|
) -> Result<String, BadRequest<String>> {
|
||||||
|
let game_state_mutex = Arc::clone(&game_state_arc.state);
|
||||||
|
let mut game_state = game_state_mutex.lock().unwrap();
|
||||||
|
let player = match player_uuids.map.get(&uuid) {
|
||||||
|
Some(player) => player,
|
||||||
|
None => return Err(BadRequest(format!("Invalid player {}.", uuid))),
|
||||||
|
};
|
||||||
|
game::change_life(&mut game_state, count, player.clone());
|
||||||
|
Ok(format!(
|
||||||
|
"{}",
|
||||||
|
game::get_game_one_player(&game_state, player.clone())
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,16 +119,41 @@ struct ArcMutexGameState {
|
|||||||
state: Arc<Mutex<GameState>>,
|
state: Arc<Mutex<GameState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PlayerUuids {
|
||||||
|
a: Uuid,
|
||||||
|
b: Uuid,
|
||||||
|
map: HashMap<Uuid, Player>,
|
||||||
|
}
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
fn rocket() -> _ {
|
fn rocket() -> _ {
|
||||||
let mut game_state = game::new();
|
let game_state = game::new();
|
||||||
let game_state_arc = Arc::new(Mutex::new(game_state));
|
let game_state_arc = Arc::new(Mutex::new(game_state));
|
||||||
|
let a_uuid: Uuid = Uuid::new_v4();
|
||||||
|
let b_uuid: Uuid = Uuid::new_v4();
|
||||||
|
let uuid_map = HashMap::from([(a_uuid, Player::A), (b_uuid, Player::B)]);
|
||||||
|
println!("A: {}", a_uuid);
|
||||||
|
println!("B: {}", b_uuid);
|
||||||
|
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.mount("/", routes![index, get_events])
|
.mount(
|
||||||
.mount("/", routes![get_state])
|
format!("/{}", a_uuid.hyphenated()),
|
||||||
.mount("/", routes![draw])
|
FileServer::from(relative!("static")),
|
||||||
.mount("/", routes![shuffle])
|
)
|
||||||
|
.mount(
|
||||||
|
format!("/{}", b_uuid.hyphenated()),
|
||||||
|
FileServer::from(relative!("static")),
|
||||||
|
)
|
||||||
|
.mount(
|
||||||
|
"/",
|
||||||
|
routes![index, get_events, get_state, draw, shuffle, pass, life,],
|
||||||
|
)
|
||||||
.manage(ArcMutexGameState {
|
.manage(ArcMutexGameState {
|
||||||
state: game_state_arc,
|
state: game_state_arc,
|
||||||
})
|
})
|
||||||
|
.manage(PlayerUuids {
|
||||||
|
a: a_uuid,
|
||||||
|
b: b_uuid,
|
||||||
|
map: uuid_map,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user