fuzzyworld

dao-game / commit

Starting to split out single source file into multiple smaller ones.

ed1a45fd541f0b03a3d1d11026673a39893d57a7 · Pavel Safronov · 2022-03-05 00:51:31 -0800 · parents 6ef12b2c637b

Starting to split out single source file into multiple smaller ones.
 src/game.ts  | 115 ++++++-----------------------------------------------------
 src/types.ts | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+), 104 deletions(-)

diff --git a/src/game.ts b/src/game.ts
index 119341f..60fa73c 100644
--- a/src/game.ts
+++ b/src/game.ts
@@ -1,84 +1,14 @@
-class Coord {
-    public row: number;
-    public col: number;
-
-    constructor(row: number, col: number) {
-        this.row = row;
-        this.col = col;
-    }
-
-    public add(coord: Coord): Coord {
-        return new Coord(this.row + coord.row, this.col + coord.col);
-    }
-
-    sub(coord: Coord): Coord {
-        return new Coord(this.row - coord.row, this.col - coord.col);
-    }
-
-    equals(otherCoord: Coord): boolean {
-        const areEqual = (this.col === otherCoord.col && this.row === otherCoord.row);
-        return areEqual;
-    }
-
-    // clock face directions
-    static get allDirections(): Coord[] {
-        const allDirections = [
-            new Coord(1, 0), // up
-            new Coord(1, 1), // up-right
-            new Coord(0, 1), // right
-            new Coord(-1, 1), // right-down
-            new Coord(-1, 0), // down
-            new Coord(-1, -1), // down-left
-            new Coord(0, -1), // left
-            new Coord(1, -1), // left-up
-        ]
-        return allDirections;
-    }
-
-}
+import { Coord, GameBoard, ListenerManager, Move } from './types'
 
 const constants = {
     selectedPieceClassName: 'selected-piece',
     selectedPlayerTextClassName: 'selected-player-text',
     activePlayerPieceClassName: 'active-player-piece',
-    blinkingClassName: 'blinking',
-    rows: 4,
-    cols: 4,
-}
-
-const gameBoard = {
-    board: [
-        0, null, null, 4,
-        null, 1, 5, null,
-        null, 6, 2, null,
-        7, null, null, 3
-    ],
-    // testBoard: [
-    //     4, null, null, null,
-    //     null, 0, 1, 5,
-    //     null, 2, 3, null,
-    //     6, null, null, 7
-    // ],
-    coordToBoardIndex: ({ row, col }: Coord) => {
-        const index = row * 4 + col;
-        return index;
-    },
-    boardIndexToCoord: (index: number) => {
-        const col = index % 4;
-        const row = Math.floor(index / 4);
-        return new Coord(row, col);
-    }
-}
-
-class Move {
-    public sourceIndex: number;
-    public destIndex: number;
-    constructor(sourceIndex: number, destIndex: number) {
-        this.sourceIndex = sourceIndex;
-        this.destIndex = destIndex;
-    }
+    possibleMoveClassName: 'possible-move',
 }
 
