소스 검색

Fix coord placement, coord cleanup, insert words, board print func

Josh Bicking 4 년 전
부모
커밋
01f156b6d3
2개의 변경된 파일94개의 추가작업 그리고 40개의 파일을 삭제
  1. 93 39
      src/board.rs
  2. 1 1
      src/main.rs

+ 93 - 39
src/board.rs

@@ -21,6 +21,7 @@ mod board {}
 
 const DEFAULT_ROWS: usize = 17;
 const DEFAULT_COLS: usize = 24;
+const BORDER_HEX_WIDTH: usize = 6;
 
 // Different actions are printed to the console at different speeds: the
 // "terminal" displaying output, vs. the player "typing", for example.
@@ -69,40 +70,45 @@ impl Board {
         Board {
             rows: r,
             cols: c,
-            c: Board::garbage_vec(r, c)
+            c: vec![' '; r * c]
         }
     }
 
-    fn garbage_vec(rows: usize, cols: usize) -> Vec<char> {
+    fn fill_with_garbage(&mut self) {
         let g: Vec<char> = "!@#$%^*()_-=+\\|/[]{}?\"\':;,.<>".chars().collect();
-        let mut b = Vec::with_capacity(rows * cols);
         let mut rng = rand::thread_rng();
 
-        for _ in 0..rows * cols {
-            b.push(*g.choose(&mut rng).unwrap());
+        for i in 0..self.rows * self.cols {
+            self.c[i] = *g.choose(&mut rng).unwrap();
         }
-
-        b
     }
 
     fn capacity(&self) -> usize {
         self.c.len()
     }
 
-    fn get(&self, i: usize) -> char {
+    fn get_i(&self, i: usize) -> char {
         self.c[i]
     }
 
-    fn getxy(&self, x: usize, y: usize) -> char {
+    fn get_xy(&self, x: usize, y: usize) -> char {
         self.c[x*y]
     }
 
-    fn set(&mut self, i: usize, c: char) {
+    fn set_i(&mut self, i: usize, c: char) {
         self.c[i] = c;
     }
 
-    fn setxy(&mut self, x: usize, y: usize, c: char) {
-        self.c[x*y] = c;
+    fn set_xy(&mut self, x: usize, y: usize, c: char) {
+        self.set_i(x*y, c);
+    }
+
+    fn set_i_str(&mut self, i: usize, s: &str) {
+        s.chars().enumerate().for_each(|(str_index, c)| self.set_i(i+str_index, c));
+    }
+
+    fn set_xy_str(&mut self, x: usize, y: usize, s: &str) {
+        s.chars().enumerate().for_each(|(str_index, c)| self.set_i((x*y)+str_index, c));
     }
 
     // Think of the board in word_len "chunks": place a slot for a word in each chunk
@@ -115,47 +121,55 @@ impl Board {
             word_len+1, word_len, chunk_len);
         }
         let mut coords: Vec<Coord> = Vec::with_capacity(num_of_words);
-        let mut starting_coord = 0;
+        let mut starting_coord: usize = 0;
         for _ in 0..num_of_words {
             let coord = Coord::new(starting_coord, word_len);
-            coords.push(coord);
             starting_coord+=chunk_len;
+            assert!(starting_coord > coord.end);
+            coords.push(coord);
         }
         coords
     }
 
     // "shake" each word slot around, in a random order, 3 times/word.
-    fn shake_words(&self, word_coords: &mut Vec<Coord>) {
+    fn shake_coords(&self, word_coords: &mut Vec<Coord>) {
         let mut rng = rand::thread_rng();
 
         for _ in 0..3 {
-            let mut positions: Vec<usize> = (0..word_coords.len()).collect();
-            positions.shuffle(&mut rng);
-            for i in positions {
+            let indices: Vec<usize> = (0..word_coords.len()).collect();
+            let shuffled_indices = copy_shuffle(&indices);
+
+            for i in shuffled_indices {
                 let coord = &word_coords[i];
                 // Where can this coord move (leaving at least 1 space between words)?
                 let mut movement_options = Vec::with_capacity(2);
 
-                let mut start = coord.start as i32;
-                let mut end = -2;
-                if i > 0 {
+                let start = coord.start as i32;
+                let previous_coord_end: i32;
+                if i == 0 {
+                    previous_coord_end = coord.start as i32;
+                } else {
                     let prev_coord = &word_coords[i-1];
-                    end = prev_coord.end as i32;
+                    previous_coord_end = prev_coord.end as i32;
                 }
-                if start - end > 1 {
+                let space_behind = start - previous_coord_end;
+                if space_behind > 1 {
                     // It can move backwards
-                    movement_options.push((start-end-1) * -1);
+                    movement_options.push((space_behind-1) * -1);
                 }
 
-                start = self.capacity() as i32;
-                end = coord.end as i32;
-                if i < word_coords.len()-1 {
+                let next_coord_start: i32;
+                let end = coord.end as i32;
+                if i == word_coords.len()-1 {
+                    next_coord_start = self.capacity() as i32;
+                } else {
                     let next_coord = &word_coords[i+1];
-                    start = next_coord.start as i32;
+                    next_coord_start = next_coord.start as i32;
                 }
-                if start - end > 1 {
+                let space_in_front = next_coord_start - end;
+                if space_in_front > 1 {
                     // It can move forwards
-                    movement_options.push(start-end-1);
+                    movement_options.push(space_in_front-1);
                 }
 
                 // Pick a movement option, & pick some amount to move
@@ -174,6 +188,23 @@ impl Board {
             }
         }
     }
+
+    fn insert_words(&mut self, words: &[String], coords: &Vec<Coord>) {
+        assert_eq!(words.len(), coords.len());
+        for (word, coord) in words.iter().zip(coords.iter()) {
+            assert_eq!(word.len(), coord.end - coord.start + 1);
+            for (ch, coord_index) in word.chars().zip(coord.start..coord.end+1) {
+                self.c[coord_index] = ch;
+            }
+        }
+    }
+
+    fn dump(&self) {
+        for chunk in self.c.chunks(self.rows) {
+            let s: String = chunk.iter().collect();
+            println!("{}", s);
+        }
+    }
 }
 
 impl Screen {
@@ -181,10 +212,12 @@ impl Screen {
         let window = initscr();
         noecho();
         window_enable_colors();
+        let mut b = Board::new(conf.rows, conf.cols);
+        b.fill_with_garbage();
         Screen {
             w: window,
             attempts_left: 4,
-            b: Board::new(conf.rows, conf.cols)
+            b: b
         }
     }
 
@@ -199,7 +232,7 @@ impl Screen {
 
     }
 
-    pub fn initialize_game(&self, conf: Config) {
+    pub fn initialize_game(&mut self, conf: Config) {
         self.print_with_delay(0, String::from("ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL"), false, TERMINAL_PRINTING_SPEED);
         self.print_with_delay(1, String::from("ENTER PASSWORD NOW"), false, TERMINAL_PRINTING_SPEED);
         self.print_with_delay(
@@ -208,7 +241,6 @@ impl Screen {
             false,
             TERMINAL_PRINTING_SPEED
         );
-        let border_hex = border_hex_gen(self.b.rows);
 
         let shuffled_words = copy_shuffle(&conf.words);
         let words = &shuffled_words[..conf.choose];
@@ -222,11 +254,16 @@ impl Screen {
         }
 
         let mut coords = self.b.build_word_coords(words.len(), word_len);
-        self.b.shake_words(&mut coords);
-
+        self.b.shake_coords(&mut coords);
         println!("{:?}", coords);
-        println!("{:?}", self.b);
+        self.b.insert_words(words, &coords);
+
+        let mut screen_buffer = Board::new(Some(self.b.rows), Some(self.b.cols + (2 * BORDER_HEX_WIDTH) + 3));
+        let border_hex = border_hex_gen(self.b.rows, self.b.cols);
+        self.add_border_hex_to_board(&mut screen_buffer, &border_hex);
 
+        self.b.dump();
+        screen_buffer.dump();
     }
 
     pub fn end_window(&self) {
@@ -250,10 +287,27 @@ impl Screen {
         }
     }
 
-    fn attempts_display(&self) -> String {
+    fn build_attempts_display(&self) -> String {
         format!("{} ATTEMPT(S) LEFT:{}", self.attempts_left, " *".repeat(self.attempts_left as usize))
     }
 
+    fn add_border_hex_to_board(&self, board: &mut Board, hex: &Vec<u32>) {
+        let left_side = (0..board.rows).zip(hex.iter());
+        let right_side = (board.rows..).zip(hex[board.rows..].iter());
+
+        for (y, hex_val) in left_side {
+            println!("Printing 0x{:x} at 0, {}", hex_val, y);
+            board.set_xy_str(0, y, &format!("0x{:x}", hex_val));
+        }
+
+        // Half the board, plus characters for the first hex values, plus 2 spaces of padding.
+        let right_hand_offset = board.cols / 2;
+        for (y, hex_val) in right_side {
+            println!("Printing 0x{:x} at {}, {}", hex_val, right_hand_offset, y);
+            board.set_xy_str(right_hand_offset, y, &format!("0x{:x}", hex_val));
+        }
+    }
+
 }
 
 fn window_enable_colors() {
@@ -263,7 +317,7 @@ fn window_enable_colors() {
     }
 }
 
-fn border_hex_gen(rows: usize) -> Vec<u32> {
+fn border_hex_gen(rows: usize, cols: usize) -> Vec<u32> {
     // Build the hex values, printed alongside the text and garbage.
     // The vector will be of length rows * 2
     // TODO: this would make a nice generator, once those are stable.
@@ -273,7 +327,7 @@ fn border_hex_gen(rows: usize) -> Vec<u32> {
     let mut ls = Vec::with_capacity(rows * 2);
     for _ in 0..rows * 2 {
         ls.push(hex);
-        hex += 12;
+        hex += (cols / 2) as u32;
     }
 
     ls

+ 1 - 1
src/main.rs

@@ -32,7 +32,7 @@ fn main() {
 
     let conf = config::load_config_file(config_location);
 
-    let screen = board::Screen::new(&conf);
+    let mut screen = board::Screen::new(&conf);
     screen.intro();
 
     screen.w.clear();