cards/src/main.rs

191 lines
4.8 KiB
Rust
Raw Normal View History

2024-04-06 21:28:25 -04:00
use rand::prelude::IteratorRandom;
use rand::thread_rng;
2024-04-05 22:38:41 -04:00
use serde::{Deserialize, Serialize};
use serde_json::Result;
use std::fs;
2024-04-06 22:38:00 -04:00
/// A CAH white card
2024-04-06 21:29:47 -04:00
#[derive(Serialize, Deserialize)]
2024-04-05 22:38:41 -04:00
struct CAHCardWhite {
2024-04-06 22:38:00 -04:00
/// Card text
2024-04-05 22:38:41 -04:00
text: String,
2024-04-06 22:38:00 -04:00
/// ID of the pack it came from
2024-04-05 22:38:41 -04:00
pack: u8,
}
2024-04-06 22:38:00 -04:00
/// A CAH black card
2024-04-06 21:29:47 -04:00
#[derive(Serialize, Deserialize)]
2024-04-05 22:38:41 -04:00
struct CAHCardBlack {
2024-04-06 22:38:00 -04:00
/// Card text
2024-04-05 22:38:41 -04:00
text: String,
2024-04-06 22:38:00 -04:00
/// Amount of cards to submit for judging
2024-04-05 22:38:41 -04:00
pick: u8,
2024-04-06 22:38:00 -04:00
/// ID of the pack it came from
2024-04-05 22:38:41 -04:00
pack: u8,
}
2024-04-06 22:38:00 -04:00
/// A CAH pack
2024-04-06 21:29:47 -04:00
#[derive(Serialize, Deserialize)]
2024-04-05 22:38:41 -04:00
struct CAHCardSet {
2024-04-06 22:38:00 -04:00
/// Name of the pack
2024-04-05 22:38:41 -04:00
name: String,
2024-04-06 22:38:00 -04:00
/// Pack Description
2024-04-05 22:38:41 -04:00
description: Option<String>,
2024-04-06 22:38:00 -04:00
/// Whether or not this is an official card pack
2024-04-05 22:38:41 -04:00
official: bool,
2024-04-06 22:38:00 -04:00
/// White card data
2024-04-05 22:38:41 -04:00
white: Option<Vec<CAHCardWhite>>,
2024-04-06 22:38:00 -04:00
/// Black card data
2024-04-05 22:38:41 -04:00
black: Option<Vec<CAHCardBlack>>,
}
2024-04-06 22:38:00 -04:00
/// A struct that represents a player
2024-04-06 21:28:25 -04:00
#[derive(Default)]
struct CAHPlayer {
2024-04-06 22:38:00 -04:00
/// The player's hand
white: Vec<CAHCardWhite>,
/// The player's wins
black: Vec<CAHCardBlack>,
2024-04-06 21:28:25 -04:00
}
2024-04-05 22:38:41 -04:00
2024-04-06 22:38:00 -04:00
/// The game master
2024-04-05 22:38:41 -04:00
#[derive(Default)]
struct CAHGame {
2024-04-06 22:38:00 -04:00
/// White draw pile
2024-04-06 21:28:25 -04:00
white: Vec<CAHCardWhite>,
2024-04-06 22:38:00 -04:00
/// Black draw pile
2024-04-06 21:28:25 -04:00
black: Vec<CAHCardBlack>,
2024-04-06 22:38:00 -04:00
/// White discard pile
white_discard: Vec<CAHCardWhite>,
/// Black discard pile
black_discard: Vec<CAHCardBlack>,
/// Indicates game active/game over
game_active: bool,
/// List of current players
2024-04-06 21:28:25 -04:00
players: Vec<CAHPlayer>,
2024-04-06 22:38:00 -04:00
// /// Reference to current card czar
2024-04-06 21:28:25 -04:00
// czar: &CAHPlayer,
2024-04-06 22:38:00 -04:00
/// Black card for the current round
current_black: Option<CAHCardBlack>,
2024-04-05 22:38:41 -04:00
}
impl CAHGame {
2024-04-06 22:38:00 -04:00
/// Build game decks from input data for game start.
/// This should only run once and at startup.
2024-04-05 22:38:41 -04:00
fn build_decks(&mut self, cards_json: Vec<CAHCardSet>) {
for pack in cards_json {
2024-04-06 21:28:25 -04:00
if let Some(white) = pack.white {
self.white.extend(white)
2024-04-05 22:38:41 -04:00
}
2024-04-06 21:28:25 -04:00
if let Some(black) = pack.black {
self.black.extend(black)
2024-04-05 22:38:41 -04:00
}
}
}
2024-04-06 22:38:00 -04:00
/// Log counts of current drawable cards
/// For testing
2024-04-05 22:38:41 -04:00
fn deck_counts(&self) {
println!(
"Deck Counts:\n {} White cards\n {} Black cards",
2024-04-06 21:28:25 -04:00
self.white.len(),
self.black.len()
2024-04-05 22:38:41 -04:00
);
}
2024-04-06 22:38:00 -04:00
/// Draw one white card at random from play deck.
2024-04-06 21:28:25 -04:00
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,
})
}
2024-04-05 22:38:41 -04:00
}
2024-04-06 22:38:00 -04:00
/// Draw one black card at random from play deck.
2024-04-06 21:28:25 -04:00
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,
})
}
}
2024-04-06 22:38:00 -04:00
/// Deal a black card and use it for the current round
/// Returns a reference to the card
fn deal_black(&mut self) -> Result<&Option<CAHCardBlack>> {
self.current_black = Some(self.draw_one_black()?);
Ok(&self.current_black)
}
2024-04-06 21:28:25 -04:00
2024-04-06 22:38:00 -04:00
/// Create a new player and add them to the game.
2024-04-06 21:28:25 -04:00
fn create_player(&mut self, player: CAHPlayer) {
self.players.push(player);
println!("Player Created!");
2024-04-05 22:38:41 -04:00
}
}
2024-04-06 22:38:00 -04:00
/// Parse json for card data
2024-04-05 22:38:41 -04:00
fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
let data: String = fs::read_to_string(path).expect("Error reading file");
let jayson: Vec<CAHCardSet> = serde_json::from_str(&data)?;
Ok(jayson)
}
fn main() -> Result<()> {
2024-04-06 22:38:00 -04:00
// choose decks
2024-04-05 22:38:41 -04:00
let cards_input_path: &str = "data/cah-cards-full.json";
let cards_json: Vec<CAHCardSet> = load_json(cards_input_path)?;
2024-04-06 22:38:00 -04:00
// setup
2024-04-05 22:38:41 -04:00
let mut cah_game = CAHGame {
..Default::default()
};
cah_game.build_decks(cards_json);
cah_game.deck_counts();
2024-04-06 21:28:25 -04:00
cah_game.create_player(CAHPlayer {
..Default::default()
});
2024-04-06 22:38:00 -04:00
// sloppy ui stuff
2024-04-06 21:28:25 -04:00
let div = "--------------------------";
2024-04-06 22:38:00 -04:00
// deal black
if let Some(black_card) = cah_game.deal_black()? {
println!(
"{}\nPick {}\n {}\n{}",
div,
black_card.pick.to_string(),
black_card.text,
div,
);
}
2024-04-06 21:28:25 -04:00
// deal white
for i in 1..11 {
let card = cah_game.draw_one_white()?;
println!("{} {}", i, card.text);
}
2024-04-06 22:38:00 -04:00
println!("{}", div);
2024-04-05 22:38:41 -04:00
2024-04-06 21:28:25 -04:00
cah_game.deck_counts();
2024-04-06 22:38:00 -04:00
// fin
2024-04-05 22:38:41 -04:00
Ok(())
}