// Cloned by Joseph Adedayo on 29 Nov 2022 from World "Tic-Tac-Toe (clone by Niall Cian Quigley)" by Niall Cian Quigley
// Please leave this clone trail here.
// Cloned by Niall Cian Quigley on 15 Nov 2022 from World "Tic-Tac-Toe" by Scott Brady
// Please leave this clone trail here.
//---- normal P5 code -------------------------------------------------------
let board;
let p1;
let p2;
let turn;
let scoreDiv;
function setup() {
p1 = new Player("X")
p2 = new Player("O")
createCanvas(400, 400);
scoreDiv = createDiv('').size(100, 25);
board = new Board(3, p1, p2)
}
function draw() {
background(180);
board.display();
}
function mousePressed() {
if (!board.winState) {
if (board.turn === "X") {
p1.select(board);
} else {
p2.select(board);
}
board.toggleTurn();
} else {
board.newGame();
}
}
// board attributes & methods
class Board {
constructor(size, p1, p2) {
this.s = size;
this.cells = [];
this.cellSize = (width-1)/this.s;
this.p1 = p1;
this.p2 = p2;
this.turn = this.p1.t;
this.winState = false;
this.resultText = "";
this.newGame();
}
display() {
let cellSize = this.cellSize;
if (this.winState) {
textSize(24);
textAlign(CENTER);
text(this.resultText, width / 2, height / 2);
text("Click anywhere for a new game", width / 2, height / 2 + 30)
} else {
this.cells.forEach(function(element) {
rect(element.r*cellSize, element.c*cellSize, cellSize, cellSize);
textSize(64);
textAlign(CENTER);
text(element.t, element.r*cellSize + cellSize/2, element.c*cellSize+cellSize/1.5)
});
}
}
update(r, c, t) {
let turn = this.turn;
this.cells.forEach(function(element) {
if (element.r === r && element.c === c && element.v === 0) {
element.t = t;
if (turn === "X") {
element.v = 1;
} else {
element.v = -1
}
}
});
let result = this.checkResult()
if (result) {
this.winState = true;
this.resultText = result + " won!";
}
}
toggleTurn() {
if (this.turn == p1.t) {
this.turn = p2.t;
scoreDiv.html("Turn: " + p2.t);
} else {
this.turn = p1.t;
scoreDiv.html("Turn: " + p1.t);
}
}
checkResult() {
let winner;
let p1 = this.p1;
let p2 = this.p2;
let rowSums = new Array(this.s);
let colSums = new Array(this.s);
let diagSums = new Array(this.s);
let numOpen = 9;
let s = this.s
for(let i = 0; i < this.s; i++) {
rowSums[i] = 0
colSums[i] = 0
diagSums[i] = 0
}
this.cells.forEach(function(element) {
rowSums[element.r] += element.v;
colSums[element.c] += element.v;
numOpen -= abs(element.v);
if (abs(element.r - element.c) === 0) {
diagSums[0] += element.v;
}
if (abs(element.r-element.c) === 2 || (element.r == 1 && element.c == 1)) {
diagSums[1] += element.v;
}
});
rowSums.forEach(function(element) {
if(element === s){
winner = p1.t;
p1.win();
}
if (element === -1*s){
winner = p2.t;
p2.win();
}
});
colSums.forEach(function(element) {
if(element === s){
winner = p1.t;
p1.win();
}
if (element === -1*s){
winner = p2.t;
p2.win();
}
});
diagSums.forEach(function(element) {
if(element === s){
winner = p1.t;
p1.win();
}
if (element === -1*s){
winner = p2.t;
p2.win();
}
});
if (numOpen === 0 ){
winner = "No one, it's a tie";
}
return winner;
}
newGame() {
this.winState = false;
this.turn = this.p1.t;
scoreDiv.html("Turn: " + this.p1.t);
this.cells = [];
for(let i = 0; i < this.s; i++) {
for (let j = 0; j < this.s; j++) {
this.cells.push({
"r": i,
"c": j,
"t": "",
"v": 0
});
}
}
}
}
class Player {
constructor(p) {
this.t = p;
this.score = 0;
}
select(board) {
if (board.turn == this.t) {
let cx = int(Math.floor(mouseX/board.cellSize));
let cy = int(Math.floor(mouseY/board.cellSize));
board.update(cx, cy, this.t);
}
}
win() {
this.score ++
}
}