aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortslil clingman <>2020-01-11 22:42:27 -0500
committertslil clingman <>2020-01-11 22:42:27 -0500
commit46e1af1e694f066fd446f7d48b876f6217463818 (patch)
tree7ca278b1e9c5bf827d1758e93ee98ab1ffd99cc3 /src
Init
Diffstat (limited to 'src')
-rw-r--r--src/board.rs134
-rw-r--r--src/main.rs157
2 files changed, 291 insertions, 0 deletions
diff --git a/src/board.rs b/src/board.rs
new file mode 100644
index 0000000..45c0d49
--- /dev/null
+++ b/src/board.rs
@@ -0,0 +1,134 @@
+use std::fmt;
+
+#[derive(PartialEq)]
+pub enum Player {
+ Black,
+ White,
+}
+
+impl fmt::Display for Player {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Player::Black => "B",
+ Player::White => "W",
+ }
+ )
+ }
+}
+
+#[derive(PartialEq)]
+pub enum Stone {
+ Flat,
+ Standing,
+ Capstone,
+}
+
+impl fmt::Display for Stone {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Stone::Flat => "",
+ Stone::Standing => "S",
+ Stone::Capstone => "C",
+ }
+ )
+ }
+}
+
+pub struct Position {
+ pub x: u8,
+ pub y: u8,
+}
+impl fmt::Display for Position {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:x}{}", 10 + self.x, self.y)
+ }
+}
+
+pub enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+impl fmt::Display for Direction {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Direction::Up => "+",
+ Direction::Down => "-",
+ Direction::Left => "<",
+ Direction::Right => ">",
+ }
+ )
+ }
+}
+
+pub enum Move {
+ Place(Player, Position, Stone),
+ Slide(Player, Position, Direction, Vec<u8>),
+}
+
+impl fmt::Display for Move {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Move::Place(player, pos, stone) => write!(f, "{}{}{}", pos, player, stone),
+ Move::Slide(_, pos, direction, drops) => write!(
+ f,
+ "{}{}{}",
+ pos,
+ direction,
+ drops.into_iter().map(|q| q.to_string()).collect::<String>()
+ ),
+ }
+ }
+}
+
+type Stack = Vec<(Stone, Player)>;
+
+pub struct Board {
+ size: u16,
+ board: Vec<Stack>,
+}
+
+impl Board {
+ fn lookup(&self, pos: &Position) -> Option<&Stack> {
+ let y: u16 = pos.y.into();
+ let x: u16 = pos.x.into();
+ // Really?
+ let idx: usize = (x + y * self.size).into();
+ self.board.get(idx)
+ }
+
+ fn is_legal_move(&self, mov: &Move) -> bool {
+ match mov {
+ Move::Place(_, pos, _) => match self.lookup(pos) {
+ Some(stack) => {
+ if stack.len() == 0 {
+ true
+ } else {
+ false
+ }
+ }
+ None => false,
+ },
+ Move::Slide(player, pos, direction, drops) => match self.lookup(pos) {
+ Some(stack) => {
+ if stack.len() == 0 {
+ true
+ } else {
+ false
+ }
+ }
+ None => false,
+ },
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..82b38af
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,157 @@
+extern crate pancurses;
+
+use pancurses::*;
+use pancurses::Input::*;
+
+mod board;
+
+use crate::board::*;
+
+struct BoardGui {
+ win : Window,
+ size : i32,
+ cell_height : i32,
+ cell_width : i32,
+ hoff : i32,
+ cur_cell : Position
+}
+
+#[derive(PartialEq)]
+enum BGAction { Quit , None }
+
+use std::convert::*;
+
+impl BoardGui {
+ fn mv_to_cell(&self, pos : &Position) {
+ let y:i32 = pos.y.into();
+ let x:i32 = pos.x.into();
+ if (y < self.size) && (x < self.size) {
+ let y = 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 {
+ self.win.mvaddch(y,x+self.hoff,'+');
+ } else {
+ self.win.mvaddch(y,x+self.hoff,'-');
+ }
+ } else if x % self.cell_width == 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 x in 0..self.size {
+ self.win.mvaddstr(self.size*self.cell_height+1,
+ self.cell_width*x+self.cell_width/2+self.hoff,
+ format!("{:x}.",x+10));
+ }
+ self.win.refresh();
+ }
+
+ fn handle_key(&mut self, key : Input) -> BGAction {
+ match key {
+ KeyUp => {
+ if 0 < self.cur_cell.y {
+ self.cur_cell.y -= 1;
+ self.mv_to_cell(&self.cur_cell);
+ }
+ BGAction::None
+ },
+ KeyDown => {
+ let y:i32 = self.cur_cell.y.into();
+ if y + 1 < self.size {
+ self.cur_cell.y += 1;
+ self.mv_to_cell(&self.cur_cell);
+ }
+ BGAction::None
+ },
+ KeyLeft => {
+ if 0 < self.cur_cell.x {
+ self.cur_cell.x -= 1;
+ self.mv_to_cell(&self.cur_cell);
+ }
+ BGAction::None
+ },
+ KeyRight => {
+ let x:i32 = self.cur_cell.x.into();
+ if x + 1< self.size {
+ self.cur_cell.x += 1;
+ self.mv_to_cell(&self.cur_cell);
+ }
+ BGAction::None
+ },
+ Character('q') => BGAction::Quit,
+ x => {
+ self.win.addstr(format!("{:?}",x));
+ self.win.refresh();
+ BGAction::None
+ }
+ }
+ }
+
+ fn init(&self) {
+ self.draw_grid();
+ self.mv_to_cell(&self.cur_cell);
+ }
+}
+
+struct MoveEntry {
+ win : Window,
+}
+
+impl MoveEntry {
+
+ fn init(&self) {
+ self.win.attrset(COLOR_PAIR(3)|A_BOLD); // ????
+ self.win.mvaddstr(0,0,"Enter move: ashtsaht");
+ // self.win.mvchgat(0,12,10,A_NORMAL,COLOR_PAIR(1));
+ self.win.refresh();
+ }
+}
+
+fn main() {
+ let screen = initscr();
+ screen.nodelay(true);
+ screen.keypad(true);
+
+ if has_colors() { start_color(); }
+
+ cbreak();
+ noecho();
+
+ curs_set(2);
+
+ screen.refresh();
+
+ let bgw = newwin(25,40,0,0);
+ let mew = newwin(1,30,25,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 me = MoveEntry { win : mew };
+
+ bg.init();
+ me.init();
+
+ loop {
+ if let Some(inp) = screen.getch() {
+ if bg.handle_key(inp) == BGAction::Quit {break}
+ }
+ }
+ endwin();
+}