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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate;
/* MOVEMENT */
/// Moves the snake IN PLACE along the `direction` Vector.
/// This is also the function that makes the snake grow
/// by keeping the tail intact, whilst adding onto the head.
///
/// The typical usage of the grow ability would be
/// to check if the snake head is touching food,
/// and if so, you would grow the snake the next time
/// that it moves.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
/// use snake::types::CoordinateVector;
/// use snake::core::travel;
///
/// let mut snake = VecDeque::from(vec![CoordinateVector(0,1)]);
/// travel(&mut snake, CoordinateVector(0,1), false);
/// assert_eq!(&snake, &VecDeque::from(vec![CoordinateVector(0,2)]));
///
/// let mut snake = VecDeque::from(vec![CoordinateVector(0,1)]);
/// travel(&mut snake, CoordinateVector(0,1), true);
/// assert_eq!(&snake, &VecDeque::from(vec![CoordinateVector(0,1), CoordinateVector(0,2)]));
/// ```
/* CONDITIONS */
/// Checks if the head of the snake is touching `object`.
/// This is useful for collision detection with food or obstacles.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
/// use snake::types::CoordinateVector;
/// use snake::core::head_touching_object;
///
/// let snake = VecDeque::from(vec![CoordinateVector(5,5), CoordinateVector(5,6)]);
///
/// let object = CoordinateVector(5,6);
/// assert_eq!(head_touching_object(&snake, object), true);
///
/// let object = CoordinateVector(4,4);
/// assert_eq!(head_touching_object(&snake, object), false);
/// ```
/// Checks if the snakes head is touching itself.
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
/// use snake::types::CoordinateVector;
/// use snake::core::head_touching_self;
///
/// let snake = VecDeque::from(vec![
/// CoordinateVector(5,5), CoordinateVector(5,6),
/// CoordinateVector(6,6), CoordinateVector(6,5),
/// CoordinateVector(5,5)]);
///
/// assert_eq!(head_touching_self(&snake), true);
///
/// let snake = VecDeque::from(vec![CoordinateVector(5,5), CoordinateVector(5,6)]);
///
/// assert_eq!(head_touching_self(&snake), false);
/// ```
/// Checks if the snakes head is out of bounds.
///
/// These bounds are given in the form of a CoordinateVector,
/// and valid bounds are from 0 to the point given by `bounds` (exclusive)
///
/// # Examples
///
/// ```
/// use std::collections::VecDeque;
/// use snake::types::CoordinateVector;
/// use snake::core::head_out_of_bounds;
///
/// let snake = VecDeque::from(vec![CoordinateVector(14,0)]);
/// assert_eq!(head_out_of_bounds(&snake, CoordinateVector(15,15)), false);
///
/// let snake = VecDeque::from(vec![CoordinateVector(-1, 15)]);
/// // -1 is out of bounds because it's less than 0 (the implied lower bound),
/// // and 15 is out of bounds because it's greater than or equal to 15 (the explicit upper bound)
/// assert_eq!(head_out_of_bounds(&snake, CoordinateVector(15,15)), true);
/// ```