PinoyNetNinja
Enthusiast
Just write down your questions in the thread below and I answer it using GPT-4 Turbo Model knowledge cut-off April 2023. Paunahan na lang, oh sa mga curious dyan, try niyo na.
${currentPlayer} wins!
);.cell[data-row="${move.row}"][data-col="${move.col}"]
);To implement an unbeatable AI using the minimax algorithm in expert mode for your Tic Tac Toe game, you'll need to modify the JavaScript code to include the minimax function and adjust theImplement minimax on expert mode to be unbeatable
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TIC TAC TOE</title>
<link rel="stylesheet" href="tictactoe.css">
</head>
<body>
<audio id="humanTurnSound" src="game.wav"></audio>
<audio id="aiTurnSound" src="game.wav"></audio>
<div style="justify-self: center;">
<h1>DIRECTION:</h1>
<p style="color: white; font-size: 50px; margin-bottom: 10px; text-align: center;">First to get 5 points win</p>
<div style="
">
<p style="color: white;font-size: 40px;margin-top: 25px;text-align: center;margin-bottom: .5px;">Score:</p>
<div style="display: flex;justify-content: center;align-items: center;">
<p style="color: white;font-size: 45px;margin-right: 10px;">X: <span id="scoreX">0</span></p>
<p style="color: white;font-size: 45px;">O: <span id="scoreO">0</span></p>
</div>
</div>
<div style="
text-align: center;
margin-top: 15px;
">
<select id="category">
<option value="Easy">Easy</option>
<option value="Difficult">Difficult</option>
<option value="Expert">Expert</option>
</select>
<div style="margin-top: 10px;">
<select id="players">
<option value="AIvsHuman">AI vs Human</option>
<option value="HumanvsHuman">Human vs Human</option>
</select>
</div>
</div>
</div>
<div class="container" style="">
<div id="game-container">
<div id="board" class="board">
</div>
</div>
<button id="reset-button" onclick="resetGame()" style="
color: white;
margin-top: 25px;
font-weight: 900;
background: linear-gradient(to right, #EBC1EE, #A277C6, #605399); /* Add more colors here */
animation: glow 2s infinite;
border-radius: 2px;
width: 150px;
height: 50px;
">Reset Game</button>
</div>
<div id="popup-container" class="popup-container">
<div class="popup-content">
<p id="popup-message"></p>
<button onclick="closePopup()">OK</button>
</div>
</div>
<footer style="position: absolute; left: 350px; bottom: -50px;">
<div style="text-align: center; background-color: rgba(71, 71, 71, 0.7); color: rgb(255, 255, 255); padding: 10px; border-radius: 10px;">
<h1 style="font-size: 34px;">Members</h1>
<p style="font-size: 30px; margin-bottom: 30px;">• Allyssa Gallo • Mary Joy Reano • Beverly Bernardino • Edward Cristobal • John Mark Oliveros</p>
</div>
</footer>
<script>
const humanTurnSound = document.getElementById('humanTurnSound');
const aiTurnSound = document.getElementById('aiTurnSound');
const rows = 5;
const columns = 6;
let currentPlayer = 'X';
let gameBoard = Array.from({ length: rows }, () => Array(columns).fill(''));
let scoreX = 0;
let scoreO = 0;
function createGameBoard() {
const boardElement = document.getElementById('board');
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
const cell = document.createElement('div');
cell.classList.add('cell');
cell.setAttribute('data-row', i);
cell.setAttribute('data-col', j);
cell.addEventListener('click', handleCellClick);
boardElement.appendChild(cell);
}
}
}
function showPopup(message) {
const popupContainer = document.getElementById('popup-container');
const popupMessage = document.getElementById('popup-message');
popupMessage.textContent = message;
popupContainer.style.display = 'flex';
}
function closePopup() {
const popupContainer = document.getElementById('popup-container');
popupContainer.style.display = 'none';
}
function handleCellClick(event) {
const clickedCell = event.target;
const row = Number(clickedCell.getAttribute('data-row'));
const col = Number(clickedCell.getAttribute('data-col'));
if (gameBoard[row][col] === '') {
gameBoard[row][col] = currentPlayer;
clickedCell.textContent = currentPlayer;
if (checkForWinner(row, col)) {
setTimeout(() => {
showPopup(${currentPlayer} wins!
);
updateScores(currentPlayer);
resetGame();
}, 100);
} else {
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
if (document.getElementById('players').value === 'AIvsHuman' && currentPlayer === 'O') {
aiTurnSound.play();
makeAIMove();
} else {
humanTurnSound.play();
}
}
}
}
function checkForWinner(row, col) {
let countHorizontal = 0;
for (let i = 0; i < columns; i++) {
if (gameBoard[row] === currentPlayer) {
countHorizontal++;
if (countHorizontal >= 6) {
return true;
}
} else {
countHorizontal = 0;
}
}
let countVertical = 0;
for (let i = 0; i < rows; i++) {
if (gameBoard[col] === currentPlayer) {
countVertical++;
if (countVertical >= 5) {
return true;
}
} else {
countVertical = 0;
}
}
let countDiagonal1 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal1++;
if (countDiagonal1 >= 5) {
return true;
}
} else {
countDiagonal1 = 0;
}
}
if ((row === 1 && col === 0) || (row === 2 && col === 1) ||
(row === 3 && col === 2) || (row === 4 && col === 3)) {
let countDiagonal2 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal2++;
if (countDiagonal2 >= 4) {
return true;
}
} else {
countDiagonal2 = 0;
}
}
}
if ((row === 0 && col === 2) || (row === 1 && col === 3) ||
(row === 2 && col === 4) || (row === 3 && col === 5)) {
let countDiagonal3 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal3++;
if (countDiagonal3 >= 4) {
return true;
}
} else {
countDiagonal3 = 0;
}
}
}
if ((row === 0 && col === 3) || (row === 1 && col === 4) ||
(row === 2 && col === 5)) {
let countDiagonal4 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal4++;
if (countDiagonal4 >= 3) {
return true;
}
} else {
countDiagonal4 = 0;
}
}
}
if ((row === 0 && col === 4) || (row === 1 && col === 5)) {
let countDiagonal5 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal5++;
if (countDiagonal5 >= 2) {
return true;
}
} else {
countDiagonal5 = 0;
}
}
}
if ((row === 3 && col === 0) || (row === 4 && col === 1)) {
let countDiagonal6 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal6++;
if (countDiagonal6 >= 2) {
return true;
}
} else {
countDiagonal6 = 0;
}
}
}
if ((row === 2 && col === 0) || (row === 3 && col === 1) || (row === 4 && col === 2)) {
let countDiagonal7 = 0;
for (let i = -Math.min(row, col); i < Math.min(rows - row, columns - col); i++) {
if (gameBoard[row + i][col + i] === currentPlayer) {
countDiagonal7++;
if (countDiagonal7 >= 3) {
return true;
}
} else {
countDiagonal7 = 0;
}
}
}
let countDiagonal8 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal8++;
if (countDiagonal8 >= 5) {
return true;
}
} else {
countDiagonal8 = 0;
}
}
if ((row === 0 && col === 1) || (row === 1 && col === 0)) {
let countDiagonal9 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal9++;
if (countDiagonal9 >= 2) {
return true;
}
} else {
countDiagonal9 = 0;
}
}
}
if ((row === 0 && col === 2) || (row === 1 && col === 1) || (row === 2 && col === 0)) {
let countDiagonal10 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal10++;
if (countDiagonal10 >= 3) {
return true;
}
} else {
countDiagonal10 = 0;
}
}
}
if ((row === 0 && col === 3) || (row === 1 && col === 2) || (row === 2 && col === 1) || (row === 3 && col === 0)) {
let countDiagonal11 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal11++;
if (countDiagonal11 >= 4) {
return true;
}
} else {
countDiagonal11 = 0;
}
}
}
if ((row === 1 && col === 5) || (row === 2 && col === 4) || (row === 3 && col === 3) || (row === 4 && col === 2)) {
let countDiagonal12 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal12++;
if (countDiagonal12 >= 4) {
return true;
}
} else {
countDiagonal12 = 0;
}
}
}
if ((row === 2 && col === 5) || (row === 3 && col === 4) || (row === 4 && col === 3)) {
let countDiagonal13 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal13++;
if (countDiagonal13 >= 3) {
return true;
}
} else {
countDiagonal13 = 0;
}
}
}
if ((row === 3 && col === 5) || (row === 4 && col === 4)) {
let countDiagonal14 = 0;
for (let i = -Math.min(row, columns - col - 1); i < Math.min(rows - row, col + 1); i++) {
if (gameBoard[row + i][col - i] === currentPlayer) {
countDiagonal14++;
if (countDiagonal14 >= 2) {
return true;
}
} else {
countDiagonal14 = 0;
}
}
}
let isDraw = true;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
if (gameBoard[j] === '') {
isDraw = false;
break;
}
}
if (!isDraw) {
break;
}
}
if (isDraw) {
showPopup('It\'s a draw!');
resetGame();
return false;
}
return false;
}
function makeAIMove() {
aiTurnSound.play();
let emptyCells = [];
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
if (gameBoard[j] === '') {
emptyCells.push({ row: i, col: j });
}
}
}
if (emptyCells.length > 0) {
if (document.getElementById('category').value === 'Difficult') {
// Difficult level strategy: Take the center or an edge
const centerAndEdges = emptyCells.filter(cell => (cell.row === 2 && cell.col === 2) || (cell.row % 2 === 0 && cell.col % 2 === 0));
const randomIndex = Math.floor(Math.random() * centerAndEdges.length);
const AIMove = centerAndEdges[randomIndex];
makeMoveAndUpdateDisplay(AIMove);
} else if (document.getElementById('category').value === 'Expert') {
// Expert level strategy: Prioritize winning moves and blocking opponent's winning moves
let winningMoveFound = false;
// Check for winning moves for the AI
for (let i = 0; i < emptyCells.length; i++) {
const testMove = emptyCells;
gameBoard[testMove.row][testMove.col] = 'O';
if (checkForWinner(testMove.row, testMove.col)) {
// Win the game if possible
makeMoveAndUpdateDisplay(testMove);
updateScores('O');
showPopup('O wins!');
resetGame();
return;
}
gameBoard[testMove.row][testMove.col] = '';
}
// Check for blocking opponent's winning moves
for (let i = 0; i < emptyCells.length; i++) {
const testMove = emptyCells;
gameBoard[testMove.row][testMove.col] = 'X';
if (checkForWinner(testMove.row, testMove.col)) {
// Block the opponent's winning move
makeMoveAndUpdateDisplay(testMove);
currentPlayer = 'X';
winningMoveFound = true;
break;
}
gameBoard[testMove.row][testMove.col] = '';
}
// If no winning moves or blocking moves, make a random move
if (!winningMoveFound) {
const randomIndex = Math.floor(Math.random() * emptyCells.length);
const AIMove = emptyCells[randomIndex];
makeMoveAndUpdateDisplay(AIMove);
}
} else {
// Basic level strategy: Make a random move
const randomIndex = Math.floor(Math.random() * emptyCells.length);
const AIMove = emptyCells[randomIndex];
makeMoveAndUpdateDisplay(AIMove);
}
}
}
function makeMoveAndUpdateDisplay(move) {
gameBoard[move.row][move.col] = 'O';
const AICell = document.querySelector(.cell[data-row="${move.row}"][data-col="${move.col}"]
);
AICell.textContent = 'O';
setTimeout(() => {
if (checkForWinner(move.row, move.col)) {
updateScores('O');
showPopup('O wins!');
resetGame();
} else {
currentPlayer = 'X';
}
}, 100);
}
function updateScores(winner) {
if (winner === 'X') {
scoreX++;
document.getElementById('scoreX').textContent = scoreX;
if (scoreX === 5) {
showPopup('Player X wins the game!');
resetScoresAndGame();
}
} else if (winner === 'O') {
scoreO++;
document.getElementById('scoreO').textContent = scoreO;
if (scoreO === 5) {
showPopup('Player O wins the game!');
resetScoresAndGame();
}
}
}
function resetScoresAndGame() {
scoreX = 0;
scoreO = 0;
document.getElementById('scoreX').textContent = scoreX;
document.getElementById('scoreO').textContent = scoreO;
resetGame();
}
function resetGame() {
gameBoard = Array.from({ length: rows }, () => Array(columns).fill(''));
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
cell.textContent = '';
});
currentPlayer = 'X';
}
createGameBoard();
</script>
</body>
</html>[/CODE]
makeAIMove
function to use it. The minimax algorithm is a recursive function that simulates all possible moves in the game to determine the best move for the AI.function minimax(board, depth, isMaximizing) {
let scores = {
'X': -10,
'O': 10,
'draw': 0
};
let result = checkWinner();
if (result !== null) {
return scores[result];
}
if (isMaximizing) {
let bestScore = -Infinity;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
if (board[i][j] === '') {
board[i][j] = 'O';
let score = minimax(board, depth + 1, false);
board[i][j] = '';
bestScore = Math.max(score, bestScore);
}
}
}
return bestScore;
} else {
let bestScore = Infinity;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
if (board[i][j] === '') {
board[i][j] = 'X';
let score = minimax(board, depth + 1, true);
board[i][j] = '';
bestScore = Math.min(score, bestScore);
}
}
}
return bestScore;
}
}
function checkWinner() {
// Implement the logic to check for a winner or a draw
// Return 'X' or 'O' if there is a winner, 'draw' if it's a draw, or null if the game is still ongoing
}
function makeAIMove() {
let bestScore = -Infinity;
let move;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < columns; j++) {
if (gameBoard[i][j] === '') {
gameBoard[i][j] = 'O';
let score = minimax(gameBoard, 0, false);
gameBoard[i][j] = '';
if (score > bestScore) {
bestScore = score;
move = { i, j };
}
}
}
}
if (move) {
gameBoard[move.i][move.j] = 'O';
document.querySelector(`.cell[data-row="${move.i}"][data-col="${move.j}"]`).textContent = 'O';
currentPlayer = 'X';
}
}
makeAIMove
function, you'll need to replace the existing logic with a call to the minimax
function to find the best move for the AI. The checkWinner
function should be implemented to check the current state of the board and return the winner or indicate a draw.checkForWinner
function to return the winner ('X' or 'O') or 'draw' instead of showing popups or resetting the game. The minimax function will use this information to calculate scores for each game state.