board.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. extern crate pancurses;
  2. use self::pancurses::{
  3. initscr, endwin, noecho, has_colors, start_color, init_pair,
  4. Window,
  5. COLOR_GREEN, COLOR_BLACK
  6. };
  7. extern crate rand;
  8. use self::rand::Rng;
  9. use self::rand::prelude::SliceRandom;
  10. use std::{thread, time};
  11. use config::{Config};
  12. // Board control and interaction. The view & controller.
  13. mod board {}
  14. const ROWS: usize = 17;
  15. const COLS: usize = 24;
  16. pub struct Board {
  17. pub w: Window,
  18. attempts_left: u8
  19. }
  20. pub fn init_board() -> Board {
  21. let window = initscr();
  22. noecho();
  23. window_enable_colors();
  24. Board{w: window, attempts_left: 4}
  25. }
  26. // Different actions are printed to the console at different speeds (the terminal displaying output, vs the player "typing")
  27. const TERMINAL_PRINTING_SPEED: time::Duration = time::Duration::from_millis(20);
  28. const TYPING_SPEED: time::Duration = time::Duration::from_millis(70);
  29. impl Board {
  30. pub fn intro(&self) {
  31. self.w.clear();
  32. thread::sleep(time::Duration::from_millis(250));
  33. self.print_with_delay(0, String::from("WELCOME TO ROBCO INDUSTRIES (TM) TERMLINK"), true, TERMINAL_PRINTING_SPEED);
  34. self.move_cursor_to(1, 0);
  35. thread::sleep(time::Duration::from_millis(30));
  36. // TODO the rest of the intro
  37. }
  38. pub fn initialize_game(&self, conf: Config) {
  39. self.print_with_delay(0, String::from("ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL"), false, TERMINAL_PRINTING_SPEED);
  40. self.print_with_delay(1, String::from("ENTER PASSWORD NOW"), false, TERMINAL_PRINTING_SPEED);
  41. self.print_with_delay(
  42. 3,
  43. self.attempts_display(),
  44. false,
  45. TERMINAL_PRINTING_SPEED
  46. );
  47. let border_hex = *border_hex_gen();
  48. let mut b = *garbage_board();
  49. let shuffled_words = copy_shuffle(&conf.words);
  50. // TODO: insert each word, of size N, into the array, with at least 1 character between each
  51. }
  52. pub fn end_window(&self) {
  53. endwin();
  54. }
  55. fn move_cursor_to(&self, y: i32, x: i32) {
  56. self.w.mv(y, x);
  57. self.w.refresh();
  58. }
  59. fn print_with_delay(&self, line: i32, string: String, skippable: bool, delay: time::Duration) {
  60. self.w.mv(line, 0);
  61. for c in string.chars() {
  62. self.w.addch(c);
  63. self.w.refresh();
  64. if skippable {
  65. // TODO keyboard skip
  66. }
  67. thread::sleep(delay);
  68. }
  69. }
  70. fn attempts_display(&self) -> String {
  71. format!("{} ATTEMPT(S) LEFT:{}", self.attempts_left, " *".repeat(self.attempts_left as usize))
  72. }
  73. }
  74. fn window_enable_colors() {
  75. if has_colors() {
  76. start_color();
  77. init_pair(1, COLOR_GREEN, COLOR_BLACK);
  78. }
  79. }
  80. fn border_hex_gen() -> Box<[u32; ROWS * 2]> {
  81. // Build the hex values, printed alongside the text and garbage.
  82. // TODO: this would make a nice generator, once those are stable.
  83. let mut rng = rand::thread_rng();
  84. let mut hex = rng.gen_range(0,200) + 63744;
  85. let mut ls: [u32; ROWS * 2] = [0; ROWS * 2];
  86. for i in 0..ROWS * 2 {
  87. ls[i] = hex;
  88. hex += 12;
  89. }
  90. Box::new(ls)
  91. }
  92. fn garbage_board() -> Box<[[char; COLS]; ROWS]> {
  93. let g: Vec<char> = "!@#$%^*()_-=+\\|/[]{}?\"\':;,.<>".chars().collect();
  94. let mut b: [[char; COLS]; ROWS] = [['\0'; COLS]; ROWS];
  95. let mut rng = rand::thread_rng();
  96. for i in 0..ROWS {
  97. for j in 0..COLS {
  98. b[i][j] = *g.choose(&mut rng).unwrap();
  99. }
  100. }
  101. Box::new(b)
  102. }
  103. fn copy_shuffle<T: Clone>(vec: &Vec<T>) -> Vec<T> {
  104. let mut rng = rand::thread_rng();
  105. let mut vec = vec.clone();
  106. vec.shuffle(&mut rng);
  107. vec
  108. }