summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2020-04-10 22:00:38 +0200
committerJustin Wernick <justin@worthe-it.co.za>2020-04-10 22:00:38 +0200
commit82ceee2c432d26589834e803af59b710a66a2636 (patch)
tree3fa1da7dcc34241c2cbb32a5d1b7e84b1d7751ba
parentdad11c774fe42885987bf74fe2bb567c2d8029f0 (diff)
Most of the game rules
-rw-r--r--src/consts.rs11
-rw-r--r--src/main.rs1
-rw-r--r--src/state.rs135
3 files changed, 137 insertions, 10 deletions
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<Position>,
+ powerup_oils: Vec<Position>,
+ powerup_boosts: Vec<Position>,
+}
+
+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;
}
}