WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 621d78b

Browse files
committed
.
1 parent 42f5b68 commit 621d78b

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
use crate::grid::Point;
2+
3+
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
4+
pub enum Direction {
5+
Left = 0,
6+
Right = 1,
7+
Up = 2,
8+
Down = 3,
9+
}
10+
11+
fn get_direction_vector(dir: Direction) -> Point {
12+
match dir {
13+
Direction::Down => Point { x: 0, y: -1 },
14+
Direction::Up => Point { x: 0, y: 1 },
15+
Direction::Left => Point { x: -1, y: 0 },
16+
Direction::Right => Point { x: 1, y: 0 },
17+
}
18+
}
19+
fn get_direction_from_vector(v: &Point) -> Direction {
20+
match v {
21+
Point { x: 0, y: -1 } => Direction::Down,
22+
Point { x: 0, y: 1 } => Direction::Up,
23+
Point { x: -1, y: 0 } => Direction::Left,
24+
Point { x: 1, y: 0 } => Direction::Right,
25+
_ => panic!(),
26+
}
27+
}
28+
29+
#[derive(Clone)]
30+
pub struct SnakeC {
31+
pub head: Point,
32+
pub body: Vec<Direction>,
33+
}
34+
impl SnakeC {
35+
pub fn get_cells(&self) -> Vec<Point> {
36+
let mut e = self.head.clone();
37+
let mut out = Vec::new();
38+
39+
out.push(e.clone());
40+
for dir in self.body.iter() {
41+
let v = get_direction_vector(*dir);
42+
e.x -= v.x;
43+
e.y -= v.y;
44+
out.push(e.clone());
45+
}
46+
47+
out
48+
}
49+
50+
pub fn is_head_self_colliding(&self) -> bool {
51+
self.get_cells()[1..].contains(&self.head)
52+
}
53+
54+
pub fn advance(&mut self, dir: Direction) -> () {
55+
let v = get_direction_vector(dir);
56+
57+
self.head.x += v.x;
58+
self.head.y += v.y;
59+
60+
self.body.pop();
61+
self.body.insert(0, dir);
62+
}
63+
}
64+
65+
impl From<Vec<Point>> for SnakeC {
66+
fn from(value: Vec<Point>) -> Self {
67+
let head = value.get(0).unwrap().clone();
68+
let body = value
69+
.windows(2)
70+
.map(|w| {
71+
let v = Point {
72+
x: w[0].x - w[1].x,
73+
y: w[0].y - w[1].y,
74+
};
75+
get_direction_from_vector(&v)
76+
})
77+
.collect();
78+
79+
Self { head, body }
80+
}
81+
}
82+
83+
#[test]
84+
fn it_should_get_the_snake_cell() {
85+
let s = SnakeC {
86+
head: Point { x: 10, y: 5 },
87+
body: vec![Direction::Up, Direction::Up, Direction::Left],
88+
};
89+
90+
assert_eq!(
91+
s.get_cells(),
92+
vec![
93+
//
94+
Point { x: 10, y: 5 },
95+
Point { x: 10, y: 4 },
96+
Point { x: 10, y: 3 },
97+
Point { x: 11, y: 3 },
98+
]
99+
);
100+
}
101+
102+
#[test]
103+
fn it_should_get_snake_from_point_list() {
104+
let s = SnakeC::from(vec![
105+
//
106+
Point { x: 10, y: 5 },
107+
Point { x: 10, y: 4 },
108+
Point { x: 10, y: 3 },
109+
Point { x: 11, y: 3 },
110+
Point { x: 12, y: 3 },
111+
Point { x: 12, y: 2 },
112+
]);
113+
114+
assert_eq!(
115+
s.get_cells(),
116+
vec![
117+
//
118+
Point { x: 10, y: 5 },
119+
Point { x: 10, y: 4 },
120+
Point { x: 10, y: 3 },
121+
Point { x: 11, y: 3 },
122+
Point { x: 12, y: 3 },
123+
Point { x: 12, y: 2 },
124+
]
125+
);
126+
}
127+
128+
#[test]
129+
fn it_should_advance_snake() {
130+
let mut s = SnakeC::from(vec![
131+
//
132+
Point { x: 10, y: 3 },
133+
Point { x: 11, y: 3 },
134+
Point { x: 12, y: 3 },
135+
Point { x: 12, y: 2 },
136+
]);
137+
138+
s.advance(Direction::Up);
139+
140+
assert_eq!(
141+
s.get_cells(),
142+
vec![
143+
//
144+
Point { x: 10, y: 4 },
145+
Point { x: 10, y: 3 },
146+
Point { x: 11, y: 3 },
147+
Point { x: 12, y: 3 },
148+
]
149+
);
150+
}
151+
152+
#[test]
153+
fn it_should_detect_self_collision() {
154+
let mut s = SnakeC::from(vec![
155+
//
156+
Point { x: 0, y: 0 },
157+
Point { x: 0, y: 1 },
158+
Point { x: 0, y: 2 },
159+
Point { x: 0, y: 3 },
160+
Point { x: 0, y: 4 },
161+
Point { x: 0, y: 5 },
162+
Point { x: 0, y: 6 },
163+
]);
164+
165+
assert_eq!(s.is_head_self_colliding(), false);
166+
167+
s.advance(Direction::Right);
168+
s.advance(Direction::Up);
169+
s.advance(Direction::Up);
170+
171+
assert_eq!(s.is_head_self_colliding(), false);
172+
173+
s.advance(Direction::Left);
174+
175+
assert_eq!(s.is_head_self_colliding(), true);
176+
}

0 commit comments

Comments
 (0)