diff options
| author | tslil clingman <> | 2020-01-15 12:41:56 -0500 |
|---|---|---|
| committer | tslil clingman <> | 2020-01-15 12:41:56 -0500 |
| commit | f6a94720061877903487ed98bfee9f19df264a9d (patch) | |
| tree | 26c50995ab043235c2699526ff44907e50d51b5f /src | |
| parent | 074103c90092a98938c1dfafb690b468fc27b093 (diff) | |
Rendering of boards, redid BoardGui using windows
Diffstat (limited to 'src')
| -rw-r--r-- | src/board.rs | 50 | ||||
| -rw-r--r-- | src/main.rs | 243 |
2 files changed, 205 insertions, 88 deletions
diff --git a/src/board.rs b/src/board.rs index eb8a638..578842c 100644 --- a/src/board.rs +++ b/src/board.rs @@ -94,7 +94,7 @@ impl fmt::Display for Action { } } -type Stack = Vec<(Player, Stone)>; +pub type Stack = Vec<(Player, Stone)>; pub struct Board<L> where @@ -115,18 +115,22 @@ where // TODO: Generate all legal actions for a given player impl<L: Fn(String)> Board<L> { - pub fn new(size: u8, log: L) -> Option<Board<L>> { - if size >= 3 && size <= 8 { - let (flats, caps) = match size { - 3 => (10, 0), - 4 => (15, 0), - 5 => (21, 1), - 6 => (30, 1), - 7 => (40, 2), - 8 => (50, 2), - _ => return None, - }; - Some(Board { + pub fn get_size(&self) -> u8 { + self.size + } + + // Defaults to 5x5 if requested things are out of range + pub fn new(size: u8, log: L) -> (Board<L>, bool) { + let (flats, caps, correct) = match size { + 3 => (10, 0, true), + 4 => (15, 0, true), + 6 => (30, 1, true), + 7 => (40, 2, true), + 8 => (50, 2, true), + _ => (21, 1, false), + }; + ( + Board { size: size, black_flats: flats, white_flats: flats, @@ -135,19 +139,17 @@ impl<L: Fn(String)> Board<L> { board: { let mut v: Vec<Stack> = Vec::new(); for _i in 0..size * size { - let t: Stack = Vec::new(); - v.push(t); + v.push(Vec::new()); } v }, log: log, - }) - } else { - None - } + }, + correct, + ) } - fn remaining_pieces(&self, player: &Player, stone: &Stone) -> u8 { + pub fn remaining_pieces(&self, player: &Player, stone: &Stone) -> u8 { match player { Player::Black => { if *stone == Stone::Capstone { @@ -174,6 +176,14 @@ impl<L: Fn(String)> Board<L> { } } + pub fn query_square(&self, pos: &Position) -> Option<&Stack> { + if self.within_bounds(pos) { + self.board.get(self.pos_to_idx(pos)) + } else { + None + } + } + fn pos_to_idx(&self, pos: &Position) -> usize { let y: usize = pos.y as usize; let x: usize = pos.x as usize; diff --git a/src/main.rs b/src/main.rs index 4528e96..6d110e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,11 +9,15 @@ use crate::board::*; struct BoardGui { win: Window, - size: i32, - cell_height: i32, - cell_width: i32, + 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)] @@ -23,77 +27,129 @@ enum BGAction { } impl BoardGui { - fn mv_to_cell(&self, pos: &Position) { - let y: i32 = pos.y as i32; - let x: i32 = pos.x as i32; - if (y < self.size) && (x < self.size) { - let y = (self.size - y) * self.cell_height + 1; - let x = self.hoff + x * self.cell_width + 1; - self.win.mv(y, x); - self.win.refresh(); - } - } - fn draw_grid(&self) { - for y in 0..self.cell_height * self.size + 1 { - for x in 0..self.cell_width * self.size + 1 { - if y % self.cell_height == 0 { - if x % self.cell_width == 0 { + 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.win.mvaddch(y, x + self.hoff, '+'); } else { self.win.mvaddch(y, x + self.hoff, '-'); } - } else if x % self.cell_width == 0 { + } else if x % w == 0 { self.win.mvaddch(y, x + self.hoff, '|'); } } } - for y in 0..self.size { - self.win.mvaddstr( - y * self.cell_height + self.cell_height / 2, - 0, - format!("{}.", self.size - y), - ); + for y in 0..s { + self.win.mvaddstr(y * h + h / 2, 0, format!("{}.", s - y)); } - for x in 0..self.size { + for x in 0..s { self.win.mvaddstr( - self.size * self.cell_height + 1, - self.cell_width * x + self.cell_width / 2 + self.hoff, + s * h + 1, + w * x + w / 2 + self.hoff, format!("{:x}.", x + 10), ); } self.win.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 (player, stone) = &stack[i as usize]; + self.draw_stone(win, i == l - 1, player, stone); + } + } + win.refresh(); + } + } + + // Is this really the best way to do this? + fn draw_board<L: Fn(String)>(&self, board: &Board<L>) { + // ???? + assert!(board.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) = board.query_square(&pos) { + self.draw_stack(&pos, stack); + } + } + } + } + fn handle_key(&mut self, key: Input) -> BGAction { match key { - KeyUp => { + KeyDown => { if 0 < self.cur_cell.y { self.cur_cell.y -= 1; - self.mv_to_cell(&self.cur_cell); + self.mv_to_cell(&self.cur_cell, 0); } BGAction::None } - KeyDown => { - let y: i32 = self.cur_cell.y as i32; - if y + 1 < self.size { + KeyUp => { + if self.cur_cell.y + 1 < self.size { self.cur_cell.y += 1; - self.mv_to_cell(&self.cur_cell); + self.mv_to_cell(&self.cur_cell, 0); } BGAction::None } KeyLeft => { if 0 < self.cur_cell.x { self.cur_cell.x -= 1; - self.mv_to_cell(&self.cur_cell); + self.mv_to_cell(&self.cur_cell, 0); } BGAction::None } KeyRight => { - let x: i32 = self.cur_cell.x as i32; - if x + 1 < self.size { + if self.cur_cell.x + 1 < self.size { self.cur_cell.x += 1; - self.mv_to_cell(&self.cur_cell); + self.mv_to_cell(&self.cur_cell, 0); } BGAction::None } @@ -106,9 +162,56 @@ impl BoardGui { } } - fn init(&self) { - self.draw_grid(); - self.mv_to_cell(&self.cur_cell); + 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 { + win: 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.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.win.refresh(); + bg } } @@ -118,9 +221,8 @@ struct MoveEntry { impl MoveEntry { fn init(&self) { - self.win.attrset(COLOR_PAIR(3) | A_BOLD); // ???? how - self.win.mvaddstr(0, 0, "Enter move: ashtsaht"); - // self.win.mvchgat(0,12,10,A_NORMAL,COLOR_PAIR(1)); + self.win.mvaddstr(0, 0, "Enter move: "); + // Make shaded box for entry self.win.refresh(); } @@ -131,61 +233,66 @@ impl MoveEntry { struct MessageLog { win: Window, + has_colours: bool, + red_colour: u8, } impl MessageLog { fn init(&self) {} fn log_error(&self, str: String) { + if self.has_colours { + self.win.attrset(ColorPair(self.red_colour)); + } // self.win.clear(); self.win.addstr(str); + self.win.attrset(Attribute::Normal); self.win.refresh(); } } fn main() { let screen = initscr(); - screen.nodelay(true); + // screen.nodelay(true); screen.keypad(true); - - if has_colors() { - start_color(); - } - cbreak(); noecho(); - curs_set(2); + let has_colours = has_colors(); + let (black_colour, white_colour, red_colour): (u8, u8, u8) = (1, 2, 3); + + if has_colours { + start_color(); + use_default_colors(); + init_pair(black_colour as i16, -1, COLOR_RED); + init_pair(white_colour as i16, -1, COLOR_BLUE); + init_pair(red_colour as i16, COLOR_RED, -1); + } + screen.refresh(); - let bgw = newwin(25, 40, 0, 0); let mew = newwin(1, 30, 25, 0); let mlw = newwin(3, 70, 26, 0); - let mut bg = BoardGui { - win: bgw, - size: 5, - cell_height: 4, - cell_width: 7, - hoff: 3, - cur_cell: Position { x: 0, y: 0 }, - }; + let mut bg = BoardGui::new(0, 0, 5, 4, 8, 3, has_colours, white_colour, black_colour); let me = MoveEntry { win: mew }; - let ml = MessageLog { win: mlw }; + let ml = MessageLog { + win: mlw, + has_colours: has_colours, + red_colour: red_colour, + }; - bg.init(); me.init(); ml.init(); - let board_option = Board::new(5, |s| MessageLog::log_error(&ml, s)); - if let Some(mut board) = board_option { - let pos = Position { x: 0, y: 0 }; - board.perform_action(Action::Place(Player::White, pos, Stone::Flat)); - board.is_legal_action(&Action::Move(Player::White, pos, Direction::Up, vec![0, 1])); - } + let (mut board, _) = Board::new(5, |s| MessageLog::log_error(&ml, s)); + let pos = Position { x: 0, y: 0 }; + board.perform_action(Action::Place(Player::White, pos, Stone::Flat)); + board.is_legal_action(&Action::Move(Player::White, pos, Direction::Up, vec![0, 1])); + bg.draw_board(&board); loop { if let Some(inp) = screen.getch() { |
