Skip to content

Commit

Permalink
Merge pull request #6 from aglgit/main
Browse files Browse the repository at this point in the history
Merge main to deploy
  • Loading branch information
aglgit authored Jan 25, 2025
2 parents 71b622d + a0885c1 commit 1c28aca
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 102 deletions.
2 changes: 0 additions & 2 deletions src/board/__tests__/boardState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ const boardState: BoardState = new BoardState(boardGenerator, boardCalculator);

test("Reset board ensures correct state", () => {
boardState.gameOver = true;
boardState.coinsThisLevel = 300;
boardState.selectedTile = boardState.grid[1][1];
boardState.selectedRow = 1;
boardState.selectedCol = 1;

boardState.resetBoard();

expect(boardState.gameOver).toBe(false);
expect(boardState.coinsThisLevel).toBe(0);
expect(boardState.selectedTile).toBe(boardState.grid[0][0]);
expect(boardState.selectedRow).toBe(0);
expect(boardState.selectedCol).toBe(0);
Expand Down
109 changes: 11 additions & 98 deletions src/board/boardListener.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Tile } from "@src/types/tiles";
import { BOARD_SIZE } from "@src/types/constants";
import BoardState from "./boardState";
import { Direction } from "../types/direction";

class BoardListener {
boardState: BoardState;
Expand All @@ -10,66 +10,37 @@ class BoardListener {
}

public gameTileMarkListener(mark: number): void {
const tile = this.boardState.selectedTile;
this.toggleMark(tile, mark);
this.boardState.toggleMark(mark);
}

public gameTileRevealListener(tile: Tile, i: number, j: number): void {
if (this.boardState.gameOver) {
if (this.boardState.gameOver || this.boardState.gameWon) {
this.boardState.resetBoard();
} else if (this.boardState.memoMode) {
this.boardState.selectedTile = tile;
this.boardState.selectedRow = i;
this.boardState.selectedCol = j;
this.boardState.toggleSelectedTile(tile, i, j);
} else {
this.boardState.selectedTile = tile;
this.boardState.selectedRow = i;
this.boardState.selectedCol = j;
this.revealTile(tile);
this.boardState.toggleSelectedTile(tile, i, j);
this.boardState.revealTile(tile);
}
}

public keyPressListener(event: KeyboardEvent): void {
switch (event.key) {
case "ArrowUp":
event.preventDefault();
if (this.boardState.selectedRow > 0) {
this.boardState.selectedRow--;
this.boardState.selectedTile =
this.boardState.grid[this.boardState.selectedRow][
this.boardState.selectedCol
];
}
this.boardState.moveSelectedTile(Direction.Up);
break;
case "ArrowDown":
event.preventDefault();
if (this.boardState.selectedRow < BOARD_SIZE - 1) {
this.boardState.selectedRow++;
this.boardState.selectedTile =
this.boardState.grid[this.boardState.selectedRow][
this.boardState.selectedCol
];
}
this.boardState.moveSelectedTile(Direction.Down);
break;
case "ArrowLeft":
event.preventDefault();
if (this.boardState.selectedCol > 0) {
this.boardState.selectedCol--;
this.boardState.selectedTile =
this.boardState.grid[this.boardState.selectedRow][
this.boardState.selectedCol
];
}
this.boardState.moveSelectedTile(Direction.Left);
break;
case "ArrowRight":
event.preventDefault();
if (this.boardState.selectedCol < BOARD_SIZE - 1) {
this.boardState.selectedCol++;
this.boardState.selectedTile =
this.boardState.grid[this.boardState.selectedRow][
this.boardState.selectedCol
];
}
this.boardState.moveSelectedTile(Direction.Right);
break;
case "Enter":
this.gameTileRevealListener(
Expand All @@ -86,70 +57,12 @@ class BoardListener {
case "1":
case "2":
case "3": {
const tile = this.boardState.selectedTile;
const mark = parseInt(event.key);
this.toggleMark(tile, mark);
this.boardState.toggleMark(mark);
break;
}
}
}

private toggleMark(tile: Tile, mark: number): void {
if (tile) {
if (tile.marks.has(mark)) {
tile.marks.delete(mark);
} else {
tile.marks.add(mark);
}
}
}

private revealTile(tile: Tile): void {
tile.revealed = true;
if (tile.voltorb) {
this.triggerGameOver();
} else {
if (tile.value > 1) {
this.boardState.num2s3s--;
}
this.boardState.coinsThisLevel =
this.boardState.coinsThisLevel > 0
? this.boardState.coinsThisLevel * tile.value
: tile.value;
}
if (this.isGamecomplete()) {
this.triggerGameComplete();
}
}

private isGamecomplete(): boolean {
return this.boardState.num2s3s === 0;
}

private triggerGameOver(): void {
this.boardState.gameOver = true;
alert("Game over!");
this.flipBoard(true);
this.boardState.level =
this.boardState.level > 1 ? this.boardState.level - 1 : 1;
}

private triggerGameComplete(): void {
this.boardState.gameOver = true;
alert("You won!");
this.flipBoard(true);
this.boardState.totalCoins += this.boardState.coinsThisLevel;
this.boardState.level++;
}

private flipBoard(reveal: boolean): void {
const grid = this.boardState.grid;
grid.forEach((row) => {
row.forEach((col) => {
col.revealed = reveal;
});
});
}
}

export default BoardListener;
11 changes: 10 additions & 1 deletion src/board/boardRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ class BoardRenderer {
}

public renderGame(): void {
this.renderGameAlert();
this.renderInfo();
this.renderBoard();
this.renderMemoButton();
}

private renderGameAlert() {
if (this.boardState.gameWon) {
alert("You won!");
} else if (this.boardState.gameOver) {
alert("Game over!");
}
}

private renderInfo(): void {
const levelElement = document.getElementById("info-level");
levelElement!.textContent = `Level: \n${this.boardState.level}`;
Expand All @@ -34,7 +43,7 @@ class BoardRenderer {
levelCoinsElement!.textContent = `Coins this level: \n${this.boardState.coinsThisLevel}`;
}

private renderBoard() {
private renderBoard(): void {
const gameBoard: HTMLElement | null =
document.getElementById("game-board");
gameBoard!.innerHTML = "";
Expand Down
101 changes: 100 additions & 1 deletion src/board/boardState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import BoardGenerator from "./boardGenerator";
import { BOARD_SIZE } from "@src/types/constants";
import { LEVELS, NUM_BOARDS_PER_LEVEL } from "@src/types/levels";
import { Tile, TileSum } from "@src/types/tiles";
import { Direction } from "../types/direction";

class BoardState {
boardGenerator: BoardGenerator;
boardCalculator: BoardCalculator;
level: number;
gameOver: boolean;
gameWon: boolean;
memoMode: boolean;
totalCoins: number;
coinsThisLevel: number;
Expand All @@ -29,6 +31,7 @@ class BoardState {

this.level = 1;
this.gameOver = false;
this.gameWon = false;
this.memoMode = false;
this.totalCoins = 0;
this.coinsThisLevel = 0;
Expand All @@ -49,7 +52,7 @@ class BoardState {

public resetBoard(): void {
this.gameOver = false;
this.coinsThisLevel = 0;
this.gameWon = false;

const levelData =
LEVELS[this.level.toString()][
Expand All @@ -68,6 +71,102 @@ class BoardState {
public toggleMemoMode(): void {
this.memoMode = !this.memoMode;
}

public toggleSelectedTile(tile: Tile, i: number, j: number): void {
this.selectedTile = tile;
this.selectedRow = i;
this.selectedCol = j;
}

public moveSelectedTile(direction: Direction) {
switch (direction) {
case Direction.Up:
if (this.selectedRow > 0) {
this.selectedRow--;
this.selectedTile =
this.grid[this.selectedRow][this.selectedCol];
}
break;
case Direction.Down:
if (this.selectedRow < BOARD_SIZE - 1) {
this.selectedRow++;
this.selectedTile =
this.grid[this.selectedRow][this.selectedCol];
}
break;
case Direction.Left:
if (this.selectedCol > 0) {
this.selectedCol--;
this.selectedTile =
this.grid[this.selectedRow][this.selectedCol];
}
break;
case Direction.Right:
if (this.selectedCol < BOARD_SIZE - 1) {
this.selectedCol++;
this.selectedTile =
this.grid[this.selectedRow][this.selectedCol];
}
break;
}
}

public toggleMark(mark: number): void {
const tile = this.selectedTile;
if (tile) {
if (tile.marks.has(mark)) {
tile.marks.delete(mark);
} else {
tile.marks.add(mark);
}
}
}

public isGamecomplete(): boolean {
return this.num2s3s === 0;
}

public revealTile(tile: Tile): void {
tile.revealed = true;
if (tile.voltorb) {
this.triggerGameOver();
} else {
if (tile.value > 1) {
this.num2s3s--;
}
this.coinsThisLevel =
this.coinsThisLevel > 0
? this.coinsThisLevel * tile.value
: tile.value;
}
if (this.isGamecomplete()) {
this.triggerGameWon();
}
}

public flipBoard(): void {
const grid = this.grid;
grid.forEach((row) => {
row.forEach((col) => {
col.revealed = true;
});
});
}

private triggerGameOver(): void {
this.gameOver = true;
this.flipBoard();
this.coinsThisLevel = 0;
this.level = this.level > 1 ? this.level - 1 : 1;
}

private triggerGameWon(): void {
this.gameWon = true;
this.flipBoard();
this.totalCoins += this.coinsThisLevel;
this.coinsThisLevel = 0;
this.level++;
}
}

export default BoardState;
6 changes: 6 additions & 0 deletions src/types/direction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum Direction {
Up,
Down,
Left,
Right,
}

0 comments on commit 1c28aca

Please sign in to comment.