Browse Source

Map editor

Christoph Stelz 1 year ago
parent
commit
bacf112bb1
4 changed files with 214 additions and 45 deletions
  1. 73 0
      Cargo.lock
  2. 4 0
      Cargo.toml
  3. 34 34
      src/lib.rs
  4. 103 11
      src/main.rs

+ 73 - 0
Cargo.lock

@@ -5,3 +5,76 @@ version = 3
 [[package]]
 name = "UbongoTrigoSolver"
 version = "0.1.0"
+dependencies = [
+ "console",
+]
+
+[[package]]
+name = "console"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "terminal_size",
+ "unicode-width",
+ "winapi",
+]
+
+[[package]]
+name = "encode_unicode"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+
+[[package]]
+name = "terminal_size"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

+ 4 - 0
Cargo.toml

@@ -6,3 +6,7 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+console = "0.15.2"
+
+[net]
+git-fetch-with-cli = true

+ 34 - 34
src/lib.rs

@@ -1,4 +1,5 @@
 use std::collections::HashMap;
+use std::io::Write;
 
 
 #[derive(Clone,Debug,PartialEq)]
@@ -266,7 +267,8 @@ fn erase_part(map: &mut Map, part: &Part, x: i8, y: i8, rotation: u8, flipped: b
     });
 }
 
