Refactor Direction and Position.
This commit is contained in:
parent
2bdfd8cc6c
commit
9751764611
6 changed files with 206 additions and 220 deletions
|
|
@ -1,58 +0,0 @@
|
|||
use factorio_blueprint::belt_finding::{brute_force::BruteforceBuilder, Direction, Position};
|
||||
|
||||
fn main() {
|
||||
let mut b = BruteforceBuilder::new(14, 6);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 0), Direction::Right),
|
||||
(Position::new(13, 0), Direction::Right),
|
||||
);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 1), Direction::Right),
|
||||
(Position::new(13, 1), Direction::Right),
|
||||
);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 2), Direction::Right),
|
||||
(Position::new(13, 2), Direction::Right),
|
||||
);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 3), Direction::Right),
|
||||
(Position::new(13, 3), Direction::Right),
|
||||
);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 4), Direction::Right),
|
||||
(Position::new(13, 4), Direction::Right),
|
||||
);
|
||||
|
||||
b.add_path(
|
||||
(Position::new(0, 5), Direction::Right),
|
||||
(Position::new(13, 5), Direction::Right),
|
||||
);
|
||||
|
||||
// b.set_blocked_range(7, 2, 10, 2, true);
|
||||
// b.set_blocked_range(7, 3, 10, 4, true);
|
||||
|
||||
b.set_blocked_range(3, 2, 10, 3, true);
|
||||
b.set_blocked(2, 0, true);
|
||||
b.set_blocked(11, 0, true);
|
||||
b.set_blocked(2, 5, true);
|
||||
b.set_blocked(11, 5, true);
|
||||
|
||||
let mut b = b.build();
|
||||
|
||||
println!("{}\n{}\n{}", b.count(), b.solution_count(), b);
|
||||
while b.next_finish_state() {
|
||||
println!("{}\n{}\n{}", b.count(), b.solution_count(), b);
|
||||
}
|
||||
println!("{}\n{}", b.count(), b.solution_count());
|
||||
|
||||
// println!("{}\n{}", b.count(), b);
|
||||
|
||||
// while b.next_state() {
|
||||
// println!("{}\n{}", b.count(), b);
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use factorio_blueprint::belt_finding::{Position, Problem};
|
||||
use factorio_blueprint::belt_finding::{common::Position, Problem};
|
||||
|
||||
fn main() {
|
||||
let mut p = Problem::new(17, 13);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use factorio_blueprint::belt_finding::{Position, Problem};
|
||||
use factorio_blueprint::belt_finding::{common::Position, Problem};
|
||||
|
||||
fn main() {
|
||||
let mut p = Problem::new(33, 13);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ use colored::Colorize;
|
|||
|
||||
use crate::misc::Map;
|
||||
|
||||
use super::{Direction, Position, COLORS};
|
||||
use super::{
|
||||
common::{Dimension, Direction, PathField},
|
||||
Position, COLORS,
|
||||
};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct BruteforceField {
|
||||
|
|
@ -13,43 +16,6 @@ pub struct BruteforceField {
|
|||
underground_horizontal: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum PathField {
|
||||
Belt {
|
||||
pos: Position,
|
||||
dir: Direction,
|
||||
},
|
||||
Underground {
|
||||
pos: Position,
|
||||
dir: Direction,
|
||||
len: u8,
|
||||
},
|
||||
}
|
||||
|
||||
impl PathField {
|
||||
fn pos(&self) -> &Position {
|
||||
match self {
|
||||
PathField::Belt { pos, dir: _ } => pos,
|
||||
PathField::Underground {
|
||||
pos,
|
||||
dir: _,
|
||||
len: _,
|
||||
} => pos,
|
||||
}
|
||||
}
|
||||
|
||||
fn dir(&self) -> &Direction {
|
||||
match self {
|
||||
PathField::Belt { pos: _, dir } => dir,
|
||||
PathField::Underground {
|
||||
pos: _,
|
||||
dir,
|
||||
len: _,
|
||||
} => dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MAX_UNDERGROUND_LENGTH: u8 = 6;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -83,12 +49,18 @@ impl BruteforceBuilder {
|
|||
}
|
||||
|
||||
pub fn build(self) -> Bruteforce {
|
||||
let dimension = Dimension {
|
||||
width: self.map.width,
|
||||
height: self.map.height,
|
||||
};
|
||||
|
||||
let mut b = Bruteforce {
|
||||
map: self.map,
|
||||
problems: Vec::new(),
|
||||
pointer_stack: vec![0],
|
||||
solution_count: 0,
|
||||
count: 0,
|
||||
dimension,
|
||||
};
|
||||
|
||||
for [start, end] in self.path {
|
||||
|
|
@ -120,6 +92,7 @@ struct Problem {
|
|||
#[derive(Clone)]
|
||||
pub struct Bruteforce {
|
||||
map: Map<BruteforceField>,
|
||||
dimension: Dimension,
|
||||
problems: Vec<Problem>,
|
||||
pointer_stack: Vec<usize>,
|
||||
solution_count: u128,
|
||||
|
|
@ -145,7 +118,7 @@ impl Bruteforce {
|
|||
self.map.get_mut(pos.x, pos.y).blocked = true;
|
||||
|
||||
for i in 0..=*len {
|
||||
let mid_pos = self.pos_in_direction(pos, dir, i.into()).unwrap();
|
||||
let mid_pos = pos.in_direction(dir, i.into(), &self.dimension).unwrap();
|
||||
if dir.vertical() {
|
||||
self.map.get_mut(mid_pos.x, mid_pos.y).underground_vertical = true;
|
||||
} else {
|
||||
|
|
@ -155,7 +128,7 @@ impl Bruteforce {
|
|||
}
|
||||
}
|
||||
|
||||
let end_pos = self.pos_in_direction(pos, dir, *len as usize).unwrap();
|
||||
let end_pos = { pos.in_direction(dir, *len as usize, &self.dimension) }.unwrap();
|
||||
self.map.get_mut(end_pos.x, end_pos.y).blocked = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -169,7 +142,7 @@ impl Bruteforce {
|
|||
self.map.get_mut(pos.x, pos.y).blocked = false;
|
||||
|
||||
for i in 0..=len {
|
||||
let mid_pos = self.pos_in_direction(&pos, &dir, i.into()).unwrap();
|
||||
let mid_pos = pos.in_direction(&dir, i.into(), &self.dimension).unwrap();
|
||||
if dir.vertical() {
|
||||
self.map.get_mut(mid_pos.x, mid_pos.y).underground_vertical = false;
|
||||
} else {
|
||||
|
|
@ -179,7 +152,7 @@ impl Bruteforce {
|
|||
}
|
||||
}
|
||||
|
||||
let end_pos = self.pos_in_direction(&pos, &dir, len.into()).unwrap();
|
||||
let end_pos = pos.in_direction(&dir, len.into(), &self.dimension).unwrap();
|
||||
self.map.get_mut(end_pos.x, end_pos.y).blocked = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -226,12 +199,14 @@ impl Bruteforce {
|
|||
match (last, &path_field) {
|
||||
(PathField::Belt { pos: _, dir: _ }, PathField::Belt { pos: _, dir: _ }) => {}
|
||||
(PathField::Belt { pos: _, dir: _ }, PathField::Underground { pos, dir, len }) => {
|
||||
let end_pos = self.pos_in_direction(pos, dir, *len as usize).unwrap();
|
||||
let end_pos = pos
|
||||
.in_direction(dir, *len as usize, &self.dimension)
|
||||
.unwrap();
|
||||
|
||||
self.map.get_mut(end_pos.x, end_pos.y).blocked = true;
|
||||
|
||||
for l in 0..=*len {
|
||||
let p = self.pos_in_direction(pos, dir, l as usize).unwrap();
|
||||
let p = pos.in_direction(dir, l as usize, &self.dimension).unwrap();
|
||||
match dir.vertical() {
|
||||
true => self.map.get_mut(p.x, p.y).underground_vertical = true,
|
||||
false => self.map.get_mut(p.x, p.y).underground_horizontal = true,
|
||||
|
|
@ -260,11 +235,11 @@ impl Bruteforce {
|
|||
len: new_len,
|
||||
},
|
||||
) => {
|
||||
let last_end_pos = self
|
||||
.pos_in_direction(&pos, &dir, last_len as usize)
|
||||
let last_end_pos = pos
|
||||
.in_direction(&dir, last_len as usize, &self.dimension)
|
||||
.unwrap();
|
||||
let new_end_pos = self
|
||||
.pos_in_direction(&pos, &dir, *new_len as usize)
|
||||
let new_end_pos = pos
|
||||
.in_direction(&dir, *new_len as usize, &self.dimension)
|
||||
.unwrap();
|
||||
|
||||
self.map.get_mut(last_end_pos.x, last_end_pos.y).blocked = false;
|
||||
|
|
@ -273,7 +248,7 @@ impl Bruteforce {
|
|||
match last_len < *new_len {
|
||||
true => {
|
||||
for l in last_len + 1..=*new_len {
|
||||
let p = self.pos_in_direction(&pos, &dir, l as usize).unwrap();
|
||||
let p = pos.in_direction(&dir, l as usize, &self.dimension).unwrap();
|
||||
match dir.vertical() {
|
||||
true => self.map.get_mut(p.x, p.y).underground_vertical = true,
|
||||
false => self.map.get_mut(p.x, p.y).underground_horizontal = true,
|
||||
|
|
@ -293,14 +268,14 @@ impl Bruteforce {
|
|||
|
||||
fn check_finish(&self, i: usize) -> bool {
|
||||
match self.problems[i].path.last().unwrap() {
|
||||
PathField::Belt { pos, dir } => self
|
||||
.pos_in_direction(pos, dir, 1)
|
||||
PathField::Belt { pos, dir } => pos
|
||||
.in_direction(dir, 1, &self.dimension)
|
||||
.filter(|p| {
|
||||
p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse()
|
||||
})
|
||||
.is_some(),
|
||||
PathField::Underground { pos, dir, len } => self
|
||||
.pos_in_direction(pos, dir, *len as usize + 1)
|
||||
PathField::Underground { pos, dir, len } => pos
|
||||
.in_direction(dir, *len as usize + 1, &self.dimension)
|
||||
.filter(|p| {
|
||||
p == &self.problems[i].end_pos && dir != &self.problems[i].end_dir.reverse()
|
||||
})
|
||||
|
|
@ -308,16 +283,6 @@ impl Bruteforce {
|
|||
}
|
||||
}
|
||||
|
||||
fn path_field_end(&self, path_field: &PathField) -> (Position, Direction) {
|
||||
match path_field {
|
||||
PathField::Belt { pos, dir } => (*pos, *dir),
|
||||
PathField::Underground { pos, dir, len } => (
|
||||
self.pos_in_direction(pos, dir, *len as usize).unwrap(),
|
||||
*dir,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn modify_underground(&mut self, pos: &Position, dir: &Direction, len: u8) -> bool {
|
||||
if len >= MAX_UNDERGROUND_LENGTH {
|
||||
return false;
|
||||
|
|
@ -332,7 +297,7 @@ impl Bruteforce {
|
|||
return false;
|
||||
}
|
||||
|
||||
let end_pos = match self.pos_in_direction(pos, dir, len as usize) {
|
||||
let end_pos = match pos.in_direction(dir, len as usize, &self.dimension) {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return false;
|
||||
|
|
@ -430,7 +395,13 @@ impl Bruteforce {
|
|||
if second_last.dir().counter_clockwise() == dir
|
||||
&& self.modify_underground(&pos, second_last.dir(), 2)
|
||||
{
|
||||
let (p, d) = self.path_field_end(self.modify_path().last().unwrap());
|
||||
let (p, d) = self
|
||||
.modify_path()
|
||||
.last()
|
||||
.unwrap()
|
||||
.end_pos(&self.dimension)
|
||||
.unwrap();
|
||||
|
||||
if self.is_next_free(&p, &d) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -440,7 +411,13 @@ impl Bruteforce {
|
|||
}
|
||||
PathField::Underground { pos, dir, len } => {
|
||||
if self.modify_underground(&pos, &dir, len + 1) {
|
||||
let (p, d) = self.path_field_end(self.modify_path().last().unwrap());
|
||||
let (p, d) = self
|
||||
.modify_path()
|
||||
.last()
|
||||
.unwrap()
|
||||
.end_pos(&self.dimension)
|
||||
.unwrap();
|
||||
|
||||
if self.is_next_free(&p, &d) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -472,16 +449,21 @@ impl Bruteforce {
|
|||
|
||||
fn is_next_free(&self, pos: &Position, dir: &Direction) -> bool {
|
||||
let i = self.modify_pointer();
|
||||
self.pos_in_direction(pos, dir, 1)
|
||||
{ pos.in_direction(dir, 1, &self.dimension) }
|
||||
.filter(|p| !self.map.get(p.x, p.y).blocked || self.problems[i].end_pos == *p)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
// Add an Path elemeent
|
||||
fn add(&mut self) -> bool {
|
||||
let (pos, dir) = self.path_field_end(self.add_path().last().unwrap());
|
||||
let (pos, dir) = self
|
||||
.add_path()
|
||||
.last()
|
||||
.unwrap()
|
||||
.end_pos(&self.dimension)
|
||||
.unwrap();
|
||||
|
||||
if let Some(p) = self.pos_in_direction(&pos, &dir, 1) {
|
||||
if let Some(p) = pos.in_direction(&dir, 1, &self.dimension) {
|
||||
if !self.map.get(p.x, p.y).blocked {
|
||||
self.apply_path_field(PathField::Belt { pos: p, dir });
|
||||
return self.is_next_free(&p, &dir);
|
||||
|
|
@ -535,19 +517,6 @@ impl Bruteforce {
|
|||
.sum()
|
||||
}
|
||||
|
||||
fn pos_in_direction(&self, pos: &Position, dir: &Direction, len: usize) -> Option<Position> {
|
||||
match dir {
|
||||
Direction::Up => pos.y.checked_sub(len).map(|y| Position::new(pos.x, y)),
|
||||
Direction::Right => Some(pos.x + len)
|
||||
.filter(|&x| x < self.map.width)
|
||||
.map(|x| Position::new(x, pos.y)),
|
||||
Direction::Down => Some(pos.y + len)
|
||||
.filter(|&y| y < self.map.height)
|
||||
.map(|y| Position::new(pos.x, y)),
|
||||
Direction::Left => pos.x.checked_sub(len).map(|x| Position::new(x, pos.y)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn count(&self) -> u128 {
|
||||
self.count
|
||||
}
|
||||
|
|
@ -605,7 +574,9 @@ impl Display for Bruteforce {
|
|||
Direction::Down => m.set(pos.x, pos.y, Some((i, "↡"))),
|
||||
Direction::Left => m.set(pos.x, pos.y, Some((i, "↞"))),
|
||||
};
|
||||
let end_pos = self.pos_in_direction(pos, dir, *len as usize).unwrap();
|
||||
let end_pos = pos
|
||||
.in_direction(dir, *len as usize, &self.dimension)
|
||||
.unwrap();
|
||||
match dir {
|
||||
Direction::Up => m.set(end_pos.x, end_pos.y, Some((i, "↥"))),
|
||||
Direction::Right => m.set(end_pos.x, end_pos.y, Some((i, "↦"))),
|
||||
|
|
|
|||
146
src/belt_finding/common.rs
Normal file
146
src/belt_finding/common.rs
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
Left,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn from_neghbors(pos: &Position, neighbor: &Position) -> Self {
|
||||
let x_diff = pos.x as i64 - neighbor.x as i64;
|
||||
let y_diff = pos.y as i64 - neighbor.y as i64;
|
||||
|
||||
match (x_diff, y_diff) {
|
||||
(1, 0) => Direction::Left,
|
||||
(0, 1) => Direction::Up,
|
||||
(-1, 0) => Direction::Right,
|
||||
(0, -1) => Direction::Down,
|
||||
_ => {
|
||||
panic!("Positions are not neighbors.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertical(&self) -> bool {
|
||||
match self {
|
||||
Direction::Up => true,
|
||||
Direction::Right => false,
|
||||
Direction::Down => true,
|
||||
Direction::Left => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn horizontal(&self) -> bool {
|
||||
!self.vertical()
|
||||
}
|
||||
|
||||
pub fn reverse(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Down,
|
||||
Direction::Right => Direction::Left,
|
||||
Direction::Down => Direction::Up,
|
||||
Direction::Left => Direction::Right,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clockwise(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Right,
|
||||
Direction::Right => Direction::Down,
|
||||
Direction::Down => Direction::Left,
|
||||
Direction::Left => Direction::Up,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn counter_clockwise(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Left,
|
||||
Direction::Right => Direction::Up,
|
||||
Direction::Down => Direction::Right,
|
||||
Direction::Left => Direction::Down,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Position {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Dimension {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
}
|
||||
|
||||
impl Position {
|
||||
pub fn new(x: usize, y: usize) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
|
||||
pub fn in_direction(
|
||||
&self,
|
||||
dir: &Direction,
|
||||
len: usize,
|
||||
dimension: &Dimension,
|
||||
) -> Option<Position> {
|
||||
match dir {
|
||||
Direction::Up => self.y.checked_sub(len).map(|y| Position::new(self.x, y)),
|
||||
Direction::Right => Some(self.x + len)
|
||||
.filter(|&x| x < dimension.width)
|
||||
.map(|x| Position::new(x, self.y)),
|
||||
Direction::Down => Some(self.y + len)
|
||||
.filter(|&y| y < dimension.height)
|
||||
.map(|y| Position::new(self.x, y)),
|
||||
Direction::Left => self.x.checked_sub(len).map(|x| Position::new(x, self.y)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum PathField {
|
||||
Belt {
|
||||
pos: Position,
|
||||
dir: Direction,
|
||||
},
|
||||
Underground {
|
||||
pos: Position,
|
||||
dir: Direction,
|
||||
len: u8,
|
||||
},
|
||||
}
|
||||
|
||||
impl PathField {
|
||||
pub fn pos(&self) -> &Position {
|
||||
match self {
|
||||
PathField::Belt { pos, dir: _ } => pos,
|
||||
PathField::Underground {
|
||||
pos,
|
||||
dir: _,
|
||||
len: _,
|
||||
} => pos,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dir(&self) -> &Direction {
|
||||
match self {
|
||||
PathField::Belt { pos: _, dir } => dir,
|
||||
PathField::Underground {
|
||||
pos: _,
|
||||
dir,
|
||||
len: _,
|
||||
} => dir,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_pos(&self, dimension: &Dimension) -> Option<(Position, Direction)> {
|
||||
match self {
|
||||
PathField::Belt { pos, dir } => Some((*pos, *dir)),
|
||||
PathField::Underground { pos, dir, len } => pos
|
||||
.in_direction(dir, *len as usize, dimension)
|
||||
.map(|p| (p, *dir)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::belt_finding::brute_force::BruteforceBuilder;
|
||||
use crate::belt_finding::{brute_force::BruteforceBuilder, common::Direction};
|
||||
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
||||
use crate::graph::wheighted_graph::WheightedGraph;
|
||||
use crate::misc::Map;
|
||||
|
|
@ -6,83 +6,10 @@ use crate::priority_queue::BinaryHeap;
|
|||
use colored::{Color, Colorize};
|
||||
use std::fmt::Display;
|
||||
|
||||
use self::common::Position;
|
||||
|
||||
pub mod brute_force;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
Left,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
fn from_neghbors(pos: &Position, neighbor: &Position) -> Self {
|
||||
let x_diff = pos.x as i64 - neighbor.x as i64;
|
||||
let y_diff = pos.y as i64 - neighbor.y as i64;
|
||||
|
||||
match (x_diff, y_diff) {
|
||||
(1, 0) => Direction::Left,
|
||||
(0, 1) => Direction::Up,
|
||||
(-1, 0) => Direction::Right,
|
||||
(0, -1) => Direction::Down,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn vertical(&self) -> bool {
|
||||
match self {
|
||||
Direction::Up => true,
|
||||
Direction::Right => false,
|
||||
Direction::Down => true,
|
||||
Direction::Left => false,
|
||||
}
|
||||
}
|
||||
|
||||
// fn horizontal(&self) -> bool {
|
||||
// !self.vertical()
|
||||
// }
|
||||
|
||||
fn reverse(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Down,
|
||||
Direction::Right => Direction::Left,
|
||||
Direction::Down => Direction::Up,
|
||||
Direction::Left => Direction::Right,
|
||||
}
|
||||
}
|
||||
|
||||
fn clockwise(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Right,
|
||||
Direction::Right => Direction::Down,
|
||||
Direction::Down => Direction::Left,
|
||||
Direction::Left => Direction::Up,
|
||||
}
|
||||
}
|
||||
|
||||
fn counter_clockwise(&self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Left,
|
||||
Direction::Right => Direction::Up,
|
||||
Direction::Down => Direction::Right,
|
||||
Direction::Left => Direction::Down,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Position {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
}
|
||||
impl Position {
|
||||
pub fn new(x: usize, y: usize) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
}
|
||||
pub mod common;
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct Field {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue