added selected highlighting, king checking
This commit is contained in:
parent
13a17d538b
commit
6d2eb8ab0a
@ -581,6 +581,7 @@ impl Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get cell index of jumpee square given from and to locations
|
||||||
pub fn jumpee_idx(&self, from: BrdIdx, to: BrdIdx) -> usize {
|
pub fn jumpee_idx(&self, from: BrdIdx, to: BrdIdx) -> usize {
|
||||||
let (row_diff, col_diff) = Board::idx_diffs(from, to);
|
let (row_diff, col_diff) = Board::idx_diffs(from, to);
|
||||||
self.cell_idx(
|
self.cell_idx(
|
||||||
@ -628,13 +629,20 @@ impl Board {
|
|||||||
let mut white: isize = 0;
|
let mut white: isize = 0;
|
||||||
|
|
||||||
for (_, square) in PieceIterator::new(self) {
|
for (_, square) in PieceIterator::new(self) {
|
||||||
if let Some(x) = square.occupant {
|
if let Some(piece) = square.occupant {
|
||||||
match x.team {
|
|
||||||
|
// kings are move valuable than men
|
||||||
|
let increment = match piece.strength {
|
||||||
|
Man => 1,
|
||||||
|
King => 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
match piece.team {
|
||||||
Black => {
|
Black => {
|
||||||
black += 1;
|
black += increment;
|
||||||
},
|
},
|
||||||
White => {
|
White => {
|
||||||
white += 1;
|
white += increment;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -648,6 +656,7 @@ impl Board {
|
|||||||
self.cell(idx).state
|
self.cell(idx).state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get new board derived from current with given move applied
|
||||||
pub fn apply_move(&self, from: BrdIdx, to: BrdIdx) -> Board {
|
pub fn apply_move(&self, from: BrdIdx, to: BrdIdx) -> Board {
|
||||||
let mut new = self.clone();
|
let mut new = self.clone();
|
||||||
|
|
||||||
@ -666,9 +675,12 @@ impl Board {
|
|||||||
Square::empty() // empty piece
|
Square::empty() // empty piece
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Board::check_kinged(&mut new, to);
|
||||||
|
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get new board derived from current with given jump applied
|
||||||
pub fn apply_jump(&self, from: BrdIdx, to: BrdIdx) -> Board {
|
pub fn apply_jump(&self, from: BrdIdx, to: BrdIdx) -> Board {
|
||||||
let mut new = self.clone();
|
let mut new = self.clone();
|
||||||
|
|
||||||
@ -693,9 +705,18 @@ impl Board {
|
|||||||
Square::empty() // empty piece
|
Square::empty() // empty piece
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Board::check_kinged(&mut new, to);
|
||||||
|
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get row index for current team, top row for black, bottom row for white
|
||||||
|
pub fn king_row_idx(&self) -> usize {
|
||||||
|
match self.current_turn {
|
||||||
|
White => self.height - 1,
|
||||||
|
Black => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
@ -725,6 +746,22 @@ impl Board {
|
|||||||
return from.team.opponent() == jumpee.team
|
return from.team.opponent() == jumpee.team
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check and apply king strength
|
||||||
|
fn check_kinged(new_board: &mut Board, idx: BrdIdx) {
|
||||||
|
if new_board.king_row_idx() == idx.row {
|
||||||
|
let cell_idx = new_board.cell_idx(idx);
|
||||||
|
let cell = new_board.cell(cell_idx);
|
||||||
|
match cell.occupant {
|
||||||
|
Some(piece) => {
|
||||||
|
new_board.set_cell(cell_idx, Square::pc(piece.team, King));
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
panic!("No piece found when checking king, idx: {}", idx);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialise a game board without game pieces
|
/// Initialise a game board without game pieces
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(width: usize, height: usize, current_turn: Team) -> Board {
|
pub fn new(width: usize, height: usize, current_turn: Team) -> Board {
|
||||||
|
@ -37,7 +37,6 @@ impl Move {
|
|||||||
/// Root-level structure for managing the game as a collection of board states
|
/// Root-level structure for managing the game as a collection of board states
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Computer {
|
pub struct Computer {
|
||||||
pub tree: Arena<Board>,
|
|
||||||
pub root_node_id: NodeId,
|
pub root_node_id: NodeId,
|
||||||
pub search_depth: usize,
|
pub search_depth: usize,
|
||||||
pub team: Team,
|
pub team: Team,
|
||||||
@ -48,19 +47,13 @@ impl Computer {
|
|||||||
let mut tree = Arena::new();
|
let mut tree = Arena::new();
|
||||||
let root_node_id = tree.new_node(initial_board);
|
let root_node_id = tree.new_node(initial_board);
|
||||||
Computer {
|
Computer {
|
||||||
tree,
|
|
||||||
root_node_id,
|
root_node_id,
|
||||||
search_depth,
|
search_depth,
|
||||||
team
|
team
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_board(&mut self, new_board: Board) {
|
/// Get vector of available moves for a given board
|
||||||
let mut tree = Arena::new();
|
|
||||||
tree.new_node(new_board);
|
|
||||||
self.tree = tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn available_turns(&self, board: &Board) -> Vec<Move> {
|
pub fn available_turns(&self, board: &Board) -> Vec<Move> {
|
||||||
|
|
||||||
// allocate capacity for 2 moves per piece, likely too much but will be shrunk
|
// allocate capacity for 2 moves per piece, likely too much but will be shrunk
|
||||||
@ -94,7 +87,7 @@ impl Computer {
|
|||||||
panic!("Unable to unwrap adjacent indices, from: {}, brd: {}", from_brd_idx, board);
|
panic!("Unable to unwrap adjacent indices, from: {}, brd: {}", from_brd_idx, board);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate over adjacent indices
|
// iterate over jumpable indices
|
||||||
if let Some(jump) = jump_op {
|
if let Some(jump) = jump_op {
|
||||||
for i in jump {
|
for i in jump {
|
||||||
let to_brd_idx = board.board_index(i);
|
let to_brd_idx = board.board_index(i);
|
||||||
@ -116,29 +109,26 @@ impl Computer {
|
|||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn gen_tree(&mut self, tree: &mut Arena<Board>, board: Board) {
|
pub fn gen_tree(&mut self, tree: &mut Arena<Board>, board: Board) {
|
||||||
|
|
||||||
// let boards = self.get_move_boards(&board);
|
// possible boards from given
|
||||||
|
let boards = self.get_move_boards(&board);
|
||||||
|
|
||||||
// let root_id = vec!(tree.new_node(board));
|
// root node of tree
|
||||||
// let ids = self.insert_boards(boards);
|
let root = tree.new_node(board);
|
||||||
|
|
||||||
// for d in 0..self.search_depth {
|
// insert possible boards
|
||||||
|
let ids = self.insert_boards(tree, boards);
|
||||||
|
// append ids to root node
|
||||||
|
ids.iter().for_each( |id| root.append(*id, tree) );
|
||||||
|
|
||||||
// for root in root_id.iter(){
|
}
|
||||||
// for id in ids.into_iter() {
|
|
||||||
// root.append(id, tree);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
pub fn insert_boards(&mut self, tree: &mut Arena<Board>, boards: Vec<Board>) -> Vec<NodeId> {
|
||||||
|
|
||||||
pub fn insert_boards(&mut self, boards: Vec<Board>) -> Vec<NodeId> {
|
|
||||||
|
|
||||||
boards
|
boards
|
||||||
.into_iter().map(
|
.into_iter().map(
|
||||||
|b| self.tree.new_node(b)
|
|b| tree.new_node(b)
|
||||||
).collect()
|
).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,19 +3,20 @@ use wasm_bindgen_test::*;
|
|||||||
|
|
||||||
use crate::board::Square;
|
use crate::board::Square;
|
||||||
use crate::board::enums::Strength::*;
|
use crate::board::enums::Strength::*;
|
||||||
|
use crate::log;
|
||||||
|
|
||||||
use Team::*;
|
use Team::*;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
// #[wasm_bindgen_test]
|
||||||
fn initial_tree_size() {
|
// fn initial_tree_size() {
|
||||||
let brd = Board::new(3, 2, White);
|
// let brd = Board::new(3, 2, White);
|
||||||
let comp = Computer::new(brd, 3, White);
|
// let comp = Computer::new(brd, 3, White);
|
||||||
|
|
||||||
assert!(!comp.tree.is_empty());
|
// assert!(!comp.tree.is_empty());
|
||||||
assert_eq!(comp.tree.count(), 1);
|
// assert_eq!(comp.tree.count(), 1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn available_moves() {
|
fn available_moves() {
|
||||||
@ -84,3 +85,21 @@ fn available_moves_std_brd() {
|
|||||||
assert_eq!(moves.len(), 7);
|
assert_eq!(moves.len(), 7);
|
||||||
assert!(moves.into_iter().all(|m| m.mv_type == MoveType::Move));
|
assert!(moves.into_iter().all(|m| m.mv_type == MoveType::Move));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn tree_insert() {
|
||||||
|
let brd = Board::init_game(Board::new(8, 8, White), 3);
|
||||||
|
let brd2 = brd.clone();
|
||||||
|
let mut comp = Computer::new(brd, 3, White);
|
||||||
|
|
||||||
|
// log!("{}", brd2);
|
||||||
|
|
||||||
|
let moves = comp.available_turns(&brd2);
|
||||||
|
log!("{}", moves.len());
|
||||||
|
|
||||||
|
let mut tree = Arena::new();
|
||||||
|
comp.gen_tree(&mut tree, brd2);
|
||||||
|
|
||||||
|
log!("{}", tree.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -8,11 +8,11 @@ use wasm_bindgen::prelude::*;
|
|||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
use crate::board::{Square, BrdIdx};
|
use crate::board::{Square, BrdIdx};
|
||||||
use crate::board::enums::{Moveable, Team};
|
use crate::board::enums::{SquareState, Moveable, Team};
|
||||||
use crate::paint::Painter;
|
use crate::paint::Painter;
|
||||||
|
|
||||||
// use Team::*;
|
// use Team::*;
|
||||||
// use SquareState::*;
|
use SquareState::*;
|
||||||
|
|
||||||
use std::fmt::{Display};
|
use std::fmt::{Display};
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ use std::fmt::{Display};
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
current: Board,
|
current: Board,
|
||||||
|
selected_piece: Option<BrdIdx>,
|
||||||
previous_boards: Vec<Board>,
|
previous_boards: Vec<Board>,
|
||||||
painter: Option<Painter>
|
painter: Option<Painter>
|
||||||
}
|
}
|
||||||
@ -56,10 +57,35 @@ impl Game {
|
|||||||
self.current.current_turn
|
self.current.current_turn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get square on current board for given index
|
||||||
pub fn current_cell_state(&self, idx: &BrdIdx) -> Square {
|
pub fn current_cell_state(&self, idx: &BrdIdx) -> Square {
|
||||||
self.current.cell(self.current.cell_idx(*idx))
|
self.current.cell(self.current.cell_idx(*idx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set given index as selected piece
|
||||||
|
/// TODO: Check whether valid square?
|
||||||
|
pub fn set_selected(&mut self, idx: &BrdIdx) {
|
||||||
|
|
||||||
|
if self.current.cell(self.current.cell_idx(*idx)).state != Occupied {
|
||||||
|
panic!("Tried to select an unoccupied or empty square");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.selected_piece = Some(*idx);
|
||||||
|
match &mut self.painter {
|
||||||
|
Some(p) => p.set_selected(&Some(*idx)),
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear currently selected piece
|
||||||
|
pub fn clear_selected(&mut self) {
|
||||||
|
self.selected_piece = None;
|
||||||
|
match &mut self.painter {
|
||||||
|
Some(p) => p.set_selected(&None),
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to make a move given a source and destination index
|
/// Attempt to make a move given a source and destination index
|
||||||
pub fn make_move(&mut self, from: BrdIdx, to: BrdIdx) -> Moveable {
|
pub fn make_move(&mut self, from: BrdIdx, to: BrdIdx) -> Moveable {
|
||||||
let able = self.current.can_move(from, to);
|
let able = self.current.can_move(from, to);
|
||||||
@ -114,6 +140,7 @@ impl Game {
|
|||||||
current: Board::init_game(
|
current: Board::init_game(
|
||||||
Board::new(width, height, first_turn), piece_rows,
|
Board::new(width, height, first_turn), piece_rows,
|
||||||
),
|
),
|
||||||
|
selected_piece: None,
|
||||||
previous_boards: Vec::with_capacity(10),
|
previous_boards: Vec::with_capacity(10),
|
||||||
painter: None,
|
painter: None,
|
||||||
}
|
}
|
||||||
@ -124,6 +151,7 @@ impl Game {
|
|||||||
current: Board::init_game(
|
current: Board::init_game(
|
||||||
Board::new(width, height, first_turn), piece_rows,
|
Board::new(width, height, first_turn), piece_rows,
|
||||||
),
|
),
|
||||||
|
selected_piece: None,
|
||||||
previous_boards: Vec::with_capacity(10),
|
previous_boards: Vec::with_capacity(10),
|
||||||
painter: Some(
|
painter: Some(
|
||||||
Painter::new(canvas_width, canvas_height, canvas_id)
|
Painter::new(canvas_width, canvas_height, canvas_id)
|
||||||
|
47
src/paint.rs
47
src/paint.rs
@ -10,7 +10,7 @@ use web_sys::CanvasRenderingContext2d;
|
|||||||
use std::f64;
|
use std::f64;
|
||||||
|
|
||||||
use crate::log;
|
use crate::log;
|
||||||
use crate::board::{Board};
|
use crate::board::{Board, BrdIdx};
|
||||||
use crate::board::iter::PieceIterator;
|
use crate::board::iter::PieceIterator;
|
||||||
|
|
||||||
use crate::board::enums::Team::*;
|
use crate::board::enums::Team::*;
|
||||||
@ -32,11 +32,16 @@ const DRAW_OUTLINE: bool = true;
|
|||||||
const WHITE_PIECE: &str = "#dbdbdb";
|
const WHITE_PIECE: &str = "#dbdbdb";
|
||||||
/// Default hex colour value for black pieces
|
/// Default hex colour value for black pieces
|
||||||
const BLACK_PIECE: &str = "#ed0000";
|
const BLACK_PIECE: &str = "#ed0000";
|
||||||
|
/// Default hex colour value for selected piece
|
||||||
|
const SELECTED_PIECE: &str = "#fffd78";
|
||||||
|
|
||||||
/// Default hex colour value for white piece outline
|
/// Default hex colour value for white piece outline
|
||||||
const WHITE_PIECE_OUTLINE: &str = "#9c9c9c";
|
const WHITE_PIECE_OUTLINE: &str = "#9c9c9c";
|
||||||
/// Default hex colour value for black piece outline
|
/// Default hex colour value for black piece outline
|
||||||
const BLACK_PIECE_OUTLINE: &str = "#a60000";
|
const BLACK_PIECE_OUTLINE: &str = "#a60000";
|
||||||
|
/// Default hex colour value for selected piece outline
|
||||||
|
// const SELECTED_PIECE_OUTLINE: &str = "#dedc73";
|
||||||
|
const SELECTED_PIECE_OUTLINE: &str = "#d1cf45";
|
||||||
/// Default hex colour value for black piece outline
|
/// Default hex colour value for black piece outline
|
||||||
const KING_OUTLINE: &str = "#ffea00";
|
const KING_OUTLINE: &str = "#ffea00";
|
||||||
/// Whether to outline pieces
|
/// Whether to outline pieces
|
||||||
@ -53,15 +58,18 @@ const PIECE_MARGIN: f64 = 10.0;
|
|||||||
pub struct Painter {
|
pub struct Painter {
|
||||||
canvas: HtmlCanvasElement,
|
canvas: HtmlCanvasElement,
|
||||||
context: CanvasRenderingContext2d,
|
context: CanvasRenderingContext2d,
|
||||||
|
selected_idx: Option<BrdIdx>,
|
||||||
|
|
||||||
white_square: JsValue,
|
white_square: JsValue,
|
||||||
black_square: JsValue,
|
black_square: JsValue,
|
||||||
|
|
||||||
white_piece: JsValue,
|
white_piece: JsValue,
|
||||||
black_piece: JsValue,
|
black_piece: JsValue,
|
||||||
|
selected_piece: JsValue,
|
||||||
|
|
||||||
white_piece_line: JsValue,
|
white_piece_line: JsValue,
|
||||||
black_piece_line: JsValue,
|
black_piece_line: JsValue,
|
||||||
|
selected_piece_line: JsValue,
|
||||||
king_line: JsValue,
|
king_line: JsValue,
|
||||||
|
|
||||||
piece_lines: bool,
|
piece_lines: bool,
|
||||||
@ -76,6 +84,11 @@ pub struct Painter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
|
/// Set selected piece by board index
|
||||||
|
pub fn set_selected(&mut self, idx: &Option<BrdIdx>) {
|
||||||
|
self.selected_idx = *idx;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a canvas by element ID
|
/// Get a canvas by element ID
|
||||||
fn get_canvas(canvas_id: &str) -> HtmlCanvasElement {
|
fn get_canvas(canvas_id: &str) -> HtmlCanvasElement {
|
||||||
// JS WINDOW
|
// JS WINDOW
|
||||||
@ -142,15 +155,18 @@ impl Painter {
|
|||||||
canvas,
|
canvas,
|
||||||
context,
|
context,
|
||||||
width, height,
|
width, height,
|
||||||
|
selected_idx: None,
|
||||||
|
|
||||||
white_square: JsValue::from_str(WHITE_SQUARE),
|
white_square: JsValue::from_str(WHITE_SQUARE),
|
||||||
black_square: JsValue::from_str(BLACK_SQUARE),
|
black_square: JsValue::from_str(BLACK_SQUARE),
|
||||||
|
|
||||||
white_piece: JsValue::from_str(WHITE_PIECE),
|
white_piece: JsValue::from_str(WHITE_PIECE),
|
||||||
black_piece: JsValue::from_str(BLACK_PIECE),
|
black_piece: JsValue::from_str(BLACK_PIECE),
|
||||||
|
selected_piece: JsValue::from_str(SELECTED_PIECE),
|
||||||
|
|
||||||
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
||||||
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
||||||
|
selected_piece_line: JsValue::from_str(SELECTED_PIECE_OUTLINE),
|
||||||
king_line: JsValue::from_str(KING_OUTLINE),
|
king_line: JsValue::from_str(KING_OUTLINE),
|
||||||
piece_lines: DRAW_PIECE_OUTLINES,
|
piece_lines: DRAW_PIECE_OUTLINES,
|
||||||
piece_line_width: PIECE_OUTLINE_WIDTH,
|
piece_line_width: PIECE_OUTLINE_WIDTH,
|
||||||
@ -172,15 +188,18 @@ impl Painter {
|
|||||||
canvas,
|
canvas,
|
||||||
context,
|
context,
|
||||||
width, height,
|
width, height,
|
||||||
|
selected_idx: None,
|
||||||
|
|
||||||
white_square: JsValue::from_str(WHITE_SQUARE),
|
white_square: JsValue::from_str(WHITE_SQUARE),
|
||||||
black_square: JsValue::from_str(BLACK_SQUARE),
|
black_square: JsValue::from_str(BLACK_SQUARE),
|
||||||
|
|
||||||
white_piece: JsValue::from_str(WHITE_PIECE),
|
white_piece: JsValue::from_str(WHITE_PIECE),
|
||||||
black_piece: JsValue::from_str(BLACK_PIECE),
|
black_piece: JsValue::from_str(BLACK_PIECE),
|
||||||
|
selected_piece: JsValue::from_str(SELECTED_PIECE),
|
||||||
|
|
||||||
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
||||||
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
||||||
|
selected_piece_line: JsValue::from_str(SELECTED_PIECE_OUTLINE),
|
||||||
king_line: JsValue::from_str(KING_OUTLINE),
|
king_line: JsValue::from_str(KING_OUTLINE),
|
||||||
piece_lines: DRAW_PIECE_OUTLINES,
|
piece_lines: DRAW_PIECE_OUTLINES,
|
||||||
piece_line_width: PIECE_OUTLINE_WIDTH,
|
piece_line_width: PIECE_OUTLINE_WIDTH,
|
||||||
@ -336,5 +355,31 @@ impl Painter {
|
|||||||
None => panic!("No piece found when attempting to draw, idx: {}, square: {:?}", idx, square),
|
None => panic!("No piece found when attempting to draw, idx: {}, square: {:?}", idx, square),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(selected_idx) = self.selected_idx {
|
||||||
|
self.context.set_fill_style(&self.selected_piece);
|
||||||
|
self.context.set_stroke_style(&self.selected_piece_line);
|
||||||
|
|
||||||
|
let center_x: f64 = (selected_idx.col as f64 * cell_width as f64) + (cell_width as f64) / 2.0;
|
||||||
|
let center_y: f64 = (selected_idx.row as f64 * cell_height as f64) + (cell_height as f64) / 2.0;
|
||||||
|
|
||||||
|
self.context.begin_path();
|
||||||
|
match self.context.arc(
|
||||||
|
center_x,
|
||||||
|
center_y,
|
||||||
|
(cell_width as f64 / 2.0) - PIECE_MARGIN, // radius
|
||||||
|
0.0, // start angle
|
||||||
|
f64::consts::PI * 2.0) // end angle
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => log!("Failed to paint selected piece, idx: {}, {:?}", selected_idx, err),
|
||||||
|
};
|
||||||
|
self.context.fill();
|
||||||
|
|
||||||
|
if self.piece_lines {
|
||||||
|
self.context.set_line_width(self.piece_line_width);
|
||||||
|
self.context.stroke()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -41,16 +41,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row p-3">
|
<div class="row p-3">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<a href="doc/draught" class="btn btn-secondary">Docs</a>
|
<a href="doc/draught" class="btn btn-secondary" target="_blank">Docs</a>
|
||||||
<!-- <button id="startBtn" class="btn btn-primary">Start</button> -->
|
<button id="startBtn" class="btn btn-primary">Start</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row p-3">
|
<div class="row p-3">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-12">
|
||||||
<h1 id="team-p"></h1>
|
<h1 id="team-p"></h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
</div>
|
||||||
|
<div class="row p-3">
|
||||||
|
<div class="col-sm-12">
|
||||||
<p hidden id="status-p"></p>
|
<p hidden id="status-p"></p>
|
||||||
<div hidden id="status-d" class="alert alert-danger" role="alert">
|
<div hidden id="status-d" class="alert alert-danger" role="alert">
|
||||||
A simple success alert—check it out!
|
A simple success alert—check it out!
|
||||||
|
59
www/index.js
59
www/index.js
@ -35,23 +35,20 @@ const statusText = document.getElementById("status-p");
|
|||||||
const statusAlert = document.getElementById("status-d");
|
const statusAlert = document.getElementById("status-d");
|
||||||
const teamText = document.getElementById("team-p");
|
const teamText = document.getElementById("team-p");
|
||||||
|
|
||||||
// const startBtn = document.getElementById("startBtn");
|
const startBtn = document.getElementById("startBtn");
|
||||||
// startBtn.onclick = start_game;
|
startBtn.onclick = start_game;
|
||||||
|
|
||||||
let statusTimeout = null;
|
let statusTimeout = null;
|
||||||
let setStatus = setStatusAlert;
|
let setStatus = setStatusAlert;
|
||||||
|
|
||||||
let current_state = GameState.HUMAN_TURN.THINKING;
|
let current_state = GameState.HUMAN_TURN.THINKING;
|
||||||
let painter = new Painter(CANVAS_WIDTH, CANVAS_HEIGHT, "game-canvas");
|
|
||||||
// painter.draw(board);
|
let game = null;
|
||||||
|
let painter = null;
|
||||||
|
|
||||||
let clicks = [];
|
let clicks = [];
|
||||||
|
|
||||||
let game = new Game(BOARD_WIDTH, BOARD_HEIGHT, PIECE_ROWS, Team.Black);
|
start_game();
|
||||||
game.set_painter(painter);
|
|
||||||
game.draw();
|
|
||||||
|
|
||||||
updateTeamText();
|
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
// CANVAS
|
// CANVAS
|
||||||
@ -75,6 +72,7 @@ canvas.addEventListener("click", (event) => {
|
|||||||
|
|
||||||
function start_game() {
|
function start_game() {
|
||||||
game = new Game(BOARD_WIDTH, BOARD_HEIGHT, PIECE_ROWS, Team.Black);
|
game = new Game(BOARD_WIDTH, BOARD_HEIGHT, PIECE_ROWS, Team.Black);
|
||||||
|
painter = new Painter(CANVAS_WIDTH, CANVAS_HEIGHT, "game-canvas");
|
||||||
game.set_painter(painter);
|
game.set_painter(painter);
|
||||||
game.draw();
|
game.draw();
|
||||||
|
|
||||||
@ -85,6 +83,7 @@ function start_game() {
|
|||||||
function process_canvas_click(cell_coord) {
|
function process_canvas_click(cell_coord) {
|
||||||
|
|
||||||
switch(current_state) {
|
switch(current_state) {
|
||||||
|
// first click of a move
|
||||||
case GameState.HUMAN_TURN.THINKING:
|
case GameState.HUMAN_TURN.THINKING:
|
||||||
if (game.current_cell_state(cell_coord).state != SquareState.Occupied ) {
|
if (game.current_cell_state(cell_coord).state != SquareState.Occupied ) {
|
||||||
return;
|
return;
|
||||||
@ -94,31 +93,36 @@ function process_canvas_click(cell_coord) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Your turn, first piece picked");
|
// console.log("Your turn, first piece picked");
|
||||||
|
|
||||||
clicks.push(cell_coord);
|
clicks.push(cell_coord);
|
||||||
current_state = GameState.HUMAN_TURN.FROM_SELECTED;
|
current_state = GameState.HUMAN_TURN.FROM_SELECTED;
|
||||||
|
game.set_selected(cell_coord);
|
||||||
|
game.draw();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// second click of a move
|
||||||
case GameState.HUMAN_TURN.FROM_SELECTED:
|
case GameState.HUMAN_TURN.FROM_SELECTED:
|
||||||
if (game.current_cell_state(cell_coord).state != SquareState.Empty ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Your turn, first piece already picked, picking second");
|
// second click is different to first, process as move
|
||||||
|
// otherwise, will skip straight to clean up (clear selected and clicks)
|
||||||
|
if (!clicks[0].eq(cell_coord)) {
|
||||||
|
|
||||||
clicks.push(cell_coord);
|
if (game.current_cell_state(cell_coord).state != SquareState.Empty ) {
|
||||||
|
return;
|
||||||
if (clicks.length != 2) {
|
}
|
||||||
setStatus(`Error: wrong number of clicks to process ${clicks.length}`);
|
|
||||||
console.error(`Error: wrong number of clicks to process ${clicks.length}`);
|
// console.log("Your turn, first piece already picked, picking second");
|
||||||
|
|
||||||
return;
|
clicks.push(cell_coord);
|
||||||
}
|
|
||||||
|
if (clicks.length != 2) {
|
||||||
if (clicks[0].eq(clicks[1])) {
|
setStatus(`Error: wrong number of clicks to process ${clicks.length}`);
|
||||||
setStatus("Move Cancelled");
|
console.error(`Error: wrong number of clicks to process ${clicks.length}`);
|
||||||
} else {
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let status = game.make_move(clicks[0], clicks[1]);
|
let status = game.make_move(clicks[0], clicks[1]);
|
||||||
|
|
||||||
@ -153,6 +157,7 @@ function process_canvas_click(cell_coord) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game.clear_selected();
|
||||||
game.draw();
|
game.draw();
|
||||||
clicks = [];
|
clicks = [];
|
||||||
current_state = GameState.HUMAN_TURN.THINKING;
|
current_state = GameState.HUMAN_TURN.THINKING;
|
||||||
|
Loading…
Reference in New Issue
Block a user