1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::collections::LinkedList;
use opengl_graphics::GlGraphics;
use piston::input::RenderArgs;
pub struct Snake {
pub gl: GlGraphics,
pub snake_parts: LinkedList<SnakePiece>,
pub width: u32,
pub d: Direction,
}
#[derive(Clone, PartialEq)]
pub enum Direction {
UP,
DOWN,
LEFT,
RIGHT,
}
#[derive(Clone)]
pub struct SnakePiece(pub u32, pub u32);
impl Snake {
pub fn render(&mut self, args: &RenderArgs) {
const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
const YELLOW: [f32; 4] = [1.0, 0.94, 0.0, 1.0];
let squares: Vec<graphics::types::Rectangle> = self
.snake_parts
.iter()
.map(|p| SnakePiece(p.0 * self.width, p.1 * self.width))
.map(|p| {
graphics::rectangle::square(
(p.0) as f64 + 2.5,
(p.1) as f64 + 2.5,
(self.width - 5) as f64,
)
})
.collect();
self.gl.draw(args.viewport(), |c, gl| {
let transform = c.transform;
for i in 0..squares.len() {
graphics::rectangle(
if i % 2 == 0 { WHITE } else { YELLOW },
squares[i],
transform,
gl,
);
}
})
}
pub fn update(&mut self, just_eaten: bool, cols: u32, rows: u32) -> bool {
let mut new_front: SnakePiece =
(*self.snake_parts.front().expect("No front of snake found.")).clone();
if (self.d == Direction::UP && new_front.1 == 0)
|| (self.d == Direction::LEFT && new_front.0 == 0)
|| (self.d == Direction::DOWN && new_front.1 == rows - 1)
|| (self.d == Direction::RIGHT && new_front.0 == cols - 1)
{
return false;
}
match self.d {
Direction::UP => new_front.1 -= 1,
Direction::DOWN => new_front.1 += 1,
Direction::LEFT => new_front.0 -= 1,
Direction::RIGHT => new_front.0 += 1,
}
if !just_eaten {
self.snake_parts.pop_back();
}
if self.is_collide(new_front.0, new_front.1) {
return false;
}
self.snake_parts.push_front(new_front);
true
}
pub fn is_collide(&self, x: u32, y: u32) -> bool {
self.snake_parts.iter().any(|p| x == p.0 && y == p.1)
}
}