|
@@ -46,7 +46,6 @@ impl Coord {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* Flip coordinate at the y-axis
|
|
|
*/
|
|
@@ -58,23 +57,8 @@ impl Coord {
|
|
|
self.a + self.b + self.c == 2
|
|
|
}
|
|
|
|
|
|
- fn right_neighbor(self) -> Coord {
|
|
|
- if self.upright() {
|
|
|
- return Coord::from(self.a, self.b, self.c - 1);
|
|
|
- } else {
|
|
|
- return Coord::from(self.a + 1, self.b, self.c);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
pub fn to_cartesian(&self) -> (i8, i8) {
|
|
|
(self.a - self.c + 1, 1 - self.b)
|
|
|
- //let y : i8 = 1 - self.b;
|
|
|
- //let x_offset : i8 = (self.b - 1).abs() / 2;
|
|
|
- //let x : i8 = 2 * (self.a - x_offset) + if self.upright() { y % 2 } else { 1 - (y % 2) };
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //return (x, y);
|
|
|
}
|
|
|
|
|
|
pub fn translate_x(&self, x: i8) -> Coord {
|
|
@@ -82,32 +66,14 @@ impl Coord {
|
|
|
}
|
|
|
|
|
|
pub fn translate_y(&self, y: i8, origin_upright: bool) -> Coord {
|
|
|
- //let m = Coord::from_ab(self.a + y, self.b - 2 * y, self.upright());
|
|
|
- //let k = Coord::from(self.a + y, self.b - 2 * y, self.c + y);
|
|
|
-
|
|
|
- //assert_eq!(m,k);
|
|
|
- //k
|
|
|
if origin_upright {
|
|
|
Coord::from_ab(self.a + (y + 1) / 2, self.b - y, self.upright())
|
|
|
} else {
|
|
|
Coord::from_ab(self.a + y / 2, self.b - y, self.upright())
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- //pub fn translate_hy(&self, y: i8) -> Coord {
|
|
|
- // let t = self.translate_y(y / 2);
|
|
|
- // if y % 2 == 0 {
|
|
|
- // t
|
|
|
- // } else {
|
|
|
- // Coord {
|
|
|
- // a: self.a,
|
|
|
- // b: self.b - 1,
|
|
|
- // c: self.c + 1,
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
- //}
|
|
|
}
|
|
|
+
|
|
|
impl std::ops::Add<Coord> for Coord {
|
|
|
type Output = Coord;
|
|
|
|
|
@@ -222,7 +188,6 @@ where F: FnMut(i8, i8) -> bool
|
|
|
|
|
|
|
|
|
let origin_upright = (x + y) % 2 == 0;
|
|
|
- //println!("origin_upright: {}", origin_upright);
|
|
|
if !origin_upright {
|
|
|
coord = coord.rotate60();
|
|
|
}
|
|
@@ -257,12 +222,12 @@ where F: FnMut(i8, i8) -> bool
|
|
|
*/
|
|
|
pub fn check_part(map: &Map, part: &Part, x: i8, y: i8, rotations: u8, flipped: bool) -> bool {
|
|
|
/* Make sure the start triangle can actually be placed */
|
|
|
- assert!(in_bound(x, y));
|
|
|
+ debug_assert!(in_bound(x, y));
|
|
|
|
|
|
//println!("Testing {},{},{},{}", x, y, rotation.to_int(), flipped);
|
|
|
- let success = for_each_triangle(part, x, y, rotations, flipped, |x, y| {
|
|
|
+ for_each_triangle(part, x, y, rotations, flipped, |x, y| {
|
|
|
if !in_bound(x,y) {
|
|
|
- return true; // TODO: switch this to false as opt
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
let prev = map[y as usize][x as usize];
|
|
@@ -270,16 +235,9 @@ pub fn check_part(map: &Map, part: &Part, x: i8, y: i8, rotations: u8, flipped:
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- //println!("Check for {},{} passed", x, y);
|
|
|
|
|
|
return true;
|
|
|
- });
|
|
|
- if success == true {
|
|
|
- //println!("Accepted.");
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
///* Once we have found a valid position with `check_part`, we can place the part on the map.
|
|
@@ -288,16 +246,8 @@ pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: i8, y: i8, rotation
|
|
|
//println!("Placing {},{},{},{}", x, y, rotation.to_int(), flipped);
|
|
|
for_each_triangle(part, x, y, rotations, flipped, |x, y| {
|
|
|
if !in_bound(x,y) {
|
|
|
- return true
|
|
|
+ return false;
|
|
|
}
|
|
|
- //println!("placing {},{}", x, y);
|
|
|
-
|
|
|
- //let prev = map[y as usize][x as usize];
|
|
|
- //if let Cell::Occupied(i) = prev {
|
|
|
- // assert_eq!(id, i);
|
|
|
- //} else {
|
|
|
- // assert!(prev.is_empty());
|
|
|
- //}
|
|
|
|
|
|
map[y as usize][x as usize] = Cell::Occupied(id);
|
|
|
|
|
@@ -305,11 +255,11 @@ pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: i8, y: i8, rotation
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-///* If a part is not placed right, we might need to remove it from the map again
|
|
|
-// */
|
|
|
+/* If a part is not placed right, we might need to remove it from the map again
|
|
|
+ */
|
|
|
fn erase_part(map: &mut Map, part: &Part, x: i8, y: i8, rotation: u8, flipped: bool) {
|
|
|
for_each_triangle(part, x, y, rotation, flipped, |x, y| {
|
|
|
- assert!(in_bound(x, y));
|
|
|
+ debug_assert!(in_bound(x, y));
|
|
|
|
|
|
map[y as usize][x as usize] = Cell::Empty;
|
|
|
true
|
|
@@ -322,7 +272,6 @@ pub fn solve(map: &mut Map, parts: &[(PartID, &Part)]) -> Option<()>{
|
|
|
}
|
|
|
|
|
|
let (id, part) = parts[0];
|
|
|
- //println!("{} parts remaining", parts.len());
|
|
|
|
|
|
// TODO: restrict to list of non-barrier position to tighten the for loops
|
|
|
for y in 0..MAP_HEIGHT {
|
|
@@ -333,20 +282,13 @@ pub fn solve(map: &mut Map, parts: &[(PartID, &Part)]) -> Option<()>{
|
|
|
|
|
|
for rotation in [0, 1, 2] {
|
|
|
for flipped in [false, true] {
|
|
|
- //println!("Testing rotation {} and flipped={}", rotation, flipped);
|
|
|
- //println!("x={},y={},r={},f={}", x, y,rotation,flipped);
|
|
|
let valid_position = check_part(&map, &part, x, y, rotation, flipped);
|
|
|
|
|
|
if valid_position {
|
|
|
// Place our part and try the others
|
|
|
- //println!("Placing");
|
|
|
place_part(map, id, &part, x, y, rotation, flipped);
|
|
|
- //print_map(&map);
|
|
|
+ print_map(&map);
|
|
|
|
|
|
- //println!("Erasing");
|
|
|
- //erase_part(map, &part, x, y, rotation, flipped);
|
|
|
-
|
|
|
- //println!("\n\n");
|
|
|
if let Some(()) = solve(map, &parts[1..]) {
|
|
|
// We have found a valid solution we can pass back!
|
|
|
return Some(());
|
|
@@ -385,7 +327,6 @@ fn switch_color_to_cell(cell: Cell) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//
|
|
|
// |O###O###O###
|
|
|
// OOO#OOO#OOO#
|
|
|
// ###O###O###O
|
|
@@ -452,8 +393,8 @@ mod test {
|
|
|
fn test_translation() {
|
|
|
assert_eq!(Coord::from(1,1,0), Coord::from(-1,1,2).translate_x(2));
|
|
|
assert_eq!(Coord::from(-1,0,3), Coord::from(2,0,0).translate_x(-3));
|
|
|
- assert_eq!(Coord::from(1,-1,2), Coord::from(-1,3,0).translate_y(2));
|
|
|
- assert_eq!(Coord::from(2,1,-1), Coord::from(3,-1,0).translate_y(-1));
|
|
|
+ assert_eq!(Coord::from(0,1,1), Coord::from(-1,3,0).translate_y(2, true));
|
|
|
+ assert_eq!(Coord::from(3,0,-1), Coord::from(3,-1,0).translate_y(-1, true));
|
|
|
|
|
|
}
|
|
|
}
|