From e2325ef896cea2e8cba30aa28af9c337eccebb03 Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:48:14 +0200 Subject: [PATCH 1/8] prefer shorthand variable name when variable is identical to property --- src/game.rs | 2 +- src/snake.rs | 6 +++--- src/window_component.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/game.rs b/src/game.rs index 4e3b6d6..ff05097 100644 --- a/src/game.rs +++ b/src/game.rs @@ -19,7 +19,7 @@ struct Food { impl Food { fn new(value: i32) -> Self { Food { - value: value, + value, icon: "$".to_string(), pos: Position::new(12, 10), } diff --git a/src/snake.rs b/src/snake.rs index f427385..bd546c2 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -28,7 +28,7 @@ impl SnakeBodyPart { fn new(position: Position, part: Part) -> Self { SnakeBodyPart { pos: position, - part: part, + part, } } @@ -52,9 +52,9 @@ impl Snake { let hash_set: HashSet = HashSet::from([p1.pos.hash(), p2.pos.hash(), p3.pos.hash()]); let snake: VecDeque = VecDeque::from([p1, p2, p3]); Snake { - snake: snake, + snake, direction: Direction::RIGHT, - texture: texture, + texture, snake_hash: hash_set, } } diff --git a/src/window_component.rs b/src/window_component.rs index 75a3c8e..ab9982c 100644 --- a/src/window_component.rs +++ b/src/window_component.rs @@ -45,8 +45,8 @@ impl Component { let posx = (window_width - width) / 2; Component { win: newwin(height, width, posy, posx), - height: height, - width: width, + height, + width, cur_y: 1, options: Vec::new(), option_len: 0, From 53a3f4acaa17bf87e53263b706d0c7077241db99 Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:48:42 +0200 Subject: [PATCH 2/8] impl default function for GameWindow struct --- src/game_window.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/game_window.rs b/src/game_window.rs index c11e44a..b9c2820 100644 --- a/src/game_window.rs +++ b/src/game_window.rs @@ -7,6 +7,12 @@ pub struct GameWindow { pub window_height: i32, } +impl Default for GameWindow { + fn default() -> Self { + Self::new() + } +} + impl GameWindow { pub fn new() -> Self { initscr(); From 391d9895e7883cb4502dd598473cdc3cee17959c Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:52:19 +0200 Subject: [PATCH 3/8] ran formatter which ensure consistent white space usage across the project --- src/game_window.rs | 28 +++++++------ src/main.rs | 13 +++--- src/snake.rs | 4 +- src/window_component.rs | 88 +++++++++++++++++++++++------------------ 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/game_window.rs b/src/game_window.rs index b9c2820..a4d3ea7 100644 --- a/src/game_window.rs +++ b/src/game_window.rs @@ -44,7 +44,13 @@ impl GameWindow { endwin(); } - pub fn pause_menu(&mut self, height: i32, width: i32, title: String, is_gameover : bool) -> Action { + pub fn pause_menu( + &mut self, + height: i32, + width: i32, + title: String, + is_gameover: bool, + ) -> Action { let mut component: Component = Component::new(height, width, self.window_height, self.window_width); @@ -68,9 +74,9 @@ impl GameWindow { napms(100); match getch() { ERR => {} - 27 => { + 27 => { component.del(); - return Action::QUIT + return Action::QUIT; } x => match component.handle_input(x) { Err(n) => return n, @@ -98,9 +104,9 @@ impl GameWindow { napms(100); match getch() { ERR => {} - 27 => { + 27 => { component.del(); - return Action::QUIT + return Action::QUIT; } x => match component.handle_input(x) { Err(n) => return n, @@ -110,8 +116,8 @@ impl GameWindow { } } - pub fn get_name(&mut self, height : i32, width: i32) -> String{ - let title: String = String::from("You Name?"); + pub fn get_name(&mut self, height: i32, width: i32) -> String { + let title: String = String::from("You Name?"); let mut component: Component = Component::new(height, width, self.window_height, self.window_width); @@ -124,8 +130,8 @@ impl GameWindow { component.display(); component.refresh(); napms(100); - match getch(){ - ERR => {}, + match getch() { + ERR => {} 10 | 27 => break, c => { if c == 263 && name.len() > 0 { @@ -133,7 +139,7 @@ impl GameWindow { } else if ( c >= 48 && c <= 57) || ( c >= 65 && c <= 90 ) || ( c >= 97 && c <= 122 ){ let ch = char::from_u32(c as u32).unwrap(); - name = format!("{}{}",name, ch ); + name = format!("{}{}", name, ch); } } }; @@ -142,6 +148,4 @@ impl GameWindow { component.del(); name } - } - diff --git a/src/main.rs b/src/main.rs index 64c447d..263b119 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use ncurses::*; use viper::game::Game; -use viper::game_window::{*}; +use viper::game_window::*; use viper::window_component::Action; fn main() { @@ -11,13 +11,9 @@ fn main() { _ => {} } let name: String = window.get_name(6, 30); - let mut game: Game = Game::new( - name, - window.window_width, - window.window_height, - ); + let mut game: Game = Game::new(name, window.window_width, window.window_height); 'curr_game: loop { - let mut is_gameover : bool = false; + let mut is_gameover: bool = false; 'game: loop { clear(); game.display(); @@ -42,10 +38,11 @@ fn main() { match window.pause_menu(6, 30, msg, is_gameover) { Action::QUIT => break 'new_game, Action::RESTART => break 'curr_game, - Action::RESUME => {}, + Action::RESUME => {} _ => {} } } } window.exit(); } + diff --git a/src/snake.rs b/src/snake.rs index bd546c2..b0e15d5 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -1,8 +1,8 @@ +use ncurses::{attroff, attron, mvprintw, A_BOLD}; use std::collections::HashSet; use std::collections::VecDeque; -use ncurses::{mvprintw, attroff, attron, A_BOLD }; -use crate::utils::{Position, Direction}; +use crate::utils::{Direction, Position}; #[derive(Clone, Copy, Debug)] enum Part { diff --git a/src/window_component.rs b/src/window_component.rs index ab9982c..a5efc03 100644 --- a/src/window_component.rs +++ b/src/window_component.rs @@ -1,41 +1,39 @@ -use ncurses::{wattroff, wattron, box_, delwin, mvwprintw, newwin, wrefresh, A_BOLD, COLOR_PAIR, KEY_ENTER, wclear }; use crate::utils::Position; +use ncurses::{ + box_, delwin, mvwprintw, newwin, wattroff, wattron, wclear, wrefresh, A_BOLD, COLOR_PAIR, + KEY_ENTER, +}; #[derive(Clone, Copy)] -pub enum Action{ +pub enum Action { QUIT, RESUME, RESTART, - START + START, } -pub struct Choice -{ +pub struct Choice { text: String, handler: Action, } - pub struct Component { win: *mut i8, height: i32, width: i32, - cur_y : i32, + cur_y: i32, options: Vec, option_len: usize, option_selected: usize, inputs: String, input_len: usize, - title :String, - title_pos: Position + title: String, + title_pos: Position, } -impl Choice{ +impl Choice { pub fn new(text: String, handler: Action) -> Self { - Choice { - text: text, - handler: handler, - } + Choice { text, handler } } } @@ -51,10 +49,10 @@ impl Component { options: Vec::new(), option_len: 0, option_selected: 0, - title : String::new(), - title_pos : Position::new(0, 0), + title: String::new(), + title_pos: Position::new(0, 0), input_len: 0, - inputs : String::new() + inputs: String::new(), } } @@ -69,7 +67,7 @@ impl Component { self.title_pos.posy = 1; } - pub fn add_choice(&mut self, choice : Choice) { + pub fn add_choice(&mut self, choice: Choice) { self.options.push(choice); self.option_len += 1; if self.option_len as i32 == self.height { @@ -82,15 +80,19 @@ impl Component { pub fn display(&mut self) { // displaying the title - wattron(self.win,COLOR_PAIR(1) | A_BOLD()); - mvwprintw(self.win, self.title_pos.posy, self.title_pos.posx, self.title.as_str()); - wattroff(self.win,COLOR_PAIR(1) | A_BOLD()); + wattron(self.win, COLOR_PAIR(1) | A_BOLD()); + mvwprintw( + self.win, + self.title_pos.posy, + self.title_pos.posx, + self.title.as_str(), + ); + wattroff(self.win, COLOR_PAIR(1) | A_BOLD()); self.cur_y = 2; //displaying inputs if self.input_len > 0 { - - let line = format!("+{}+", "-".repeat(self.width as usize - 4) ); + let line = format!("+{}+", "-".repeat(self.width as usize - 4)); mvwprintw(self.win, self.cur_y, 1, line.as_str()); self.cur_y += 1; let p = (self.width - (self.inputs.len() as i32)) / 2; @@ -101,17 +103,15 @@ impl Component { mvwprintw(self.win, self.cur_y, 1, line.as_str()); } - // displaying the options - if self.option_len > 0 { + if self.option_len > 0 { for i in 0..self.option_len { let p = (self.width - (self.options[i].text.len() as i32)) / 2; if i == self.option_selected { wattron(self.win, A_BOLD()); mvwprintw(self.win, self.cur_y, p, self.options[i].text.as_str()); wattroff(self.win, A_BOLD()); - } - else{ + } else { mvwprintw(self.win, self.cur_y, p, self.options[i].text.as_str()); } self.cur_y += 1; @@ -122,16 +122,15 @@ impl Component { pub fn handle_input(&mut self, x: i32) -> Result<(), Action> { match x { 115 | 258 => { - self.option_selected = ( self.option_selected + 1 ) % self.option_len; - }, + self.option_selected = (self.option_selected + 1) % self.option_len; + } 119 | 259 => { if self.option_selected == 0 { self.option_selected = self.option_len - 1; + } else { + self.option_selected = (self.option_selected - 1) % self.option_len; } - else { - self.option_selected = ( self.option_selected - 1 ) % self.option_len; - } - }, + } KEY_ENTER | 10 => { match self.option_handler(self.options[self.option_selected].handler){ Err(n) => return Err(n), @@ -153,12 +152,24 @@ impl Component { self.inputs = input; } - fn option_handler(&mut self, action : Action ) -> Result<(), Action> { + fn option_handler(&mut self, action: Action) -> Result<(), Action> { match action { - Action::QUIT => { self.del(); return Err(Action::QUIT) }, - Action::RESTART => { self.del(); return Err(Action::RESTART) }, - Action::RESUME => { self.del(); return Err(Action::RESUME) }, - Action::START => { self.del(); return Err(Action::START )} + Action::QUIT => { + self.del(); + Err(Action::QUIT) + } + Action::RESTART => { + self.del(); + Err(Action::RESTART) + } + Action::RESUME => { + self.del(); + Err(Action::RESUME) + } + Action::START => { + self.del(); + Err(Action::START) + } } } @@ -173,5 +184,4 @@ impl Component { pub fn clear(&self) { wclear(self.win); } - } From 143478736de00969b77a484a44074199778f317f Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:52:49 +0200 Subject: [PATCH 4/8] format import statements --- src/game.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game.rs b/src/game.rs index ff05097..3684a1a 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,7 +1,7 @@ -use ncurses::{mvprintw, attroff, attron, A_BOLD, COLOR_PAIR, addstr }; +use crate::snake::Snake; +use crate::utils::{Direction, Position}; +use ncurses::{addstr, attroff, attron, mvprintw, A_BOLD, COLOR_PAIR}; use rand::Rng; -use crate::snake::{Snake}; -use crate::utils::{ Position, Direction }; pub struct Game { username: String, From b85f7b8c1abf381a2cd70d912b42147ae74308be Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:53:10 +0200 Subject: [PATCH 5/8] ensure consistent spacing in function --- src/game.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game.rs b/src/game.rs index 3684a1a..6ba4fb9 100644 --- a/src/game.rs +++ b/src/game.rs @@ -33,8 +33,8 @@ impl Food { fn relocate(&mut self, width: i32, height: i32) -> () { let mut rng = rand::thread_rng(); - self.pos.posy = rng.gen_range(1..=height-2); - self.pos.posx = rng.gen_range(1..=width-2); + self.pos.posy = rng.gen_range(1..=height - 2); + self.pos.posx = rng.gen_range(1..=width - 2); } } From 4bc8fc4e7adbbf2399e91409ee7fddac22498db0 Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:55:10 +0200 Subject: [PATCH 6/8] add logic for variable snake speed when holding in keys --- src/game.rs | 20 ++++++++++++++++---- src/main.rs | 9 +++++++-- src/snake.rs | 2 ++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/game.rs b/src/game.rs index 6ba4fb9..0ddfbf3 100644 --- a/src/game.rs +++ b/src/game.rs @@ -67,19 +67,31 @@ impl Game { match ch { 119 | 259 => match self.snake.direction { Direction::BOTTOM => {} - _ => self.snake.direction = Direction::TOP, + _ => { + self.snake.direction = Direction::TOP; + self.snake.speed = 4; + } }, // w 97 | 260 => match self.snake.direction { Direction::RIGHT => {} - _ => self.snake.direction = Direction::LEFT, + _ => { + self.snake.direction = Direction::LEFT; + self.snake.speed = 4; + } }, // A 115 | 258 => match self.snake.direction { Direction::TOP => {} - _ => self.snake.direction = Direction::BOTTOM, + _ => { + self.snake.direction = Direction::BOTTOM; + self.snake.speed = 4; + } }, //s 100 | 261 => match self.snake.direction { Direction::LEFT => {} - _ => self.snake.direction = Direction::RIGHT, + _ => { + self.snake.direction = Direction::RIGHT; + self.snake.speed = 4; + } }, // D _ => {} } diff --git a/src/main.rs b/src/main.rs index 263b119..6b3d3f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ use viper::game_window::*; use viper::window_component::Action; fn main() { + timeout(0); + let mut window = GameWindow::new(); 'new_game: loop { match window.start_menu(6, 30 ){ @@ -27,12 +29,15 @@ fn main() { break 'game; } }; - napms(100); match getch() { - ERR => {} + ERR => { + game.snake.speed = 1; + } 27 => break 'game, n => game.control_snake(n), } + let speed = 100 / game.snake.speed; + napms(speed); } let msg: String = format!("Score : {}", game.score); match window.pause_menu(6, 30, msg, is_gameover) { diff --git a/src/snake.rs b/src/snake.rs index b0e15d5..a1a8548 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -20,6 +20,7 @@ pub struct SnakeBodyPart { pub struct Snake { pub snake: VecDeque, pub direction: Direction, + pub speed: i32, texture: (String, String, String), snake_hash: HashSet, } @@ -56,6 +57,7 @@ impl Snake { direction: Direction::RIGHT, texture, snake_hash: hash_set, + speed: 1, } } From 37e6c3e42e3a96aeee1351a48ab657cba592e68f Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:56:55 +0200 Subject: [PATCH 7/8] remove unnecessary explicit return type when the function doesn't return anything --- src/game.rs | 10 +++++----- src/snake.rs | 6 +++--- src/window_component.rs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game.rs b/src/game.rs index 0ddfbf3..3253f79 100644 --- a/src/game.rs +++ b/src/game.rs @@ -25,13 +25,13 @@ impl Food { } } - fn display(&self) -> () { + fn display(&self) { attron(COLOR_PAIR(1) | A_BOLD()); mvprintw(self.pos.posy, self.pos.posx, self.icon.as_str()); attroff(COLOR_PAIR(1) | A_BOLD()); } - fn relocate(&mut self, width: i32, height: i32) -> () { + fn relocate(&mut self, width: i32, height: i32) { let mut rng = rand::thread_rng(); self.pos.posy = rng.gen_range(1..=height - 2); self.pos.posx = rng.gen_range(1..=width - 2); @@ -53,7 +53,7 @@ impl Game { } } - pub fn update_score(&mut self, width: i32, height: i32) -> () { + pub fn update_score(&mut self, width: i32, height: i32) { if let Some(head) = self.snake.snake.front_mut() { if head.pos == self.food.pos { self.score += self.food.value; @@ -97,10 +97,10 @@ impl Game { } } - pub fn display(&mut self) -> () { + pub fn display(&mut self) { let data = format!("USER : {} | SCORE : {}", self.username, self.score); addstr(&data); self.snake.display(); self.food.display(); } -} \ No newline at end of file +} diff --git a/src/snake.rs b/src/snake.rs index a1a8548..08cc677 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -33,13 +33,13 @@ impl SnakeBodyPart { } } - fn display(&self, texture: (String, String, String)) -> () { let ch: String; match self.part { Part::HEAD => ch = texture.0.clone(), Part::BODY => ch = texture.1.clone(), Part::TAIL => ch = texture.2.clone(), } + fn display(&self, texture: (String, String, String)) { mvprintw(self.pos.posy, self.pos.posx, ch.as_str()); } } @@ -78,7 +78,7 @@ impl Snake { Ok(()) } - pub fn extend_back(&mut self) -> () { + pub fn extend_back(&mut self) { if let Some(curr_tail) = self.snake.back_mut() { curr_tail.part = Part::BODY; let p: SnakeBodyPart = @@ -108,7 +108,7 @@ impl Snake { Ok(()) } - pub fn display(&self) -> () { + pub fn display(&self) { attron(A_BOLD()); for part in self.snake.iter() { part.display(self.texture.clone()); diff --git a/src/window_component.rs b/src/window_component.rs index a5efc03..460a96c 100644 --- a/src/window_component.rs +++ b/src/window_component.rs @@ -147,7 +147,7 @@ impl Component { self.input_len as i32 } - pub fn update_input(&mut self, input: String, index: i32) -> () { + pub fn update_input(&mut self, input: String, index: i32) { let _ = index - 1; self.inputs = input; } From 730c2290eaf498cab4611ed56eb280faa57a9525 Mon Sep 17 00:00:00 2001 From: Marius Kluften Date: Wed, 4 Oct 2023 14:59:41 +0200 Subject: [PATCH 8/8] attempt to improve readability of certain pattern matches in the code --- src/game_window.rs | 26 +++++++++++++++----------- src/main.rs | 5 ++--- src/snake.rs | 13 ++++++------- src/window_component.rs | 7 ++----- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/game_window.rs b/src/game_window.rs index a4d3ea7..ad8ba32 100644 --- a/src/game_window.rs +++ b/src/game_window.rs @@ -78,10 +78,11 @@ impl GameWindow { component.del(); return Action::QUIT; } - x => match component.handle_input(x) { - Err(n) => return n, - _ => {} - }, + x => { + if let Err(n) = component.handle_input(x) { + return n; + } + } } } } @@ -108,10 +109,11 @@ impl GameWindow { component.del(); return Action::QUIT; } - x => match component.handle_input(x) { - Err(n) => return n, - _ => {} - }, + x => { + if let Err(n) = component.handle_input(x) { + return n; + } + } } } } @@ -134,10 +136,12 @@ impl GameWindow { ERR => {} 10 | 27 => break, c => { - if c == 263 && name.len() > 0 { + if c == 263 && !name.is_empty() { name.truncate(name.len() - 1); - } - else if ( c >= 48 && c <= 57) || ( c >= 65 && c <= 90 ) || ( c >= 97 && c <= 122 ){ + } else if (48..=57).contains(&c) + || (65..=90).contains(&c) + || (97..=122).contains(&c) + { let ch = char::from_u32(c as u32).unwrap(); name = format!("{}{}", name, ch); } diff --git a/src/main.rs b/src/main.rs index 6b3d3f3..dcadd88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,9 +8,8 @@ fn main() { let mut window = GameWindow::new(); 'new_game: loop { - match window.start_menu(6, 30 ){ - Action::QUIT => break 'new_game, - _ => {} + if let Action::QUIT = window.start_menu(6, 30) { + break 'new_game; } let name: String = window.get_name(6, 30); let mut game: Game = Game::new(name, window.window_width, window.window_height); diff --git a/src/snake.rs b/src/snake.rs index 08cc677..65ab2a0 100644 --- a/src/snake.rs +++ b/src/snake.rs @@ -33,18 +33,16 @@ impl SnakeBodyPart { } } - let ch: String; - match self.part { - Part::HEAD => ch = texture.0.clone(), - Part::BODY => ch = texture.1.clone(), - Part::TAIL => ch = texture.2.clone(), - } fn display(&self, texture: (String, String, String)) { + let ch: String = match self.part { + Part::HEAD => texture.0.clone(), + Part::BODY => texture.1.clone(), + Part::TAIL => texture.2.clone(), + }; mvprintw(self.pos.posy, self.pos.posx, ch.as_str()); } } - impl Snake { pub fn new(position: Position, texture: (String, String, String)) -> Self { let p1 = SnakeBodyPart::new(position, Part::HEAD); @@ -75,6 +73,7 @@ impl Snake { } self.snake.push_front(p); } + Ok(()) } diff --git a/src/window_component.rs b/src/window_component.rs index 460a96c..83f941b 100644 --- a/src/window_component.rs +++ b/src/window_component.rs @@ -132,11 +132,8 @@ impl Component { } } KEY_ENTER | 10 => { - match self.option_handler(self.options[self.option_selected].handler){ - Err(n) => return Err(n), - _ => {} - }; - }, + self.option_handler(self.options[self.option_selected].handler)?; + } _ => {} } Ok(())