initial commit with board skeleton
This commit is contained in:
commit
98abdcea45
44
.github/workflows/test.yml
vendored
Normal file
44
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
name: test and deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install wasm-pack
|
||||||
|
uses: jetli/wasm-pack-action@v0.3.0
|
||||||
|
|
||||||
|
- name: Build Rust for WASM
|
||||||
|
run: wasm-pack build
|
||||||
|
|
||||||
|
- name: Test WASM in-browser
|
||||||
|
run: wasm-pack test --firefox --chrome --headless
|
||||||
|
|
||||||
|
# - name: Install Node
|
||||||
|
# uses: actions/setup-node@v2
|
||||||
|
# with:
|
||||||
|
# node-version: 16
|
||||||
|
|
||||||
|
# - name: Install Node Modules
|
||||||
|
# run: npm ci
|
||||||
|
# working-directory: ./www
|
||||||
|
|
||||||
|
# - name: Build Js
|
||||||
|
# run: npm run build --if-present
|
||||||
|
# working-directory: ./www
|
||||||
|
|
||||||
|
# - name: Deploy To Pages
|
||||||
|
# uses: peaceiris/actions-gh-pages@v3
|
||||||
|
# with:
|
||||||
|
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# publish_dir: ./www/dist
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/
|
||||||
|
wasm-pack.log
|
55
Cargo.toml
Normal file
55
Cargo.toml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
[package]
|
||||||
|
name = "draught"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["aj <andrewjpack@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
repository = "https://github.com/Sarsoo/checkers"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook",
|
||||||
|
"random_init"
|
||||||
|
]
|
||||||
|
|
||||||
|
random_init = ["rand", "rand_pcg"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = "0.2.74"
|
||||||
|
rand = {version = "0.8.4", optional = true }
|
||||||
|
rand_pcg = {version = "0.3.1", optional = true }
|
||||||
|
indextree = "4.3.1"
|
||||||
|
|
||||||
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||||
|
# code size when deploying.
|
||||||
|
console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||||
|
|
||||||
|
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||||
|
# compared to the default allocator's ~10K. It is slower than the default
|
||||||
|
# allocator, however.
|
||||||
|
#
|
||||||
|
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||||
|
wee_alloc = { version = "0.4.5", optional = true }
|
||||||
|
|
||||||
|
[dependencies.web-sys]
|
||||||
|
version = "0.3.45"
|
||||||
|
features = [
|
||||||
|
"console",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependencies.getrandom]
|
||||||
|
features = ["js"]
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen-test = "0.3.24"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Tell `rustc` to optimize for small code size.
|
||||||
|
opt-level = "s"
|
||||||
|
|
||||||
|
[package.metadata.wasm-pack.profile.release]
|
||||||
|
wasm-opt = false
|
||||||
|
|
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Draught
|
||||||
|
===============
|
||||||
|
|
||||||
|
![gof-ci](https://github.com/sarsoo/draught/actions/workflows/test.yml/badge.svg)
|
||||||
|
|
||||||
|
## [Try it Out!](https://sarsoo.github.io/draught/)
|
||||||
|
|
||||||
|
WASM-based checkers game. Looking to implement a minimax based AI.
|
||||||
|
|
||||||
|
Rust WASM module for game logic with a JS frontend for rendering and processing user input.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
1. Setup a Rust + wasm-pack environment and a Node environment
|
||||||
|
2. Build the Rust library into a WASM module
|
||||||
|
- `wasm-pack build`
|
||||||
|
3. Move to the Js workspace
|
||||||
|
- `cd www`
|
||||||
|
4. Install the Js dependencies
|
||||||
|
- `npm install`
|
||||||
|
5. Build the Js frontend with Rust WASM module
|
||||||
|
- `npm run build`
|
280
src/lib.rs
Normal file
280
src/lib.rs
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
mod utils;
|
||||||
|
|
||||||
|
use std::fmt::{Display, Write};
|
||||||
|
use std::option::Option;
|
||||||
|
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
extern crate indextree;
|
||||||
|
use indextree::Arena;
|
||||||
|
|
||||||
|
pub const STD_WIDTH: usize = 8;
|
||||||
|
pub const STD_HEIGHT: usize = 8;
|
||||||
|
|
||||||
|
// use rand::prelude::*;
|
||||||
|
|
||||||
|
// use rand_pcg::Pcg64Mcg;
|
||||||
|
|
||||||
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
|
// allocator.
|
||||||
|
// #[cfg(feature = "wee_alloc")]
|
||||||
|
// #[global_allocator]
|
||||||
|
// static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
|
||||||
|
macro_rules! log {
|
||||||
|
( $( $t:tt )* ) => {
|
||||||
|
web_sys::console::log_1(&format!( $( $t )* ).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn init_game() {
|
||||||
|
log!("initialising wasm");
|
||||||
|
utils::set_panic_hook();
|
||||||
|
|
||||||
|
#[cfg(feature = "random_init")]
|
||||||
|
log!("random layout enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum Team {
|
||||||
|
Black = 0,
|
||||||
|
White = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum Strength {
|
||||||
|
Man = 0,
|
||||||
|
King = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum SquareState {
|
||||||
|
Empty = 0,
|
||||||
|
Occupied = 1,
|
||||||
|
Unplayable = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SquareState {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
SquareState::Empty => {write!(f, "{}", 'E')},
|
||||||
|
SquareState::Occupied => {write!(f, "{}", 'O')},
|
||||||
|
SquareState::Unplayable => {write!(f, "{}", 'U')},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Piece {
|
||||||
|
id: u8,
|
||||||
|
team: Team,
|
||||||
|
strength: Strength
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Square {
|
||||||
|
occupant: Option<Piece>,
|
||||||
|
state: SquareState
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Square {
|
||||||
|
fn new(state: SquareState, occupant: Option<Piece>) -> Square{
|
||||||
|
Square {
|
||||||
|
occupant,
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub struct BrdIdx {
|
||||||
|
row: usize,
|
||||||
|
col: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl BrdIdx {
|
||||||
|
pub fn from(row: usize, col: usize) -> BrdIdx {
|
||||||
|
BrdIdx{
|
||||||
|
row, col
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// BOARD
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Board {
|
||||||
|
cells: Vec<Square>,
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
|
||||||
|
current_turn: Team
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Board {
|
||||||
|
pub fn cell(&self, idx: usize) -> &Square {
|
||||||
|
&self.cells[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grid_cell(&self, idx: BrdIdx) -> &Square {
|
||||||
|
self.cell(self.cell_idx(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell_mut(&mut self, idx: usize) -> &mut Square {
|
||||||
|
&mut self.cells[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Board {
|
||||||
|
pub fn cell_index(&self, row: usize, col: usize) -> usize {
|
||||||
|
(row * self.width) + col
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell_idx(&self, idx: BrdIdx) -> usize {
|
||||||
|
self.cell_index(idx.row, idx.col)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn board_index(&self, idx: usize) -> BrdIdx {
|
||||||
|
let row = idx / self.width;
|
||||||
|
let col = idx - (row * self.width);
|
||||||
|
BrdIdx::from(row, col)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn diagonal_indices(&self, idx: BrdIdx) -> Option<Vec<usize>> {
|
||||||
|
if self.cell_state(self.cell_idx(idx)) == SquareState::Unplayable {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let height_idx = self.height - 1;
|
||||||
|
let width_idx = self.width - 1;
|
||||||
|
|
||||||
|
let mut cells = Vec::with_capacity(4);
|
||||||
|
|
||||||
|
if idx.row > 0 {
|
||||||
|
if idx.col > 0 {
|
||||||
|
cells.push(
|
||||||
|
self.cell_index(idx.row - 1, idx.col - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx.col < width_idx {
|
||||||
|
cells.push(
|
||||||
|
self.cell_index(idx.row - 1, idx.col + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx.row < height_idx {
|
||||||
|
if idx.col > 0 {
|
||||||
|
cells.push(
|
||||||
|
self.cell_index(idx.row + 1, idx.col - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx.col < width_idx {
|
||||||
|
cells.push(
|
||||||
|
self.cell_index(idx.row + 1, idx.col + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cells.shrink_to_fit();
|
||||||
|
Some(cells)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn can_move(&self, from: BrdIdx, to: BrdIdx) -> bool {
|
||||||
|
// let diagonals = self.diagonal_indices(from);
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn new(width: usize, height: usize) -> Board {
|
||||||
|
let total_cells = width * height;
|
||||||
|
|
||||||
|
let mut cells: Vec<Square> = Vec::with_capacity(total_cells);
|
||||||
|
let mut playable = false;
|
||||||
|
|
||||||
|
for i in 0..height {
|
||||||
|
for _ in 0..width {
|
||||||
|
if playable {
|
||||||
|
cells.push(Square::new(SquareState::Empty, None));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cells.push(Square::new(SquareState::Unplayable, None));
|
||||||
|
}
|
||||||
|
playable = !playable;
|
||||||
|
}
|
||||||
|
playable = i % 2 == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Board {
|
||||||
|
cells,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
|
||||||
|
current_turn: Team::Black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_turn(&self) -> Team {
|
||||||
|
self.current_turn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cells(&self) -> *const Square {
|
||||||
|
self.cells.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn num_cells(&self) -> usize {
|
||||||
|
self.cells.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell_state(&self, idx: usize) -> SquareState {
|
||||||
|
self.cell(idx).state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Board {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result{
|
||||||
|
let mut string = String::new();
|
||||||
|
|
||||||
|
for i in 0..self.height {
|
||||||
|
for j in 0..self.width {
|
||||||
|
write!(string, "{}",
|
||||||
|
self.cell_state( // empty, unocc, unplayable
|
||||||
|
self.cell_index( // 1d vec idx from 2d board idx
|
||||||
|
i, j // 2d board idx
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
string.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "{}", string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// GAME
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct Game {
|
||||||
|
current: Board,
|
||||||
|
tree: Arena<Board>
|
||||||
|
}
|
10
src/utils.rs
Normal file
10
src/utils.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
pub fn set_panic_hook() {
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
}
|
131
tests/board.rs
Normal file
131
tests/board.rs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
//! Test suite for the Web and headless browsers.
|
||||||
|
|
||||||
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
|
extern crate wasm_bindgen_test;
|
||||||
|
// use wasm_bindgen_test::*;
|
||||||
|
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};
|
||||||
|
|
||||||
|
wasm_bindgen_test_configure!(run_in_browser);
|
||||||
|
|
||||||
|
extern crate web_sys;
|
||||||
|
use web_sys::console;
|
||||||
|
|
||||||
|
extern crate draught;
|
||||||
|
use draught::{Board, BrdIdx, SquareState, STD_WIDTH, STD_HEIGHT};
|
||||||
|
|
||||||
|
macro_rules! log {
|
||||||
|
( $( $t:tt )* ) => {
|
||||||
|
web_sys::console::log_1(&format!( $( $t )* ).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn create() {
|
||||||
|
let board = Board::new(STD_WIDTH, STD_HEIGHT);
|
||||||
|
assert!(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn std_num_cells() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(64, board.num_cells());
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// INDEXING
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn cell_index_top_left() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(0, board.cell_index(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn cell_index_central() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(9, board.cell_index(1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn cell_index_central_2() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(17, board.cell_index(2, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn board_index() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
|
||||||
|
// first row
|
||||||
|
assert_eq!(BrdIdx::from(0, 5), board.board_index(5));
|
||||||
|
// second row
|
||||||
|
assert_eq!(BrdIdx::from(1, 6), board.board_index(14));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// SQUARE STATE
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn first_square_unplayable() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(SquareState::Unplayable, board.cell_state(board.cell_index(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn first_square_row_5_unplayable() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(SquareState::Empty, board.cell_state(board.cell_index(5, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_unplayable() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(None, board.diagonal_indices(BrdIdx::from(7, 7)));
|
||||||
|
assert_eq!(None, board.diagonal_indices(BrdIdx::from(0, 0)));
|
||||||
|
assert_eq!(None, board.diagonal_indices(BrdIdx::from(1, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_central() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![1, 3, 17, 19]), board.diagonal_indices(BrdIdx::from(1, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_top_row() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![8, 10]), board.diagonal_indices(BrdIdx::from(0, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_left_column() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![1, 17]), board.diagonal_indices(BrdIdx::from(1, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_bottom_row() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![49, 51]), board.diagonal_indices(BrdIdx::from(7, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_right_column() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![14, 30]), board.diagonal_indices(BrdIdx::from(2, 7)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_top_right() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![14]), board.diagonal_indices(BrdIdx::from(0, 7)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn moveable_indices_bottom_left() {
|
||||||
|
let board = Board::new(8, 8);
|
||||||
|
assert_eq!(Some(vec![49]), board.diagonal_indices(BrdIdx::from(7, 0)));
|
||||||
|
}
|
2
www/.gitignore
vendored
Normal file
2
www/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
5
www/bootstrap.js
vendored
Normal file
5
www/bootstrap.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// A dependency graph that contains any wasm must all be imported
|
||||||
|
// asynchronously. This `bootstrap.js` file does the single async import, so
|
||||||
|
// that no one else needs to worry about it again.
|
||||||
|
import("./index.js")
|
||||||
|
.catch(e => console.error("Error importing `index.js`:", e));
|
49
www/index.html
Normal file
49
www/index.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<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"
|
||||||
|
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
|
||||||
|
<title>game of life</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
/* position: absolute; */
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="card container text-center p-4 m-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h1>Draught 🚀</h1>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <pre id="game-of-life-canvas"></pre> -->
|
||||||
|
<canvas id="game-canvas" class="pb-2"></canvas>
|
||||||
|
|
||||||
|
<script src="./bootstrap.js"></script>
|
||||||
|
|
||||||
|
<a href="https://github.com/sarsoo"><img src="https://storage.googleapis.com/sarsooxyzstatic/andy.png" class=" pb-2" style="width: 150px" /></a>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
9
www/index.js
Normal file
9
www/index.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { init_game } from "draught";
|
||||||
|
import { memory } from "draught/draught_bg.wasm";
|
||||||
|
|
||||||
|
// let PLAY = true;
|
||||||
|
// let PLAY = false;
|
||||||
|
init_game();
|
||||||
|
|
||||||
|
const canvas = document.getElementById("game-canvas");
|
||||||
|
const ctx = canvas.getContext('2d');
|
34
www/package.json
Normal file
34
www/package.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "draught",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Rust wasm-based checkers game",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --config webpack.config.js",
|
||||||
|
"start": "webpack serve --config webpack.config.js --progress"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/Sarsoo/draught.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"webassembly",
|
||||||
|
"wasm",
|
||||||
|
"rust",
|
||||||
|
"webpack"
|
||||||
|
],
|
||||||
|
"author": "sarsoo",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/Sarsoo/draught/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/Sarsoo/draught#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"gameoflife": "file:../pkg"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"copy-webpack-plugin": "^9.0.0",
|
||||||
|
"webpack": "^5.40.0",
|
||||||
|
"webpack-cli": "^4.7.2",
|
||||||
|
"webpack-dev-server": "^3.11.2"
|
||||||
|
}
|
||||||
|
}
|
23
www/webpack.config.js
Normal file
23
www/webpack.config.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: "./bootstrap.js",
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, "dist"),
|
||||||
|
filename: "bootstrap.js",
|
||||||
|
},
|
||||||
|
mode: "development",
|
||||||
|
experiments: {
|
||||||
|
asyncWebAssembly: true
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
from: path.resolve(__dirname, "index.html")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user