+const gameBoard = new GameBoard();
+const listenerManager: ListenerManager = new ListenerManager();
 
 const player: { isRedTurn: boolean, selectedPieceId: number | undefined, moveHistory: Move[] } = {
     isRedTurn: false,
@@ -101,33 +31,10 @@ const dom = {
     undoButton: document.getElementById('undo-button') as HTMLInputElement,
 }
 
-const listenerManager: {
-    listeners: { element: Element, type: string, listener: (event: Event) => void }[],
-    addListener: (element: Element, type: string, listener: (event: Event) => void) => void,
-    removeListeners: () => void,
-} = {
-    listeners: [],
-
-    addListener: (element: Element, type: string, listener: (event: Event) => void): void => {
-        const { listeners } = listenerManager;
-        element.addEventListener(type, listener);
-        listeners.push({ element, type, listener });
-    },
-
-    removeListeners: () => {
-        const { listeners } = listenerManager;
-        listeners.forEach(value => {
-            const { element, type, listener } = value;
-            element.removeEventListener(type, listener);
-        });
-        listeners.length = 0;
-    }
-}
-
 const resetBoard = () => {
     // resetCells
     dom.cells().forEach(cell => {
-        cell.classList.remove(constants.blinkingClassName);
+        cell.classList.remove(constants.possibleMoveClassName);
     });
 
     // reset pieces
@@ -189,8 +96,8 @@ const nextMove = () => {
                         const pos = new Coord(testPos.row + direction.row, testPos.col + direction.col);
                         const index = gameBoard.coordToBoardIndex(pos);
                         const withinBounds =
-                            pos.row >= 0 && pos.row < constants.rows &&
-                            pos.col >= 0 && pos.col < constants.cols;
+                            pos.row >= 0 && pos.row < gameBoard.rows &&
+                            pos.col >= 0 && pos.col < gameBoard.cols;
                         const isOccupied = Number.isInteger(gameBoard.board[index]);
                         if (isOccupied || !withinBounds) {
                             break;
@@ -217,7 +124,7 @@ const nextMove = () => {
                 const previousPiece = document.getElementById(previousSelectedPieceId.toString());
                 previousPiece.classList.remove(constants.selectedPieceClassName);
                 dom.cells().forEach(cell => {
-                    cell.classList.remove(constants.blinkingClassName);
+                    cell.classList.remove(constants.possibleMoveClassName);
                 });
             }
 
@@ -237,7 +144,7 @@ const nextMove = () => {
             allowedMoveIndices.forEach(i => {
                 const cell = dom.cells()[i];
                 listenerManager.addListener(cell, 'click', async () => await makeMove(i));
-                cell.classList.add(constants.blinkingClassName);
+                cell.classList.add(constants.possibleMoveClassName);
             });
         };
 
@@ -364,10 +271,10 @@ const init = () => {
     // create board and pieces
     let isWhite = true;
     const table = document.getElementById('table');
-    for (let r = 0; r < constants.rows; r++) {
+    for (let r = 0; r < gameBoard.rows; r++) {
         const tr = document.createElement('tr');
         table.appendChild(tr);
-        for (let c = 0; c < constants.cols; c++) {
+        for (let c = 0; c < gameBoard.cols; c++) {
             const td = document.createElement('td');
             tr.appendChild(td);
             td.className = isWhite ? 'white' : 'black';
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..9ba103b
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,103 @@
+export class Coord {
+    public row: number;
+    public col: number;
+
+    constructor(row: number, col: number) {
+        this.row = row;
+        this.col = col;
+    }
+
+    public add(coord: Coord): Coord {
+        return new Coord(this.row + coord.row, this.col + coord.col);
+    }
+
+    sub(coord: Coord): Coord {
+        return new Coord(this.row - coord.row, this.col - coord.col);
+    }
+
+    equals(otherCoord: Coord): boolean {
+        const areEqual = (this.col === otherCoord.col && this.row === otherCoord.row);
+        return areEqual;
+    }
+
+    // clock face directions
+    static get allDirections(): Coord[] {
+        const allDirections = [
+            new Coord(1, 0), // up
+            new Coord(1, 1), // up-right
+            new Coord(0, 1), // right
+            new Coord(-1, 1), // right-down
+            new Coord(-1, 0), // down
+            new Coord(-1, -1), // down-left
+            new Coord(0, -1), // left
+            new Coord(1, -1), // left-up
+        ]
+        return allDirections;
+    }
+
+}
+
+export class Move {
+    public sourceIndex: number;
+    public destIndex: number;
+    constructor(sourceIndex: number, destIndex: number) {
+        this.sourceIndex = sourceIndex;
+        this.destIndex = destIndex;
+    }
+}
+
+interface Listener {
+    element: Element;
+    type: string;
+    listener: (event: Event) => void;
+}
+
+export class ListenerManager {
+    private listeners: Listener[] = [];
+
+    public addListener(element: Element, type: string, listener: (event: Event) => void): void {
+        const { listeners } = this;
+        element.addEventListener(type, listener);
+        listeners.push({ element, type, listener });
+    }
+
+    public removeListeners() {
+        const { listeners } = this;
+        listeners.forEach(value => {
+            const { element, type, listener } = value;
+            element.removeEventListener(type, listener);
+        });
+        listeners.length = 0;
+    }
+}
+
+export class GameBoard {
+    public board: number[];
+    public rows: number;
+    public cols: number;
+    // testBoard: [
+    //     4, null, null, null,
+    //     null, 0, 1, 5,
+    //     null, 2, 3, null,
+    //     6, null, null, 7
+    // ],
+    public constructor() {
+        this.board = [
+            0, null, null, 4,
+            null, 1, 5, null,
+            null, 6, 2, null,
+            7, null, null, 3
+        ];
+        this.rows = 4;
+        this.cols = 4;
+    }
+    public coordToBoardIndex({ row, col }: Coord): number {
+        const index = row * 4 + col;
+        return index;
+    }
+    public boardIndexToCoord(index: number): Coord {
+        const col = index % 4;
+        const row = Math.floor(index / 4);
+        return new Coord(row, col);
+    }
+}
\ No newline at end of file