I'm a self taught programmer and I got my hands on a TicTacToe project, but I got stucked at the following part. I did a relatively working TicTacToe(inspired from youtube) then I wanted to do a responsive TicTacToe matrix that changes it's numbers from(0-9) in X's and O's in the console depending of the inputs of the first game. But now I'm stuck at trying to find a way to check the winners of the matrix oh and I'm trying to start the "checking" from the last X or O
Hopefully seeing the code is much more easier to understand. I'd really really appreciate some help!
const statusDiv = document.querySelector('.status');
const resetDiv = document.querySelector('.reset');
const cellDivs = document.querySelectorAll('.game-cell');
// game constants
const xSymbol = '×';
const oSymbol = '○';
// game variables
let gameIsLive = true;
let xIsNext = true;
var currentPlayer = 0;
//Random generated
function getInputValue() {
document.getElementById("formInput").style.display = "none";
document.getElementById("container").style.display = "inline";
let player1Input = document.getElementById("player1Input").value;
let player2Input = document.getElementById("player2Input").value;
currentPlayer = 1;
var random = Math.random() * 100;
if (random <= 60) {
currentPlayer = 1;
statusDiv.innerHTML = player1Input + " turn";
statusDiv.style.color = "blue";
}
else {
currentPlayer = 2;
statusDiv.innerHTML = player2Input + " turn";
statusDiv.style.color = "red";
}
}
// statusDiv.style.filter= "green";
//functions
const letterToSymbol = (letter) => letter === 'x' ? xSymbol : oSymbol;
const handleWin = (letter) => {
gameIsLive = false;
if (currentPlayer === 1) {
statusDiv.innerHTML = player1Input.value + " has won!";
statusDiv.style.color = "blue";
} else {
statusDiv.innerHTML = player2Input.value + " has won!";
statusDiv.style.color = "red";
}
};
const checkGameStatus = () => {
const topLeft = cellDivs[0].classList[1];
const topMiddle = cellDivs[1].classList[1];
const topRight = cellDivs[2].classList[1];
const middleLeft = cellDivs[3].classList[1];
const middleMiddle = cellDivs[4].classList[1];
const middleRight = cellDivs[5].classList[1];
const bottomLeft = cellDivs[6].classList[1];
const bottomMiddle = cellDivs[7].classList[1];
const bottomRight = cellDivs[8].classList[1];
// check winner
if (topLeft && topLeft === topMiddle && topLeft === topRight) {
handleWin(topLeft);
cellDivs[0].classList.add('won');
cellDivs[1].classList.add('won');
cellDivs[2].classList.add('won');
} else if (middleLeft && middleLeft === middleMiddle && middleLeft === middleRight) {
handleWin(middleLeft);
cellDivs[3].classList.add('won');
cellDivs[4].classList.add('won');
cellDivs[5].classList.add('won');
} else if (bottomLeft && bottomLeft === bottomMiddle && bottomLeft === bottomRight) {
handleWin(bottomLeft);
cellDivs[6].classList.add('won');
cellDivs[7].classList.add('won');
cellDivs[8].classList.add('won');
} else if (topLeft && topLeft === middleLeft && topLeft === bottomLeft) {
handleWin(topLeft);
cellDivs[0].classList.add('won');
cellDivs[3].classList.add('won');
cellDivs[6].classList.add('won');
} else if (topMiddle && topMiddle === middleMiddle && topMiddle === bottomMiddle) {
handleWin(topMiddle);
cellDivs[1].classList.add('won');
cellDivs[4].classList.add('won');
cellDivs[7].classList.add('won');
} else if (topRight && topRight === middleRight && topRight === bottomRight) {
handleWin(topRight);
cellDivs[2].classList.add('won');
cellDivs[5].classList.add('won');
cellDivs[8].classList.add('won');
} else if (topLeft && topLeft === middleMiddle && topLeft === bottomRight) {
handleWin(topLeft);
cellDivs[0].classList.add('won');
cellDivs[4].classList.add('won');
cellDivs[8].classList.add('won');
} else if (topRight && topRight === middleMiddle && topRight === bottomLeft) {
handleWin(topRight);
cellDivs[2].classList.add('won');
cellDivs[4].classList.add('won');
cellDivs[6].classList.add('won');
} else if (topLeft && topMiddle && topRight && middleLeft && middleMiddle && middleRight && bottomLeft && bottomMiddle && bottomRight) {
gameIsLive = false;
statusDiv.innerHTML = 'Game is tied!';
} else {
xIsNext = !xIsNext;
if (currentPlayer === 2) {
statusDiv.innerHTML = player1Input.value + ` turn`;
statusDiv.style.color = "blue";
currentPlayer = 1;
} else {
currentPlayer = 2;
statusDiv.style.color = "red";
statusDiv.innerHTML = player2Input.value + ` turn`;
}
}
};
// event Handlers
const handleReset = () => {
document.getElementById("formInput").style.display = "inline";
document.getElementById("container").style.display = "none";
xIsNext = true;
statusDiv.innerHTML = `Press Start Game`;
for (const cellDiv of cellDivs) {
cellDiv.classList.remove('x');
cellDiv.classList.remove('o');
cellDiv.classList.remove('won');
document.location.reload()
}
gameIsLive = true;
};
const handleCellClick = (e) => {
const classList = e.target.classList;
if (!gameIsLive || classList[1] === 'x' || classList[1] === 'o') {
return;
}
if (currentPlayer === 1) {
classList.add('playerOneColour');
} else {
classList.add('playerTwoColour');
}
if (xIsNext) {
classList.add("x");
} else {
classList.add('o');
}
checkGameStatus();
};
// event listeners
resetDiv.addEventListener('click', handleReset);
for (const cellDiv of cellDivs) {
cellDiv.addEventListener('click', handleCellClick);
cellDiv.addEventListener('click', handleCellSelection);
}
//Matrix Builder
var counter = 0;
var matrix = [];
for (var i = 0; i < 3; i++) {
matrix[i] = [];
for (var j = 0; j < 3; j++) {
matrix[i][j] = [];
matrix[i][j] = counter;
++counter;
}
}
// 0,1,2,3,4,5,6,7,8
// 0,1,2,0,1,2,0,1,2
var playerCounter = 1;
var currentPlayer = 1;
function handleCellSelection(e) {
playerCounter++;
let htmlElement = e.target;
let cellType = htmlElement.getAttribute("data-cell");
let reuseNTI = numberToIndexes(cellType);
let matrixIndex = indexInMatrix(reuseNTI[0], reuseNTI[1]);
let isWinnerFunction = isPlayerWinner(matrix);
function indexInMatrix(index1, index2) {
if (currentPlayer === 2) {
return matrix[index1].splice([index2], 1, "X")
currentPlayer = 1;
} else {
return matrix[index1].splice([index2], 1, "O");
currentPlayer = 2;
}
}
function isPlayerWinner(matrix, currentPlayer) {
if (playerCounter < 6) {
return;
} else {
var xSign = "X";
var oSign = "O";
let rowX = 0;
let rowO = 0;
//TO DO CHECK COLUMN
for (var i = 0; i < matrix[0].length; i++) {
if (xSign === matrix[i][reuseNTI[0]]) {
rowX++
} else if (oSign === matrix[i][reuseNTI[0]]) {
rowO++
console.log(rowO)
}
// console.log(matrix[i, 0].lastIndexOf("X")) ; //000↓,111↓,222↓
// console.log(matrix[i, 0].lastIndexOf("O"));
}
//TO DO CHECK ROW
for (var i = 0; i < matrix[0].length; i++) {
if (xSign === matrix[reuseNTI[0][i]]) {
} else if (oSign === matrix[reuseNTI[0]][i]) {
}
// console.log(matrix[0, i].lastIndexOf("X")) ; //row is 000->,111->,222->
// console.log(matrix[0, i].lastIndexOf("O"));
}
//TO DO CHECK PRIMARY DIAGONAL
for (var i = 0; i < matrix[0].length; i++) {
if (xSign === matrix[i][i]) {
} else if (oSign === matrix[i][i]) {
}
// matrix[i][i];
// console.log(matrix[i, i].lastIndexOf("X")); //012->,012->,012->
// console.log(matrix[i, i].lastIndexOf("O"));
}
//TO DO CHECK SECONDARY DIAGONAL
for (var i = 0; i < matrix[0].length; i++) {
if (xSign === matrix[i][matrix.length - 1 - i]) {
} else if (oSign === matrix[i][matrix.length - 1 - i]) {
}
// matrix[i][matrix.length - 1 - i];
// console.log(matrix[i, matrix.length - 1 - i].lastIndexOf("X"));
// console.log(matrix[i, [matrix.length - 1 - i]].lastIndexOf("O"));
}
}
}
isPlayerWinner(matrix);
console.log(matrix);
}
function numberToIndexes(number) {
let row = Math.floor(number / 3);
let column = number % 3;
return [row, column];
}
var cellSize = 100;
var cellSpace = 10;
var matrixRows = matrix.length;
var matrixColumns = matrix[0].length;
for (var i = 0; i < matrixRows; i++) {
for (var j = 0; j < matrixColumns; j++) {
var cell = document.createElement("div");
cell.setAttribute("class", "cell");
matrixStage.appendChild(cell);
cell.style.top = i * (cellSize + cellSpace) + "px";
cell.style.left = j * (cellSize + cellSpace) + "px";
}
}
function newMatrixGrid() {
var grid3x3 = document.getElementById("matrixMaker").value;
if (grid3x3 == "3") {
var matrixStage = document.querySelector("#matrixStage").style.display = "block";
} else {
matrixStage = document.querySelector("#matrixStage").style.display = "none";
}
}
#player1{
color: blue;
}
#player2{
color: red;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
color: #545454;
display: grid;
font-family: sans-serif;
justify-content: center;
}
.container {
background: #ffffff;
margin: 50px;
padding: 50px;
border-radius: 25px;
}
.title {
text-align: center;
}
.title span {
color: #F2EBD3;
}
.status-action {
color:blue;
display: flex;
margin-top: 25px;
font-size: 25px;
justify-content: space-around;
height: 30px;
}
.status span {
color: red;
}
.reset {
color: black;
cursor: pointer;
}
.reset:hover {
color: #10976c;
}
.game-grid {
background: #000000;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 15px;
margin-top: 50px;
}
.game-cell {
background:white;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
height: 200px;
width: 200px;
}
.playerOneColour{
filter: invert(9%) sepia(100%) saturate(7261%) hue-rotate(247deg) brightness(91%) contrast(146%);
}
.playerTwoColour{
filter: invert(14%) sepia(95%) saturate(6042%) hue-rotate(358deg) brightness(109%) contrast(117%);
}
.x {
color: transparent;
cursor: default;
}
.o {
color: transparent;
cursor: default;
}
.x::after {
background-image: url(../Resources/X.png);
background-size:contain;
background-repeat: no-repeat;
margin-top: 80px;
content: '×';
}
.o::after {
background-image: url(../Resources/O.png);
background-size:contain;
background-repeat: no-repeat;
margin-top: 100px;
content: '○';
}
.won::after {
filter: invert(100%) sepia() saturate(10000%) hue-rotate(0deg);
}
@media only screen and (min-width: 1024px) {
.game-grid {
margin-top: 25px;
grid-gap: 10px;
}
.game-cell {
height: 150px;
width: 150px;
}
.x::after {
font-size: 150px;
}
.o::after {
font-size: 175px;
}
}
@media only screen and (max-width: 540px) {
.container {
margin: 25px;
padding: 25px;
}
.game-cell {
height: 100px;
width: 100px;
}
.x::after {
font-size: 100px;
}
.o::after {
font-size: 125px;
}
}
#matrixStage{
position:relative;
}
.cell
{
position: absolute;
width: 100px;
height: 100px;
border: 1px solid black;
background-color: white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Play XO</title>
<link rel="StyleSheet" href="Styles/index.css">
</head>
<body>
<form id="formInput">
<h1>Play X O </h1><br>
<label for="player1" id="player1">Player 1:</label><br>
<input type="text" id="player1Input"><br>
<label for="player1" id="player2">Player 2:</label><br>
<input type="text" id="player2Input"><br><br>
<button type="button" onclick="getInputValue();"> Start Game</button>
</form>
<br>
</form>
<div class="container" style="display:none" id="container">
<h1 class="title">Play X O </h1>
<div class="status-action">
<div class="status">Player 1 turn</div>
<div class="reset">Reset</div>
</div>
<div class="game-grid">
<div class="game-cell" data-cell="0"></div>
<div class="game-cell" data-cell="1"></div>
<div class="game-cell" data-cell="2"></div>
<div class="game-cell" data-cell="3"></div>
<div class="game-cell" data-cell="4"></div>
<div class="game-cell" data-cell="5"></div>
<div class="game-cell" data-cell="6"></div>
<div class="game-cell" data-cell="7"></div>
<div class="game-cell" data-cell="8"></div>
</div>
</div>
<select name="matrix-size" id="matrixMaker" onchange="newMatrixGrid()">
<option value="3">3X3</option>
<option value="4">4X4</option>
<option value="5">5X5</option>
</select>
</br></br></br>
<div id="matrixStage"></div>
<script src="Scripts/index.js"></script>
</body>
</html>
I think you can simplify your isPlayerWinner function by ignoring if you are looking for Xs or Os. You must assume the last token used was not the winner in the previous turn or the game would already be finished.
So if you have matrix = [[0,1,2],[3,4,5],[6,7,8]] and the numbers will be progressively replaced by x or o just check if all items in a combination are equal
function isPlayerWinner(){
for(let i=0; i<3; i++){
const row = matrix[i][0] === matrix[i][1] && matrix[i][1] === matrix[i][2];
const column = matrix[0][i] === matrix[1][i] && matrix[1][i] === matrix[2][i];
if(column || row){
return true
}
}
if(matrix[0][0] === matrix[1][1] && matrix[1][1] === matrix[2][2]){
return true;
}
if(matrix[0][2] === matrix[1][1] && matrix[1][1] === matrix[2][0]){
return true;
}
return false
}