Skip to content

Commit

Permalink
Merge pull request #2 from RiteshS1/improvement2
Browse files Browse the repository at this point in the history
improved main functionalities
  • Loading branch information
RiteshS1 authored Nov 12, 2024
2 parents d3a8e32 + 90e8a48 commit 80ad3f9
Show file tree
Hide file tree
Showing 5 changed files with 557 additions and 68 deletions.
14 changes: 8 additions & 6 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chess Game</title>
<title>Chessical</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>♔ Chessical ♔</h1>
<div id="board"></div>

<div class="captured-area">
<div id="captured-black" class="captured-pieces"></div>
<div id="captured-white" class="captured-pieces"></div>
<div id="captured-white" class="captured-pieces">White Captured Pieces</div>
<div id="captured-black" class="captured-pieces">Black Captured Pieces</div>
</div>

<div id="evaluation-bar">
<div id="evaluation-score"></div>
</div>

<button id="suggest-best-move">Suggest Best Move</button>

<script src="../scripts/board.js"></script>
<script src="../scripts/evaluation.js"></script>
<script src="../scripts/bestmove.js"></script>
</body>
</html>
</html>
49 changes: 49 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ h1{
width: 80px;
height: 80px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.square-label {
font-size: 12px;
color: #888;
}

.white {
Expand Down Expand Up @@ -66,4 +73,46 @@ h1{
padding: 0.9em;
border-radius: 25px;
font-size: 0.8em;
}

#evaluation-bar {
width: 30px;
height: 400px;
border: 1px solid #ccc;
position: fixed;
right: 50px;
top: 50%;
transform: translateY(-50%);
overflow: hidden;
}

#evaluation-score {
width: 100%;
height: 50%; /* Start at neutral position */
background-color: #000;
position: absolute;
bottom: 0;
transition: height 0.3s ease;
}

.highlighted-square {
background-color: rgba(255, 255, 0, 0.5) !important;
animation: highlightPulse 4s ease-in-out;
}

@keyframes highlightPulse {
0% { background-color: rgba(255, 255, 0, 0.5); }
80% { background-color: rgba(255, 255, 0, 0.5); }
100% { background-color: inherit; }
}

.move-notation {
position: absolute;
bottom: 5px;
right: 5px;
font-size: 12px;
color: #000;
background: rgba(255, 255, 255, 0.8);
padding: 2px 4px;
border-radius: 3px;
}
178 changes: 123 additions & 55 deletions scripts/bestmove.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,35 @@ let isWhiteTurn = true; // Track current turn
function suggestBestMove() {
console.log("Suggesting best move...");
updateBoardState(); // Update the current board state
const depth = 3;
const depth = 3; // Adjust the search depth as needed
const bestMove = findBestMove(depth);

if (bestMove) {
console.log("Best move found:", bestMove);
highlightBestMove(bestMove);
console.log("Best move found:", bestMove.moveNotation);
highlightBestMove(bestMove.from, bestMove.to);
} else {
console.log("No valid moves found");
}
}

