const board = [ ["T", "C", "F", "Q", "K", "F", "C", "T"], ["P", "P", "P", "P", "P", "P", "P", "P"], ["", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", ""], ["p", "p", "p", "p", "p", "p", "p", "p"], ["t", "c", "f", "q", "k", "f", "c", "t"] ]; const player = { host: false, playedMove: board, roomId: null, username: "", socketId: "", symbol: "X", turn: false, win: false, isBlackPlayer: true, pieces: ["T", "C", "F", "Q", "K", "P"], echec: false }; const socket = io(); const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const roomId = urlParams.get('room'); if (roomId) { document.getElementById('start').innerText = "Rejoindre"; } const usernameInput = document.getElementById('username'); const gameCard = document.getElementById('game-card'); const userCard = document.getElementById('user-card'); const restartArea = document.getElementById('restart-area'); const waitingArea = document.getElementById('waiting-area'); const roomsCard = document.getElementById('rooms-card'); const roomsList = document.getElementById('rooms-list'); const turnMsg = document.getElementById('turn-message'); const linkToShare = document.getElementById('link-to-share'); let ennemyUsername = ""; socket.emit('get rooms'); socket.on('list rooms', (rooms) => { let html = ""; if (rooms.length > 0) { rooms.forEach(room => { if (room.players.length !== 2) { html += `<li class="list-group-item d-flex justify-content-between"> <p class="p-0 m-0 flex-grow-1 fw-bold">Salon de ${room.players[0].username} - ${room.id}</p> <button class="btn btn-sm btn-success join-room" data-room="${room.id}">Rejoindre</button> </li>`; } }); } if (html !== "") { roomsCard.classList.remove('d-none'); roomsList.innerHTML = html; for (const element of document.getElementsByClassName('join-room')) { element.addEventListener('click', joinRoom, false) } } }); $("#form").on('submit', function (e) { e.preventDefault(); player.username = usernameInput.value; if (roomId) { player.roomId = roomId; } else { player.host = true; player.isBlackPlayer = false; player.pieces = ["t", "c", "f", "q", "k", "p"]; player.turn = true; } player.socketId = socket.id; userCard.hidden = true; waitingArea.classList.remove('d-none'); roomsCard.classList.add('d-none'); socket.emit('playerData', player); }); $("#restart").on('click', function () { restartGame(); }) socket.on('join room', (roomId) => { player.roomId = roomId; linkToShare.innerHTML = `<a href="${window.location.href}?room=${player.roomId}" target="_blank">${window.location.href}?room=${player.roomId}</a>`; }); socket.on('start game', (players) => { console.log(players, "Le jeu commence"); startGame(players); console.log(player.isBlackPlayer) if (player.isBlackPlayer) { document.getElementById('chessboard').classList.add('black-perspective'); console.log("échiquier inversé") } }); socket.on('play', (moveData) => { console.log("[Client] Mouvement reçu : ", moveData.move.to.x, 'et', moveData.move.to.y,'et', tour, 'et', selectedPosition); selectedPiece = moveData.move.piece; row=moveData.move.from.x; col=moveData.move.from.y; newRow=moveData.move.to.x; newCol=moveData.move.to.y; selectedPosition = { row,col }; board[newRow][newCol] = moveData.move.piece; board[selectedPosition.row][selectedPosition.col] = ""; // Réinitialiser la pièce sélectionnée selectedPiece =null; selectedPosition = null; draw() // Ne remplace PAS l'échiquier complet, mais applique le coup reçu //movePiece(moveData.move.piece, newRow, newCol); // Applique le coup reçu sur l'échiquier local et redessine l'échiquier // if (ennemyPlayer.win) { // setTurnMessage('alert-info', 'alert-danger', `C'est perdu ! <b>${ennemyPlayer.username}</b> a gagné !`); // //calculateWin(ennemyPlayer.playedCell, 'O'); // showRestartArea(); // return; // } // if (calculateEquality()) { // setTurnMessage('alert-info', 'alert-warning', "C'est une egalité !"); // return; // } setTurnMessage('alert-info', 'alert-success', "C'est ton tour de jouer"); player.turn = true; // } else { // if (player.win) { // $("#turn-message").addClass('alert-success').html("Félicitations, tu as gagné la partie !"); // showRestartArea(); // return; // } // if (calculateEquality()) { // setTurnMessage('alert-info', 'alert-warning', "C'est une egalité !"); // showRestartArea(); // return; // } // } }); socket.on('play again', (players) => { restartGame(players); }) function startGame(players) { restartArea.classList.add('d-none'); waitingArea.classList.add('d-none'); turnMsg.classList.remove('d-none'); const ennemyPlayer = players.find(p => p.socketId != player.socketId); draw(); ennemyUsername = ennemyPlayer.username; tour = {currentPlayer: player, ennemyPlayer: ennemyPlayer}; console.log(ennemyPlayer); if (player.host && player.turn) { setTurnMessage('alert-info', 'alert-success', "C'est ton tour de jouer"); } else { setTurnMessage('alert-success', 'alert-info', `C'est au tour de <b>${ennemyUsername}</b> de jouer`); } } function setTurnMessage(classToRemove, classToAdd, html) { turnMsg.classList.remove(classToRemove); turnMsg.classList.add(classToAdd); turnMsg.innerHTML = html; } const joinRoom = function () { if (usernameInput.value !== "") { player.username = usernameInput.value; player.socketId = socket.id; player.roomId = this.dataset.room; socket.emit('playerData', player); userCard.hidden = true; waitingArea.classList.remove('d-none'); roomsCard.classList.add('d-none'); } } const canvas = document.getElementById("chessboard"); const ctx = canvas.getContext("2d"); const size = 60; // Taille des cases // Disposition initiale de l'échiquier // Charger les images des pièces const pieceImages = { "p": "pion_blanc.png", "P": "pion_noir.png", "t": "tour_blanc.png", "T": "tour_noir.png", "c": "cavalier_blanc.png", "C": "cavalier_noir.png", "f": "fou_blanc.png", "F": "fou_noir.png", "q": "reine_blanc.png", "Q": "reine_noir.png", "k": "roi_blanc.png", "K": "roi_noir.png" }; // Dessiner l'échiquier avec les couleurs des cases function drawBoard() { for (let row = 0; row < 8; row++) { for (let col = 0; col < 8; col++) { ctx.fillStyle = (row + col) % 2 === 0 ? "#F5DEB3" : "#8B4513"; ctx.fillRect(col * size, row * size, size, size); } } } // Dessiner les pièces sur l'échiquier function drawPieces() { for (let row = 0; row < 8; row++) { for (let col = 0; col < 8; col++) { const piece = board[row][col]; if (piece !== "") { let img = new Image(); img.src = "chess_pieces/" + pieceImages[piece]; if (player.isBlackPlayer){ img.onload = function () { ctx.save(); ctx.translate((col) * size, (row) * size); ctx.rotate(Math.PI); ctx.drawImage(img, -size, -size, size, size); ctx.restore(); }; img.onerror = function (e) { console.log("Erreur de chargement de l'image : ", img.src); // En cas d'erreur de chargement }; } else{ img.onload = function () { ctx.drawImage(img, col * size, row * size, size, size); }; img.onerror = function (e) { console.log("Erreur de chargement de l'image : ", img.src); // En cas d'erreur de chargement }; } } } } } // Fonction principale pour dessiner l'échiquier function draw() { drawBoard(); drawPieces(); } // Appeler la fonction pour afficher l'échiquier //Mouvement des pièces sur l'échiquier let selectedPiece = null; let selectedPosition = null; canvas.addEventListener("click", function(event) { const col = Math.floor(event.offsetX / size); const row = Math.floor(event.offsetY / size); if (selectedPiece) { /* socket.emit('play', { move: { from:{ x:selectedPosition.row, y:selectedPosition.col }, to: { x: row, y: col }, // Position d'arrivée piece: selectedPiece // Nom de la pièce (ex: "pion", "tour", etc.) } }); */ movePiece(selectedPiece, row, col); } else { selectPiece(row, col); } }); function selectPiece(row, col) { if (player.turn) { const current_piece = board[row][col]; selectedPosition = {row, col}; if (current_piece !== "" && player.pieces.includes(current_piece)) { // Vérifier que ce n'est pas une case vide selectedPiece = current_piece; highlightMoves(tour,current_piece, row, col); } } } function highlightMoves(tour,piece, row, col) { let ennemyPieces = []; if (player.isBlackPlayer===false){ ennemyPieces = ["T", "C", "F", "Q", "K", "P"]; direction=-1; } else{direction=1; ennemyPieces = ["t", "c", "f", "q", "k", "p"]; } let moves = []; console.log(piece.toLowerCase() === "p"); if (piece.toLowerCase() === "p") { if(row===6 && player.isBlackPlayer===false){ if (board[row + 2*direction][col] === "") { moves.push({row: row + 2*direction,col}); } } if(row===1 && player.isBlackPlayer===true){ if (board[row +2*direction][col] === "") { moves.push({row: row + 2*direction,col}); } } if (board[row + direction] && board[row + direction][col] === "") { moves.push({ row: row + direction, col }); } if (ennemyPieces.includes(board[row + direction][col + direction])){ moves.push({row: row +direction, col: col + direction }) } if (ennemyPieces.includes(board[row + direction][col - direction])){ moves.push({row: row +direction, col: col - direction }) } } if (piece.toLowerCase() === "t") { // Déplacements vers le haut for (let r = row - 1; r >= 0; r--) { if (board[r][col] === "") { moves.push({ row: r, col }); } else { if (ennemyPieces.includes(board[r][col])) { moves.push({ row: r, col }); // Capture possible } break // Bloqué par une pièce } } // Déplacements vers le bas for (let r = row + 1; r < 8; r++) { if (board[r][col] === "") { moves.push({ row: r, col }); } else { if (ennemyPieces.includes(board[r][col])) { moves.push({ row: r, col }); } break; } } // Déplacements vers la gauche for (let c = col - 1; c >= 0; c--) { if (board[row][c] === "") { moves.push({ row, col: c }); } else { if (ennemyPieces.includes(board[row][c])) { moves.push({ row, col: c }); } break; } } // Déplacements vers la droite for (let c = col + 1; c < 8; c++) { if (board[row][c] === "") { moves.push({ row, col: c }); } else { if (ennemyPieces.includes(board[row][c])) { moves.push({ row, col: c }); } break; } } } if (piece.toLowerCase() === "f") { // Déplacements en haut à gauche for (let r = row - 1, c = col - 1; r >= 0 && c >= 0; r--, c--) { if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; // Bloqué par une pièce } } // Déplacements en haut à droite for (let r = row - 1, c = col + 1; r >= 0 && c < 8; r--, c++) { if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } // Déplacements en bas à gauche for (let r = row + 1, c = col - 1; r < 8 && c >= 0; r++, c--) { if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } // Déplacements en bas à droite for (let r = row + 1, c = col + 1; r < 8 && c < 8; r++, c++) { if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } } if (piece.toLowerCase() === "k") { let directions = [ { dr: -1, dc: 0 }, // Haut { dr: 1, dc: 0 }, // Bas { dr: 0, dc: -1 }, // Gauche { dr: 0, dc: 1 }, // Droite { dr: -1, dc: -1 }, // Diagonale haut-gauche { dr: -1, dc: 1 }, // Diagonale haut-droite { dr: 1, dc: -1 }, // Diagonale bas-gauche { dr: 1, dc: 1 } // Diagonale bas-droite ]; for (let { dr, dc } of directions) { let newRow = row + dr; let newCol = col + dc; // Vérifie que la nouvelle position est sur l'échiquier if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) { if (board[newRow][newCol] === "" || ennemyPieces.includes(board[newRow][newCol])) { moves.push({ row: newRow, col: newCol }); } } } if (row==7) { if (board[row][col]){} } } if (piece.toLowerCase() === "c") { let movesL = [ { dr: -2, dc: -1 }, { dr: -2, dc: 1 }, // Haut gauche, Haut droite { dr: 2, dc: -1 }, { dr: 2, dc: 1 }, // Bas gauche, Bas droite { dr: -1, dc: -2 }, { dr: -1, dc: 2 }, // Gauche haut, Droite haut { dr: 1, dc: -2 }, { dr: 1, dc: 2 } // Gauche bas, Droite bas ]; for (let { dr, dc } of movesL) { let newRow = row + dr; let newCol = col + dc; // Vérifie que la nouvelle position est sur l'échiquier if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) { if (board[newRow][newCol] === "" || ennemyPieces.includes(board[newRow][newCol])) { moves.push({ row: newRow, col: newCol }); } } } } if (piece.toLowerCase() === "q") { // Déplacements verticaux (haut et bas) for (let r = row - 1; r >= 0; r--) { // Haut if (board[r][col] === "") { moves.push({ row: r, col }); } else { if (ennemyPieces.includes(board[r][col])) { moves.push({ row: r, col }); // Capture possible } break; // Bloqué par une pièce } } for (let r = row + 1; r < 8; r++) { // Bas if (board[r][col] === "") { moves.push({ row: r, col }); } else { if (ennemyPieces.includes(board[r][col])) { moves.push({ row: r, col }); } break; } } // Déplacements horizontaux (gauche et droite) for (let c = col - 1; c >= 0; c--) { // Gauche if (board[row][c] === "") { moves.push({ row, col: c }); } else { if (ennemyPieces.includes(board[row][c])) { moves.push({ row, col: c }); } break; } } for (let c = col + 1; c < 8; c++) { // Droite if (board[row][c] === "") { moves.push({ row, col: c }); } else { if (ennemyPieces.includes(board[row][c])) { moves.push({ row, col: c }); } break; } } // Déplacements diagonaux (haut-gauche, haut-droite, bas-gauche, bas-droite) for (let r = row - 1, c = col - 1; r >= 0 && c >= 0; r--, c--) { // Haut-Gauche if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } for (let r = row - 1, c = col + 1; r >= 0 && c < 8; r--, c++) { // Haut-Droite if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } for (let r = row + 1, c = col - 1; r < 8 && c >= 0; r++, c--) { // Bas-Gauche if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } for (let r = row + 1, c = col + 1; r < 8 && c < 8; r++, c++) { // Bas-Droite if (board[r][c] === "") { moves.push({ row: r, col: c }); } else { if (ennemyPieces.includes(board[r][c])) { moves.push({ row: r, col: c }); } break; } } } return moves; } function find_pieces(piece,board){ for (let i=0; i<8;i++){ for (let j=0; j<8;j++){ if (board[i][j] === piece){ return [i,j]; } } } } // function echec(tour, board) { // // Trouve la position du roi ennemi // let kingRow, kingCol; // if (player.turn === true) { // attackingPlayer = player; // [kingRow, kingCol] = find_pieces('k', board); // Roi noir (adverse) si c'est au joueur blanc de jouer // } else { // attackingPlayer = ennemyPlayer; // [kingRow, kingCol] = find_pieces('K', board); // Roi blanc (adverse) si c'est au joueur noir de jouer // } // let allPositions = []; // for (let i = 0; i < board.length; i++) { // for (let j = 0; j < board[i].length; j++) { // const piece = board[i][j]; // if (piece) { // const moves = highlightMoves(piece, board, i, j); // allPositions.push({ piece, position: { i, j }, moves }); // // 🔍 Vérifie si un des mouvements possibles atteint le roi // for (let move of moves) { // if (move.i === kingRow && move.j === kingCol) { // console.log(`Le roi est en échec par la pièce ${piece} en position (${i}, ${j})`); // return true; // Roi est en échec // } // } // } // } // } // } function movePiece(piece, newRow, newCol) { if (!piece) return; // Vérifier si le mouvement est valide const validMoves = highlightMoves(tour, piece, selectedPosition.row, selectedPosition.col); // Vérifier que validMoves est un tableau et qu'il contient des objets avec { row, col } const isValidMove = Array.isArray(validMoves) && validMoves.some(m => m.row === newRow && m.col === newCol); if (isValidMove) { // Déplacer la pièce board[newRow][newCol] = piece; board[selectedPosition.row][selectedPosition.col] = ""; // Réinitialiser la pièce sélectionnée console.log(selectedPosition.row,selectedPosition.col) //currentPlayer=(currentPlayer+1)%2; socket.emit('play', { move: { from:{ x:selectedPosition.row, y:selectedPosition.col }, to: { x: newRow, y: newCol }, // Position d'arrivée piece: selectedPiece // Nom de la pièce (ex: "pion", "tour", etc.) } }); setTurnMessage('alert-success', 'alert-info', `C'est au tour de <b>${ennemyUsername}</b> de jouer`) player.turn = false; selectedPiece =null; selectedPosition = null; [tour.currentPlayer, tour.ennemyPlayer] = [tour.ennemyPlayer, tour.currentPlayer]; // if (echec(tour,board)===true){ // console.log('echeeeeeeeeecs') // } // Redessiner le plateau draw(); } else { // Si le mouvement est invalide, tu pourrais afficher un message console.log("Mouvement invalide !"); selectedPiece=null; } }