fuzzyworld

dao-game / commit

Formatting, styles, general polish.

b4baeb1d8a818c174d48da1be86afc5523ff49f8 · Pavel Safronov · 2022-02-26 23:51:46 -0800 · parents b9e3c2cabd75

Formatting, styles, general polish.
 game.js    | 138 +++++++++++++++++++++++++++++++++----------------------------
 index.html |  36 ++++++++++++----
 styles.css |  15 ++++++-
 3 files changed, 116 insertions(+), 73 deletions(-)

diff --git a/game.js b/game.js
index b1edb19..5de5c28 100644
--- a/game.js
+++ b/game.js
@@ -12,11 +12,20 @@ class Coord {
 
     /**
      * @param {Coord} coord
+     * @returns {Coord}
      * @memberof Coord
      */
     add(coord) {
-        this.row += coord.row;
-        this.col += coord.col;
+        return new Coord(this.row + coord.row, this.col + coord.col);
+    }
+
+    /**
+     * @param {Coord} coord
+     * @returns {Coord}
+     * @memberof Coord
+     */
+    sub(coord) {
+        return new Coord(this.row - coord.row, this.col - coord.col);
     }
 
     /**
@@ -24,7 +33,8 @@ class Coord {
      * @memberof Coord
      */
     equals(otherCoord) {
-        return (this.col === otherCoord.col && this.row === otherCoord.col);
+        const areEqual = (this.col === otherCoord.col && this.row === otherCoord.row);
+        return areEqual;
     }
 }
 
@@ -34,13 +44,20 @@ const selectedPlayerTextClassName = 'selected-player-text';
 const activePlayerPieceClassName = 'active-player-piece';
 const blinkingClassName = 'blinking';
 
