瀏覽代碼

Pre-refactor

Christoph Stelz 1 年之前
父節點
當前提交
741416d078
共有 2 個文件被更改,包括 149 次插入7 次删除
  1. 53 6
      src/lib.rs
  2. 96 1
      src/main.rs

+ 53 - 6
src/lib.rs

@@ -124,7 +124,6 @@ impl Edge {
         let shift_direction = if upright { -1 } else { 1 };
 
         let shifted = (self.to_int() + shift_direction * shift_amount).rem_euclid(3);
-        println!("Shifted: {}", shifted);
 
         Edge::from_int(shifted)
     }
@@ -136,6 +135,10 @@ pub fn generate_parts() -> HashMap<PartID, Part> {
         (1, vec![Edge::LEFT, Edge::LEFT, Edge::BOTTOMTOP, Edge::BOTTOMTOP, Edge::RIGHT, Edge::BOTTOMTOP, Edge::LEFT]),
         (2, vec![Edge::RIGHT, Edge::BOTTOMTOP, Edge::RIGHT, Edge::RIGHT, Edge::BOTTOMTOP]),
         (3, vec![Edge::RIGHT, Edge::BOTTOMTOP, Edge::LEFT, Edge::BOTTOMTOP, Edge::RIGHT]),
+        (4, vec![Edge::BOTTOMTOP, Edge::RIGHT, Edge::RIGHT, Edge::RIGHT, Edge::RIGHT]),
+        (5, vec![Edge::LEFT, Edge::BOTTOMTOP, Edge::LEFT, Edge::LEFT, Edge::LEFT]),
+        (6, vec![Edge::RIGHT, Edge::RIGHT, Edge::RIGHT, Edge::BOTTOMTOP, Edge::BOTTOMTOP, Edge::RIGHT]),
+        (7, vec![Edge::LEFT, Edge::LEFT, Edge::BOTTOMTOP, Edge::LEFT, Edge::RIGHT, Edge::RIGHT]),
     ])
 }
 
@@ -155,7 +158,7 @@ pub type MapIO = (MapSideIO, MapSideIO);
  * Each cell can be a Barrier (meaning no part may be placed on the cell), Empty (meaning at the
  * current time, it is not occupied by a part) or Occupied.
  */
-#[derive(Copy, Clone)]
+#[derive(PartialEq, Debug, Copy, Clone)]
 pub enum Cell {
     Barrier,
     Empty,
@@ -175,6 +178,17 @@ impl Cell {
     }
 }
 
+impl std::fmt::Display for Cell {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Cell::Barrier => write!(f, "B"),
+            Cell::Empty => write!(f, " "),
+            Cell::Occupied(id) => write!(f, "{}", id),
+        }
+    }
+
+}
+
 /*
  * A triangular grid looks like this:
  *       __  __
@@ -288,14 +302,13 @@ pub fn check_part(map: &Map, part: &Part, x: u8, y: u8, rotation: Edge) -> bool
             return false;
         }
     }
-    println!("");
 
     return true;
 }
 
 /* Once we have found a valid position with `check_part`, we can place the part on the map.
  */
-fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Edge) {
+pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Edge) {
     map[y as usize][x as usize] = Cell::Occupied(id);
 
     let mut mx : u8 = x;
@@ -304,6 +317,8 @@ fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Ed
     for movement in part {
         let rotated_movement = movement.rotate(&rotation, is_upright(x, y));
         (mx, my) = move_along_edge(mx, my, rotated_movement).unwrap();
+        let prev = map[my as usize][mx as usize];
+        assert!(prev == Cell::Empty || prev == Cell::Occupied(id));
         map[my as usize][mx as usize] = Cell::Occupied(id);
     }
 
@@ -333,7 +348,7 @@ pub fn solve(map: &mut Map, parts: &[(PartID, &Part)]) -> Option<()>{
     let (id, part) = parts[0];
 
 
-    // Todo: limit to non-barrier positions
+    // TODO: restrict to list of non-barrier position to tighten the for loops
     for x in 0..MAP_WIDTH {
         for y in 0..MAP_HEIGHT {
             if !map[y as usize][x as usize].is_empty() {
@@ -441,6 +456,38 @@ mod test {
         assert_eq!(1, called);
 
     }
-    
 
+    #[test]
+    fn halting_problem() {
+        let B = Cell::Barrier;
+        let E = Cell::Empty;
+
+        let mut map : Map = [
+            [B, B, E, E, E, B, E, E, E, B, B, B, B, B, B, B],
+            [B, E, E, E, E, B, B, E, E, E, B, B, B, B, B, B],
+            [E, E, E, E, E, B, E, E, E, E, E, E, B, B, B, B],
+            [E, E, E, B, E, B, E, E, E, E, E, B, B, B, B, B],
+            [B, B, B, B, B, B, B, B, B, E, B, B, B, B, B, B],
+        ];
+
+        let parts = generate_parts();
+
+        let available_parts : Vec<(PartID, &Part)> = [2,3,4,5,6,7].iter()
+            .map(|x| (*x, &parts[&x]))
+            .collect();
+
+        let result = solve(&mut map, &available_parts);
+
+        assert!(result.is_some());
+
+        for y in 0..MAP_HEIGHT {
+            for x in 0..MAP_WIDTH {
+                print!("{}", map[y as usize][x as usize]);
+            }
+            println!("");
+        }
+        assert!(false);
+
+
+    }
 }

+ 96 - 1
src/main.rs

@@ -1,3 +1,98 @@
+use UbongoTrigoSolver::*;
+fn foreground_color(idx: u8) {
+    print!("\x1B[38;5;{}m", idx);
+}
+
+fn background_color(idx: u8) {
+    print!("\x1B[48;5;{}m", idx);
+}
+
+mod lib;
+
+fn switch_color_to_cell(cell: Cell)  {
+    match cell {
+        Cell::Barrier => foreground_color(0),
+        Cell::Empty => foreground_color(15),
+        Cell::Occupied(1) => foreground_color(94),
+        Cell::Occupied(2) => foreground_color(89),
+        Cell::Occupied(3) => foreground_color(202),
+        Cell::Occupied(4) => foreground_color(220),
+        Cell::Occupied(5) => foreground_color(22),
+        Cell::Occupied(6) => foreground_color(196),
+        Cell::Occupied(7) => foreground_color(27),
+        _ => {}
+    }
+}
+
+//
+//  |O###O###O###
+//  OOO#OOO#OOO#
+//  ###O###O###O
+//  |#OOO#OOO#OOO
+fn print_map(m: &Map) {
+    for y in 0..MAP_HEIGHT {
+        if y % 2 == 0 {
+            switch_color_to_cell(Cell::Barrier);
+            print!("█");
+        }
+        for x in 0..MAP_WIDTH {
+            switch_color_to_cell(m[y as usize][x as usize]);
+
+            if (x + y) % 2 == 0 {
+                print!("o");
+            } else {
+                print!("###");
+            }
+        }
+        
+        switch_color_to_cell(Cell::Barrier);
+        println!("");
+
+        if y % 2 == 1 {
+            switch_color_to_cell(Cell::Barrier);
+            print!("█");
+        }
+        for x in 0..MAP_WIDTH {
+            switch_color_to_cell(m[y as usize][x as usize]);
+            if (x + y) % 2 == 1 {
+                print!("#");
+            } else {
+                print!("ooo");
+            }
+        }
+        println!("");
+
+    }
+
+}
+
+
 fn main() {
-    println!("Hello, world!");
+    foreground_color(0); // black
+    background_color(0); // white
+    let B = Cell::Barrier;
+    let E = Cell::Empty;
+
+    let mut map : Map = [
+        [B, B, E, E, E, B, E, E, E, B, B, B, B, B, B, B],
+        [B, E, E, E, E, B, B, E, E, E, B, B, B, B, B, B],
+        [E, E, E, E, E, B, E, E, E, E, E, E, B, B, B, B],
+        [E, E, E, B, E, B, E, E, E, E, E, B, B, B, B, B],
+        [B, B, B, B, B, B, B, B, B, E, B, B, B, B, B, B],
+    ];
+    let parts = generate_parts();
+
+    let available_parts : Vec<(PartID, &Part)> = [1,2,3,4,5,6,7].iter()
+        .map(|x| (*x, &parts[&x]))
+        .collect();
+
+
+    //let (_, part1) = available_parts[0];
+    //place_part(&mut map, 1, &part1, 3, 2, Edge::BOTTOMTOP);
+    //print_map(&map);
+    let result = solve(&mut map, &available_parts[1..]);
+    assert!(result.is_some());
+    print_map(&map);
+
+
 }