Μάθημα : Σχεδιασμός και ανάπτυξη Ιστοτόπων
Κωδικός : 0540865369
0540865369 - ΒΙΟΛΕΤΤΑ ΚΟΥΖΙΩΚΑ
html
Δευτέρα 5 Μαΐου 2025 - 10:26 π.μ. - από τον χρήστη
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Chess Trainer Web App</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
#boardContainer {
margin: 20px auto;
width: fit-content;
}
table {
border-collapse: collapse;
}
#board td {
width: 60px;
height: 60px;
text-align: center;
vertical-align: middle;
border: 1px solid #999;
position: relative;
}
.square.light {
background-color: #EEEED2;
}
.square.dark {
background-color: #769656;
}
#mode3UI {
margin-top: 10px;
}
#board td.selected {
outline: 3px solid yellow;
}
</style>
</head>
<body>
<h1>Chess Trainer Web App</h1>
<div id="controls">
<button id="mode1Btn">Coordinate Training</button>
<button id="mode2Btn">Random Piece Movement</button>
<button id="mode3Btn">Play Against Bot</button>
</div>
<div id="mode1UI" style="display:none; margin: 10px;">
<p id="prompt1"></p>
<p id="feedback1"></p>
</div>
<div id="mode2UI" style="display:none; margin: 10px;">
<p id="prompt2"></p>
<p id="feedback2"></p>
</div>
<div id="mode3UI" style="display:none; margin: 10px;">
<div>
<label>Select Color:</label>
<input type="radio" name="color" id="whiteRadio" value="w">White
<input type="radio" name="color" id="blackRadio" value="b">Black
<input type="radio" name="color" id="randomRadio" value="r">Random
</div>
<div style="margin-top:5px;">
<label>Bot ELO: <span id="eloValue">1500</span></label>
<input type="range" id="eloSlider" min="1000" max="3000" step="100" value="1500">
</div>
<div style="margin-top:5px;">
<button id="startBtn" style="display:none;">Start Game</button>
</div>
<p id="status3"></p>
</div>
<div id="boardContainer">
<table id="board"></table>
</div>
<!-- Include chess.js library from CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>
<script>
// Global state variables
let currentMode = null;
let targetCoord = null;
let pieceType2 = null, pieceColor2 = null, origin2 = null, target2 = null;
let randomChess = null;
let selectedSquare2 = null;
let gameChess = null;
let userColor = null;
let gameActive = false;
let currentTurn = null;
let selectedSquare3 = null;
// Function to create an empty chess board (orientation: 'white' or 'black')
function createBoard(orientation) {
const board = document.getElementById('board');
board.innerHTML = '';
for (let i = 0; i < 8; i++) {
const row = document.createElement('tr');
let rank, startFileCode, endFileCode, fileStep;
if (orientation === 'white') {
rank = 8 - i;
startFileCode = 'a'.charCodeAt(0);
endFileCode = 'h'.charCodeAt(0);
fileStep = 1;
} else { // black orientation
rank = i + 1;
startFileCode = 'h'.charCodeAt(0);
endFileCode = 'a'.charCodeAt(0);
fileStep = -1;
}
for (let fileCode = startFileCode; (fileStep > 0 ? fileCode <= endFileCode : fileCode >= endFileCode); fileCode += fileStep) {
const file = String.fromCharCode(fileCode);
const cell = document.createElement('td');
// Determine square color
const fileIndex = file.charCodeAt(0) - 'a'.charCodeAt(0) + 1;
const rankIndex = rank;
const isDark = (fileIndex + rankIndex) % 2 === 0;
cell.className = 'square ' + (isDark ? 'dark' : 'light');
row.appendChild(cell);
}
board.appendChild(row);
}
}
// Update board display for mode 3 (play vs bot) using chess.js game state
function updateBoardUI() {
if (!gameChess) return;
// Clear existing pieces
const cells = document.querySelectorAll('#board td');
cells.forEach(td => td.innerHTML = '');
// Place pieces according to gameChess position
gameChess.board().forEach((row, i) => {
row.forEach((piece, j) => {
if (piece) {
// Determine square coordinate
const file = String.fromCharCode('a'.charCodeAt(0) + j);
const rank = 8 - i;
const squareId = file + rank;
const cell = document.getElementById(squareId);
if (cell) {
const img = document.createElement('img');
const color = piece.color === 'w' ? 'white' : 'black';
let typeName = '';
switch(piece.type) {
case 'p': typeName = 'pawn'; break;
case 'r': typeName = 'rook'; break;
case 'n': typeName = 'knight'; break;
case 'b': typeName = 'bishop'; break;
case 'q': typeName = 'queen'; break;
case 'k': typeName = 'king'; break;
}
img.src = 'images/' + color + '_' + typeName + '.png';
img.alt = piece.type;
img.style.width = '50px';
img.style.height = '50px';
cell.appendChild(img);
}
}
});
});
}
// Generate a new random target coordinate for Mode 1 (coordinate training)
function pickNewCoordinate() {
const files = 'abcdefgh';
const ranks = '12345678';
const file = files[Math.floor(Math.random() * files.length)];
const rank = ranks[Math.floor(Math.random() * ranks.length)];
targetCoord = file + rank;
document.getElementById('prompt1').textContent = 'Click square: ' + targetCoord;
document.getElementById('feedback1').textContent = '';
}
// Initialize Mode 1 (coordinate training)
function startMode1() {
currentMode = 'mode1';
document.getElementById('mode1UI').style.display = 'block';
document.getElementById('mode2UI').style.display = 'none';
document.getElementById('mode3UI').style.display = 'none';
createBoard('white'); // empty board for coordinate training
pickNewCoordinate();
document.getElementById('feedback1').textContent = '';
}
// Initialize Mode 2 (random piece movement)
function newMode2() {
currentMode = 'mode2';
document.getElementById('mode1UI').style.display = 'none';
document.getElementById('mode2UI').style.display = 'block';
document.getElementById('mode3UI').style.display = 'none';
// Choose a random piece and move
randomChess = new Chess();
randomChess.clear();
selectedSquare2 = null;
// Remove any previous selection highlight
const prevSel = document.querySelectorAll('#board td.selected');
prevSel.forEach(td => td.classList.remove('selected'));
let moves;
const types = ['p','n','b','r','q','k'];
do {
pieceType2 = types[Math.floor(Math.random() * types.length)];
pieceColor2 = (Math.random() < 0.5) ? 'w' : 'b';
const file = 'abcdefgh'[Math.floor(Math.random() * 8)];
const rank = '12345678'[Math.floor(Math.random() * 8)];
origin2 = file + rank;
randomChess.clear();
randomChess.put({ type: pieceType2, color: pieceColor2 }, origin2);
moves = randomChess.moves({ square: origin2 });
} while (moves.length === 0);
// Pick a random target from legal moves
const allMoves = randomChess.moves({ verbose: true, square: origin2 });
const chosenMove = allMoves[Math.floor(Math.random() * allMoves.length)];
target2 = chosenMove.to;
// Set prompt text
let pieceName = '';
switch(pieceType2) {
case 'p': pieceName = 'pawn'; break;
case 'r': pieceName = 'rook'; break;
case 'n': pieceName = 'knight'; break;
case 'b': pieceName = 'bishop'; break;
case 'q': pieceName = 'queen'; break;
case 'k': pieceName = 'king'; break;
}
const colorName = (pieceColor2 === 'w') ? 'white' : 'black';
document.getElementById('prompt2').textContent = 'Move the ' + colorName + ' ' + pieceName + ' from ' + origin2 + ' to ' + target2;
document.getElementById('feedback2').textContent = '';
// Display the piece on the board
createBoard('white');
const cell = document.getElementById(origin2);
const img = document.createElement('img');
img.src = 'images/' + colorName + '_' + pieceName + '.png';
img.alt = pieceName;
img.style.width = '50px';
img.style.height = '50px';
cell.appendChild(img);
}
// Initialize Mode 3 (play against bot) UI
function initMode3() {
currentMode = 'mode3';
document.getElementById('mode1UI').style.display = 'none';
document.getElementById('mode2UI').style.display = 'none';
document.getElementById('mode3UI').style.display = 'block';
createBoard('white'); // show empty board initially
document.getElementById('status3').textContent = '';
document.getElementById('startBtn').style.display = 'none';
// Reset radio selections
document.querySelectorAll('input[name="color"]').forEach(r => r.checked = false);
}
// Start game against bot (Mode 3)
function startGame() {
// Determine user color
const selected = document.querySelector('input[name="color"]:checked').value;
if (selected === 'r') {
userColor = (Math.random() < 0.5) ? 'w' : 'b';
} else {
userColor = selected;
}
gameChess = new Chess();
gameActive = true;
selectedSquare3 = null;
// Disable color selection and start button
document.getElementById('whiteRadio').disabled = true;
document.getElementById('blackRadio').disabled = true;
document.getElementById('randomRadio').disabled = true;
document.getElementById('startBtn').disabled = true;
// Setup board orientation and pieces
if (userColor === 'w') {
createBoard('white');
} else {
createBoard('black');
}
updateBoardUI();
document.getElementById('status3').textContent = 'Game started. ' + (userColor === 'w' ? 'Your turn (White).' : 'Bot (White) moves first.');
// If user is black, let bot (white) move first
if (userColor === 'b') {
doBotMove();
}
currentTurn = userColor;
}
// Bot makes a random move
function doBotMove() {
if (!gameActive) return;
const moves = gameChess.moves({ verbose: true });
if (moves.length === 0) {
document.getElementById('status3').textContent = 'Game over!';
gameActive = false;
return;
}
const botMove = moves[Math.floor(Math.random() * moves.length)];
gameChess.move(botMove);
updateBoardUI();
if (gameChess.game_over()) {
document.getElementById('status3').textContent = 'Game over!';
gameActive = false;
} else {
currentTurn = userColor;
document.getElementById('status3').textContent = 'Your turn.';
}
}
// Handle clicks on the board for all modes
document.getElementById('board').addEventListener('click', function(event) {
const target = event.target;
const cell = target.tagName === 'TD' ? target : target.closest('td');
if (!cell) return;
const square = cell.id;
if (currentMode === 'mode1') {
// Coordinate Training Mode
if (square === targetCoord) {
document.getElementById('feedback1').textContent = 'Correct!';
targetCoord = null;
setTimeout(pickNewCoordinate, 1000);
} else {
document.getElementById('feedback1').textContent = 'Incorrect, try again.';
}
} else if (currentMode === 'mode2') {
// Random Piece Movement Mode
if (!selectedSquare2) {
// No piece selected yet
if (square === origin2) {
selectedSquare2 = square;
cell.classList.add('selected');
document.getElementById('feedback2').textContent = '';
} else {
document.getElementById('feedback2').textContent = 'Click the highlighted piece.';
}
} else {
// Piece has been selected, attempt move
const selectedCell = document.getElementById(selectedSquare2);
selectedCell.classList.remove('selected');
if (square === target2) {
// Move piece visually
selectedCell.innerHTML = '';
const targetCell = cell;
const img = document.createElement('img');
const colorName = (pieceColor2 === 'w') ? 'white' : 'black';
let pieceName = '';
switch(pieceType2) {
case 'p': pieceName = 'pawn'; break;
case 'r': pieceName = 'rook'; break;
case 'n': pieceName = 'knight'; break;
case 'b': pieceName = 'bishop'; break;
case 'q': pieceName = 'queen'; break;
case 'k': pieceName = 'king'; break;
}
img.src = 'images/' + colorName + '_' + pieceName + '.png';
img.alt = pieceName;
img.style.width = '50px';
img.style.height = '50px';
targetCell.appendChild(img);
document.getElementById('feedback2').textContent = 'Correct!';
selectedSquare2 = null;
setTimeout(newMode2, 1000);
} else {
document.getElementById('feedback2').textContent = 'Incorrect, try again.';
selectedSquare2 = null;
}
}
} else if (currentMode === 'mode3') {
// Play Against Bot Mode
if (!gameActive) return;
if (currentTurn !== userColor) return;
if (!selectedSquare3) {
// Select a piece to move
const piece = gameChess.get(square);
if (piece && piece.color === userColor) {
selectedSquare3 = square;
cell.classList.add('selected');
document.getElementById('status3').textContent = '';
} else {
document.getElementById('status3').textContent = 'Select your piece!';
}
} else {
const selectedCell = document.getElementById(selectedSquare3);
selectedCell.classList.remove('selected');
// Attempt move
if (square === selectedSquare3) {
// Deselected the piece if same square clicked again
selectedSquare3 = null;
return;
}
const move = gameChess.move({ from: selectedSquare3, to: square, promotion: 'q' });
if (!move) {
document.getElementById('status3').textContent = 'Illegal move!';
selectedSquare3 = null;
return;
}
updateBoardUI();
selectedSquare3 = null;
// Check for end of game
if (gameChess.game_over()) {
document.getElementById('status3').textContent = 'Game over!';
gameActive = false;
return;
}
// Let bot play
document.getElementById('status3').textContent = 'Bot is thinking...';
currentTurn = (userColor === 'w' ? 'b' : 'w');
setTimeout(doBotMove, 500);
}
}
});
// Mode selection buttons
document.getElementById('mode1Btn').addEventListener('click', startMode1);
document.getElementById('mode2Btn').addEventListener('click', newMode2);
document.getElementById('mode3Btn').addEventListener('click', initMode3);
// Show Start button when a color is selected (Mode 3)
document.querySelectorAll('input[name="color"]').forEach(radio => {
radio.addEventListener('change', function() {
document.getElementById('startBtn').style.display = 'inline';
});
});
document.getElementById('startBtn').addEventListener('click', startGame);
// Update displayed ELO when slider is moved
document.getElementById('eloSlider').addEventListener('input', function() {
document.getElementById('eloValue').textContent = this.value;
});
// Initialize an empty board on load
createBoard('white');
</script>
</body>
</html>
Σχόλια (0)