-pub fn solve(map: &mut Map, parts: &[(PartID, Part)]) -> Option<()>{
+pub fn solve(map: &mut Map, parts: &[(PartID, Part)]) -> Option<()>
+{
     if parts.len() == 0 {
         return Some(());
     }
@@ -287,7 +289,8 @@ pub fn solve(map: &mut Map, parts: &[(PartID, Part)]) -> Option<()>{
                     if valid_position {
                         // Place our part and try the others
                         place_part(map, *id, &part, x, y, rotation, flipped);
-                        print_map(&map);
+
+                        //t.as_ref().map(|&&&mut Term| print_map(term, map));
                         
                         if let Some(()) = solve(map, &parts[1..]) {
                             // We have found a valid solution we can pass back!
@@ -312,18 +315,18 @@ pub fn background_color(idx: u8) {
     print!("\x1B[48;5;{}m", idx);
 }
 
-fn switch_color_to_cell(cell: Cell)  {
+fn color_for_cell(cell: Cell) -> console::Color {
     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),
-        _ => {}
+        Cell::Barrier => console::Color::Color256(0),
+        Cell::Empty => console::Color::Color256(15),
+        Cell::Occupied(1) => console::Color::Color256(94),
+        Cell::Occupied(2) => console::Color::Color256(89),
+        Cell::Occupied(3) => console::Color::Color256(202),
+        Cell::Occupied(4) => console::Color::Color256(220),
+        Cell::Occupied(5) => console::Color::Color256(22),
+        Cell::Occupied(6) => console::Color::Color256(196),
+        Cell::Occupied(7) => console::Color::Color256(27),
+        _ => console::Color::Black
     }
 }
 
@@ -331,42 +334,39 @@ fn switch_color_to_cell(cell: Cell)  {
 //  OOO#OOO#OOO#
 //  ###O###O###O
 //  |#OOO#OOO#OOO
-pub fn print_map(m: &Map) {
+use console::style;
+pub fn print_map(t: &mut console::Term, m: &Map) {
     for y in 0..MAP_HEIGHT {
         if y % 2 == 0 {
-            switch_color_to_cell(Cell::Barrier);
-            print!("█");
+            write!(t, "{}", style("█").fg(color_for_cell(Cell::Barrier)));
         }
         for x in 0..MAP_WIDTH {
-            switch_color_to_cell(m[y as usize][x as usize]);
-
-            if (x + y) % 2 == 0 {
-                print!("o");
+            let c = if (x + y) % 2 == 0 {
+                "∧"
             } else {
-                print!("###");
-            }
+                "\\#/"
+            };
+
+            write!(t, "{}", style(c).fg(color_for_cell(m[y as usize][x as usize])));
         }
         
-        switch_color_to_cell(Cell::Barrier);
-        println!("");
+        write!(t, "{}", style("\n").fg(color_for_cell(Cell::Barrier)));
 
         if y % 2 == 1 {
-            switch_color_to_cell(Cell::Barrier);
-            print!("█");
+            write!(t, "{}", style("█").fg(color_for_cell(Cell::Barrier)));
         }
         for x in 0..MAP_WIDTH {
-            switch_color_to_cell(m[y as usize][x as usize]);
-            if (x + y) % 2 == 1 {
-                print!("#");
+            let c = if (x + y) % 2 == 1 {
+                 "v"
             } else {
-                print!("ooo");
-            }
+                "/_\\"
+            };
+
+            write!(t, "{}", style(c).fg(color_for_cell(m[y as usize][x as usize])));
         }
-        println!("");
+        write!(t, "{}", style("\n").fg(color_for_cell(Cell::Barrier)));
 
     }
-    foreground_color(15);
-    background_color(0);
 }
 
 #[cfg(test)]

+ 103 - 11
src/main.rs

@@ -1,21 +1,113 @@
 use UbongoTrigoSolver::*;
+use std::io::Read;
+use std::io::Write;
+use console::Key;
 
-const B :Cell = Cell::Barrier;
+const B: Cell = Cell::Barrier;
 const E: Cell = Cell::Empty;
 
 fn main() {
+    console::set_colors_enabled(true);
+    let mut t = console::Term::stdout();
+    let mut running = true;
     let mut map : Map = [
-        [B, B, E, E, E, B, B, B, E, E, E, B, B, B, B, B],
-        [B, E, E, E, E, E, B, B, B, E, E, E, B, B, B, B],
-        [E, E, E, E, E, E, B, B, E, E, E, E, E, E, B, B],
-        [E, E, E, B, E, B, B, 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],
+        [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+        [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+        [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+        [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+        [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
     ];
 
-    let parts : Vec<(PartID, Part)> = generate_parts();
+    let mut cursor_x : i8= 0;
+    let mut cursor_y : i8= 0;
+    let mut unused_piece = 1;
+
+    while running {
+        t.clear_screen();
+        let mut map_clone = map.clone();
+        map_clone[cursor_y as usize][cursor_x as usize] = Cell::Occupied(1);
+        print_map(&mut t, &map_clone);
+        write!(&mut t, "\nUnused piece: {}\nW, A, S, D to navigate.\nSpace bar to toggle between empty and barrier.\n1-7 to choose unused piece.\nEnter to start calculation.\nq to quit.\n", unused_piece);
+
+        let pressed_key = t.read_key().expect("Input error");
+
+        match pressed_key {
+            Key::Char('d') => {
+                if cursor_x == MAP_WIDTH -1 {
+                    cursor_y = (cursor_y + 1).rem_euclid(MAP_HEIGHT);
+                }
+
+                cursor_x = (cursor_x + 1).rem_euclid(MAP_WIDTH);
+            },
+            Key::Char('w') => {
+                cursor_y = (cursor_y - 1).rem_euclid(MAP_HEIGHT);
+            },
+            Key::Char('s') => {
+                cursor_y = (cursor_y + 1).rem_euclid(MAP_HEIGHT);
+            },
+            Key::Char('a') => {
+                if cursor_x == 0 {
+                    cursor_y = (cursor_y - 1).rem_euclid(MAP_HEIGHT);
+                }
+
+                cursor_x = (cursor_x - 1).rem_euclid(MAP_WIDTH);
+            },
+            Key::Char(' ') => {
+                let current_cell = &mut map[cursor_y as usize][cursor_x as usize];
+                let updated_cell = match current_cell {
+                    Cell::Empty => Cell::Barrier,
+                    _ => Cell::Empty
+                };
+
+                *current_cell = updated_cell;
+                if cursor_x == MAP_WIDTH -1 {
+                    cursor_y = (cursor_y + 1).rem_euclid(MAP_HEIGHT);
+                }
+
+                cursor_x = (cursor_x + 1).rem_euclid(MAP_WIDTH);
+            },
+            Key::Char('q') => {
+                running = false;
+            },
+            Key::Char('1') => { unused_piece = 1; println!("Unused: {}", unused_piece); }
+            Key::Char('2') => { unused_piece = 2; println!("Unused: {}", unused_piece); }
+            Key::Char('3') => { unused_piece = 3; println!("Unused: {}", unused_piece); }
+            Key::Char('4') => { unused_piece = 4; println!("Unused: {}", unused_piece); }
+            Key::Char('5') => { unused_piece = 5; println!("Unused: {}", unused_piece); }
+            Key::Char('6') => { unused_piece = 6; println!("Unused: {}", unused_piece); }
+            Key::Char('7') => { unused_piece = 7; println!("Unused: {}", unused_piece); }
+            Key::Enter => {
+                running = false;
+                let mut used_parts = vec!();
+                for (part_id, part) in generate_parts() {
+                    if part_id != unused_piece {
+                        used_parts.push((part_id, part));
+                        println!("Adding {}", part_id);
+                    }
+                }
+                let result = solve(&mut map, &used_parts[..]);
+                print_map(&mut t, &map);
+            }
+            _ => {}
+        };
+    }
+    //let mut map : Map = [
+    //    [B, B, E, E, E, B, B, B, E, E, E, B, B, B, B, B],
+    //    [B, E, E, E, E, E, B, B, B, E, E, E, B, B, B, B],
+    //    [E, E, E, E, E, E, B, B, E, E, E, E, E, E, B, B],
+    //    [E, E, E, B, E, B, B, 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],
+    //];
+
+    //let parts : Vec<(PartID, Part)> = generate_parts();
+
+    //print_map(&map);
+    //let result = solve(&mut map, &parts[1..7], true);
+    //assert!(result.is_some());
+    //print_map(&map);
+    //
+
 
-    print_map(&map);
-    let result = solve(&mut map, &parts[1..]);
-    assert!(result.is_some());
-    print_map(&map);
 }
+
+