casino 0.3.0

A casino built right into your terminal
Documentation
use anyhow::{Context, Result};
use casino::blackjack::play_blackjack;
use casino::config::Config;
use casino::craps::play_craps;
use casino::roulette::play_roulette;
use casino::slots::play_slots;
use casino::{baccarat::play_baccarat, Casino};
use clap::{Parser, Subcommand};
use inquire::Select;
use std::fs;
use tabled::settings::object::Columns;
use tabled::settings::{Alignment, Panel, Style};
use tabled::Table;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    #[command(subcommand)]
    command: Option<Commands>,
}

#[derive(Debug, Subcommand)]
enum Commands {
    /// Play some baccarat
    Baccarat,
    /// Play a hand of blackjack
    Blackjack,
    /// Play a round of roulette
    Roulette,
    /// Spin a slot machine
    Slots,
    /// Play a game of craps
    Craps,
    /// Show lifetime statistics
    Stats,
    /// Show currency balance
    Balance,
    /// Clears game state and statistics
    Reset,
}

fn main() -> Result<()> {
    let args = Args::parse();

    match &args.command {
        Some(Commands::Stats) => {
            let state = Casino::from_filesystem()?;

            let global_stats = vec![state.stats];
            let mut global_table = Table::kv(global_stats);
            global_table
                .with(Style::sharp())
                .with(Panel::header("Global"));
            global_table.modify(Columns::last(), Alignment::right());
            println!("{}", global_table);

            println!();

            let baccarat_stats = vec![state.stats.baccarat];
            let mut baccarat_table = Table::kv(baccarat_stats);
            baccarat_table
                .with(Style::sharp())
                .with(Panel::header("Baccarat"));
            baccarat_table.modify(Columns::last(), Alignment::right());
            println!("{}", baccarat_table);

            println!();

            let blackjack_stats = vec![state.stats.blackjack];
            let mut blackjack_table = Table::kv(blackjack_stats);
            blackjack_table
                .with(Style::sharp())
                .with(Panel::header("Blackjack"));
            blackjack_table.modify(Columns::last(), Alignment::right());
            println!("{}", blackjack_table);

            println!();

            let roulette_stats = vec![state.stats.roulette];
            let mut roulette_table = Table::kv(roulette_stats);
            roulette_table
                .with(Style::sharp())
                .with(Panel::header("Roulette"));
            roulette_table.modify(Columns::last(), Alignment::right());
            println!("{}", roulette_table);
            println!();

            let slots_stats = vec![state.stats.slots];
            let mut slots_table = Table::kv(slots_stats);
            slots_table
                .with(Style::sharp())
                .with(Panel::header("Slots"));
            slots_table.modify(Columns::last(), Alignment::right());
            println!("{}", slots_table);
        }
        Some(Commands::Baccarat) => {
            play_baccarat()?;
        }
        Some(Commands::Blackjack) => {
            play_blackjack()?;
        }
        Some(Commands::Roulette) => {
            play_roulette()?;
        }
        Some(Commands::Slots) => {
            play_slots()?;
        }
        Some(Commands::Craps) => {
            play_craps()?;
        }
        Some(Commands::Balance) => {
            let state = Casino::from_filesystem()?;
            println!("{}", state.bankroll);
        }
        Some(Commands::Reset) => {
            let cfg_path = Config::default_path();
            let config = Config::from_path(&cfg_path)?;

            if config.save_path.try_exists()? {
                println!("Deleting save file at {}", config.save_path.display());
                fs::remove_file(&config.save_path).with_context(|| "Failed to remove save file")?;
            }
            if config.stats_path.try_exists()? {
                println!("Deleting stats file at {}", config.stats_path.display());
                fs::remove_file(&config.stats_path)
                    .with_context(|| "Failed to remove stats file")?;
            }
        }
        None => {
            let options = vec!["Baccarat", "Blackjack", "Roulette", "Slots", "Craps"];

            let ans = Select::new("What would you like to play?", options).prompt();

            match ans {
                Ok("Baccarat") => {
                    play_baccarat()?;
                }
                Ok("Blackjack") => play_blackjack()?,
                Ok("Roulette") => {
                    play_roulette()?;
                }
                Ok("Slots") => {
                    play_slots()?;
                }
                Ok("Craps") => {
                    play_craps()?;
                }
                Ok(_) => panic!("Unknown option"),
                Err(_) => panic!("Error fetching your choice"),
            }
        }
    }
    Ok(())
}