ChessAnalyzer / index.html
Raven7's picture
Update index.html
088cfa5 verified
raw
history blame
13.7 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Chess Analyzer</title>
<style>
:root {
--board-size: min(80vh, 600px);
--square-size: calc(var(--board-size) / 8);
--primary-dark: #2c3e50;
--primary-light: #34495e;
--highlight: #f1c40f;
--move-highlight: rgba(46, 204, 113, 0.4);
--check-highlight: rgba(231, 76, 60, 0.4);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
background: var(--primary-dark);
color: #ecf0f1;
min-height: 100vh;
display: flex;
}
.container {
display: grid;
grid-template-columns: var(--board-size) 300px;
gap: 2rem;
margin: auto;
padding: 2rem;
background: var(--primary-light);
border-radius: 1rem;
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.board-container {
width: var(--board-size);
height: var(--board-size);
position: relative;
}
.chessboard {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(8, 1fr);
border: 4px solid #2c3e50;
border-radius: 4px;
overflow: hidden;
}
.square {
display: flex;
align-items: center;
justify-content: center;
font-size: calc(var(--square-size) * 0.7);
cursor: pointer;
transition: all 0.2s;
position: relative;
user-select: none;
}
.white { background: #f0d9b5; }
.black { background: #b58863; }
.square.selected {
background: var(--highlight) !important;
}
.square.valid-move::after {
content: '';
position: absolute;
width: 25%;
height: 25%;
background: rgba(0,0,0,0.2);
border-radius: 50%;
}
.square.last-move {
background: var(--move-highlight) !important;
}
.square.check {
background: var(--check-highlight) !important;
}
.controls {
display: flex;
flex-direction: column;
gap: 1rem;
}
.status-panel {
background: rgba(0,0,0,0.2);
padding: 1rem;
border-radius: 0.5rem;
}
.move-list {
background: rgba(0,0,0,0.2);
padding: 1rem;
border-radius: 0.5rem;
flex-grow: 1;
overflow-y: auto;
height: 300px;
}
.move-row {
display: grid;
grid-template-columns: 30px 1fr 1fr;
padding: 0.3rem;
gap: 0.5rem;
}
.move-row:hover {
background: rgba(255,255,255,0.1);
border-radius: 0.3rem;
}
button {
background: #3498db;
color: white;
border: none;
padding: 0.8rem;
border-radius: 0.5rem;
cursor: pointer;
font-weight: 500;
transition: background 0.2s;
}
button:hover {
background: #2980b9;
}
.piece {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: calc(var(--square-size) * 0.7);
cursor: grab;
}
.piece:active {
cursor: grabbing;
}
@media (max-width: 1024px) {
.container {
grid-template-columns: 1fr;
grid-template-rows: auto auto;
}
.board-container {
margin: auto;
}
}
</style>
</head>
<body>
<div class="container">
<div class="board-container">
<div class="chessboard" id="board"></div>
</div>
<div class="controls">
<div class="status-panel">
<h3>Position Analysis</h3>
<p id="status">White to move</p>
<p id="evaluation">Evaluation: 0.0</p>
</div>
<div class="move-list" id="moveList">
<!-- Moves will be inserted here -->
</div>
<button onclick="analyzePosition()">Analyze Position</button>
<button onclick="resetBoard()">Reset Board</button>
</div>
</div>
<script>
class ChessGame {
constructor() {
this.board = this.createInitialBoard();
this.currentPlayer = 'white';
this.selectedPiece = null;
this.moveHistory = [];
this.validMoves = [
{type: 'K', move: {dx: [-1,0,1], dy: [-1,0,1]}},
{type: 'Q', move: {dx: [-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7],
dy: [-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7]}},
{type: 'R', move: {dx: [-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7],
dy: [0]}},
{type: 'B', move: {dx: [-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7],
dy: [-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7]}},
{type: 'N', move: {dx: [-2,-2,-1,-1,1,1,2,2],
dy: [-1,1,-2,2,-2,2,-1,1]}},
{type: 'P', move: {dx: [0], dy: [-1,1]}}
];
this.initializeBoard();
}
createInitialBoard() {
return [
['♜', '♞', '♝', '♛', '♚', '♝', '♞', '♜'],
['♟', '♟', '♟', '♟', '♟', '♟', '♟', '♟'],
[null, null, null, null, null, null, null, null],
[null, null, null, null, null, null, null, null],
[null, null, null, null, null, null, null, null],
[null, null, null, null, null, null, null, null],
['♙', '♙', '♙', '♙', '♙', '♙', '♙', '♙'],
['♖', '♘', '♗', '♕', '♔', '♗', '♘', '♖']
];
}
// Initialize the board display
initializeBoard() {
const boardElement = document.getElementById('board');
boardElement.innerHTML = '';
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const square = document.createElement('div');
square.className = `square ${(row + col) % 2 === 0 ? 'white' : 'black'}`;
square.dataset.row = row;
square.dataset.col = col;
square.onclick = (e) => this.handleSquareClick(e);
if (this.board[row][col]) {
const piece = document.createElement('div');
piece.className = 'piece';
piece.textContent = this.board[row][col];
square.appendChild(piece);
}
boardElement.appendChild(square);
}
}
this.updateStatus();
}
// Handle square clicks
handleSquareClick(event) {
const square = event.target.closest('.square');
const row = parseInt(square.dataset.row);
const col = parseInt(square.dataset.col);
if (this.selectedPiece) {
this.tryMove(row, col);
} else if (this.board[row][col]) {
this.selectPiece(row, col);
}
}
// Select a piece to move
selectPiece(row, col) {
const piece = this.board[row][col];
if (!piece) return;
document.querySelectorAll('.square').forEach(sq => {
sq.classList.remove('selected');
sq.classList.remove('valid-move');
});
document.querySelector(`[data-row="${row}"][data-col="${col}"]`).classList.add('selected');
this.selectedPiece = { row, col };
this.showValidMoves(row, col);
}
// Try to make a move
tryMove(toRow, toCol) {
if (this.isValidMove(this.selectedPiece.row, this.selectedPiece.col, toRow, toCol)) {
this.makeMove(this.selectedPiece.row, this.selectedPiece.col, toRow, toCol);
}
document.querySelectorAll('.square').forEach(sq => {
sq.classList.remove('selected');
sq.classList.remove('valid-move');
});
this.selectedPiece = null;
}
// Check if move is valid
isValidMove(fromRow, fromCol, toRow, toCol) {
// Simplified validation
const piece = this.board[fromRow][fromCol];
return piece !== null;
}
// Execute a move
makeMove(fromRow, fromCol, toRow, toCol) {
const piece = this.board[fromRow][fromCol];
this.board[fromRow][fromCol] = null;
this.board[toRow][toCol] = piece;
this.moveHistory.push({
piece,
from: { row: fromRow, col: fromCol },
to: { row: toRow, col: toCol }
});
this.currentPlayer = this.currentPlayer === 'white' ? 'black' : 'white';
this.initializeBoard();
this.updateMoveList();
}
// Show valid moves for selected piece
showValidMoves(row, col) {
const piece = this.board[row][col];
const moves = this.getValidMoves(piece, row, col);
moves.forEach(move => {
const square = document.querySelector(
`[data-row="${move.row}"][data-col="${move.col}"]`
);
if (square) square.classList.add('valid-move');
});
}
// Get valid moves for a piece
getValidMoves(piece, row, col) {
// Simplified move generation
return [{row: row + 1, col}, {row: row - 1, col},
{row, col: col + 1}, {row, col: col - 1}]
.filter(pos => pos.row >= 0 && pos.row < 8 &&
pos.col >= 0 && pos.col < 8);
}
// Update game status display
updateStatus() {
document.getElementById('status').textContent =
`${this.currentPlayer.charAt(0).toUpperCase() +
this.currentPlayer.slice(1)} to move`;
}
// Update move list display
updateMoveList() {
const moveList = document.getElementById('moveList');
moveList.innerHTML = '';
for (let i = 0; i < this.moveHistory.length; i += 2) {
const moveRow = document.createElement('div');
moveRow.className = 'move-row';
const moveNumber = document.createElement('span');
moveNumber.textContent = `${Math.floor(i/2 + 1)}.`;
const whiteMove = document.createElement('span');
whiteMove.textContent = this.formatMove(this.moveHistory[i]);
const blackMove = document.createElement('span');
if (this.moveHistory[i + 1]) {
blackMove.textContent = this.formatMove(this.moveHistory[i + 1]);
}
moveRow.appendChild(moveNumber);
moveRow.appendChild(whiteMove);
moveRow.appendChild(blackMove);
moveList.appendChild(moveRow);
}
moveList.scrollTop = moveList.scrollHeight;
}
// Format move for display
formatMove(move) {
const files = 'abcdefgh';
const ranks = '87654321';
return `${move.piece}${files[move.from.col]}${ranks[move.from.row]}-${files[move.to.col]}${ranks[move.to.row]}`;
}
}
const game = new ChessGame();
function analyzePosition() {
const eval = (Math.random() * 2 - 1).toFixed(2);
document.getElementById('evaluation').textContent = `Evaluation: ${eval}`;
}
function resetBoard() {
game.board = game.createInitialBoard();
game.currentPlayer = 'white';
game.selectedPiece = null;
game.moveHistory = [];
game.initializeBoard();
}
</script>
</body>
</html>