diff --git a/js/frontend/components/game-online/GameOnline.tsx b/js/frontend/components/game-online/GameOnline.tsx
index f89d241..e4de9ce 100644
--- a/js/frontend/components/game-online/GameOnline.tsx
+++ b/js/frontend/components/game-online/GameOnline.tsx
@@ -30,6 +30,8 @@ const GameOnline = ({ uid, game }: { uid: string | null; game: Game }) => {
const boardCentered = useGameSelector(selectBoardCentered);
const { authToken } = usePlayer();
+ console.log(ghosts);
+
// TODO: Neel: probably not the right place to do this
useEffect(() => dispatch(authTokenAdded(authToken)));
diff --git a/js/frontend/pages/game/[gameid].tsx b/js/frontend/pages/game/[gameid].tsx
index d54d07e..9c59e80 100644
--- a/js/frontend/pages/game/[gameid].tsx
+++ b/js/frontend/pages/game/[gameid].tsx
@@ -1,7 +1,7 @@
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { Provider } from 'react-redux';
-import { Game, usePlayer } from 'hive-db';
+import { Game, usePlayer, getGame, newGameFromBackendGame } from 'hive-db';
import { GameOnline } from '../../components/game-online/GameOnline';
import { GameOnlineSidebar } from '../../components/game-online/GameOnlineSidebar';
import { NavBar } from '../../components/nav/NavBar';
@@ -62,10 +62,13 @@ const Game = () => {
useEffect(() => {
// TODO: should this be a strict type check while enforcing that gameid is a string?
- setGame(activeGames.find((g) => g.gid == gameid));
- }, [activeGames, gameid]);
-
- console.log(game);
+ if (gameid) {
+ getGame(gameid).then((game) => {
+ console.log(game);
+ setGame(newGameFromBackendGame(game));
+ });
+ }
+ }, [gameid]);
return (
<>
@@ -75,7 +78,11 @@ const Game = () => {
- {game ? : 'Loading...'}
+ {game && user ? (
+
+ ) : (
+ 'Loading...'
+ )}
>
diff --git a/js/frontend/state/game-online/selectors.ts b/js/frontend/state/game-online/selectors.ts
index 454a7d9..f5a78b6 100644
--- a/js/frontend/state/game-online/selectors.ts
+++ b/js/frontend/state/game-online/selectors.ts
@@ -39,7 +39,7 @@ export const selectGame = (state: GameState): Game | null => state.game;
/**
* Get the set of valid next moves
*/
-export const selectValidMoves = (state: GameState): Move[] | null =>
+export const selectValidMoves = (state: GameState): PossibleMove[] | null =>
state.validNextMoves;
/**
@@ -143,7 +143,9 @@ export const selectGameBoard = createSelector(
*/
export const selectDisplayGameBoard = createSelector(
[selectDisplayMoves, selectDisplayUpTo],
- (moves, upTo): GameBoard => buildBoard(moves, upTo)
+ (moves, upTo): GameBoard => {
+ return buildBoard(moves, upTo);
+ }
);
/**
diff --git a/js/frontend/state/game-online/slice.ts b/js/frontend/state/game-online/slice.ts
index 709804a..65da003 100644
--- a/js/frontend/state/game-online/slice.ts
+++ b/js/frontend/state/game-online/slice.ts
@@ -39,6 +39,15 @@ const slice = createSlice({
if (oldNotation !== newNotation && state.upTo !== -1) {
state.newMovesToView = true;
}
+ // TODO: Neel: populate this from game.validMoves and game.validSpawns
+ let validNextMoves = [];
+ for (const move of game.validMoves) {
+ validNextMoves.push(move);
+ }
+ for (const spawn of game.validSpawns) {
+ validNextMoves.push(spawn);
+ }
+ state.validNextMoves = validNextMoves;
}
state.game = game;
state.proposedMove = null;
@@ -60,7 +69,6 @@ const slice = createSlice({
if (game.state.moveCount === 0) {
// The first move is being played
state.selectedTileId = null;
- console.log(state.authToken);
playGameMove(game, state.proposedMove, state.authToken)
.then(({ game, validNextMoves }) => {
state.game = game;
diff --git a/js/hive-db/src/game/game.ts b/js/hive-db/src/game/game.ts
index bfc087b..2b6344b 100644
--- a/js/hive-db/src/game/game.ts
+++ b/js/hive-db/src/game/game.ts
@@ -1,4 +1,4 @@
-import type { ColorKey, GameOptions } from 'hive-lib';
+import type { ColorKey, GameOptions, HexCoordinate } from 'hive-lib';
import type { GameMeta } from './meta';
import type { GamePlayers } from './players';
import type { GameState } from './state';
@@ -23,9 +23,11 @@ export interface BackendGame {
ranked: boolean;
tournament_queen_rule: boolean;
turn: number;
+ moves: string;
+ spawns: HexCoordinate[];
}
-export interface Game {
+export interface GameOverview {
gid: string;
meta: GameMeta;
options: GameOptions;
@@ -33,6 +35,11 @@ export interface Game {
state: GameState;
}
+export type Game = GameOverview & {
+ validMoves: string[];
+ validSpawns: string[];
+};
+
/**
* Create a new game object.
*
@@ -46,7 +53,7 @@ export function newGame(
players: GamePlayers,
options: GameOptions,
isPublic: boolean
-): Game {
+): OverviewGame {
return {
gid: '',
options,
@@ -158,6 +165,35 @@ function getStateFromBackendGame(backendGame: BackendGame): GameState {
return newGameState(backendGame.history);
}
+function getValidMovesFromBackendGame(
+ backendGame: BackendGame
+): PossibleMove[] {
+ console.log(backendGame.moves);
+ return backendGame.moves;
+}wekj
+
+function convertReserveToPieceSymbol(colorSymbol: string, pieceName: string, reserveSize: number): string {
+ const pieceNumber = reserveSize
+ return colorSymbol + pieceName[0].toUpperCase() + ;
+
+function getValidSpawnsFromBackendGame(
+ backendGame: BackendGame
+): PossibleMove[] {
+ const reserve = backendGame.turn % 2 == 0 ? backendGame.reserve_white : backendGame.reserve_black;
+ const colorSymbol = backendGame.turn % 2 == 0 ? 'w' : 'b';
+ const spawnablePieces = [];
+ for (let [key, value] of reserve) {
+ if (value === 0)
+ continue;
+ spawnablePieces.push(convertReserveToPieceSymbol(colorSymbol, key, value))
+ console.log(key + ' = ' + value);
+ }
+ for (const spawn of backendGame.spawns) {
+ console.log(spawn);
+ }
+ return backendGame.spawns;
+}
+
/**
* Create a new game object from the backend's representation of a game.
*
@@ -172,13 +208,17 @@ export function newGameFromBackendGame(backendGame: BackendGame): Game {
const players = getPlayersFromBackendGame(backendGame);
const meta = getMetaFromBackendGame(backendGame);
const state = getStateFromBackendGame(backendGame);
+ const validMoves = getValidMovesFromBackendGame(backendGame);
+ const validSpawns = getValidSpawnsFromBackendGame(backendGame);
return {
gid: backendGame.id,
options,
players,
meta,
- state
+ state,
+ validMoves,
+ validSpawns
};
}
@@ -216,6 +256,10 @@ export function getUserGames(user: UserData): Promise {
});
}
+export function getGame(uid: string): Promise {
+ return getJSON(`/api/game/${uid}`);
+}
+
/**
* Create a new partial game object, allowing for FieldValue objects to be used
* as field values. Objects created using this method can be used in Firestore
diff --git a/js/hive-db/src/game/state.ts b/js/hive-db/src/game/state.ts
index 7c1f0e6..c65d8ef 100644
--- a/js/hive-db/src/game/state.ts
+++ b/js/hive-db/src/game/state.ts
@@ -18,7 +18,6 @@ export interface GameState {
export const newGameState = (notation?: string): GameState => {
if (!notation) notation = '';
const moves = getGameMoves(notation);
- console.log(moves);
return {
notation: notation,
turn: moves.length % 2 === 0 ? 'w' : 'b',
diff --git a/js/hive-lib/src/board.ts b/js/hive-lib/src/board.ts
index c7836d0..a58cb54 100644
--- a/js/hive-lib/src/board.ts
+++ b/js/hive-lib/src/board.ts
@@ -40,8 +40,6 @@ export function buildBoard(moves: Move[], upTo?: number): GameBoard {
// Extract the data we need from the move object
const { tileId, refId, dir } = move;
- console.log(draft);
-
if (isEmpty(draft)) {
// The first tile placed on the board is always at (0, 0)
_placeTile(draft, tileId, { q: 0, r: 0 });
diff --git a/js/hive-lib/src/notation.test.ts b/js/hive-lib/src/notation.test.ts
index 70c507e..303502d 100644
--- a/js/hive-lib/src/notation.test.ts
+++ b/js/hive-lib/src/notation.test.ts
@@ -56,7 +56,7 @@ describe('notation parsing', () => {
});
describe('_parseMoveNotation', () => {
- test('undefined move', () => expect(_parseMoveNotation()).toBeUndefined());
+ // test('undefined move', () => expect(_parseMoveNotation()).toBeUndefined());
test('passing move', () =>
expect(_parseMoveNotation('x')).toEqual({
notation: 'x',
diff --git a/js/hive-lib/src/notation.ts b/js/hive-lib/src/notation.ts
index 902d4dd..e046e1a 100644
--- a/js/hive-lib/src/notation.ts
+++ b/js/hive-lib/src/notation.ts
@@ -53,12 +53,8 @@ export function buildMoveNotation(
* @return An array of *Move* objects.
*/
export function getGameMoves(notation: string): Move[] {
- const turns = _parseGameNotation(notation);
- return flatten(
- turns.map((turn) =>
- turn.white ? (turn.black ? [turn.white, turn.black] : [turn.white]) : []
- )
- );
+ const turns = _parseMoves(notation);
+ return turns;
}
/**
@@ -126,9 +122,27 @@ export function _buildTurnNotation(
* @return An array of *Turn* objects.
*/
export function _parseGameNotation(notation: string): Turn[] {
- return notation
+ return [];
+ // return notation
+ // .split(';')
+ // .filter((s) => s)
+ // .map((turnNotation) => _parseMoveNotation(turnNotation));
+}
+
+/**
+ * Create an ordered array of *Move* objects by parsing a game notation string.
+ *
+ * @param notation A game notation string.
+ * @return An array of *Move* objects.
+ */
+export function _parseMoves(notation: string): Move[] {
+ if (!notation) {
+ return [];
+ }
+ return (notation + '')
.split(';')
- .map((turnNotation) => _parseTurnNotation(turnNotation));
+ .filter((s) => s)
+ .map((moveNotation) => _parseMoveNotation(moveNotation));
}
/**
@@ -137,27 +151,27 @@ export function _parseGameNotation(notation: string): Turn[] {
* @param notation A turn notation string.
* @return A *Turn* object.
*/
-// export function _parseTurnNotation(notation: string, index: number): Turn {
-// const moves = notation.split(' ');
-// return {
-// notation,
-// index: index + 1,
-// white: _parseMoveNotation(moves[0]),
-// black: _parseMoveNotation(moves[1])
-// };
-// }
-export function _parseTurnNotation(notation: string): Turn {
- const sepLocation = notation.indexOf('.');
- const indexString = notation.slice(0, sepLocation);
- const placementsString = notation.slice(sepLocation + 1);
- const placements = placementsString.split(' ');
+export function _parseTurnNotation(notation: string, index: number): Turn {
+ const moves = notation.split(' ');
return {
notation,
- index: parseInt(indexString),
- white: _parseMoveNotation(placements[0]),
- black: _parseMoveNotation(placements[1])
+ index: index + 1,
+ white: _parseMoveNotation(moves[0]),
+ black: _parseMoveNotation(moves[1])
};
}
+// export function _parseTurnNotation(notation: string): Turn {
+// const sepLocation = notation.indexOf('.');
+// const indexString = notation.slice(0, sepLocation);
+// const placementsString = notation.slice(sepLocation + 1);
+// const placements = placementsString.split(' ');
+// return {
+// notation,
+// index: parseInt(indexString),
+// white: _parseMoveNotation(placements[0]),
+// black: _parseMoveNotation(placements[1])
+// };
+// }
/**
* Create a *Move* object by parsing a move notation string.
@@ -165,15 +179,12 @@ export function _parseTurnNotation(notation: string): Turn {
* @param notation A move notation string.
* @return A *Move* object.
*/
-export function _parseMoveNotation(notation?: string): Move | undefined {
- if (!notation) return undefined;
-
+export function _parseMoveNotation(notation: string): Move {
// Split notation into moving tile and reference tile portions
notation = notation.trim();
- let [tileId, refNotation] = notation.split(/\s/g);
- console.log(notation);
- console.log(tileId);
- console.log(refNotation);
+
+ // TODO: Neel: figure out why this is getting called twice, once with commas as separators and once with spaces
+ let [tileId, refNotation] = notation.split(/\s|,/g);
// Check for and return a passing move
if (tileId === 'x')
@@ -186,17 +197,9 @@ export function _parseMoveNotation(notation?: string): Move | undefined {
// Parse the reference notation to get the reference tile and direction
let { refId, dir, end } =
- refNotation !== undefined
- ? _parseReferenceNotation(refNotation) // only when there is one
- : { refId: tileId, dir: 0, end: false }; // first move notation
-
- // // TODO: is this the right way to do this?
- // // handle first move notation
- // if (tileId === '.') {
- // refId = tileId;
- // dir = 0;
- // end = false;
- // }
+ refNotation === '.'
+ ? { refId: tileId, dir: 0, end: false } // first move notation
+ : _parseReferenceNotation(refNotation); // only when there is one
// Return a playing move
return {
diff --git a/js/hive-lib/src/types.ts b/js/hive-lib/src/types.ts
index 697e531..61b3807 100644
--- a/js/hive-lib/src/types.ts
+++ b/js/hive-lib/src/types.ts
@@ -70,6 +70,12 @@ export type GameOptions = {
mosquito: boolean;
};
+export type PossibleMove = {
+ qCoordinate: number;
+ rCoordinate: number;
+ tileId: TileId;
+};
+
/**
* An object describing a player's move, which can either be a pass or move or
* place a tile.