diff options
| author | tslil clingman <> | 2020-01-19 23:26:29 -0800 |
|---|---|---|
| committer | tslil clingman <> | 2020-01-19 23:26:29 -0800 |
| commit | 8110985e6636e511f0a2e85a6f30aa8ff109320d (patch) | |
| tree | 7e6c1b38d04db474aac5cdac2593878f167cac8a /src/main.rs | |
| parent | 4d18fad08c185e07d030f6574963ec6de8441ee5 (diff) | |
Parsing `by hand', gui in separate module
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 350 |
1 files changed, 9 insertions, 341 deletions
diff --git a/src/main.rs b/src/main.rs index 043702a..c7281cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,345 +1,10 @@ -extern crate pancurses; - -use pancurses::Input::*; -use pancurses::*; - mod game; -use crate::game::*; - -pub struct GameLog { - action_window: Window, - pieces_window: Window, -} - -impl GameLog { - pub fn new(ypos: i32, xpos: i32, height: i32, width: i32) -> GameLog { - GameLog { - pieces_window: newwin(2, width, ypos, xpos), - action_window: newwin(height, width, ypos + 3, xpos), - } - } - - pub fn update<L: Fn(String)>(&self, game: &Game<L>) { - self.pieces_window.clear(); - self.pieces_window.addstr(format!( - "W: {:2} B: {:2}\nWC: {} BC: {}", - game.query_pieces(Player::White, Stone::Flat), - game.query_pieces(Player::Black, Stone::Flat), - game.query_pieces(Player::White, Stone::Capstone), - game.query_pieces(Player::Black, Stone::Capstone), - )); - self.pieces_window.refresh(); - - self.action_window.clear(); - self.action_window.addstr(game.query_action_lines()); - self.action_window.refresh(); - } -} - -pub struct BoardGUI { - board_window: Window, - cell_windows: Vec<Window>, - size: u8, - cell_height: u8, - cell_width: u8, - hoff: i32, - cur_cell: Position, - has_colours: bool, - white_colour: u8, - black_colour: u8, -} - -#[derive(PartialEq)] -pub enum BGAction { - Quit, - None, -} - -impl BoardGUI { - fn draw_grid(&self) { - let s: i32 = self.size as i32; - let h: i32 = self.cell_height as i32; - let w: i32 = self.cell_width as i32; - for y in 0..h * s + 1 { - for x in 0..w * s + 1 { - if y % h == 0 { - if x % w == 0 { - self.board_window.mvaddch(y, x + self.hoff, '+'); - } else { - self.board_window.mvaddch(y, x + self.hoff, '-'); - } - } else if x % w == 0 { - self.board_window.mvaddch(y, x + self.hoff, '|'); - } - } - } - for y in 0..s { - self.board_window - .mvaddstr(y * h + h / 2, 0, format!("{}.", s - y)); - } - for x in 0..s { - self.board_window.mvaddstr( - s * h + 1, - w * x + w / 2 + self.hoff, - format!("{:x}.", x + 10), - ); - } - self.board_window.refresh(); - } - - fn pos_to_idx(&self, pos: &Position) -> usize { - let y = pos.y as usize; - let x = pos.x as usize; - x + y * (self.size as usize) - } - - fn mv_to_cell(&self, pos: &Position, line: i32) { - if let Some(win) = self.cell_windows.get(self.pos_to_idx(pos)) { - win.mv(line, 0); - win.refresh(); - } - } - - fn draw_stone(&self, win: &Window, top: bool, player: &Player, stone: &Stone) { - if self.has_colours { - match player { - Player::Black => win.attrset(ColorPair(self.black_colour)), - Player::White => win.attrset(ColorPair(self.white_colour)), - }; - if top { - win.addch(match stone { - Stone::Flat => '#', - Stone::Standing => '/', - Stone::Capstone => '*', - }); - } else { - win.addstr(format!("{}", player)); - } - } else { - win.addstr(format!("{}", player)); - if top { - win.addstr(format!("{}", stone)); - } - } - } - - fn draw_stack(&self, pos: &Position, stack: &Stack) { - if let Some(win) = self.cell_windows.get(self.pos_to_idx(pos)) { - win.mv(0, 0); - let l = stack.len() as i32; - if l > 0 { - for i in 0..l { - let piece = &stack[i as usize]; - self.draw_stone(win, i == l - 1, &piece.player, &piece.stone); - } - } - win.refresh(); - } - } - - pub fn update<L: Fn(String)>(&self, game: &Game<L>) { - // Is this really the `best' way? - assert!(game.get_size() == self.size); - let mut pos = Position { x: 0, y: 0 }; - for y in 0..self.size { - pos.y = y; - for x in 0..self.size { - pos.x = x; - if let Some(stack) = game.query_square(&pos) { - self.draw_stack(&pos, stack); - } - } - } - } - - fn read_action(&mut self) -> BGAction { - loop { - if let Some(key) = self.board_window.getch() { - match key { - KeyDown => { - if 0 < self.cur_cell.y { - self.cur_cell.y -= 1; - self.mv_to_cell(&self.cur_cell, 0); - } - } - KeyUp => { - if self.cur_cell.y + 1 < self.size { - self.cur_cell.y += 1; - self.mv_to_cell(&self.cur_cell, 0); - } - } - KeyLeft => { - if 0 < self.cur_cell.x { - self.cur_cell.x -= 1; - self.mv_to_cell(&self.cur_cell, 0); - } - } - KeyRight => { - if self.cur_cell.x + 1 < self.size { - self.cur_cell.x += 1; - self.mv_to_cell(&self.cur_cell, 0); - } - } - Character('q') => return BGAction::Quit, - - x => { - self.board_window.addstr(format!("{:?}", x)); - self.board_window.refresh(); - } - } - } - } - } +mod gui; +mod parser; - pub fn new( - ypos: i32, - xpos: i32, - size: u8, - cell_height: u8, - cell_width: u8, - hoff: u8, - has_colours: bool, - white_colour: u8, - black_colour: u8, - ) -> BoardGUI { - let mut cell_windows: Vec<Window> = Vec::new(); - - let hoff = hoff as i32; - let s: i32 = size as i32; - let h: i32 = cell_height as i32; - let w: i32 = cell_width as i32; - for i in 0..s * s { - let y: i32 = i / s; - let x: i32 = i % s; - cell_windows.push(newwin(h - 1, w - 1, (s - y - 1) * h + 1, hoff + x * w + 1)); - } - - let bg = BoardGUI { - board_window: newwin(h * s + 3, w * s + 3 + hoff, ypos, xpos), - cell_windows: cell_windows, - size: size, - cell_height: cell_height, - cell_width: cell_width, - hoff: hoff, - cur_cell: Position { x: 0, y: 0 }, - has_colours: has_colours, - black_colour: black_colour, - white_colour: white_colour, - }; - - bg.board_window.keypad(true); - bg.board_window.nodelay(false); - - bg.draw_grid(); - - // for i in 0..s * s { - // let y: i32 = i / s; - // let x: i32 = i % s; - // let y = (s - y - 1) * h + 1; - // let x = hoff + x * w + 1; - // bg.cell_windows[i as usize].addstr(format!("{}:({},{})", i, y, x)); - // bg.cell_windows[i as usize].refresh(); - // } - - bg.mv_to_cell(&bg.cur_cell, 0); - bg.board_window.refresh(); - bg - } -} - -pub struct ActionEntry { - window: Window, - max_len: usize, - xstart: i32, -} - -impl ActionEntry { - pub fn new(ypos: i32, xpos: i32, max_len: usize) -> ActionEntry { - let txt = "Action entry: "; - let xstart = txt.len() as i32; - let width = max_len as i32 + xstart + 1; - - let ae = ActionEntry { - window: newwin(1, width, ypos, xpos), - max_len: max_len, - xstart: xstart, - }; - - ae.window.nodelay(false); - ae.window.keypad(true); - - ae.window.addstr(txt); - - for _i in 0..max_len { - ae.window.addch('_'); - } - - ae.window.mv(0, xstart); - ae.window.refresh(); - ae - } - - fn read_action(&self) -> String { - self.window.mv(0, self.xstart); - self.window.refresh(); - - let mut result = String::new(); - loop { - if let Some(inp) = self.window.getch() { - match inp { - Character('\n') => return result, - KeyEnter => return result, // TODO: is this ever used? - Character(c) => { - if result.len() < self.max_len { - result.push(c); - self.window.addch(c); - } - } - KeyBackspace => { - if !result.is_empty() { - result.pop(); - let (y, x) = (self.window.get_cur_y(), self.window.get_cur_x()); - self.window.mv(y, x - 1); - self.window.addch('_'); - self.window.mv(y, x - 1); - } - } - _ => (), - }; - } - self.window.refresh(); - } - } -} - -pub struct MessageLog { - window: Window, -} - -impl MessageLog { - pub fn new( - ypos: i32, - xpos: i32, - height: i32, - width: i32, - has_colours: bool, - red_colour: u8, - ) -> MessageLog { - let ml = MessageLog { - window: newwin(height, width, ypos, xpos), - }; - if has_colours { - ml.window.attrset(ColorPair(red_colour)); - } - ml - } - - pub fn log_error(&self, str: String) { - self.window.clear(); - self.window.addstr(str); - self.window.refresh(); - } -} +use crate::game::*; +use crate::gui::*; +use crate::parser::*; fn main() { let screen = initscr(); @@ -376,7 +41,10 @@ fn main() { board_gui.update(&game); game_log.update(&game); - log(action_entry.read_action()); + match parse_action(game.query_current_player(), &action_entry.read_action()) { + Ok(act) => log(format!("{}", act)), + Err(err) => log(err), + } // game_state.perform_action(&action); // game_state.is_legal_action(&Action::Move(Player::White, pos, Direction::Up, vec![0, 1])); |
