Skip to content

Commit

Permalink
Piece moving in frontend and engine (#4)
Browse files Browse the repository at this point in the history
Co-authored-by: Solomon Pierce <[email protected]>
  • Loading branch information
jamespeilunli and spierceVR authored Jul 31, 2023
1 parent f97ab34 commit 0237ad6
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 14 deletions.
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
[package]
name = "chess"
name = "chess_engine"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib"]

[dependencies]
chess = "3.2.0"
lazy_static = "1.4.0"
wasm-bindgen = "0.2"
23 changes: 15 additions & 8 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,27 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.css"
integrity="sha384-q94+BZtLrkL1/ohfjR8c6L+A6qzNH9R2hBLwyoAfu3i/WCvQjzL2RQJ3uNHDISdU" crossorigin="anonymous">

<title>Document</title>
</head>

<body>
<div id="myBoard" style="width: 400px"></div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2"
crossorigin="anonymous"></script>

<script src="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.js"
integrity="sha384-8Vi8VHwn3vjQ9eUHUxex3JSN/NFqUg3QbPyX8kWyb93+8AC/pPWTzj+nHtbC5bxD"
crossorigin="anonymous"></script>
<script src="js/index.js"></script>

<title>Document</title>
</head>

<body>
<div id="myBoard" style="width: 400px"></div>
<script type="module" src="js/output.js"></script>
<script type="module" src="js/index.js"></script>
<div id="promotionModal" style="display: none;">
<p>Choose a piece to promote to:</p>
<button id="queenPromoButton">Queen</button>
<button id="rookPromoButton">Rook</button>
<button id="bishopPromoButton">Bishop</button>
<button id="knightPromoButton">Knight</button>
</div>
</body>

</html>
65 changes: 63 additions & 2 deletions client/js/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,63 @@
var ruyLopez = 'r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R'
var board = Chessboard('myBoard')
import init, { get_engine_move } from "../pkg/chess_engine.js";

document.getElementById("queenPromoButton").addEventListener("click", () => {
handlePromotion('q')
}, false);
document.getElementById("rookPromoButton").addEventListener("click", () => {
handlePromotion('r')
}, false);
document.getElementById("bishopPromoButton").addEventListener("click", () => {
handlePromotion('b')
}, false);
document.getElementById("knightPromoButton").addEventListener("click", () => {
handlePromotion('n')
}, false);

let promotionData;

function handlePromotion(piece) {
closePromotionModal();
let { source, target, oldPos } = promotionData;
makeMove(source, target, oldPos, piece);
}

function openPromotionModal() {
console.log("JS: open modal");
document.getElementById("promotionModal").style.display = "block";
}

function closePromotionModal() {
document.getElementById("promotionModal").style.display = "none";
}

function onDrop(source, target, piece, newPos, oldPos, orientation) {
console.log('JS: Source: ' + source, 'Target: ' + target);
console.log("piece: ", piece);
if (source[1] == 7 && piece == "wP") { // promotion
promotionData = { source: source, target: target, oldPos: oldPos };
openPromotionModal();
}
else { // not a promotion
makeMove(source, target, oldPos, "");
}
}

let config = {
draggable: true,
position: 'start',
onDrop: onDrop,
sparepieces: true
}
window.board = Chessboard('myBoard', config);

function makeMove(source, target, oldPos, promo) {
init().then(() => {
let engine_output = get_engine_move(source, target, promo);
console.log("JS: returned engine move:", engine_output);
if (engine_output === "illegal move") {
window.board.position(oldPos);
} else {
window.board.position(engine_output);
}
});
}
5 changes: 5 additions & 0 deletions client/js/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function my_alert(message) {
console.log(message);
}


62 changes: 62 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//use chess::MoveGen;
//use chess::{Board, Square, Color};
//use std::str::FromStr;
//use chess::EMPTY;
use chess::{Piece, Board, ChessMove, Square, MoveGen};
use wasm_bindgen::prelude::*;
use std::str::FromStr;
use std::sync::Mutex;

#[macro_use]
extern crate lazy_static;

lazy_static! {
static ref BOARD : Mutex<Board> = Mutex::new(Board::default());
}

#[wasm_bindgen(module="/client/js/output.js")]
extern {
pub fn my_alert(s: &str);
pub fn update_board(s: &str);
}

#[wasm_bindgen]
pub fn get_engine_move(source_str: &str, target_str: &str, promotion_str: &str) -> String { // TODO: recieves a player move and returns an FEN containing the new position with the engine move as a response
let source : Square = Square::from_str(source_str).unwrap();
let target : Square = Square::from_str(target_str).unwrap();
let promotion : Option<Piece> = match promotion_str {
"n" => Some(Piece::Knight),
"q" => Some(Piece::Queen),
"b" => Some(Piece::Bishop),
"r" => Some(Piece::Rook),
_ => None,
};

let result = make_move(ChessMove::new(source, target, promotion), &BOARD.lock().unwrap());
match result {
Ok(_) => (),
Err(_) => return "illegal move".to_string(),
}
let engine_move = evaluate(&result.unwrap()).unwrap();
let engine_result = make_move(engine_move, &result.unwrap());
match engine_result {
Ok(_) => (),
Err(_) => panic!("engine made illegal move"),
}
*BOARD.lock().unwrap() = engine_result.unwrap();
return engine_result.unwrap().to_string();
}

fn evaluate(board : &Board) -> Option<ChessMove> { // returns the first legal move based on the board (will implement algorithm to return the "best" move later)
return MoveGen::new_legal(&board).next();
}

fn make_move(chess_move : ChessMove, board : &Board) -> Result<Board, &'static str> {
let mut result = *board;
if !board.legal(chess_move) {
my_alert("RUST: illegal move made");
return Err("illegal move made");
}
board.make_move(chess_move, &mut result);
return Ok(result);
}
3 changes: 0 additions & 3 deletions src/main.rs

This file was deleted.

0 comments on commit 0237ad6

Please sign in to comment.