aboutsummaryrefslogtreecommitdiffstats
path: root/wwb/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'wwb/src/main.rs')
-rw-r--r--wwb/src/main.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/wwb/src/main.rs b/wwb/src/main.rs
new file mode 100644
index 0000000..b09c7c4
--- /dev/null
+++ b/wwb/src/main.rs
@@ -0,0 +1,147 @@
+use chrono::Local;
+use env_logger::{Builder, Env, Target};
+use std::io::Write;
+use std::process::exit;
+use std::sync::{Arc, Mutex};
+use wwb::*;
+
+/// Roll a d6 and return the result.
+fn roll_d6() -> u8 {
+ fastrand::u8(1..=6)
+}
+
+fn current_space_pretty(current_space: u16) -> String {
+ if current_space == 0 {
+ "Start".to_string()
+ } else if current_space == BOARD_SIZE + 1 {
+ "Finish".to_string()
+ } else {
+ current_space.to_string()
+ }
+}
+
+fn main() {
+ let env = Env::new().filter_or("RUST_LOG", "info");
+ // Create logger
+ Builder::from_env(env)
+ .format(|buf, record| {
+ writeln!(
+ buf,
+ "{} - {}",
+ Local::now().format("%Y-%m-%dT%H:%M:%S"),
+ record.args()
+ )
+ })
+ .target(Target::Stdout)
+ .init();
+
+ let game = Arc::new(Mutex::new(Game::default()));
+
+ // Set up Ctrl-C handler to print the game state before exiting.
+ let game_clone = Arc::clone(&game);
+ ctrlc::set_handler(move || {
+ let game = game_clone.lock().unwrap();
+ log::error!("{:#?}", *game);
+ exit(0);
+ })
+ .expect("Error setting Ctrl-C handler");
+
+ loop {
+ let mut game = game.lock().unwrap();
+ game.turn_count += 1;
+ // Game loop:
+ // Player rolls d6
+ // If not 5, next player's turn
+ // If 5, roll d6 again
+ // If not 5, go back to space 0
+ // If 5 again, go ahead a space
+ // If players are on the same space that is NOT 0, move BOTH back to space 0
+ // Next player's turn
+ // Roll the dice
+
+ // This will probably not work properly when the turn count goes above 2^32 on a 32-bit machine and 3^64 on a 64-bit machine.
+ let current_player_number = game.turn_count as usize % PLAYER_COUNT;
+ let mut current_space = game.players[current_player_number].current_space;
+ let current_turn_pretty = game
+ .turn_count
+ .to_string()
+ .as_bytes()
+ .rchunks(3)
+ .rev()
+ .map(std::str::from_utf8)
+ .collect::<Result<Vec<&str>, _>>()
+ .unwrap()
+ .join(",");
+
+ let roll = roll_d6();
+ log::debug!(
+ "Player {} rolled a {} on turn {} from space {}",
+ current_player_number,
+ roll,
+ current_turn_pretty,
+ current_space_pretty(current_space)
+ );
+
+ if roll != 5 {
+ continue;
+ }
+ current_space += 1;
+ // Check if the player has won by reaching the space after the last space.
+ if current_space == BOARD_SIZE + 1 {
+ println!("Player {} has reached the Finish space and won on turn {}!", current_player_number, current_turn_pretty);
+ break;
+ }
+
+ if current_space > game.players[current_player_number].high_score {
+ log::info!(
+ "Player {} has a new high score of {} on turn {}",
+ current_player_number,
+ current_space_pretty(current_space),
+ current_turn_pretty
+ );
+ game.players[current_player_number].high_score = current_space;
+ }
+
+ let mut collision: bool = false;
+
+ for player in game.players.iter_mut() {
+ if player.current_space == current_space && player.current_space != 0 {
+ log::debug!(
+ "Two players collided on space {} on turn {}",
+ current_space_pretty(current_space),
+ current_turn_pretty
+ );
+ player.current_space = 0;
+ current_space = 0;
+ collision = true;
+ }
+ }
+
+ // No need to run this logic if there was a collision and the current player is already at 0.
+ if !collision {
+ if roll_d6() == 5 {
+ log::debug!(
+ "Player {} rolled a 5 again on turn {} gets to stay on space {}",
+ current_player_number,
+ current_turn_pretty,
+ current_space_pretty(current_space)
+ );
+ } else {
+ log::debug!(
+ "Player {} rolled a non-5 after rolling a 5 on turn {} and goes back to Start",
+ current_player_number,
+ current_turn_pretty
+ );
+ current_space = 0;
+ }
+ }
+
+ game.players[current_player_number].current_space = current_space;
+ log::debug!(
+ "Player {} ends turn {} on space {}",
+ current_player_number,
+ current_turn_pretty,
+ current_space_pretty(current_space)
+ );
+ }
+}