-// board
-const board = [
+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
@@ -54,13 +71,6 @@ const allDirections = [
     { row: 0, col: -1 }, // left
     { row: 1, col: -1 }, // left-up
 ]
-/** @type {Coord[]} */
-const squareCoords = [
-    new Coord(0, 0),
-    new Coord(3, 0),
-    new Coord(3, 3),
-    new Coord(0, 3),
-];
 
 let isWhite = true;
 const table = document.getElementById('table');
@@ -238,54 +248,49 @@ const selectPiece = (event) => {
     const allowedMoveIndices = getAllowedMoveIndicesForIndex(pieceIndex);
     allowedMoveIndices.forEach(i => {
         const cell = cells()[i];
-        addListener(cell, 'click', () => makeMove(i));
+        addListener(cell, 'click', async () => await makeMove(i));
         cell.classList.add(blinkingClassName);
     });
 };
 
-const makeMove = (destIndex) => {
-    // find current piece
-    const piece = getPieceElementById(selectedPieceId);
-    const pieceId = Number.parseInt(piece.id)
-    const pieceIndex = board.indexOf(pieceId);
-
-    // do animation logic
-    const startCoords = boardIndexToCoord(pieceIndex);
-    const endCoords = boardIndexToCoord(destIndex);
-    const coordDiff = new Coord(
-        endCoords.row - startCoords.row,
-        endCoords.col - startCoords.col);
-
-    const cellWidth = cells()[0].clientWidth;
-    const cellHeight = cells()[0].clientHeight;
-
+const makeMove = async (destIndex) => {
     removeListeners();
 
-    const animation = piece.animate([
-        // keyframes
-        { opacity: 1 },
-        { opacity: 0 },
-    ], {
-        duration: 500,
-        iterations: 1
-    });
-
-    animation.onfinish = () => {
-        // move piece to destination cell
-        const pieceHtml = cells()[pieceIndex].innerHTML;
-        cells()[pieceIndex].innerHTML = '';
-        cells()[destIndex].innerHTML = pieceHtml;
-
-        // move piece on board
-        board[pieceIndex] = null;
-        board[destIndex] = pieceId;
-
-        const elem = getPieceElementById(pieceId);
-        elem.classList.remove(selectedPieceClassName);
-
-        checkForWin();
-        nextMove();
-    };
+    // find current piece
+    const piece = getPieceElementById(selectedPieceId);
+    // unselect piece
+    piece.classList.remove(selectedPieceClassName);
+
+    // create clone for new position
+    const destPiece = piece.cloneNode(true);
+    // add to destination cell
+    cells()[destIndex].appendChild(destPiece);
+
+    // start animations
+    const destAnimation = cells()[destIndex].animate([{ opacity: 0 }, { opacity: 1 }], { duration: 1000, iterations: 1 })
+    const sourceAnimation = piece.animate([{
+        opacity: 1,
+        width: '45px',
+        height: '45px'
+    }, {
+        opacity: 0,
+        width: '5px',
+        height: '5px'
+    },], { duration: 1000, iterations: 1 });
+
+    // await animations
+    console.error('starting animation')
+    await Promise.all([sourceAnimation.finished, destAnimation.finished]);
+    console.error('animations done')
+
+    // remove old piece
+    piece.parentNode.removeChild(piece);
+    board[board.indexOf(selectedPieceId)] = null;
+    // set new piece
+    board[destIndex] = selectedPieceId;
+
+    checkForWin();
+    nextMove();
 }
 
 const nextMove = () => {
@@ -338,23 +343,29 @@ const elementsToCoords = (elements) => {
  * @returns {boolean}
  */
 const doCoordsFormSquare = (coords) => {
-    const areInSquare = coords.some((cornerCoord) => {
-        const offsetCoords = allDirections.map(d => cornerCoord.add(d));
-        const presentOffsets = coords.filter(c => offsetCoords.includes(c)).length;
-        const isSquare = presentOffsets === 4;
-        return isSquare;
-    });
-    return areInSquare;
+    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 = () => {
     console.error(`testing win for ${isRedTurn ? 'red' : 'blue'}`);
-    return;
 
     const playerCoords = elementsToCoords(
         isRedTurn ? redPieces() : bluePieces())
     const otherCoords = elementsToCoords(
         isRedTurn ? bluePieces() : redPieces());
+    /** @type {Coord[]} */
+    const squareCoords = [
+        new Coord(0, 0),
+        new Coord(3, 0),
+        new Coord(3, 3),
+        new Coord(0, 3),
+    ];
 
     // winning conditions:
     // 1. all in one row
@@ -367,7 +378,7 @@ const checkForWin = () => {
     const firstPiece = playerCoords[0];
     const allInRow = playerCoords.every(pc => pc.row === firstPiece.row)
     const allInCol = playerCoords.every(pc => pc.col === firstPiece.col)
-    const allInCorners = playerCoords.every(pc => squareCoords.filter(sc => pc.equals(sc)).length > 0);
+    const allInCorners = playerCoords.every(pc => squareCoords.findIndex(sc => pc.equals(sc)) >= 0);
     const allInSquare = doCoordsFormSquare(playerCoords);
 
     const winnerName = isRedTurn ? 'Red' : 'Blue';
@@ -396,4 +407,5 @@ const checkForWin = () => {
 
 
 // start!
+// checkForWin();
 nextMove();
\ No newline at end of file
diff --git a/index.html b/index.html
index d504b04..dbe5541 100644
--- a/index.html
+++ b/index.html
@@ -12,26 +12,44 @@
     <body>
         <main>
             <div class="red-turn-text mobile">
-                Red
+                Red's turn
             </div>
 
+            <div class="title">
+                <a
+                    href='https://en.wikipedia.org/wiki/Dao_(game)'
+                    target='_blank'>Board game Dao</a>.
+            </div>
             <table id="table">
             </table>
 
             <div class="desktop">
-                <div class="red-turn-text">
-                    Red
-                </div>
-                <p id="divider">|</p>
-                <div class="blue-turn-text">
-                    Blue
-                </div>
+                <span class="red-turn-text">
+                    Red's turn
+                </span>
+                <span id="divider">|</span>
+                <span class="blue-turn-text">
+                    Blue's turn
+                </span>
             </div>
 
             <div class="blue-turn-text mobile">
-                Blue
+                Blue's turn
             </div>
         </main>
+        <div class="info">
+            The game consists of only one simple rule and three ways
+            to
+            win. Pieces move in a straight line, including
+            diagonally,
+            as far as possible with no jumps. The three ways to win
+            are
+            arranging your pieces in a straight line on the board
+            (not
+            diagonally), occupying the four corners, or forming a
+            2x2
+            square anywhere on the board.
+        </div>
     </body>
 
 </html>
\ No newline at end of file
diff --git a/styles.css b/styles.css
index 4f666e7..c202c26 100644
--- a/styles.css
+++ b/styles.css
@@ -19,7 +19,14 @@ body {
 div {
     display: flex;
     justify-content: space-between;
-    z-index: 0;
+    /* display: inline;
+    flex: 1; */
+}
+
+.title {
+    text-align: center;
+    font-family: "open sans";
+    font-size: 40px;
 }
 
 .mobile {
@@ -95,6 +102,12 @@ td {
     color: black;
 }
 
+.info {
+    text-align: center;
+    font-family: "open sans";
+    font-size: 20px;
+}
+
 .blinking {
     animation: blinkingText 1.5s infinite;
 }