Skip to content

Commit d1f7648

Browse files
committed
/
1 parent 1fea409 commit d1f7648

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2430
-0
lines changed

cargo/Cargo.lock

Lines changed: 413 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cargo/Cargo.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[workspace]
2+
resolver = "3"
3+
4+
members = [
5+
"snk-js",
6+
"snk-grid",
7+
# "snk-solver",
8+
# "snk-gif-creator"
9+
]
10+
11+
[workspace.package]
12+
version = "1.0.0"
13+
edition = "2024"
14+
authors = ["platane"]
15+
16+
[workspace.dependencies]
17+
snk-grid = { path = "snk-grid" }
18+
snk-solver = { path = "snk-solver" }

cargo/snk-grid/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "snk-grid"
3+
4+
version.workspace = true
5+
edition.workspace = true
6+
authors.workspace = true

cargo/snk-grid/src/direction.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use crate::point::{Point, add};
2+
3+
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
4+
#[repr(u8)]
5+
pub enum Direction {
6+
UP,
7+
DOWN,
8+
LEFT,
9+
RIGHT,
10+
}
11+
12+
pub const DIRECTIONS: [Direction; 4] = [
13+
Direction::UP,
14+
Direction::DOWN,
15+
Direction::LEFT,
16+
Direction::RIGHT,
17+
];
18+
19+
impl Direction {
20+
pub fn to_point(&self) -> Point {
21+
match self {
22+
Direction::UP => Point { x: 0, y: 1 },
23+
Direction::DOWN => Point { x: 0, y: -1 },
24+
Direction::LEFT => Point { x: -1, y: 0 },
25+
Direction::RIGHT => Point { x: 1, y: 0 },
26+
}
27+
}
28+
}
29+
30+
pub fn add_direction(a: Point, dir: Direction) -> Point {
31+
add(a, dir.to_point())
32+
}
33+
34+
pub fn iter_directions() -> impl Iterator<Item = Direction> {
35+
DIRECTIONS.iter().map(|dir| dir.clone())
36+
}
37+
38+
pub fn iter_neighbour(p: Point) -> impl Iterator<Item = Point> {
39+
iter_directions().map(move |dir| add_direction(p, dir))
40+
}
41+
42+
#[test]
43+
fn it_should_iter_direction() {
44+
let directions: Vec<_> = iter_directions().collect();
45+
46+
assert_eq!(
47+
directions,
48+
vec![
49+
Direction::UP,
50+
Direction::DOWN,
51+
Direction::LEFT,
52+
Direction::RIGHT,
53+
]
54+
);
55+
}
56+
57+
#[test]
58+
fn it_should_iter_direction_point() {
59+
let directions: Vec<_> = iter_directions().map(|d| d.to_point()).collect();
60+
61+
assert_eq!(
62+
directions,
63+
vec![
64+
Point { x: 0, y: 1 },
65+
Point { x: 0, y: -1 },
66+
Point { x: -1, y: 0 },
67+
Point { x: 1, y: 0 }
68+
]
69+
);
70+
}

