<!DOCTYPE html><html><head><title>Project 3: Notation Input Trainer</title><linkrel="stylesheet"href="https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.css"><style>body{font-family:sans-serif;display:flex;flex-direction:column;align-items:center;background-color:#f4f4f4;padding:20px;}h1{margin-bottom:10px;}/* Responsive Board Container */#myBoard{width:90%;max-width:500px;margin:20pxauto;}/* Input Controls */.input-container{display:flex;gap:10px;margin-bottom:20px;width:90%;max-width:500px;}#moveInput{flex-grow:1;padding:12px;font-size:18px;border:2pxsolid#ccc;border-radius:4px;}#submitBtn{padding:10px20px;font-size:16px;background-color:#4CAF50;color:white;border:none;cursor:pointer;border-radius:4px;}/* Status & History */#status{font-weight:bold;margin-bottom:10px;color:#333;}#pgn-output{background:#fff;padding:15px;border:1pxsolid#ddd;width:90%;max-width:500px;min-height:50px;font-family:monospace;font-size:14px;}</style></head><body><h1>♟️ Type & Play</h1><divid="status">White to move</div><divid="myBoard"></div><divclass="input-container"><inputtype="text"id="moveInput"placeholder="Type move (e.g. e4, Nf3)..."autofocus><buttonid="submitBtn">Move</button></div><divid="pgn-output"></div><br><buttonid="resetBtn"style="padding: 8px 16px; cursor: pointer;">Reset Game</button><script src="https://code.jquery.com/jquery-3.5.1.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script><script src="https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.js"></script><script>// --- 1. SETUP ---varboard=null;vargame=newChess();// Configuration: Local images + Responsive + No Draggingvarconfig={position:'start',draggable:false,// Strictly no dragging!pieceTheme:'img/chesspieces/wikipedia/{piece}.png'};// Initialize Boardboard=Chessboard('myBoard',config);window.addEventListener('resize',board.resize);// Responsive fix// DOM ElementsconstmoveInput=document.getElementById('moveInput');conststatusDisplay=document.getElementById('status');constpgnDisplay=document.getElementById('pgn-output');// --- 2. CORE LOGIC ---functionhandleMove(){constmoveText=moveInput.value.trim();if(!moveText)return;// Try to make the move in the game logic// chess.js requires SAN (Standard Algebraic Notation) by defaultconstmove=game.move(moveText);if(move===null){// INVALID MOVEspeak("Invalid move");// Shake the input box to show error visually (optional CSS trick)moveInput.style.borderColor="red";setTimeout(()=>moveInput.style.borderColor="#ccc",500);return;}// VALID MOVEboard.position(game.fen());// Update boardspeak(move.san);// Voice notationupdateStatus();// Update turn info// Clear input for next turnmoveInput.value='';moveInput.focus();}functionupdateStatus(){letstatus='';letmoveColor=(game.turn()==='b')?'Black':'White';// Check for Checkmate / Drawif(game.in_checkmate()){status='Game over, '+moveColor+' is in checkmate.';speak("Checkmate!");}elseif(game.in_draw()){status='Game over, drawn position';speak("Draw!");}else{status=moveColor+' to move';if(game.in_check()){status+=', '+moveColor+' is in check';speak("Check!");}}statusDisplay.innerText=status;pgnDisplay.innerHTML=game.pgn();// Show full history}functionspeak(text){if('speechSynthesis'inwindow){constut=newSpeechSynthesisUtterance(text);window.speechSynthesis.speak(ut);}}// --- 3. EVENT LISTENERS ---// Submit button clickdocument.getElementById('submitBtn').addEventListener('click',handleMove);// "Enter" key in input boxmoveInput.addEventListener('keydown',(e)=>{if(e.key==='Enter'){handleMove();}});// Reset Gamedocument.getElementById('resetBtn').addEventListener('click',()=>{game.reset();board.start();moveInput.value='';updateStatus();speak("Game reset");moveInput.focus();});// Initial StatusupdateStatus();</script></body></html>