Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Piece moving in frontend and engine #4

Merged
merged 9 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.