cargo/snk-grid/src/grid.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
use crate::point::Point;
2+
3+
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
4+
#[repr(u8)]
5+
pub enum Color {
6+
Empty = 0,
7+
Color1 = 1,
8+
Color2 = 2,
9+
Color3 = 3,
10+
Color4 = 4,
11+
}
12+
impl Default for Color {
13+
fn default() -> Self {
14+
Color::Empty
15+
}
16+
}
17+
18+
pub fn iter_rectangle_fill(width: i8, height: i8) -> impl Iterator<Item = Point> {
19+
(0..height).flat_map(move |y| (0..width).map(move |x| Point { x, y }))
20+
}
21+
pub fn iter_rectangle_hull(width: i8, height: i8) -> impl Iterator<Item = Point> {
22+
(1..(width - 1))
23+
.map(|x| Point { x, y: 0 })
24+
.chain((1..(width - 1)).map(move |x| Point { x, y: height - 1 }))
25+
.chain((0..height).map(move |y| Point { x: 0, y }))
26+
.chain((0..height).map(move |y| Point { x: width - 1, y }))
27+
}
28+
29+
#[derive(Clone, Debug, PartialEq)]
30+
pub struct Grid<T: Copy> {
31+
pub width: u8,
32+
pub height: u8,
33+
pub cells: Vec<T>,
34+
}
35+
impl<T: Copy> Grid<T> {
36+
fn get_index(&self, x: i8, y: i8) -> usize {
37+
return (x as usize) * (self.height as usize) + (y as usize);
38+
}
39+
40+
pub fn fill(&mut self, value: T) -> () {
41+
self.cells.fill(value);
42+
}
43+
pub fn get(&self, p: Point) -> T {
44+
let i = self.get_index(p.x, p.y);
45+
return self.cells[i];
46+
}
47+
pub fn set(&mut self, p: Point, value: T) -> () {
48+
let i = self.get_index(p.x, p.y);
49+
self.cells[i] = value;
50+
}
51+
pub fn is_inside(&self, p: Point) -> bool {
52+
0 <= p.x && p.x < (self.width as i8) && 0 <= p.y && p.y < (self.height as i8)
53+
}
54+
pub fn is_inside_margin(&self, p: Point, m: i8) -> bool {
55+
-m <= p.x && p.x < (self.width as i8) + m && -m <= p.y && p.y < (self.height as i8) + m
56+
}
57+
58+
/// ⚠️ assuming the point is inside the grid
59+
pub fn distance_from_outside(&self, p: Point) -> u8 {
60+
let x = p.x as u8;
61+
let y = p.y as u8;
62+
y.min(self.height - 1 - y).min(x).min(self.width - 1 - x)
63+
}
64+
65+
pub fn create_with_value(width: u8, height: u8, value: T) -> Grid<T> {
66+
let n = (width as usize) * (height as usize);
67+
let cells = (0..n).map(|_| value).collect();
68+
69+
Grid {
70+
width,
71+
height,
72+
cells,
73+
}
74+
}
75+
}
76+
impl<T: Default + Copy> Grid<T> {
77+
pub fn create_with_default(width: u8, height: u8) -> Grid<T> {
78+
let n = (width as usize) * (height as usize);
79+
let cells = (0..n).map(|_| T::default()).collect();
80+
81+
Grid {
82+
width,
83+
height,
84+
cells,
85+
}
86+
}
87+
}
88+
89+
impl Grid<Color> {
90+
pub fn is_walkable(&self, walkable: Color, p: Point) -> bool {
91+
!self.is_inside(p) || self.get(p) <= walkable
92+
}
93+
}
94+
95+
#[test]
96+
fn it_should_sort_cell() {
97+
assert_eq!(Color::Empty < Color::Color1, true);
98+
assert_eq!(Color::Color1 < Color::Color2, true);
99+
assert_eq!(Color::Color2 < Color::Color3, true);
100+
assert_eq!(Color::Color3 < Color::Color4, true);
101+
}
102+
#[test]
103+
fn it_should_grid_create() {
104+
let grid = Grid::<Color>::create_with_default(30, 10);
105+
106+
assert_eq!(grid.width, 30);
107+
assert_eq!(grid.height, 10);
108+
assert_eq!(grid.get(Point { x: 2, y: 3 }), Color::Empty);
109+
}
110+
#[test]
111+
fn it_should_grid_setter() {
112+
let mut grid = Grid::<Color>::create_with_default(20, 10);
113+
114+
grid.set(Point { x: 12, y: 3 }, Color::Color1);
115+
116+
assert_eq!(grid.get(Point { x: 12, y: 3 }), Color::Color1);
117+
}
118+
#[test]
119+
fn it_should_iterate() {
120+
assert_eq!(
121+
iter_rectangle_fill(2, 2).collect::<std::collections::HashSet<_>>(),
122+
std::collections::HashSet::from([
123+
Point { x: 0, y: 0 },
124+
Point { x: 0, y: 1 },
125+
Point { x: 1, y: 0 },
126+
Point { x: 1, y: 1 },
127+
])
128+
);
129+
}
130+
131+
#[test]
132+
fn it_should_iterate_hull() {
133+
assert_eq!(
134+
iter_rectangle_hull(3, 3).collect::<std::collections::HashSet<_>>(),
135+
std::collections::HashSet::from([
136+
Point { x: 0, y: 0 },
137+
Point { x: 0, y: 1 },
138+
Point { x: 0, y: 2 },
139+
Point { x: 2, y: 0 },
140+
Point { x: 2, y: 1 },
141+
Point { x: 2, y: 2 },
142+
Point { y: 0, x: 0 },
143+
Point { y: 0, x: 1 },
144+
Point { y: 0, x: 2 },
145+
Point { y: 2, x: 0 },
146+
Point { y: 2, x: 1 },
147+
Point { y: 2, x: 2 },
148+
])
149+
);
150+
}

0 commit comments

Comments
 (0)