There's a function called "table" that creates a clickable table, where the clicked values are stored in a variable called "board". After initializing the "board", another matrix called "a" is created with values {0,1,2,3,4,5,6,7,8}. The "getlines" function checks all possible winning combinations in rows, columns, and diagonals. The problem is with the "checkWinner3()", "minimax()", and "computermovedifficult()" functions. In these functions:
Every move results in a score of -Infinity. Only the first 'O' is written on the board, and subsequent 'O's are not written.
let winner = null;
let wins = 0;
let turn = "X";
let board = initializeBoard(3);
function generateTable() {
const table = document.getElementById("board");
table.innerHTML = "";
// Generate rows and cells based on the matrix size
for (let i = 0; i < 3; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 3; j++) {
const cell = document.createElement("td");
cell.setAttribute(
"onclick",
`cellClick(${i * 3 + j})`,
);
row.appendChild(cell);
}
table.appendChild(row);
}}
generateTable();
function initializeBoard() {
let board = [];
for (let i = 0; i <= 9; i++) {
board.push(null);
}
return board;}
console.log(board);
let lines1 = [[]];
function getlines(a) {
let ijk = 3 - 2;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (j < ijk) {
if (
isValidIndex(a, i, j) &&
isValidIndex(
a,
i,
j + 1,
) &&
isValidIndex(a, i, j + 2)
) {
lines1.push([
a[i][j],
a[i][j + 1],
a[i][j + 2],
]);
}
}
if (i < ijk) {
if (
isValidIndex(a, i, j) &&
isValidIndex(
a,
i + 1,
j,
) &&
isValidIndex(a, i + 2, j)
) {
lines1.push([
a[i][j],
a[i + 1][j],
a[i + 2][j],
]);
}
}
// for left diagonal
if (i < ijk && j < ijk) {
if (
isValidIndex(a, i, j) &&
isValidIndex(
a,
i + 1,
j + 1,
) &&
isValidIndex(
a,
i + 2,
j + 2,
)
) {
lines1.push([
a[i][j],
a[i + 1][
j +
1
],
a[i + 2][
j +
2
],
]);
}
}
// for right diagonal
if (i < ijk && j >= 2) {
if (
isValidIndex(a, i, j) &&
isValidIndex(
a,
i + 1,
j - 1,
) &&
isValidIndex(
a,
i + 2,
j - 2,
)
) {
lines1.push([
a[i][j],
a[i + 1][
j -
1
],
a[i + 2][
j -
2
],
]);
}
}
lines1 = lines1.filter((arr) => arr.length > 0);
}
}
return lines1;
}
function isValidIndex(array, row, col) {
return (
row >= 0 &&
row < array.length &&
col >= 0 &&
col < array[row].length
);
}
function generateMatrixWin(matrixSize) {
let matrix = [];
let count = 0;
// Create the matrix
for (let i = 0; i < 3; i++) {
let row = [];
for (let j = 0; j < 3; j++) {
row.push(count);
count++;
}
matrix.push(row);
}
return matrix;
}
// Test the function with a matrix size of 5
let resultMatrix = generateMatrixWin(3);
let a = generateMatrixWin(3);
// Print the result matrix
for (let i = 0; i < resultMatrix.length; i++) {
console.log(a[i].join("\t"));
}
function checkWinner3() {
lines = getlines(a);
// Iterate through rows
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (
board[a] &&
board[a] === board[b] &&
board[a] === board[c]
) {
console.log(board[a]);
return board[a];
}
}
for (let i = 0; i < 9; i++) {
if (!board[i]) {
return null;
}
}
return "draw";
}
function printBoard() {
const table = document.getElementById("board");
for (let i = 0; i < 9; i++) {
const row = Math.floor(i / 3);
const col = i % 3;
table.rows[row].cells[col].textContent = board[i];
}
}
function cellClick(index) {
if (!winner && !board[index]) {
board[index] = turn;
printBoard();
winner = checkWinner3();
if (winner) {
if (winner === "draw") {
document.getElementById(
"result",
).textContent =
"It's a draw! Thanks for playing.";
} else {
document.getElementById(
"result",
).textContent =
`Congratulations! ${winner} have won! Thanks for playing.`;
}
} else {
turn =
turn === "X"
? computermovedifficult()
: "X";
}
}
}
// }
function computermoveeasy() {
const table = document.getElementById("board");
do {
index = Math.floor(Math.random() * board.length);
} while (board[index] !== null);
board[index] = "O"; // Place the computer's move at the randomly generated index
for (let i = 0; i <= 9; i++) {
const row = Math.floor(i / 3);
const col = i % 3;
table.rows[row].cells[col].textContent = board[i];
}
turn = "X";
lines = getlines(a);
// Iterate through rows
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (
board[a] &&
board[a] === board[b] &&
board[a] === board[c]
) {
console.log("WINS" + board[a]);
document.getElementById("result").textContent =
`Congratulations! ${board[a]} have won! Thanks for playing.`;
return board[a];
}
}
}
function computermovedifficult() {
let bestScore = -Infinity;
let bestMove = null;
const table = document.getElementById("board");
for (let index = 0; index < 9; index++) {
// if (board[index] === null) {
if (
board[index] === null ||
board[index] === undefined ||
board[index] === ""
) {
board[index] = "O";
let score = minimax(board, 0, false);
board[index] = ""; // Undo the move
console.log(`Move: ${index}, Score: ${score}`);
if (score > bestScore) {
bestScore = score;
bestMove = index;
}
}
}
board[bestMove] = "O"; // Update the board with the best move
console.log("Best Move:", bestMove); // Log the best move for debugging
console.log("Best Score:", bestScore); // Log the best score for debugging
console.log("Updated Board:", board); // Log the updated board array for debugging
turn = "X";
return turn;
}
function minimax(board, depth, isMaximizing) {
lines = getlines(a);
// Iterate through rows
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
for (let i = 0; i < 9; i++) {
if (!board[i]) {
result = null;
}
}
result = "draw";
if (
board[a] &&
board[a] === board[b] &&
board[a] === board[c]
) {
console.log(board[a]);
result = board[a];
}
}
if (result !== null) {
// Adjust scores based on the result
if (result === "draw") {
console.log("draw");
return 0;
} else if (result === "O") {
return 10 - depth;
} else if (result === "X") {
return depth - 10;
}
}
if (depth >= 5) {
return 0; // Return 0 when reaching the maximum depth
}
if (isMaximizing) {
let bestScore = -Infinity;
for (let i = 0; i < 9; i++) {
if (board[i] === "") {
board[i] = "O";
let score = minimax(
board,
depth + 1,
false,
);
board[i] = null;
bestScore = Math.max(
score,
bestScore,
);
turn = "X";
}
}
return bestScore;
} else {
let bestScore = Infinity;
for (let i = 0; i < 9; i++) {
// ===''
if (board[i] === "") {
board[i] = "X";
let score = minimax(
board,
depth + 1,
true,
);
board[i] = null;
bestScore = Math.min(
score,
bestScore,
);
turn = "O";
}
}
return bestScore;
}
}
body, html { height: 100%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction:column; }
table { border-collapse: collapse; }
td { border: 1px solid black;
width: 50px;
height: 50px;
text-align: center;
font-size: 20px; }
.result {
margin-top: 50px;
font-size: 1.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.2/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tic Tac Toe</title>
</head>
<body>
<h1>Tic Tac Toe</h1> <br>
<table id="board"> </table>
<div id="result" class="result"></div>
</body>
<!-- language: css -->
.result {
margin-top: 50px;
font-size: 1.5em;
}
<!-- end snippet -->
<!-- language: html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.2/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tic Tac Toe</title>
</head>
<body>
<h1>Tic Tac Toe</h1> <br>
<table id="board"> </table>
<div id="result" class="result"></div>
</body>
<!-- end snippet -->