parent
ce53388d26
commit
709e573b99
@ -0,0 +1,73 @@ |
||||
import { BoardgameState } from "../../shared/boardgame-state.ts"; |
||||
import { CurrentOutcome, SquareState, formatSquareState } from "../../shared/datatypes.ts"; |
||||
import { getDisplayStates } from "../../shared/display.ts"; |
||||
import { gamesRules } from "../../shared/rules.ts"; |
||||
import { TrackingTools } from "../lib/query-tracking-utils.ts"; |
||||
|
||||
export class BoardGameComponent extends HTMLElement { |
||||
private readonly trackingTools = new TrackingTools(this); |
||||
|
||||
handleTrackedValueUpdate(newValue: string | null) { |
||||
const rules = gamesRules.tictactoe; |
||||
|
||||
const gameState = BoardgameState.fromSerialized(newValue); |
||||
if (!gameState) { |
||||
throw new Error("Empty game state"); |
||||
} |
||||
const currentOutcome = gameState.board ? rules.getBoardOutcome(gameState.board) : CurrentOutcome.Undecided; |
||||
|
||||
const displayStates = getDisplayStates(gameState, currentOutcome); |
||||
for (const [className, shouldDisplay] of Object.entries(displayStates)) { |
||||
for (const element of this.querySelectorAll(`.${className}`)) { |
||||
(element as HTMLElement).style.display = shouldDisplay ? "" : "none"; |
||||
} |
||||
} |
||||
|
||||
for (const tbodyUntyped of this.querySelectorAll("tbody.game-board")) { |
||||
const tbody = tbodyUntyped as HTMLTableSectionElement; |
||||
for (let rowNumber = 0; rowNumber < tbody.rows.length; rowNumber++) { |
||||
const row = tbody.rows[rowNumber]; |
||||
if (!row) { |
||||
continue; |
||||
} |
||||
|
||||
for (let columnNumber = 0; columnNumber < row.cells.length; columnNumber++) { |
||||
const cell = row.cells[columnNumber]; |
||||
if (!cell) { |
||||
continue; |
||||
} |
||||
|
||||
for (const button of cell.querySelectorAll("button")) { |
||||
if (!gameState.board) { |
||||
button.value = gameState.serialize(); |
||||
button.disabled = true; |
||||
button.innerText = " "; |
||||
} else { |
||||
const squareState = gameState.board.get(rowNumber, columnNumber); |
||||
const nextGameState = |
||||
squareState === SquareState.Unoccupied && currentOutcome === CurrentOutcome.Undecided |
||||
? gameState.withMove(rowNumber, columnNumber) |
||||
: gameState; |
||||
|
||||
button.value = nextGameState.serialize(); |
||||
button.disabled = nextGameState === gameState; |
||||
button.innerText = formatSquareState(squareState); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
connectedCallback() { |
||||
this.trackingTools.connectedCallback(); |
||||
} |
||||
|
||||
attributeChangedCallback() { |
||||
this.trackingTools.attributeChangedCallback(); |
||||
} |
||||
|
||||
disconnectedCallback() { |
||||
this.trackingTools.disconnectedCallback(); |
||||
} |
||||
} |
Loading…
Reference in new issue