Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions technical-fundamentals/coding/__tests__/connect4.test.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { describe, it, expect, vi } from "vitest";
import { Connect4, PLAYER_ONE, PLAYER_TWO } from "../connect4.mjs";
import { describe, it, expect } from "vitest";
import { Connect4, PLAYER_ONE } from "../connect4.mjs";

describe("Connect4", () => {
it("It should allow you play within bounds", async () => {
const c4 = new Connect4({ width: 10, height: 10 });
expect(c4.getValue(10, 1)).toBeFalsy();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if it was part of the challenge or a bug in the test. 10 should be out if it is a 10 by 10 matrix. I took this direction since in the next test
"it should detect horizontal winning" the position 0 is used for the column.

expect(c4.getValue(9, 1)).toBeFalsy();
c4.play(1);
expect(c4.getValue(10, 1)).toEqual(PLAYER_ONE);
expect(c4.getValue(9, 1)).toEqual(PLAYER_ONE);
});

it("It should do nothing if you play out of bounds", async () => {
Expand All @@ -33,14 +33,14 @@ describe("Connect4", () => {
expect(c4.winner()).toEqual(PLAYER_ONE);
});

it("it should detect diagonal winning", () => {
it("it should detect diagonal winning right", () => {
const c4 = new Connect4({ width: 10, height: 10 });
const plays = [1, 2, 2, 3, 4, 3, 3, 4, 5, 4, 4];
plays.forEach((p) => c4.play(p));
expect(c4.winner()).toEqual(PLAYER_ONE);
});

it("it should detect diagonal winning", () => {
it("it should detect diagonal winning left", () => {
const c4 = new Connect4({ width: 10, height: 10 });
const plays = [1, 2, 2, 3, 4, 3, 3, 4, 5, 4, 4].reverse();
plays.forEach((p) => c4.play(p));
Expand Down
129 changes: 120 additions & 9 deletions technical-fundamentals/coding/connect4.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,131 @@
/**
Connect4
Connect4

Connect4 is a game where two players take turns placing a token on columns that drop to the bottom.
When a player forms 4 of his tokens in a line - horizontally, vertically,or diagonally - the player wins.
Connect4 is a game where two players take turns placing a token on columns that drop to the bottom.
When a player forms 4 of his tokens in a line - horizontally, vertically,or diagonally - the player wins.

[Visualization](https://i.ebayimg.com/images/g/DzMAAOSwSjxj6m0e/s-l1600.jpg)
[Visualization](https://i.ebayimg.com/images/g/DzMAAOSwSjxj6m0e/s-l1600.jpg)

Implement Connect 4 with the class below.
*/
Implement Connect 4 with the class below.
*/

export const PLAYER_ONE = 1;
export const PLAYER_TWO = 2;

export class Connect4 {
constructor() {}
play(col) {}
checkWinner() {}
board = [];
currentPlayer;
theWinner;
constructor() {
this.board = Array.from({length: 10}, () => Array(10).fill(0));
this.currentPlayer = PLAYER_ONE;
}
play(col) {

if (this.theWinner) return;

for (let row=this.board.length - 1; row>=0; row--) {
if (this.board[row][col] === 0) {
this.board[row][col] = this.currentPlayer;
this.checkWinner(row, col);
break;
}
}

this.currentPlayer = this.currentPlayer === PLAYER_ONE ? PLAYER_TWO : PLAYER_ONE;

}

getValue(row, col) {
if (row<0 || col<0 || row>this.board.length - 1 || col>this.board[0].length) {
return false;
}

return this.board[row][col];
}
checkWinner(row, col) {

const height = this.board.length;
const width = this.board[0].length;

const checkFour = (self, count) => {
if (count >= 4) {
self.theWinner = self.currentPlayer;
return true;
}
}

let count = 0;
//vertically bottom
let y = row;
while (y<=height - 1 && this.currentPlayer === this.board[y][col]) {
y++;
count++;
}
if (checkFour(this, count)) return;

//horizontally left
count = 0;
let x = col;
while (x>=0 && this.currentPlayer === this.board[row][x]) {
x--;
count++;
}
if (checkFour(this, count)) return;
//horizontally right
x = col+1;
while (x<=width && this.currentPlayer === this.board[row][x]) {
x++;
count++;
}
if (checkFour(this, count)) return;

// diagonally left top
count = 0;
x = col;
y = row;
while (x>=0 && y>=0 && this.currentPlayer === this.board[y][x]) {
x--;
y--;
count++;
}
if (checkFour(this, count)) return;

// diagonally right bottom
x = col+1;
y = row+1;
while (x<=width - 1 && y<=height - 1 && this.currentPlayer === this.board[y][x]) {
x++;
y++;
count++;
}
if (checkFour(this, count)) return;

// diagonally right top
count = 0;
x = col;
y = row;
while (x<=width - 1 && y>=0 && this.currentPlayer === this.board[y][x]) {
x++;
y--;
count++;
}
if (checkFour(this, count)) return;

// diagonally left bottom
x = col-1;
y = row+1;
while (x>=0 && y<=height - 1 && this.currentPlayer === this.board[y][x]) {
x--;
y++;
count++;
}
checkFour(this, count);

}
print() {}

winner() {
return this.theWinner;
}
}