make library
This commit is contained in:
parent
cc2ca6ea86
commit
aa02be7c55
6 changed files with 229 additions and 236 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -1105,6 +1105,12 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcards"
|
name = "libcards"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"rand",
|
||||||
|
"serde",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linear-map"
|
name = "linear-map"
|
||||||
|
|
|
@ -4,3 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
rand = "0.8.5"
|
||||||
|
serde = "1.0.204"
|
||||||
|
tracing = "0.1.40"
|
||||||
|
|
|
@ -1,3 +1,217 @@
|
||||||
pub fn test() {
|
use anyhow::Result;
|
||||||
println!("ligma!");
|
use rand::prelude::IteratorRandom;
|
||||||
|
use rand::thread_rng;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// New game request structure
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct NewGameRequest {
|
||||||
|
/// Game name
|
||||||
|
pub name: String,
|
||||||
|
/// Game host
|
||||||
|
pub host: CAHPlayer,
|
||||||
|
/// Chosen packs
|
||||||
|
pub packs: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Game join request structure
|
||||||
|
pub struct GameJoinRequest {
|
||||||
|
/// Game id
|
||||||
|
pub id: u8, // increase later
|
||||||
|
/// Game password
|
||||||
|
pub password: Option<String>,
|
||||||
|
/// Player info
|
||||||
|
pub player: CAHPlayer,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A CAH white card
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct CAHCardWhite {
|
||||||
|
/// Card text
|
||||||
|
pub text: String,
|
||||||
|
/// ID of the pack it came from
|
||||||
|
pack: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A CAH black card
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct CAHCardBlack {
|
||||||
|
/// Card text
|
||||||
|
pub text: String,
|
||||||
|
/// Amount of cards to submit for judging
|
||||||
|
pick: u8,
|
||||||
|
/// ID of the pack it came from
|
||||||
|
pack: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A CAH pack
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct CAHCardSet {
|
||||||
|
/// Name of the pack
|
||||||
|
name: String,
|
||||||
|
/// Pack Description
|
||||||
|
description: Option<String>,
|
||||||
|
/// Whether or not this is an official card pack
|
||||||
|
official: bool,
|
||||||
|
/// White card data
|
||||||
|
white: Option<Vec<CAHCardWhite>>,
|
||||||
|
/// Black card data
|
||||||
|
black: Option<Vec<CAHCardBlack>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Player roles
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub enum PlayerRole {
|
||||||
|
/// Player is host
|
||||||
|
Host,
|
||||||
|
/// Player is a player in a game where another player is host
|
||||||
|
Player,
|
||||||
|
/// Player is just spectating
|
||||||
|
Spectator,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A struct that represents a player
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CAHPlayer {
|
||||||
|
/// Player's username
|
||||||
|
pub name: String,
|
||||||
|
/// This player's role
|
||||||
|
pub role: PlayerRole,
|
||||||
|
/// The player's hand
|
||||||
|
pub white: Vec<CAHCardWhite>,
|
||||||
|
/// The player's wins
|
||||||
|
pub black: Vec<CAHCardBlack>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The game master
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CAHGame {
|
||||||
|
/// The name of the game
|
||||||
|
pub name: String,
|
||||||
|
/// White draw pile
|
||||||
|
pub white: Vec<CAHCardWhite>,
|
||||||
|
/// Black draw pile
|
||||||
|
pub black: Vec<CAHCardBlack>,
|
||||||
|
/// White discard pile
|
||||||
|
pub white_discard: Vec<CAHCardWhite>,
|
||||||
|
/// Black discard pile
|
||||||
|
pub black_discard: Vec<CAHCardBlack>,
|
||||||
|
/// Indicates game active/game over
|
||||||
|
pub game_active: bool,
|
||||||
|
/// List of current players
|
||||||
|
pub players: Vec<CAHPlayer>,
|
||||||
|
// /// Reference to current card czar
|
||||||
|
// czar: &CAHPlayer,
|
||||||
|
/// Black card for the current round
|
||||||
|
pub current_black: Option<CAHCardBlack>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CAHGame {
|
||||||
|
/// Build game decks from input data for game start.
|
||||||
|
/// This should only run once and at startup.
|
||||||
|
fn _build_decks(&mut self, cards_json: Vec<CAHCardSet>) -> Result<()> {
|
||||||
|
for pack in cards_json {
|
||||||
|
if let Some(white) = pack.white {
|
||||||
|
self.white.extend(white)
|
||||||
|
}
|
||||||
|
if let Some(black) = pack.black {
|
||||||
|
self.black.extend(black)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(request: NewGameRequest) -> Result<Self> {
|
||||||
|
let mut game = CAHGame {
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
tracing::debug!("Creating game {}", &request.name);
|
||||||
|
game.name = request.name;
|
||||||
|
|
||||||
|
// game.build_decks(request.packs)?;
|
||||||
|
game.create_player(request.host)?;
|
||||||
|
game.deal_black()?;
|
||||||
|
|
||||||
|
Ok(game)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn join(request:GameJoinRequest)
|
||||||
|
|
||||||
|
/// Log counts of current drawable cards
|
||||||
|
/// For testing
|
||||||
|
pub fn deck_counts(&self) {
|
||||||
|
tracing::debug!(
|
||||||
|
"Deck Counts:\n {} White cards\n {} Black cards",
|
||||||
|
self.white.len(),
|
||||||
|
self.black.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw one white card at random from play deck.
|
||||||
|
fn draw_one_white(&mut self) -> Result<CAHCardWhite> {
|
||||||
|
let deck = &mut self.white;
|
||||||
|
|
||||||
|
// this feels sloppy
|
||||||
|
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
|
||||||
|
Ok(deck.swap_remove(index))
|
||||||
|
} else {
|
||||||
|
Ok(CAHCardWhite {
|
||||||
|
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
|
||||||
|
pack: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw one black card at random from play deck.
|
||||||
|
fn draw_one_black(&mut self) -> Result<CAHCardBlack> {
|
||||||
|
let deck = &mut self.black;
|
||||||
|
|
||||||
|
// this feels sloppy
|
||||||
|
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
|
||||||
|
Ok(deck.swap_remove(index))
|
||||||
|
} else {
|
||||||
|
Ok(CAHCardBlack {
|
||||||
|
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
|
||||||
|
pick: 0,
|
||||||
|
pack: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deal a black card and use it for the current round
|
||||||
|
fn deal_black(&mut self) -> Result<()> {
|
||||||
|
self.current_black = Some(self.draw_one_black()?);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new player and add them to the game.
|
||||||
|
pub fn create_player(&mut self, mut player: CAHPlayer) -> Result<()> {
|
||||||
|
tracing::debug!("Creating player {} as {:?}", &player.name, &player.role);
|
||||||
|
|
||||||
|
let mut hand_buf = vec![];
|
||||||
|
for _ in 0..10 {
|
||||||
|
hand_buf.push(self.draw_one_white()?);
|
||||||
|
}
|
||||||
|
tracing::debug!("Dealing hand to {}", &player.name);
|
||||||
|
player.white.extend(hand_buf);
|
||||||
|
|
||||||
|
self.players.push(player);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn game_start(&mut self) -> Result<()> {
|
||||||
|
self.game_active = true;
|
||||||
|
tracing::debug!("Game Active!");
|
||||||
|
|
||||||
|
if let Some(black) = &self.current_black {
|
||||||
|
tracing::debug!("{}", black.text);
|
||||||
|
} else {
|
||||||
|
tracing::debug!("YOU DONE FUCKED UP (no current black card)");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,35 +2,7 @@ use crate::api::{greeting, Message, User};
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use crate::Arc;
|
use crate::Arc;
|
||||||
use crate::CAHGame;
|
use crate::CAHGame;
|
||||||
use crate::CAHPlayer;
|
use libcards::*;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
/// New game request structure
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct NewGameRequest {
|
|
||||||
/// Game name
|
|
||||||
pub name: String,
|
|
||||||
/// Game host
|
|
||||||
pub host: CAHPlayer,
|
|
||||||
/// Chosen packs
|
|
||||||
pub packs: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Game join request structure
|
|
||||||
pub struct GameJoinRequest {
|
|
||||||
/// Game id
|
|
||||||
pub id: u8, // increase later
|
|
||||||
/// Game password
|
|
||||||
pub password: Option<String>,
|
|
||||||
/// Player info
|
|
||||||
pub player: CAHPlayer,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create user/login request structure
|
|
||||||
pub struct UserLoginRequest {
|
|
||||||
pub username: String,
|
|
||||||
pub token: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &User) {
|
pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &User) {
|
||||||
let tx = &state.tx;
|
let tx = &state.tx;
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
use crate::message_handler::*; //change this
|
|
||||||
use rand::prelude::IteratorRandom;
|
|
||||||
use rand::thread_rng;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
/// A CAH white card
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct CAHCardWhite {
|
|
||||||
/// Card text
|
|
||||||
pub text: String,
|
|
||||||
/// ID of the pack it came from
|
|
||||||
pack: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A CAH black card
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct CAHCardBlack {
|
|
||||||
/// Card text
|
|
||||||
pub text: String,
|
|
||||||
/// Amount of cards to submit for judging
|
|
||||||
pick: u8,
|
|
||||||
/// ID of the pack it came from
|
|
||||||
pack: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A CAH pack
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct CAHCardSet {
|
|
||||||
/// Name of the pack
|
|
||||||
name: String,
|
|
||||||
/// Pack Description
|
|
||||||
description: Option<String>,
|
|
||||||
/// Whether or not this is an official card pack
|
|
||||||
official: bool,
|
|
||||||
/// White card data
|
|
||||||
white: Option<Vec<CAHCardWhite>>,
|
|
||||||
/// Black card data
|
|
||||||
black: Option<Vec<CAHCardBlack>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Player roles
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub enum PlayerRole {
|
|
||||||
/// Player is host
|
|
||||||
Host,
|
|
||||||
/// Player is a player in a game where another player is host
|
|
||||||
Player,
|
|
||||||
/// Player is just spectating
|
|
||||||
Spectator,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct that represents a player
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct CAHPlayer {
|
|
||||||
/// Player's username
|
|
||||||
pub name: String,
|
|
||||||
/// This player's role
|
|
||||||
pub role: PlayerRole,
|
|
||||||
/// The player's hand
|
|
||||||
pub white: Vec<CAHCardWhite>,
|
|
||||||
/// The player's wins
|
|
||||||
pub black: Vec<CAHCardBlack>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The game master
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct CAHGame {
|
|
||||||
/// The name of the game
|
|
||||||
pub name: String,
|
|
||||||
/// White draw pile
|
|
||||||
pub white: Vec<CAHCardWhite>,
|
|
||||||
/// Black draw pile
|
|
||||||
pub black: Vec<CAHCardBlack>,
|
|
||||||
/// White discard pile
|
|
||||||
pub white_discard: Vec<CAHCardWhite>,
|
|
||||||
/// Black discard pile
|
|
||||||
pub black_discard: Vec<CAHCardBlack>,
|
|
||||||
/// Indicates game active/game over
|
|
||||||
pub game_active: bool,
|
|
||||||
/// List of current players
|
|
||||||
pub players: Vec<CAHPlayer>,
|
|
||||||
// /// Reference to current card czar
|
|
||||||
// czar: &CAHPlayer,
|
|
||||||
/// Black card for the current round
|
|
||||||
pub current_black: Option<CAHCardBlack>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CAHGame {
|
|
||||||
/// Build game decks from input data for game start.
|
|
||||||
/// This should only run once and at startup.
|
|
||||||
fn build_decks(&mut self, cards_json: Vec<CAHCardSet>) -> Result<()> {
|
|
||||||
for pack in cards_json {
|
|
||||||
if let Some(white) = pack.white {
|
|
||||||
self.white.extend(white)
|
|
||||||
}
|
|
||||||
if let Some(black) = pack.black {
|
|
||||||
self.black.extend(black)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(request: NewGameRequest) -> Result<Self> {
|
|
||||||
let mut game = CAHGame {
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
tracing::debug!("Creating game {}", &request.name);
|
|
||||||
game.name = request.name;
|
|
||||||
|
|
||||||
// game.build_decks(request.packs)?;
|
|
||||||
game.create_player(request.host)?;
|
|
||||||
game.deal_black()?;
|
|
||||||
|
|
||||||
Ok(game)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn join(request:GameJoinRequest)
|
|
||||||
|
|
||||||
/// Log counts of current drawable cards
|
|
||||||
/// For testing
|
|
||||||
pub fn deck_counts(&self) {
|
|
||||||
tracing::debug!(
|
|
||||||
"Deck Counts:\n {} White cards\n {} Black cards",
|
|
||||||
self.white.len(),
|
|
||||||
self.black.len()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw one white card at random from play deck.
|
|
||||||
fn draw_one_white(&mut self) -> Result<CAHCardWhite> {
|
|
||||||
let deck = &mut self.white;
|
|
||||||
|
|
||||||
// this feels sloppy
|
|
||||||
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
|
|
||||||
Ok(deck.swap_remove(index))
|
|
||||||
} else {
|
|
||||||
Ok(CAHCardWhite {
|
|
||||||
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
|
|
||||||
pack: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw one black card at random from play deck.
|
|
||||||
fn draw_one_black(&mut self) -> Result<CAHCardBlack> {
|
|
||||||
let deck = &mut self.black;
|
|
||||||
|
|
||||||
// this feels sloppy
|
|
||||||
if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) {
|
|
||||||
Ok(deck.swap_remove(index))
|
|
||||||
} else {
|
|
||||||
Ok(CAHCardBlack {
|
|
||||||
text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(),
|
|
||||||
pick: 0,
|
|
||||||
pack: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deal a black card and use it for the current round
|
|
||||||
fn deal_black(&mut self) -> Result<()> {
|
|
||||||
self.current_black = Some(self.draw_one_black()?);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new player and add them to the game.
|
|
||||||
pub fn create_player(&mut self, mut player: CAHPlayer) -> Result<()> {
|
|
||||||
tracing::debug!("Creating player {} as {:?}", &player.name, &player.role);
|
|
||||||
|
|
||||||
let mut hand_buf = vec![];
|
|
||||||
for _ in 0..10 {
|
|
||||||
hand_buf.push(self.draw_one_white()?);
|
|
||||||
}
|
|
||||||
tracing::debug!("Dealing hand to {}", &player.name);
|
|
||||||
player.white.extend(hand_buf);
|
|
||||||
|
|
||||||
self.players.push(player);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn game_start(&mut self) -> Result<()> {
|
|
||||||
self.game_active = true;
|
|
||||||
tracing::debug!("Game Active!");
|
|
||||||
|
|
||||||
if let Some(black) = &self.current_black {
|
|
||||||
tracing::debug!("{}", black.text);
|
|
||||||
} else {
|
|
||||||
tracing::debug!("YOU DONE FUCKED UP (no current black card)");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,17 +8,12 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tower_http::{
|
use tower_http::services::ServeDir;
|
||||||
services::{ServeDir, ServeFile},
|
|
||||||
trace::TraceLayer,
|
|
||||||
};
|
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
pub mod gamemaster;
|
use libcards::*;
|
||||||
use crate::gamemaster::*;
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
use crate::api::*;
|
use crate::api::*;
|
||||||
use crate::message_handler::*;
|
|
||||||
|
|
||||||
/// Parse json for card data
|
/// Parse json for card data
|
||||||
fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
|
fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
|
||||||
|
@ -110,7 +105,6 @@ async fn css() -> Css<&'static str> {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let _ = libcards::test();
|
|
||||||
// stuff for logging
|
// stuff for logging
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(
|
.with(
|
||||||
|
|
Loading…
Add table
Reference in a new issue