From 82ceee2c432d26589834e803af59b710a66a2636 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Fri, 10 Apr 2020 22:00:38 +0200 Subject: Most of the game rules --- src/consts.rs | 11 +++++ src/main.rs | 1 + src/state.rs | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 src/consts.rs diff --git a/src/consts.rs b/src/consts.rs new file mode 100644 index 0000000..6ebc9af --- /dev/null +++ b/src/consts.rs @@ -0,0 +1,11 @@ +pub const SPEED_0: usize = 0; +pub const SPEED_1: usize = 3; +pub const SPEED_2: usize = 6; +pub const SPEED_3: usize = 8; +pub const SPEED_4: usize = 9; +pub const SPEED_BOOST: usize = 15; + +pub const BOOST_DURATION: usize = 5; + +pub const HEIGHT: usize = 4; +pub const WIDTH: usize = 1500; diff --git a/src/main.rs b/src/main.rs index a565e73..81bc3b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use std::io::prelude::*; use std::io::stdin; mod command; +mod consts; mod json; mod state; diff --git a/src/state.rs b/src/state.rs index 2f81d5d..b87db1b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,12 +1,30 @@ use crate::command::Command; +use crate::consts::*; pub struct GameState { players: [Player; 2], + obstacles: Vec, + powerup_oils: Vec, + powerup_boosts: Vec, +} + +pub struct Player { + position: Position, + next_position: Position, + speed: usize, + boost_remaining: usize, + oils: usize, + boosts: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Position { + x: usize, + y: usize, } -pub struct Player {} impl GameState { - fn update(&mut self, commands: [Command; 2]) { + pub fn update(&mut self, commands: [Command; 2]) { self.do_command(0, &commands[0]); self.do_command(1, &commands[1]); self.update_player_collisions(); @@ -16,22 +34,119 @@ impl GameState { fn do_command(&mut self, player_index: usize, command: &Command) { use Command::*; + // TODO: Command validation assertions match command { Nothing => {} - Accelerate => unimplemented!(), - Decelerate => unimplemented!(), - TurnLeft => unimplemented!(), - TurnRight => unimplemented!(), - UseBoost => unimplemented!(), - UseOil => unimplemented!(), + Accelerate => self.players[player_index].accelerate(), + Decelerate => self.players[player_index].decelerate(), + TurnLeft => self.players[player_index].turn(false), + TurnRight => self.players[player_index].turn(true), + UseBoost => self.players[player_index].boost(), + UseOil => { + self.players[player_index].oils -= 1; + let player_position = self.players[player_index].position; + self.obstacles.push(Position { + x: player_position.x - 1, + y: player_position.y, + }); + } } + + self.players[player_index].set_next_position_x(); } fn update_player_collisions(&mut self) { - //TODO + + // TODO: One player rear-ending another + // TODO: Ending up in the same block from different lanes } fn update_player_travel(&mut self) { - //TODO + for player in &mut self.players { + player.move_along(&self.obstacles, &self.powerup_oils, &self.powerup_boosts); + } + } +} + +impl Player { + fn accelerate(&mut self) { + self.speed = match self.speed { + i if i < SPEED_1 => SPEED_1, + i if i < SPEED_2 => SPEED_2, + i if i < SPEED_3 => SPEED_3, + _ => SPEED_4, + }; + } + + fn decelerate(&mut self) { + self.speed = match self.speed { + i if i <= SPEED_1 => SPEED_0, + i if i <= SPEED_2 => SPEED_1, + i if i <= SPEED_3 => SPEED_2, + i if i <= SPEED_4 => SPEED_3, + _ => SPEED_4, + }; + self.boost_remaining = 0; + } + + fn decelerate_from_obstacle(&mut self) { + self.speed = match self.speed { + i if i <= SPEED_2 => SPEED_1, + i if i <= SPEED_3 => SPEED_2, + i if i <= SPEED_4 => SPEED_3, + _ => SPEED_4, + }; + self.boost_remaining = 0; + } + + fn turn(&mut self, right: bool) { + if right { + self.next_position.y = self.position.y + 1; + } else { + self.next_position.y = self.position.y - 1; + } + } + + fn boost(&mut self) { + self.speed = SPEED_BOOST; + self.boost_remaining = BOOST_DURATION; + self.boosts -= 1; + } + + fn set_next_position_x(&mut self) { + if self.position.y == self.next_position.y { + self.next_position.x = self.position.x + self.speed; + } else { + self.next_position.x = self.position.x + self.speed - 1; + } + } + + fn move_along( + &mut self, + obstacles: &[Position], + powerup_oils: &[Position], + powerup_boosts: &[Position], + ) { + let start_x = if self.position.y == self.next_position.y { + self.position.x + 1 + } else { + self.position.x + }; + for x in start_x..=self.next_position.x { + let position = Position { + x, + y: self.next_position.y, + }; + if obstacles.contains(&position) { + self.decelerate_from_obstacle(); + } + if powerup_oils.contains(&position) { + self.oils += 1; + } + if powerup_boosts.contains(&position) { + self.boosts += 1; + } + } + self.position = self.next_position; } } -- cgit v1.2.3