beginning canvas drawing, fixing warnings
This commit is contained in:
parent
74a2757df9
commit
f9e20a57bf
17
Cargo.toml
17
Cargo.toml
@ -9,16 +9,10 @@ repository = "https://github.com/Sarsoo/checkers"
|
|||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["console_error_panic_hook",
|
default = ["console_error_panic_hook"]
|
||||||
"random_init"
|
|
||||||
]
|
|
||||||
|
|
||||||
random_init = ["rand", "rand_pcg"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2.74"
|
wasm-bindgen = "0.2.74"
|
||||||
rand = {version = "0.8.4", optional = true }
|
|
||||||
rand_pcg = {version = "0.3.1", optional = true }
|
|
||||||
indextree = "4.3.1"
|
indextree = "4.3.1"
|
||||||
|
|
||||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
@ -38,10 +32,13 @@ wee_alloc = { version = "0.4.5", optional = true }
|
|||||||
version = "0.3.45"
|
version = "0.3.45"
|
||||||
features = [
|
features = [
|
||||||
"console",
|
"console",
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies.getrandom]
|
'CanvasRenderingContext2d',
|
||||||
features = ["js"]
|
'Document',
|
||||||
|
'Element',
|
||||||
|
'HtmlCanvasElement',
|
||||||
|
'Window',
|
||||||
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "0.3.24"
|
wasm-bindgen-test = "0.3.24"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use std::fmt::{Display, Write};
|
use std::fmt::{Display};
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::board::{Board, Piece, Square};
|
use crate::board::{Board, Square};
|
||||||
use crate::board::enums::*;
|
use crate::board::enums::*;
|
||||||
|
|
||||||
pub struct RowIndexIterator<'a> {
|
pub struct RowIndexIterator<'a> {
|
||||||
@ -104,9 +104,10 @@ impl<'a> Iterator for PieceIterator<'a> {
|
|||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::board::enums::SquareState;
|
use crate::board::enums::SquareState;
|
||||||
|
use crate::board::Piece;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
use crate::log;
|
// use crate::log;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ use iter::*;
|
|||||||
use std::fmt::{Display, Write};
|
use std::fmt::{Display, Write};
|
||||||
use std::option::Option;
|
use std::option::Option;
|
||||||
|
|
||||||
|
use crate::log;
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -119,8 +121,8 @@ impl Square {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub struct BrdIdx {
|
pub struct BrdIdx {
|
||||||
row: usize,
|
pub row: usize,
|
||||||
col: usize
|
pub col: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -781,10 +783,13 @@ impl Display for Board {
|
|||||||
for j in 0..self.width {
|
for j in 0..self.width {
|
||||||
let idx = self.cell_index(i, j);
|
let idx = self.cell_index(i, j);
|
||||||
|
|
||||||
match self.cell_state(idx) {
|
let result = match self.cell_state(idx) {
|
||||||
Empty => { write!(string, "_ "); },
|
Empty => write!(string, "_ "),
|
||||||
Occupied => { write!(string, "{} ", self.cell(idx).occupant.unwrap().team); },
|
Occupied => write!(string, "{} ", self.cell(idx).occupant.unwrap().team),
|
||||||
Unplayable => { write!(string, ". "); },
|
Unplayable => write!(string, ". "),
|
||||||
|
};
|
||||||
|
if let Err(err) = result {
|
||||||
|
log!("Error printing cell state, ({}, {}), {}", i, j, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string.push('\n');
|
string.push('\n');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
use crate::log;
|
// use crate::log;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ wasm_bindgen_test_configure!(run_in_browser);
|
|||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn create() {
|
fn create() {
|
||||||
let board = Board::new(STD_WIDTH, STD_HEIGHT, Black);
|
let _ = Board::new(STD_WIDTH, STD_HEIGHT, Black);
|
||||||
assert!(true);
|
assert!(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
//! AI player logic
|
//! AI player logic
|
||||||
|
|
||||||
use indextree::{Arena, NodeId, Node};
|
use indextree::{Arena, NodeId};
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
use wasm_bindgen::prelude::*;
|
// use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use crate::log;
|
// use crate::log;
|
||||||
|
|
||||||
use crate::board::{Square, Board, BrdIdx};
|
use crate::board::{Board, BrdIdx};
|
||||||
use crate::board::enums::{SquareState, MoveType, Moveable, Team, Strength};
|
use crate::board::enums::{MoveType, Moveable, Team};
|
||||||
use crate::board::iter::{PieceIterator};
|
use crate::board::iter::{PieceIterator};
|
||||||
|
|
||||||
use Team::*;
|
// use Team::*;
|
||||||
use Strength::*;
|
// use Strength::*;
|
||||||
use SquareState::*;
|
// use SquareState::*;
|
||||||
|
|
||||||
use std::fmt::{Display, Write};
|
// use std::fmt::{Display, Write};
|
||||||
|
|
||||||
#[cfg(test)] pub mod tests;
|
#[cfg(test)] pub mod tests;
|
||||||
|
|
||||||
@ -116,9 +116,23 @@ impl Computer {
|
|||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_tree(&mut self, board: Board) {
|
// pub fn gen_tree(&mut self, tree: &mut Arena<Board>, board: Board) {
|
||||||
|
|
||||||
}
|
// let boards = self.get_move_boards(&board);
|
||||||
|
|
||||||
|
// let root_id = vec!(tree.new_node(board));
|
||||||
|
// let ids = self.insert_boards(boards);
|
||||||
|
|
||||||
|
// for d in 0..self.search_depth {
|
||||||
|
|
||||||
|
// for root in root_id.iter(){
|
||||||
|
// for id in ids.into_iter() {
|
||||||
|
// root.append(id, tree);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn insert_boards(&mut self, boards: Vec<Board>) -> Vec<NodeId> {
|
pub fn insert_boards(&mut self, boards: Vec<Board>) -> Vec<NodeId> {
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
|
use crate::board::Square;
|
||||||
|
use crate::board::enums::Strength::*;
|
||||||
|
|
||||||
|
use Team::*;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
@ -66,7 +71,7 @@ fn available_moves_jumps() {
|
|||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn available_moves_std_brd() {
|
fn available_moves_std_brd() {
|
||||||
let brd = Board::init_game(Board::new(8, 8, White), 3);
|
let brd = Board::init_game(Board::new(8, 8, White), 3);
|
||||||
let mut brd2 = brd.clone();
|
let brd2 = brd.clone();
|
||||||
let comp = Computer::new(brd, 3, White);
|
let comp = Computer::new(brd, 3, White);
|
||||||
|
|
||||||
// log!("{}", brd2);
|
// log!("{}", brd2);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! Top-level object for managing [`Board`]s, applying and managing turns
|
||||||
|
|
||||||
use crate::board::Board;
|
use crate::board::Board;
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
@ -6,12 +8,13 @@ use wasm_bindgen::prelude::*;
|
|||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
use crate::board::{Square, BrdIdx};
|
use crate::board::{Square, BrdIdx};
|
||||||
use crate::board::enums::{SquareState, Moveable, Team};
|
use crate::board::enums::{Moveable, Team};
|
||||||
|
use crate::paint::Painter;
|
||||||
|
|
||||||
use Team::*;
|
// use Team::*;
|
||||||
use SquareState::*;
|
// use SquareState::*;
|
||||||
|
|
||||||
use std::fmt::{Display, Write};
|
use std::fmt::{Display};
|
||||||
|
|
||||||
#[cfg(test)] pub mod tests;
|
#[cfg(test)] pub mod tests;
|
||||||
|
|
||||||
@ -21,6 +24,7 @@ use std::fmt::{Display, Write};
|
|||||||
pub struct Game {
|
pub struct Game {
|
||||||
current: Board,
|
current: Board,
|
||||||
previous_boards: Vec<Board>,
|
previous_boards: Vec<Board>,
|
||||||
|
painter: Option<Painter>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
@ -37,6 +41,16 @@ impl Game {
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl Game {
|
impl Game {
|
||||||
|
/// Get pointer to current board's squares
|
||||||
|
pub fn current_board_cells(&self) -> *const Square {
|
||||||
|
self.current.cells()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get pointer to current board's squares
|
||||||
|
pub fn current_board_len(&self) -> usize {
|
||||||
|
self.current.num_cells()
|
||||||
|
}
|
||||||
|
|
||||||
/// Current turn's team
|
/// Current turn's team
|
||||||
pub fn current_turn(&self) -> Team {
|
pub fn current_turn(&self) -> Team {
|
||||||
self.current.current_turn
|
self.current.current_turn
|
||||||
@ -94,6 +108,30 @@ impl Game {
|
|||||||
Board::new(width, height, first_turn), piece_rows,
|
Board::new(width, height, first_turn), piece_rows,
|
||||||
),
|
),
|
||||||
previous_boards: Vec::with_capacity(10),
|
previous_boards: Vec::with_capacity(10),
|
||||||
|
painter: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_canvas(width: usize, height: usize, piece_rows: usize, first_turn: Team, canvas_id: &str, canvas_width: u32, canvas_height: u32) -> Game {
|
||||||
|
Game {
|
||||||
|
current: Board::init_game(
|
||||||
|
Board::new(width, height, first_turn), piece_rows,
|
||||||
|
),
|
||||||
|
previous_boards: Vec::with_capacity(10),
|
||||||
|
painter: Some(
|
||||||
|
Painter::new(canvas_width, canvas_height, canvas_id)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_painter(&mut self, value: Painter) {
|
||||||
|
self.painter = Some(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self) {
|
||||||
|
match &self.painter {
|
||||||
|
Some(p) => p.draw(&self.current),
|
||||||
|
None => log!("No painter to draw board with")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,4 +140,4 @@ impl Display for Game {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result{
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result{
|
||||||
write!(f, "{}", self.current)
|
write!(f, "{}", self.current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
use crate::log;
|
// use crate::log;
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
use crate::board::{Piece};
|
// use crate::board::{Piece};
|
||||||
use crate::board::enums::Strength::*;
|
use crate::board::enums::Strength::*;
|
||||||
|
use crate::board::enums::Team::*;
|
||||||
|
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
|
@ -6,6 +6,7 @@ pub mod board;
|
|||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod game;
|
pub mod game;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
|
pub mod paint;
|
||||||
pub mod comp;
|
pub mod comp;
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
@ -13,6 +14,8 @@ use wasm_bindgen::prelude::*;
|
|||||||
|
|
||||||
pub use board::Board;
|
pub use board::Board;
|
||||||
pub use game::Game;
|
pub use game::Game;
|
||||||
|
pub use comp::Computer;
|
||||||
|
pub use paint::Painter;
|
||||||
|
|
||||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
// allocator.
|
// allocator.
|
||||||
@ -30,9 +33,6 @@ macro_rules! log {
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn init_game() {
|
pub fn init_game() {
|
||||||
log!("initialising wasm");
|
log!("Initialising WebAssembly");
|
||||||
utils::set_panic_hook();
|
utils::set_panic_hook();
|
||||||
|
|
||||||
#[cfg(feature = "random_init")]
|
|
||||||
log!("random layout enabled");
|
|
||||||
}
|
}
|
330
src/paint.rs
Normal file
330
src/paint.rs
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
//! Components for painting board states onto HTML canvases
|
||||||
|
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen::{JsCast, JsValue};
|
||||||
|
|
||||||
|
use web_sys::HtmlCanvasElement;
|
||||||
|
use web_sys::CanvasRenderingContext2d;
|
||||||
|
|
||||||
|
use std::f64;
|
||||||
|
|
||||||
|
use crate::log;
|
||||||
|
use crate::board::{Board};
|
||||||
|
use crate::board::iter::PieceIterator;
|
||||||
|
|
||||||
|
use crate::board::enums::Team::*;
|
||||||
|
|
||||||
|
/// Default hex colour value for white square background
|
||||||
|
const WHITE_SQUARE: &str = "#FFFFFF";
|
||||||
|
/// Default hex colour value for black square background
|
||||||
|
const BLACK_SQUARE: &str = "#000000";
|
||||||
|
|
||||||
|
/// Default hex colour value for outline of black squares
|
||||||
|
const SQUARE_OUTLINE: &str = "#9c9c9c";
|
||||||
|
/// Line width when outlining black squares
|
||||||
|
const OUTLINE_WIDTH: f64 = 3.0;
|
||||||
|
/// Whether to outline black squares
|
||||||
|
const DRAW_OUTLINE: bool = true;
|
||||||
|
|
||||||
|
/// Default hex colour value for white pieces
|
||||||
|
const WHITE_PIECE: &str = "#dbdbdb";
|
||||||
|
/// Default hex colour value for black pieces
|
||||||
|
const BLACK_PIECE: &str = "#ed0000";
|
||||||
|
|
||||||
|
/// Default hex colour value for white piece outline
|
||||||
|
const WHITE_PIECE_OUTLINE: &str = "#9c9c9c";
|
||||||
|
/// Default hex colour value for black piece outline
|
||||||
|
const BLACK_PIECE_OUTLINE: &str = "#a60000";
|
||||||
|
/// Whether to outline pieces
|
||||||
|
const DRAW_PIECE_OUTLINES: bool = true;
|
||||||
|
/// Line width for outlining pieces
|
||||||
|
const PIECE_OUTLINE_WIDTH: f64 = 3.0;
|
||||||
|
|
||||||
|
/// Margin from square to define piece radius
|
||||||
|
const PIECE_MARGIN: f64 = 10.0;
|
||||||
|
|
||||||
|
/// Used to paint boards onto HTML canvases
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Painter {
|
||||||
|
canvas: HtmlCanvasElement,
|
||||||
|
context: CanvasRenderingContext2d,
|
||||||
|
|
||||||
|
white_square: JsValue,
|
||||||
|
black_square: JsValue,
|
||||||
|
|
||||||
|
white_piece: JsValue,
|
||||||
|
black_piece: JsValue,
|
||||||
|
|
||||||
|
white_piece_line: JsValue,
|
||||||
|
black_piece_line: JsValue,
|
||||||
|
|
||||||
|
piece_lines: bool,
|
||||||
|
piece_line_width: f64,
|
||||||
|
|
||||||
|
square_outline: JsValue,
|
||||||
|
outline_width: f64,
|
||||||
|
draw_outline: bool,
|
||||||
|
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Painter {
|
||||||
|
/// Get a canvas by element ID
|
||||||
|
fn get_canvas(canvas_id: &str) -> HtmlCanvasElement {
|
||||||
|
// JS WINDOW
|
||||||
|
let window = match web_sys::window(){
|
||||||
|
Some(win) => win,
|
||||||
|
None => panic!("No Js window returned"),
|
||||||
|
};
|
||||||
|
// JS DOCUMENT
|
||||||
|
let document = match window.document() {
|
||||||
|
Some(doc) => doc,
|
||||||
|
None => panic!("No Js window document returned"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// CANVAS
|
||||||
|
let canvas = match document.get_element_by_id(canvas_id) {
|
||||||
|
Some(el) => el,
|
||||||
|
None => panic!("No element found for {}", canvas_id),
|
||||||
|
};
|
||||||
|
let canvas = match canvas.dyn_into::<web_sys::HtmlCanvasElement>() {
|
||||||
|
Ok(el) => el,
|
||||||
|
Err(err) => panic!("Failed to cast canvas {:?}", err),
|
||||||
|
};
|
||||||
|
|
||||||
|
canvas
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a 2D canvas context for a given canvas
|
||||||
|
fn get_canvas_context(canvas: &HtmlCanvasElement) -> CanvasRenderingContext2d {
|
||||||
|
|
||||||
|
// CANVAS CONTEXT
|
||||||
|
let context = match canvas.get_context("2d") {
|
||||||
|
Ok(op) => match op {
|
||||||
|
// UNWRAP OPTION
|
||||||
|
Some(object) => object,
|
||||||
|
None => panic!("Nothing found when unwrapping canvas context"),
|
||||||
|
},
|
||||||
|
Err(err) => panic!("Error when getting canvas context: {:?}", err),
|
||||||
|
};
|
||||||
|
// CAST CONTEXT
|
||||||
|
let context = match context.dyn_into::<web_sys::CanvasRenderingContext2d>() {
|
||||||
|
Ok(dyn_cast) => dyn_cast,
|
||||||
|
Err(cast_err) => panic!("Error when casting canvas context: {:?}", cast_err)
|
||||||
|
};
|
||||||
|
|
||||||
|
context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Painter {
|
||||||
|
|
||||||
|
/// Default constructor which queries for canvas by ID
|
||||||
|
#[wasm_bindgen(constructor)]
|
||||||
|
pub fn new(width: u32, height: u32, canvas_id: &str) -> Painter {
|
||||||
|
|
||||||
|
let canvas = Painter::get_canvas(canvas_id);
|
||||||
|
|
||||||
|
canvas.set_width(width);
|
||||||
|
canvas.set_height(height);
|
||||||
|
|
||||||
|
let context = Painter::get_canvas_context(&canvas);
|
||||||
|
|
||||||
|
Painter {
|
||||||
|
canvas,
|
||||||
|
context,
|
||||||
|
width, height,
|
||||||
|
|
||||||
|
white_square: JsValue::from_str(WHITE_SQUARE),
|
||||||
|
black_square: JsValue::from_str(BLACK_SQUARE),
|
||||||
|
|
||||||
|
white_piece: JsValue::from_str(WHITE_PIECE),
|
||||||
|
black_piece: JsValue::from_str(BLACK_PIECE),
|
||||||
|
|
||||||
|
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
||||||
|
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
||||||
|
piece_lines: DRAW_PIECE_OUTLINES,
|
||||||
|
piece_line_width: PIECE_OUTLINE_WIDTH,
|
||||||
|
|
||||||
|
square_outline: JsValue::from_str(SQUARE_OUTLINE),
|
||||||
|
outline_width: OUTLINE_WIDTH,
|
||||||
|
draw_outline: DRAW_OUTLINE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructor with given canvas element
|
||||||
|
pub fn new_with_canvas(width: u32, height: u32, canvas: HtmlCanvasElement) -> Painter {
|
||||||
|
canvas.set_width(width);
|
||||||
|
canvas.set_height(height);
|
||||||
|
|
||||||
|
let context = Painter::get_canvas_context(&canvas);
|
||||||
|
|
||||||
|
Painter {
|
||||||
|
canvas,
|
||||||
|
context,
|
||||||
|
width, height,
|
||||||
|
|
||||||
|
white_square: JsValue::from_str(WHITE_SQUARE),
|
||||||
|
black_square: JsValue::from_str(BLACK_SQUARE),
|
||||||
|
|
||||||
|
white_piece: JsValue::from_str(WHITE_PIECE),
|
||||||
|
black_piece: JsValue::from_str(BLACK_PIECE),
|
||||||
|
|
||||||
|
white_piece_line: JsValue::from_str(WHITE_PIECE_OUTLINE),
|
||||||
|
black_piece_line: JsValue::from_str(BLACK_PIECE_OUTLINE),
|
||||||
|
piece_lines: DRAW_PIECE_OUTLINES,
|
||||||
|
piece_line_width: PIECE_OUTLINE_WIDTH,
|
||||||
|
|
||||||
|
square_outline: JsValue::from_str(SQUARE_OUTLINE),
|
||||||
|
outline_width: OUTLINE_WIDTH,
|
||||||
|
draw_outline: DRAW_OUTLINE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set new square outline colour value
|
||||||
|
pub fn set_square_outline(&mut self, value: JsValue) {
|
||||||
|
self.square_outline = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set new line width for outlining squares
|
||||||
|
pub fn set_outline_width(&mut self, value: f64) {
|
||||||
|
self.outline_width = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set whether squares are outlined
|
||||||
|
pub fn set_draw_outline(&mut self, value: bool) {
|
||||||
|
self.draw_outline = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the canvas dimensions to the given width and height
|
||||||
|
pub fn reset_dimensions(&self) {
|
||||||
|
self.canvas.set_width(self.width);
|
||||||
|
self.canvas.set_height(self.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether given canvas dimensions divide evenly by given board dimenions
|
||||||
|
pub fn validate_board_dim(&self, board: &Board) -> bool {
|
||||||
|
let mut ans = true;
|
||||||
|
|
||||||
|
if self.height as usize % board.height != 0 {
|
||||||
|
log!("Canvas and board heights do not evenly divide, Canvas({}) / Board({}) = {} px/cell", self.height, board.height, self.height as f32 / board.height as f32);
|
||||||
|
ans = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.width as usize % board.width != 0 {
|
||||||
|
log!("Canvas and board widths do not evenly divide, Canvas({}) / Board({}) = {} px/cell", self.width, board.width, self.width as f32 / board.width as f32);
|
||||||
|
ans = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ans
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw a board onto the canvas
|
||||||
|
pub fn draw(&self, board: &Board) {
|
||||||
|
|
||||||
|
self.validate_board_dim(board);
|
||||||
|
|
||||||
|
let cell_height = self.height as usize / board.height;
|
||||||
|
let cell_width = self.width as usize / board.width;
|
||||||
|
|
||||||
|
self.context.set_fill_style(&self.white_square);
|
||||||
|
self.context.fill_rect(0.0, 0.0, self.width as f64, self.height as f64);
|
||||||
|
|
||||||
|
self.context.set_fill_style(&self.black_square);
|
||||||
|
self.context.set_stroke_style(&self.square_outline);
|
||||||
|
self.context.set_line_width(self.outline_width);
|
||||||
|
|
||||||
|
// Draw black squares onto canvas
|
||||||
|
for i in 0..board.height {
|
||||||
|
for j in 0..board.width {
|
||||||
|
|
||||||
|
if i % 2 == 0 {
|
||||||
|
if j % 2 == 1 {
|
||||||
|
self.context.fill_rect(
|
||||||
|
(j * cell_width) as f64,
|
||||||
|
(i * cell_height) as f64,
|
||||||
|
cell_width as f64,
|
||||||
|
cell_height as f64
|
||||||
|
);
|
||||||
|
|
||||||
|
if self.draw_outline {
|
||||||
|
self.context.stroke_rect(
|
||||||
|
(j * cell_width) as f64,
|
||||||
|
(i * cell_height) as f64,
|
||||||
|
cell_width as f64,
|
||||||
|
cell_height as f64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if j % 2 == 0 {
|
||||||
|
self.context.fill_rect(
|
||||||
|
(j * cell_width) as f64,
|
||||||
|
(i * cell_height) as f64,
|
||||||
|
cell_width as f64,
|
||||||
|
cell_height as f64
|
||||||
|
);
|
||||||
|
|
||||||
|
if self.draw_outline {
|
||||||
|
self.context.stroke_rect(
|
||||||
|
(j * cell_width) as f64,
|
||||||
|
(i * cell_height) as f64,
|
||||||
|
cell_width as f64,
|
||||||
|
cell_height as f64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw pieces onto canvas
|
||||||
|
for (idx, square) in PieceIterator::new(board) {
|
||||||
|
match square.occupant {
|
||||||
|
Some(piece) => {
|
||||||
|
|
||||||
|
let brd_idx = board.board_index(idx);
|
||||||
|
|
||||||
|
match piece.team {
|
||||||
|
Black => {
|
||||||
|
self.context.set_fill_style(&self.black_piece);
|
||||||
|
self.context.set_stroke_style(&self.black_piece_line);
|
||||||
|
},
|
||||||
|
White => {
|
||||||
|
self.context.set_fill_style(&self.white_piece);
|
||||||
|
self.context.set_stroke_style(&self.white_piece_line);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let center_x: f64 = (brd_idx.col as f64 * cell_width as f64) + (cell_width as f64) / 2.0;
|
||||||
|
let center_y: f64 = (brd_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 draw piece, idx: {}, square: {:?}, {:?}", idx, square, err),
|
||||||
|
};
|
||||||
|
self.context.fill();
|
||||||
|
|
||||||
|
if self.piece_lines {
|
||||||
|
self.context.set_line_width(self.piece_line_width);
|
||||||
|
self.context.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
None => panic!("No piece found when attempting to draw, idx: {}, square: {:?}", idx, square),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
extern crate wasm_bindgen_test;
|
extern crate wasm_bindgen_test;
|
||||||
// use wasm_bindgen_test::*;
|
// use wasm_bindgen_test::*;
|
||||||
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
|
// use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
|
||||||
|
|
||||||
wasm_bindgen_test_configure!(run_in_browser);
|
// wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
|
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
|
||||||
<title>game of life</title>
|
<title>draught</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
/* position: absolute; */
|
/* position: absolute; */
|
||||||
|
39
www/index.js
39
www/index.js
@ -1,9 +1,40 @@
|
|||||||
import { init_game } from "draught";
|
import { Game, Board, Painter, Team, init_game } from "draught";
|
||||||
import { memory } from "draught/draught_bg.wasm";
|
import { memory } from "draught/draught_bg.wasm";
|
||||||
|
|
||||||
// let PLAY = true;
|
|
||||||
// let PLAY = false;
|
|
||||||
init_game();
|
init_game();
|
||||||
|
|
||||||
|
const CANVAS_WIDTH = 480;
|
||||||
|
const CANVAS_HEIGHT = 480;
|
||||||
|
|
||||||
|
const BOARD_WIDTH = 8;
|
||||||
|
const BOARD_HEIGHT = 8;
|
||||||
|
|
||||||
|
const PIECE_ROWS = 3;
|
||||||
|
|
||||||
const canvas = document.getElementById("game-canvas");
|
const canvas = document.getElementById("game-canvas");
|
||||||
const ctx = canvas.getContext('2d');
|
canvas.addEventListener("click", (event) => {
|
||||||
|
var mousepos = getMousePos(canvas, event);
|
||||||
|
// console.log(mousepos);
|
||||||
|
var cell = {
|
||||||
|
x: Math.floor((mousepos.x / CANVAS_WIDTH) * BOARD_WIDTH),
|
||||||
|
y: Math.floor((mousepos.y / CANVAS_HEIGHT) * BOARD_HEIGHT),
|
||||||
|
}
|
||||||
|
console.log(cell);
|
||||||
|
})
|
||||||
|
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let painter = new Painter(CANVAS_WIDTH, CANVAS_HEIGHT, "game-canvas");
|
||||||
|
|
||||||
|
// let board = new Board(BOARD_WIDTH, BOARD_HEIGHT, Team.Black);
|
||||||
|
// painter.draw(board);
|
||||||
|
|
||||||
|
let game = new Game(BOARD_WIDTH, BOARD_HEIGHT, PIECE_ROWS, Team.Black, "game-canvas", CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||||
|
game.set_painter(painter);
|
||||||
|
game.draw();
|
||||||
|
Loading…
Reference in New Issue
Block a user