Cargo clippy fixes
Did cargo clippy fixes Added github workflows
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
name: Rust Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
default: true
|
||||
override: true
|
||||
|
||||
- name: Build
|
||||
run: cargo build --release
|
||||
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
||||
|
||||
- name: Strip
|
||||
run: strip target/release/snake
|
||||
|
||||
- name: Compress
|
||||
run: tar cvzf snake.tar.gz LICENSE target/release/snake
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
snake.tar.gz
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Rust Build Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
||||
@@ -1,2 +1 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
|
||||
Generated
+229
-16
@@ -1,5 +1,40 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.66"
|
||||
@@ -8,26 +43,80 @@ checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.0"
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.81"
|
||||
name = "dirs"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||
checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.10.1+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
|
||||
|
||||
[[package]]
|
||||
name = "ncurses"
|
||||
@@ -53,10 +142,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.0"
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18519b42a40024d661e1714153e9ad0c3de27cd495760ceb09710920f1098b1e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
@@ -76,11 +183,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8b34ba8cfb21243bd8df91854c830ff0d785fff2e82ebd4434c2644cb9ada18"
|
||||
checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -92,16 +199,122 @@ dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.121"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6159e3c76cab06f6bc466244d43b35e77e9500cd685da87620addadc2a4c40b1"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.121"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3fcab8778dc651bc65cfab2e4eb64996f3c912b74002fb379c94517e1f27c46"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snake"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"ncurses",
|
||||
"rand",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
@@ -8,4 +8,9 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
ncurses = "5.100.0"
|
||||
serde = { version = "1.0.121", features = ["derive"] }
|
||||
# serde = "1.0.121"
|
||||
# serde_derive = "1.0.121"
|
||||
toml = "0.5.8"
|
||||
rand = "0.8.0"
|
||||
dirs = "3.0.1"
|
||||
|
||||
+65
-68
@@ -1,32 +1,43 @@
|
||||
extern crate rand;
|
||||
use crate::settings::Config;
|
||||
use core::iter::Iterator;
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::LinkedList;
|
||||
use std::ops::Sub;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
#[derive(Debug)]
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
#[serde(tag = "type", content = "value")]
|
||||
pub enum Difficulty {
|
||||
Linear(f32),
|
||||
Flat,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
impl Copy for Direction {}
|
||||
impl Clone for Direction {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl PartialEq for Direction {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(&Self::Up, &Self::Up) => true,
|
||||
(&Self::Down, &Self::Down) => true,
|
||||
(&Self::Left, &Self::Left) => true,
|
||||
(&Self::Right, &Self::Right) => true,
|
||||
_ => false,
|
||||
}
|
||||
// match (self, other) {
|
||||
// (&Self::Up, &Self::Up) => true,
|
||||
// (&Self::Down, &Self::Down) => true,
|
||||
// (&Self::Left, &Self::Left) => true,
|
||||
// (&Self::Right, &Self::Right) => true,
|
||||
// _ => false,
|
||||
// }
|
||||
matches!(
|
||||
(self, other),
|
||||
(&Self::Up, &Self::Up)
|
||||
| (&Self::Down, &Self::Down)
|
||||
| (&Self::Left, &Self::Left)
|
||||
| (&Self::Right, &Self::Right)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,46 +52,29 @@ impl Direction {
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
// impl std::fmt::Debug for Direction {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// // write!(f,)
|
||||
// write!(
|
||||
// f,
|
||||
// "{}",
|
||||
// match *self {
|
||||
// Self::Up => (),
|
||||
// _ => (),
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
pub enum CellType {
|
||||
Food,
|
||||
Snake,
|
||||
Empty,
|
||||
// Empty,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct Cell {
|
||||
line: u32,
|
||||
col: u32,
|
||||
ctype: CellType,
|
||||
_ctype: CellType,
|
||||
}
|
||||
impl PartialEq for Cell {
|
||||
fn eq(&self, other: &Cell) -> bool {
|
||||
if (self.line == other.line) && (self.col == other.col) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
(self.line == other.line) && (self.col == other.col)
|
||||
}
|
||||
}
|
||||
impl Sub for Cell {
|
||||
type Output = (i32, i32);
|
||||
fn sub(self, rhs: Cell) -> (i32, i32) {
|
||||
return (
|
||||
(
|
||||
self.line as i32 - rhs.line as i32,
|
||||
self.col as i32 - rhs.col as i32,
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
impl Cell {
|
||||
@@ -88,7 +82,7 @@ impl Cell {
|
||||
Cell {
|
||||
line: l,
|
||||
col: c,
|
||||
ctype: t,
|
||||
_ctype: t,
|
||||
}
|
||||
}
|
||||
pub fn random(lines: u32, cols: u32) -> Cell {
|
||||
@@ -100,16 +94,16 @@ impl Cell {
|
||||
)
|
||||
}
|
||||
pub fn posyx(&self) -> (u32, u32) {
|
||||
return (self.line, self.col);
|
||||
(self.line, self.col)
|
||||
}
|
||||
pub fn posy(&self) -> u32 {
|
||||
return self.line;
|
||||
self.line
|
||||
}
|
||||
pub fn posx(&self) -> u32 {
|
||||
return self.col;
|
||||
self.col
|
||||
}
|
||||
pub fn chtype(&mut self, ctype: CellType) {
|
||||
self.ctype = ctype;
|
||||
pub fn _chtype(&mut self, ctype: CellType) {
|
||||
self._ctype = ctype;
|
||||
}
|
||||
pub fn is_adjacent(&self, other: &Cell) -> Option<Direction> {
|
||||
match *self - *other {
|
||||
@@ -135,17 +129,20 @@ impl Clone for Cell {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum FailState {
|
||||
Wall,
|
||||
Snake,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum GameState {
|
||||
Failed(FailState),
|
||||
Ready,
|
||||
// Playing,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Board {
|
||||
maxlines: u32,
|
||||
maxcols: u32,
|
||||
@@ -165,10 +162,9 @@ impl Board {
|
||||
}
|
||||
pub fn check_collision(&mut self, snake: &Snake) -> bool {
|
||||
let (snake_line, snake_col): (u32, u32) = snake.posyx();
|
||||
if (snake_line >= self.maxlines - 1)
|
||||
|| (snake_col >= self.maxcols - 1)
|
||||
|| (snake_line <= 0)
|
||||
|| (snake_col <= 0)
|
||||
if (snake_line >= self.maxlines - 1) || (snake_col >= self.maxcols - 1)
|
||||
// || (snake_line <= 0)
|
||||
// || (snake_col <= 0)
|
||||
{
|
||||
self.gamestate = GameState::Failed(FailState::Wall);
|
||||
return true;
|
||||
@@ -182,17 +178,13 @@ impl Board {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
pub fn check_food(&self, snake: &Snake) -> bool {
|
||||
if self.food_posyx() == snake.posyx() {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
self.food_posyx() == snake.posyx()
|
||||
}
|
||||
pub fn food_posyx(&self) -> (u32, u32) {
|
||||
return self.food.posyx();
|
||||
self.food.posyx()
|
||||
}
|
||||
// pub fn food_posy(&self) -> u32 {
|
||||
// return self.food.line;
|
||||
@@ -205,11 +197,11 @@ impl Board {
|
||||
pub fn spawn_food(&mut self, snake: &Snake) {
|
||||
let mut food: Cell = Cell::random(self.maxlines, self.maxcols);
|
||||
let mut spawned_food = false;
|
||||
while spawned_food != true {
|
||||
while !spawned_food {
|
||||
// check for colliosions with the snake body until a free spot is found and spawn the food there
|
||||
spawned_food = true;
|
||||
let mut snake_iter = snake.iter();
|
||||
for snake_cell in snake_iter.next() {
|
||||
let snake_iter = snake.iter();
|
||||
for snake_cell in snake_iter {
|
||||
if *snake_cell == food {
|
||||
// O(n) ; I think this is nessacary/ I don't know how to reduce the order
|
||||
// if food collides with the snake body then set food to a new random position and set spawned food to false
|
||||
@@ -228,26 +220,27 @@ pub struct Snake {
|
||||
head: Cell,
|
||||
body: LinkedList<Cell>,
|
||||
direction: Direction,
|
||||
difficulty: Difficulty,
|
||||
grow: bool,
|
||||
speed: u32,
|
||||
last_tail: Option<Cell>,
|
||||
}
|
||||
impl Snake {
|
||||
pub fn new(head: Cell) -> Snake {
|
||||
pub fn new(head: Cell, config: &Config) -> Snake {
|
||||
let mut temp_body: LinkedList<Cell> = LinkedList::new();
|
||||
temp_body.push_front(head);
|
||||
Snake {
|
||||
head,
|
||||
body: temp_body,
|
||||
// length: 1,
|
||||
difficulty: config.difficulty,
|
||||
direction: Direction::Right,
|
||||
grow: false,
|
||||
speed: 15,
|
||||
grow: true,
|
||||
speed: config.speed,
|
||||
last_tail: Some(head),
|
||||
}
|
||||
}
|
||||
pub fn posyx(&self) -> (u32, u32) {
|
||||
return (self.head.line, self.head.col);
|
||||
(self.head.line, self.head.col)
|
||||
}
|
||||
pub fn smove(&mut self, _direction: Direction) {
|
||||
// smove because move is already a keyword
|
||||
@@ -257,7 +250,7 @@ impl Snake {
|
||||
} else {
|
||||
direction = _direction
|
||||
}
|
||||
if self.grow == false {
|
||||
if !self.grow {
|
||||
self.last_tail = Some(self.body.pop_back().unwrap());
|
||||
|
||||
// self.grow = false;
|
||||
@@ -285,16 +278,20 @@ impl Snake {
|
||||
sleep(Duration::from_millis((1000 / self.speed) as u64));
|
||||
self.smove(self.direction);
|
||||
}
|
||||
pub fn scale_difficulty(&mut self) {
|
||||
match self.difficulty {
|
||||
Difficulty::Flat => (),
|
||||
Difficulty::Linear(scale) => self.speed = (self.speed as f32 * scale) as u32,
|
||||
}
|
||||
}
|
||||
pub fn grow(&mut self) {
|
||||
self.scale_difficulty();
|
||||
self.grow = true;
|
||||
}
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Cell> {
|
||||
return self.body.iter();
|
||||
self.body.iter()
|
||||
}
|
||||
pub fn remove(&self) -> Option<Cell> {
|
||||
return self.last_tail;
|
||||
}
|
||||
pub fn set_speed(&mut self, speed: u32) {
|
||||
self.speed = speed;
|
||||
self.last_tail
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ pub fn destroy_window(win: WINDOW) {
|
||||
delwin(win); // delete the window
|
||||
}
|
||||
|
||||
pub fn clear_window(win: WINDOW) {
|
||||
wmove(win, 0, 0);
|
||||
wclrtobot(win);
|
||||
}
|
||||
|
||||
pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
// let mut snake_iter = snake.iter();
|
||||
let (mut prev, mut current, _next): (&Cell, &Cell, &Cell);
|
||||
@@ -45,12 +50,10 @@ pub fn draw_snake(snake: &Snake, game_win: WINDOW) {
|
||||
prev.posx() as i32,
|
||||
&format!("{}", std::char::from_u32(0x0298).unwrap_or('O')),
|
||||
);
|
||||
match snake.remove() {
|
||||
Some(tail) => {
|
||||
mvwaddstr(game_win, tail.posy() as i32, tail.posx() as i32, " ");
|
||||
}
|
||||
None => (),
|
||||
if let Some(tail) = snake.remove() {
|
||||
mvwaddstr(game_win, tail.posy() as i32, tail.posx() as i32, " ");
|
||||
}
|
||||
|
||||
let _current = snake_iter.next();
|
||||
current = match _current {
|
||||
Some(cell) => cell,
|
||||
|
||||
+24
-15
@@ -1,24 +1,28 @@
|
||||
mod backend;
|
||||
mod frontend;
|
||||
use crate::menu;
|
||||
use crate::settings::Config;
|
||||
// use ncurses::*;
|
||||
pub use backend::Difficulty;
|
||||
use backend::{Board, Cell, Snake};
|
||||
use ncurses::{
|
||||
getmaxyx, nodelay, stdscr, wgetch, wrefresh, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_UP, WINDOW,
|
||||
};
|
||||
pub fn start() {
|
||||
pub fn start(config: &Config) {
|
||||
let (mut mlines, mut mcols): (i32, i32) = (0, 0);
|
||||
let game_win: WINDOW;
|
||||
let mut ch: i32;
|
||||
let (vmargin, hmargin): (u32, u32) = (5, 10);
|
||||
getmaxyx(stdscr(), &mut mlines, &mut mcols);
|
||||
|
||||
game_win = frontend::game_window(mlines as u32, mcols as u32, vmargin, hmargin);
|
||||
let mut snake = Snake::new(Cell::new(
|
||||
mlines as u32 / 2 - vmargin,
|
||||
mcols as u32 / 2 - hmargin,
|
||||
backend::CellType::Snake,
|
||||
)); //Initialise snake in the middle of the screen
|
||||
let mut snake = Snake::new(
|
||||
Cell::new(
|
||||
mlines as u32 / 2 - vmargin,
|
||||
mcols as u32 / 2 - hmargin,
|
||||
backend::CellType::Snake,
|
||||
),
|
||||
config,
|
||||
); //Initialise snake in the middle of the screen
|
||||
let mut board = Board::new(mlines as u32 - vmargin * 2, mcols as u32 - hmargin * 2);
|
||||
nodelay(game_win, true);
|
||||
loop {
|
||||
@@ -46,15 +50,20 @@ pub fn start() {
|
||||
//112 is keycode for 'p'
|
||||
0 => (), //resume
|
||||
1 => {
|
||||
snake = Snake::new(Cell::new(
|
||||
mlines as u32 / 2,
|
||||
mcols as u32 / 2,
|
||||
backend::CellType::Snake,
|
||||
)); //Initialise snake in the middle of the screen
|
||||
board = Board::new(mlines as u32 - vmargin * 2, mcols as u32 - hmargin * 2);
|
||||
} //restart
|
||||
snake = Snake::new(
|
||||
Cell::new(
|
||||
mlines as u32 / 2 - vmargin,
|
||||
mcols as u32 / 2 - hmargin,
|
||||
backend::CellType::Snake,
|
||||
),
|
||||
config,
|
||||
); //Initialise snake in the middle of the screen
|
||||
|
||||
board = Board::new(mlines as u32 - vmargin * 2, mcols as u32 - hmargin * 2); //restart
|
||||
frontend::clear_window(game_win);
|
||||
}
|
||||
2 => break, //exit
|
||||
_ => (), //other charachters just in case
|
||||
_ => (), //other charachters just in case
|
||||
}
|
||||
wrefresh(game_win);
|
||||
nodelay(game_win, true);
|
||||
|
||||
+4
-1
@@ -2,6 +2,7 @@ extern crate ncurses;
|
||||
mod game;
|
||||
mod highscore;
|
||||
mod menu;
|
||||
mod settings;
|
||||
// use game::{Cell, Snake};
|
||||
// use ncurses::*;
|
||||
use ncurses::{
|
||||
@@ -12,6 +13,7 @@ use ncurses::{
|
||||
fn main() {
|
||||
// let (lines, cols): (i32, i32) = (0, 0);
|
||||
setlocale(LcCategory::all, "");
|
||||
let config = settings::Config::new().unwrap();
|
||||
initscr();
|
||||
raw();
|
||||
keypad(stdscr(), true);
|
||||
@@ -27,11 +29,12 @@ fn main() {
|
||||
}
|
||||
loop {
|
||||
match menu::main_menu_control() {
|
||||
0 => game::start(),
|
||||
0 => game::start(&config),
|
||||
1 => highscore::show(),
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
endwin();
|
||||
config.write();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
extern crate dirs;
|
||||
extern crate serde;
|
||||
// extern crate serde_derive;
|
||||
extern crate toml;
|
||||
use serde::{Deserialize, Serialize};
|
||||
// use serde_derive::{Deserialize, Serialize};
|
||||
use crate::game::Difficulty;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::thread::sleep;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub difficulty: Difficulty,
|
||||
pub speed: u32,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Result<Self, std::io::Error> {
|
||||
let config_path = Config::config_path().unwrap();
|
||||
if config_path.exists() {
|
||||
let mut config_file = File::open(config_path).unwrap();
|
||||
let mut config_file_str: String = String::new();
|
||||
config_file.read_to_string(&mut config_file_str).unwrap();
|
||||
// let config: Config = toml::from_str(&config_file_str).expect("Error in config file");
|
||||
let config: Config = match toml::from_str(&config_file_str) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Error in parsing config file {} due to {}",
|
||||
Config::config_path().unwrap().to_str().unwrap(),
|
||||
e,
|
||||
);
|
||||
eprintln!("Falling back to using the default values");
|
||||
sleep(std::time::Duration::from_millis(3000));
|
||||
Config::default()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(config)
|
||||
} else {
|
||||
Ok(Config::default())
|
||||
}
|
||||
}
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
difficulty: Difficulty::Flat, //Default set to ten blocks per second
|
||||
speed: 10,
|
||||
}
|
||||
}
|
||||
pub fn write(&self) {
|
||||
let config_file_str: String = toml::to_string(self).unwrap();
|
||||
let config_path = Config::config_path().unwrap();
|
||||
let mut config_file: File =
|
||||
File::create(config_path).expect("Couldn't open config file to write");
|
||||
config_file
|
||||
.write_all(config_file_str.as_bytes())
|
||||
.expect("Couldn't write to file");
|
||||
}
|
||||
fn config_path() -> Result<PathBuf, std::io::Error> {
|
||||
let config_path: PathBuf = match dirs::config_dir() {
|
||||
Some(mut path) => {
|
||||
path.push("snake");
|
||||
path.push("snake.toml");
|
||||
path
|
||||
}
|
||||
None => {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"snake.toml not found",
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok(config_path)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
mod backend;
|
||||
pub use backend::Config;
|
||||
Reference in New Issue
Block a user