dao-game / commit
Reorgs and preparing to implement undo/reset.
game.js | 220 ++++++++++++++++++++++++++++++++----------------------------- index.html | 20 +++--- styles.css | 66 ++++++++++++------- 3 files changed, 166 insertions(+), 140 deletions(-) diff --git a/game.js b/game.js index 74909e5..ba642c7 100644 --- a/game.js +++ b/game.js @@ -43,21 +43,6 @@ const selectedPieceClassName = 'selected-piece'; const selectedPlayerTextClassName = 'selected-player-text'; const activePlayerPieceClassName = 'active-player-piece'; const blinkingClassName = 'blinking'; - -const standardBoard = [ - 0, null, null, 4, - null, 1, 5, null, - null, 6, 2, null, - 7, null, null, 3 -]; -const testBoard = [ - 4, null, null, null, - null, 0, 1, 5, - null, 2, 3, null, - 6, null, null, 7 -]; - -const board = standardBoard; const rows = 4; const cols = 4; // clock face directions @@ -71,7 +56,42 @@ const allDirections = [ { row: 0, col: -1 }, // left { row: 1, col: -1 }, // left-up ] +const standardBoard = [ + 0, null, null, 4, + null, 1, 5, null, + null, 6, 2, null, + 7, null, null, 3 +]; +const testBoard = [ + 4, null, null, null, + null, 0, 1, 5, + null, 2, 3, null, + 6, null, null, 7 +]; +const board = standardBoard; + +// player properties +let isRedTurn = false; +let selectedPieceId = -1; +/** @type {Coord[]} */ +const moveHistory = []; + +// DOM references +const defaultRedPiece = document.getElementById('default-red-piece'); +const defaultBluePiece = document.getElementById('default-blue-piece'); +const cells = () => Array.from(document.querySelectorAll("td")); +const redPieces = () => Array.from(document.querySelectorAll('.red-piece:not(#default-red-piece')); +const bluePieces = () => Array.from(document.querySelectorAll('.blue-piece:not(#default-blue-piece')); +const redTurnText = () => Array.from(document.querySelectorAll(".red-turn-text")); +const blueTurnText = () => Array.from(document.querySelectorAll(".blue-turn-text")); +const resetButton = document.getElementById('reset-button'); +resetButton.addEventListener('click', () => { + if (confirm('Reset?')) { + window.location.reload(); + } +}); +// create board and pieces let isWhite = true; const table = document.getElementById('table'); for (let r = 0; r < rows; r++) { @@ -85,11 +105,6 @@ for (let r = 0; r < rows; r++) { } isWhite = !isWhite; } -// DOM references -const defaultRedPiece = document.getElementById('default-red-piece'); -const defaultBluePiece = document.getElementById('default-blue-piece'); -const cells = () => Array.from(document.querySelectorAll("td")); - board.forEach((value, index) => { if (value !== null) { const isRed = value < 4; @@ -100,16 +115,6 @@ board.forEach((value, index) => { } }); -const redPieces = () => Array.from(document.querySelectorAll(".red-piece")); -const bluePieces = () => Array.from(document.querySelectorAll(".blue-piece")); -const redTurnText = () => Array.from(document.querySelectorAll(".red-turn-text")); -const blueTurnText = () => Array.from(document.querySelectorAll(".blue-turn-text")); -const divider = () => Array.from(document.querySelector("#divider")); - -// player properties -let isRedTurn = false; -let selectedPieceId = -1; - /** @type {{element: Element, type: string, listener: (event: Event) => void}[]} */ const listeners = []; @@ -173,47 +178,6 @@ const setActivePlayerPieces = () => { }); }; -/** - * @param {number} pieceId - * @returns {number[]} - */ -const getAllowedMoveIndicesForIndex = (boardIndex) => { - const coord = boardIndexToCoord(boardIndex); - - const farthestCoords = allDirections - .map(direction => getFarthestCoord(coord, direction)) - .filter(farCoord => farCoord !== undefined); - - const farthestIndices = farthestCoords.map(coordToBoardIndex); - return farthestIndices; -}; -/** - * - * - * @param {Coord} startCoord - * @param {Coord} direction - * @returns {Coord} - */ -const getFarthestCoord = (startCoord, direction) => { - let farthestPos = undefined; - let testPos = startCoord; - while (true) { - const pos = new Coord(testPos.row + direction.row, testPos.col + direction.col); - const index = coordToBoardIndex(pos); - const withinBounds = - pos.row >= 0 && pos.row < rows && - pos.col >= 0 && pos.col < cols; - const isOccupied = Number.isInteger(board[index]); - if (isOccupied || !withinBounds) { - break; - } else { - farthestPos = pos; - testPos = pos; - } - } - return farthestPos; -}; - /** * * @@ -226,6 +190,49 @@ const getPieceElementById = (pieceId) => { /** @param {Event} event */ const selectPiece = (event) => { + /** + * @param {number} pieceId + * @returns {number[]} + */ + const getAllowedMoveIndicesForIndex = (boardIndex) => { + /** + * + * + * @param {Coord} startCoord + * @param {Coord} direction + * @returns {Coord} + */ + const getFarthestCoord = (startCoord, direction) => { + let farthestPos = undefined; + let testPos = startCoord; + while (true) { + const pos = new Coord(testPos.row + direction.row, testPos.col + direction.col); + const index = coordToBoardIndex(pos); + const withinBounds = + pos.row >= 0 && pos.row < rows && + pos.col >= 0 && pos.col < cols; + const isOccupied = Number.isInteger(board[index]); + if (isOccupied || !withinBounds) { + break; + } else { + farthestPos = pos; + testPos = pos; + } + } + return farthestPos; + }; + + const coord = boardIndexToCoord(boardIndex); + + const farthestCoords = allDirections + .map(direction => getFarthestCoord(coord, direction)) + .filter(farCoord => farCoord !== undefined); + + const farthestIndices = farthestCoords.map(coordToBoardIndex); + return farthestIndices; + }; + + const previousSelectedPieceId = selectedPieceId; if (previousSelectedPieceId >= 0) { const previousPiece = getPieceElementById(previousSelectedPieceId); @@ -319,43 +326,44 @@ const nextMove = () => { setActivePlayerPieces(); }; -/** - * @param {Element[]} elements - * @returns {number[]} - */ -const elementsToBoardIndexes = (elements) => { - const indices = elements.map(pp => { - const pieceId = Number.parseInt(pp.id); - const pieceIndex = board.indexOf(pieceId); - return pieceIndex; - }); - return indices; -}; -/** - * @param {Element[]} elements - * @return {Coord[]} - */ -const elementsToCoords = (elements) => { - const indices = elementsToBoardIndexes(elements); - const coords = indices.map(pieceIndex => boardIndexToCoord(pieceIndex)); - return coords; -}; - -/** - * @param {Coord[]} coords - * @returns {boolean} - */ -const doCoordsFormSquare = (coords) => { - const allRows = coords.map(c => c.row); - const allCols = coords.map(c => c.col); - const min = new Coord(Math.min(...allRows), Math.min(...allCols)); - const max = new Coord(Math.max(...allRows), Math.max(...allCols)); - const diff = max.sub(min); - const isSquare = (diff.row === 1 && diff.col === 1); - return isSquare; -}; const checkForWin = () => { + /** + * @param {Element[]} elements + * @return {Coord[]} + */ + const elementsToCoords = (elements) => { + /** + * @param {Element[]} elements + * @returns {number[]} + */ + const elementsToBoardIndexes = (elements) => { + const indices = elements.map(pp => { + const pieceId = Number.parseInt(pp.id); + const pieceIndex = board.indexOf(pieceId); + return pieceIndex; + }); + return indices; + }; + + const indices = elementsToBoardIndexes(elements); + const coords = indices.map(pieceIndex => boardIndexToCoord(pieceIndex)); + return coords; + }; + /** + * @param {Coord[]} coords + * @returns {boolean} + */ + const doCoordsFormSquare = (coords) => { + const allRows = coords.map(c => c.row); + const allCols = coords.map(c => c.col); + const min = new Coord(Math.min(...allRows), Math.min(...allCols)); + const max = new Coord(Math.max(...allRows), Math.max(...allCols)); + const diff = max.sub(min); + const isSquare = (diff.row === 1 && diff.col === 1); + return isSquare; + }; + const playerCoords = elementsToCoords( isRedTurn ? redPieces() : bluePieces()) const otherCoords = elementsToCoords( diff --git a/index.html b/index.html index 64b6d31..db50b20 100644 --- a/index.html +++ b/index.html @@ -16,26 +16,26 @@ <p class='piece blue-piece' id='default-blue-piece'></p> </div> <main> - <div class="red-turn-text mobile"> - Red's turn - </div> - <table id="table"> </table> - <div class="desktop"> + <div class="controls"> <span class="red-turn-text"> Red's turn </span> - <span id="divider">|</span> + <span class="divider">|</span> + <button type="button" class="button" id="undo-button"> + Undo + </button> + <span class="divider">|</span> + <button type="button" class="button" id="reset-button"> + Reset + </button> + <span class="divider">|</span> <span class="blue-turn-text"> Blue's turn </span> </div> - - <div class="blue-turn-text mobile"> - Blue's turn - </div> </main> <hr /> <div class="title"> diff --git a/styles.css b/styles.css index 9fcb6de..1cd85a7 100644 --- a/styles.css +++ b/styles.css @@ -1,6 +1,7 @@ :root { --default-size: 5px; --active-size: 40px; + --cell-size: 80px; /* --p1-color: crimson; --p2-color: mediumblue; */ } @@ -40,39 +41,54 @@ div { font-size: 40px; } -.mobile { - display: none; -} - -.desktop { - margin: 0; - width: 100%; -} - td { - width: 65px; - height: 65px; + width: var(--cell-size); + height: var(--cell-size); text-align: center; } -#divider { +.controls { font-size: 90px; margin-left: 15px; margin-right: 15px; -} - -.red-turn-text { - text-align: center; - color: lightgray; font-family: "open sans"; font-size: 55px; + border-radius: 10px; + padding: 10px; +} + +.divider { + font-size: 90px; + margin-left: 15px; + margin-right: 15px; } -.blue-turn-text { +.red-turn-text, .blue-turn-text { text-align: center; - font-family: "open sans"; - font-size: 55px; color: lightgray; + background-color: white; + /* border: 1px solid black; */ + border-radius: 10px; + padding: 10px; +} + +.red-turn-text.selected-player-text { + background-color: red; +} + +.blue-turn-text.selected-player-text { + background-color: blue; +} + +.selected-player-text { + color: white; +} + +.button { + border-radius: 10px; + padding: 10px; + background-color: darkseagreen; + font-size: 60px; } .white { @@ -110,10 +126,6 @@ td { animation: activePulsing 1s infinite; } -.selected-player-text { - color: black; -} - .info { text-align: center; font-family: "open sans"; @@ -129,6 +141,12 @@ td { 100%{opacity: 1;} } +@keyframes fade-in { + 0%{opacity: 0;} + 50%{opacity: .5;} + 100%{opacity: 1;} +} + @keyframes disabledToActive { from { width: var(--default-size);