Μάθημα : Σχεδιασμός και ανάπτυξη Ιστοτόπων

Κωδικός : 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>
    // 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');
          cell.id = file + rank;
          // 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)