make library

This commit is contained in:
Adam 2024-07-21 00:52:47 -04:00
parent cc2ca6ea86
commit aa02be7c55
6 changed files with 229 additions and 236 deletions

6
Cargo.lock generated
View file

@ -1105,6 +1105,12 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libcards"
version = "0.1.0"
dependencies = [
"anyhow",
"rand",
"serde",
"tracing",
]
[[package]]
name = "linear-map"

View file

@ -4,3 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.86"
rand = "0.8.5"
serde = "1.0.204"
tracing = "0.1.40"

View file

@ -1,3 +1,217 @@
pub fn test() {
println!("ligma!");
use anyhow::Result;
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(())
}
}

View file

@ -2,35 +2,7 @@ use crate::api::{greeting, Message, User};
use crate::AppState;
use crate::Arc;
use crate::CAHGame;
use crate::CAHPlayer;
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,
}
use libcards::*;
pub async fn message_handler(message: Message, state: &Arc<AppState>, who: &User) {
let tx = &state.tx;

View file

@ -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(())
}
}

View file

@ -8,17 +8,12 @@ use std::{
sync::{Arc, Mutex},
};
use tokio::sync::broadcast;
use tower_http::{
services::{ServeDir, ServeFile},
trace::TraceLayer,
};
use tower_http::services::ServeDir;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
pub mod gamemaster;
use crate::gamemaster::*;
use libcards::*;
pub mod api;
use crate::api::*;
use crate::message_handler::*;
/// Parse json for card data
fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
@ -110,7 +105,6 @@ async fn css() -> Css<&'static str> {
#[tokio::main]
async fn main() -> Result<()> {
let _ = libcards::test();
// stuff for logging
tracing_subscriber::registry()
.with(