dao-game / commit
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