Skip to content

Commit

Permalink
feat: detect other diagonal wins for lower win piece counts
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdcvlsc committed Jul 3, 2023
1 parent 8527d3e commit 9f7b8c9
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
lib/Minimax.md
lib/ProjectExplanation.md

# Logs
logs
*.log
Expand Down
84 changes: 63 additions & 21 deletions lib/TicTacToe.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ function randomInteger(min, max) {
return Math.round(Math.random() * (max - min) + min);
}

function intSum(min, max) {
return ((max - min) + 1) * (min + max) / 2;
}

/** A single thread, blocking, **tic-tac-toe** class game representation that
* can use the **`minimax`** algorithm to search for the best possible move.
*/
Expand Down Expand Up @@ -231,34 +235,72 @@ class TicTacToe {
}

// check diag \
let samePieceSecondLastDiag = 1;
for (let i = 0; i < this.grid - 1; ++i) {
if (
this.board[i * this.grid + i] === this.board[(i + 1) * this.grid + (i + 1)] &&
this.board[i * this.grid + i] !== NA
) {
samePieceSecondLastDiag++;
if (samePieceSecondLastDiag === this.pieceWinCount) {
this.winner = this.board[i * this.grid + i];
return this.board[i * this.grid + i];
for (let i = 0; i < this.grid; ++i) {
let samePiece = 1, prevPiece = null;
for (let j = 0; j < i + 1; ++j) {
const CURRENT_INDEX = (this.grid - i) + ((this.grid + 1) * j) - 1;
if (prevPiece === this.board[CURRENT_INDEX] && this.board[CURRENT_INDEX] !== NA) {
samePiece++;
if (samePiece === this.pieceWinCount) {
this.winner = this.board[CURRENT_INDEX];
return this.board[CURRENT_INDEX];
}
} else {
samePiece = 1;
}
} else {
samePieceSecondLastDiag = 1;
prevPiece = this.board[CURRENT_INDEX];
}
}

for (let i = 1; i < this.grid; ++i) {
let samePiece = 1, prevPiece = null;
for (let j = 0; this.grid - i - j > 0; ++j) {
const CURRENT_INDEX = (i * this.grid) + ((this.grid + 1) * j);
if (prevPiece === this.board[CURRENT_INDEX] && this.board[CURRENT_INDEX] !== NA) {
samePiece++;
if (samePiece === this.pieceWinCount) {
this.winner = this.board[CURRENT_INDEX];
return this.board[CURRENT_INDEX];
}
} else {
samePiece = 1;
}
prevPiece = this.board[CURRENT_INDEX];
}
}

// check diag /
const diagStep = this.grid - 1;
let samePieceLastDiag = 1;
for (let i = 0; i < this.grid; ++i) {
let samePiece = 1, prevPiece = null;
for (let j = 0; j < i + 1; ++j) {
const CURRENT_INDEX = i + (j * this.grid) - j;
if (prevPiece === this.board[CURRENT_INDEX] && this.board[CURRENT_INDEX] !== NA) {
samePiece++;
if (samePiece === this.pieceWinCount) {
this.winner = this.board[CURRENT_INDEX];
return this.board[CURRENT_INDEX];
}
} else {
samePiece = 1;
}
prevPiece = this.board[CURRENT_INDEX];
}
}

for (let i = 1; i < this.grid; ++i) {
if (this.board[i * diagStep] === this.board[(i + 1) * diagStep] && this.board[i * diagStep] !== NA) {
samePieceLastDiag++;
if (samePieceLastDiag === this.pieceWinCount) {
this.winner = this.board[i * diagStep];
return this.board[i * diagStep];
let samePiece = 1, prevPiece = null;
for (let j = 0; this.grid - i - j > 0; ++j) {
const CURRENT_INDEX = ((this.grid * (i + 1)) - 1) + ((this.grid - 1) * j);
if (prevPiece === this.board[CURRENT_INDEX] && this.board[CURRENT_INDEX] !== NA) {
samePiece++;
if (samePiece === this.pieceWinCount) {
this.winner = this.board[CURRENT_INDEX];
return this.board[CURRENT_INDEX];
}
} else {
samePiece = 1;
}
} else {
samePieceLastDiag = 1;
prevPiece = this.board[CURRENT_INDEX];
}
}

Expand Down
57 changes: 57 additions & 0 deletions tests.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,63 @@
import { TicTacToe, NA, P1, P2 } from './lib/TicTacToe.js';

const t = new TicTacToe({ gridLength: 3 });
const fbf = new TicTacToe({ gridLength: 4, winCount: 3 });
let failedTests = 0;

const fbfWinners = [NA, P1, P2, P1, P2, P1, P2, P1, P2];
const fbfBoardStates = [
[
P2, NA, NA, P2,
NA, P1, NA, NA,
NA, NA, P2, NA,
P1, NA, NA, P1
],
[
NA, NA, P1, NA,
NA, P1, NA, NA,
P1, NA, NA, NA,
NA, NA, NA, NA
],[
NA, NA, NA, NA,
NA, NA, NA, P2,
NA, NA, P2, NA,
NA, P2, NA, NA
],[
NA, P1, NA, NA,
NA, NA, P1, NA,
NA, NA, NA, P1,
NA, NA, NA, NA
],[
NA, NA, NA, NA,
P2, NA, NA, NA,
NA, P2, NA, NA,
NA, NA, P2, NA
],[
NA, NA, NA, NA,
NA, NA, P1, NA,
NA, P1, NA, NA,
P1, NA, NA, NA
],[
NA, NA, NA, NA,
NA, P2, NA, NA,
NA, NA, P2, NA,
NA, NA, NA, P2
],[
NA, NA, NA, P1,
NA, NA, P1, NA,
NA, P1, NA, NA,
NA, NA, NA, NA
],[
P2, NA, NA, NA,
NA, P2, NA, NA,
NA, NA, P2, NA,
NA, NA, NA, NA
],
];

console.log('============ 4x4 - piece 3 win state tests ============ ');
failedTests += fbf.testEvaluation(fbfBoardStates, fbfWinners);

const winners = [NA, P1, P1, P1, P1, P1, P1, P2, P2, P2, P2, P2, P2, P1, P1, P2, P2, NA];

const winBoardStates = [
Expand All @@ -26,6 +81,7 @@ const winBoardStates = [
[P2, P1, P2, P1, P2, NA, NA, P1, NA], // no winner
];

console.log('============ 3x3 win state tests ============ ');
failedTests += t.testEvaluation(winBoardStates, winners);

const correctMoves = [
Expand Down Expand Up @@ -86,6 +142,7 @@ const moveBoardStates = [
[P1, NA, P1, P2, NA, P2, P1, P2, P1],
];

console.log('============ 3x3 move generation test ============ ');
failedTests += t.testGenerateMoves(moveBoardStates, correctMoves);

if (failedTests > 0) {
Expand Down

0 comments on commit 9f7b8c9

Please sign in to comment.