function findBestMove(depth) {
const possibleMoves = generateAllPossibleMoves(isWhiteTurn);
console.log("Generated possible moves:", possibleMoves.length);

if (possibleMoves.length === 0) {
const kingPos = findKingPosition(isWhiteTurn);
if (kingPos && isKingInCheck(kingPos.row, kingPos.col, isWhiteTurn)) {
console.log("Checkmate!");
} else {
console.log("Stalemate!");
}
return null;
}

let bestMove = null;
let bestValue = isWhiteTurn ? -Infinity : Infinity;

for (const move of possibleMoves) {
// Make the move temporarily
const capturedPiece = makeTemporaryMove(move);
const value = evaluateMove(move, depth);

// Evaluate the position
const value = minimax(depth - 1, -Infinity, Infinity, !isWhiteTurn);
console.log(`Move ${move.from}->${move.to} evaluated to ${value}`);

// Undo the move
undoTemporaryMove(move, capturedPiece);

// Update best move if necessary
if (isWhiteTurn && value > bestValue) {
bestValue = value;
bestMove = move;
Expand All @@ -41,85 +40,139 @@ function findBestMove(depth) {
bestMove = move;
}
}

return bestMove;
}

function evaluateMove(move, depth) {
// Make the move temporarily
const sourceSquare = document.querySelector(`[data-index="${move.from}"]`);
const targetSquare = document.querySelector(`[data-index="${move.to}"]`);
const targetPiece = targetSquare.querySelector('.piece');

sourceSquare.removeChild(move.piece);
if (targetPiece) {
targetSquare.removeChild(targetPiece);
}
targetSquare.appendChild(move.piece);

// Evaluate position
const value = minimax(depth - 1, -Infinity, Infinity, !isWhiteTurn);

// Undo the move
targetSquare.removeChild(move.piece);
if (targetPiece) {
targetSquare.appendChild(targetPiece);
}
sourceSquare.appendChild(move.piece);

return value;
}

function generateAllPossibleMoves(isWhite) {
const moves = [];
const kingPos = findKingPosition(isWhite);
const inCheck = kingPos && isKingInCheck(kingPos.row, kingPos.col, isWhite);

const squares = document.querySelectorAll('.square');

squares.forEach(sourceSquare => {
const piece = sourceSquare.querySelector('.piece');
if (!piece) return;

const pieceColor = piece.getAttribute('data-piece').split('_')[0];
if ((isWhite && pieceColor !== 'white') || (!isWhite && pieceColor !== 'black')) return;
const pieceType = piece.getAttribute('data-piece');
if ((isWhite && !pieceType.startsWith('white')) ||
(!isWhite && !pieceType.startsWith('black'))) {
return;
}

const sourceIndex = parseInt(sourceSquare.getAttribute('data-index'));

squares.forEach(targetSquare => {
const targetIndex = parseInt(targetSquare.getAttribute('data-index'));
if (sourceIndex === targetIndex) return;

if (isValidMove(piece, sourceIndex, targetIndex)) {
moves.push({
from: sourceIndex,
to: targetIndex,
piece: piece,
pieceType: piece.getAttribute('data-piece')
});
try {
if (isValidMove(piece, sourceIndex, targetIndex)) {
// If in check, only add moves that resolve check
if (!inCheck || doesMoveResolveCheck(piece, sourceIndex, targetIndex)) {
moves.push({
from: sourceIndex,
to: targetIndex,
piece: piece,
pieceType: pieceType,
moveNotation: getAlgebraicNotation(sourceIndex, targetIndex, pieceType)
});
}
}
} catch (error) {
console.error('Error validating move:', error);
}
});
});

console.log(`Generated ${moves.length} valid moves for ${isWhite ? 'white' : 'black'}`);
return moves;
}

function getAlgebraicNotation(sourceIndex, targetIndex, pieceType) {
const files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
const ranks = [8, 7, 6, 5, 4, 3, 2, 1];

const sourceFile = files[sourceIndex % 8];
const sourceRank = ranks[Math.floor(sourceIndex / 8)];
const targetFile = files[targetIndex % 8];
const targetRank = ranks[Math.floor(targetIndex / 8)];

const pieceChar = pieceType.split('_')[1].toUpperCase().charAt(0);

return `${pieceChar}${sourceFile}${sourceRank}${targetFile}${targetRank}`;
}

function makeTemporaryMove(move) {
const sourceSquare = document.querySelector(`[data-index="${move.from}"]`);
const targetSquare = document.querySelector(`[data-index="${move.to}"]`);
const capturedPiece = targetSquare.querySelector('.piece');

if (capturedPiece) {
targetSquare.removeChild(capturedPiece);
}

sourceSquare.removeChild(move.piece);
targetSquare.appendChild(move.piece);

updateBoardState(); // Update the internal board state
return capturedPiece;
}

function undoTemporaryMove(move, capturedPiece) {
const sourceSquare = document.querySelector(`[data-index="${move.from}"]`);
const targetSquare = document.querySelector(`[data-index="${move.to}"]`);

targetSquare.removeChild(move.piece);
sourceSquare.appendChild(move.piece);

if (capturedPiece) {
targetSquare.appendChild(capturedPiece);
}

updateBoardState(); // Update the internal board state
}

function minimax(depth, alpha, beta, isMaximizingPlayer) {
if (depth === 0) {
return evaluatePosition();
}

const possibleMoves = generateAllPossibleMoves(isMaximizingPlayer);

if (isMaximizingPlayer) {
let maxEval = -Infinity;
for (const move of possibleMoves) {
const capturedPiece = makeTemporaryMove(move);
const eval = minimax(depth - 1, alpha, beta, false);
undoTemporaryMove(move, capturedPiece);

maxEval = Math.max(maxEval, eval);
alpha = Math.max(alpha, eval);
if (beta <= alpha) break;
Expand All @@ -131,7 +184,7 @@ function minimax(depth, alpha, beta, isMaximizingPlayer) {
const capturedPiece = makeTemporaryMove(move);
const eval = minimax(depth - 1, alpha, beta, true);
undoTemporaryMove(move, capturedPiece);

minEval = Math.min(minEval, eval);
beta = Math.min(beta, eval);
if (beta <= alpha) break;
Expand All @@ -141,37 +194,52 @@ function minimax(depth, alpha, beta, isMaximizingPlayer) {
}

function evaluatePosition() {
// Get the current evaluation from the evaluation.js file
return evaluateBoard();
return evaluateBoard(); // This function is from evaluation.js
}

function highlightBestMove(move) {
// Remove existing highlights
document.querySelectorAll('.square').forEach(square => {
if (square.classList.contains('white')) {
square.style.backgroundColor = '#f0d9b5';
} else {
square.style.backgroundColor = '#b58863';
}
});

// Highlight the suggested move
const sourceSquare = document.querySelector(`[data-index="${move.from}"]`);
const targetSquare = document.querySelector(`[data-index="${move.to}"]`);
function highlightBestMove(sourceIndex, targetIndex) {
// Clear any existing highlights first
clearHighlights();

const sourceSquare = document.querySelector(`[data-index="${sourceIndex}"]`);
const targetSquare = document.querySelector(`[data-index="${targetIndex}"]`);

if (sourceSquare && targetSquare) {
sourceSquare.style.backgroundColor = '#aaffaa';
targetSquare.style.backgroundColor = '#aaffaa';
// Add highlights
sourceSquare.classList.add('highlighted-square');
targetSquare.classList.add('highlighted-square');

// Add move notation
const notationElement = document.createElement('div');
notationElement.classList.add('move-notation');
notationElement.textContent = getAlgebraicNotation(sourceIndex, targetIndex, sourceSquare.querySelector('.piece').getAttribute('data-piece'));
targetSquare.appendChild(notationElement);

// Remove highlights after 4 seconds
setTimeout(() => {
clearHighlights();
}, 4000);
}
}

function clearHighlights() {
// Remove all highlights
document.querySelectorAll('.highlighted-square').forEach(square => {
square.classList.remove('highlighted-square');
});

// Remove all move notations
document.querySelectorAll('.move-notation').forEach(notation => {
notation.remove();
});
}

// Add event listener for the suggest move button
document.getElementById('suggest-best-move').addEventListener('click', () => {
console.log("Suggest move button clicked");
suggestBestMove();
});

// Function to update turn (should be called after each move in board.js)
function updateTurn() {
isWhiteTurn = !isWhiteTurn;
}
Loading

0 comments on commit 80ad3f9

Please sign in to comment.