Skip to content

Commit

Permalink
Merge pull request #24 from averycrespi/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
averycrespi authored Jul 17, 2020
2 parents c9467ea + bbb6789 commit 6b9c190
Show file tree
Hide file tree
Showing 32 changed files with 351 additions and 378 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"email": "averycrespi@gmail.com"
},
"license": "MIT",
"version": "1.0.0",
"version": "1.1.0",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.29",
"@fortawesome/free-brands-svg-icons": "^5.13.1",
Expand Down
14 changes: 14 additions & 0 deletions src/api/storage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { loadCredentials, saveCredentials } from "./storage";

import { Player } from "../logic";

test("load missing credentials", () =>
expect(loadCredentials("match", Player.Red)).toBe(null));

test("save and load credentials", () => {
const matchID = "match";
const player = Player.Red;
const credentials = "credentials";
saveCredentials(matchID, player, credentials);
expect(loadCredentials(matchID, player)).toBe(credentials);
});
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { GRID_HEIGHT, GRID_WIDTH } from "../../logic/grid";
import React, { useEffect } from "react";

interface GameHistoryProps {
history: Array<string>;
interface EventsProps {
events: Array<string>;
scale: number;
}

/** Render the history of a game. */
const GameHistory = ({ history, scale }: GameHistoryProps) => {
const Events = ({ events, scale }: EventsProps) => {
useEffect(() => {
const div = document.getElementById("history");
if (div) {
// Scroll to the bottom when the history is updated.
// Scroll to the bottom on update.
div.scrollTop = div.scrollHeight;
}
});
Expand All @@ -28,18 +27,15 @@ const GameHistory = ({ history, scale }: GameHistoryProps) => {
}}
>
<table>
<thead>
<th>History</th>
</thead>
<tbody>
{history.length === 0 && (
{events.length === 0 && (
<tr>
<td>
<i>Events will appear here.</i>
</td>
</tr>
)}
{history.map((e) => (
{events.map((e) => (
<tr>
<td>{e}</td>
</tr>
Expand All @@ -50,4 +46,4 @@ const GameHistory = ({ history, scale }: GameHistoryProps) => {
);
};

export default GameHistory;
export default Events;
1 change: 0 additions & 1 deletion src/components/Board/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface GridProps {
onCellClick(index: number): void;
}

/** Render a 2D array of cells. */
const Grid = ({ cells, highlighted, scale, onCellClick }: GridProps) => {
let grid = [];
for (let y = 0; y < GRID_HEIGHT; y++) {
Expand Down
1 change: 0 additions & 1 deletion src/components/Board/GridCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ interface GridCellProps {
readonly cell: Cell;
}

/** Render a cell in the grid. */
const GridCell = ({ cell }: GridCellProps) => {
if (!cell) {
return null;
Expand Down
22 changes: 10 additions & 12 deletions src/components/Board/GridController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { canMove, possibleMovements } from "../../logic/move";
import { canPlace, possiblePlacements } from "../../logic/place";
import { canRotate, possibleRotations } from "../../logic/rotate";

import GameHistory from "./GameHistory";
import Events from "./Events";
import Grid from "./Grid";
import TokenSelector from "./TokenSelector";

Expand All @@ -25,19 +25,18 @@ interface GridControllerProps {
readonly isActive: boolean;
readonly cells: Array<Cell>;
readonly hand: Array<Token>;
readonly history: Array<string>;
readonly events: Array<string>;
readonly player: Player;
placePiece(token: Token, index: number): void;
movePiece(srcIndex: number, destIndex: number): void;
rotatePiece(token: Token, index: number): void;
}

/** Render a grid controller. */
const GridController = ({
isActive,
cells,
hand,
history,
events,
player,
placePiece,
movePiece,
Expand Down Expand Up @@ -114,19 +113,18 @@ const GridController = ({
</div>
<div className="col no-padding">
<div className="padding-left-large">
<GameHistory history={history} scale={CELL_SCALE} />
<Events events={events} scale={CELL_SCALE} />
</div>
</div>
</div>
<div className="row flex-center">
<div className="col no-padding">
{isActive && (
<TokenSelector
hand={hand}
selected={selectedToken}
onTokenSelect={onTokenSelect}
/>
)}
<TokenSelector
isActive={isActive}
hand={hand}
selected={selectedToken}
onTokenSelect={onTokenSelect}
/>
</div>
</div>
</div>
Expand Down
1 change: 0 additions & 1 deletion src/components/Board/TokenIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface TokenIconProps {
token: Token;
}

/** Render a token as an icon. */
const TokenIcon = ({ token }: TokenIconProps) => {
switch (token) {
case Token.Blocker:
Expand Down
7 changes: 4 additions & 3 deletions src/components/Board/TokenSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import React from "react";
import TokenIcon from "./TokenIcon";

interface TokenSelectorProps {
readonly isActive: boolean;
readonly hand: Array<Token>;
readonly selected?: Token;
onTokenSelect(token: Token): void;
}

/** Render a token selector. */
const TokenSelector = ({
isActive,
hand,
selected,
onTokenSelect,
Expand All @@ -27,8 +28,8 @@ const TokenSelector = ({
Token.Mine,
];
for (const token of tokens) {
// Tanks can be rotated, so never disable their buttons.
const disabled = !hand.includes(token) && !isTank(token);
// Always show tanks when the selector is active.
const disabled = !isActive || (!hand.includes(token) && !isTank(token));
const count = hand.filter((t) => t === token).length;
div.push(
<button
Expand Down
3 changes: 1 addition & 2 deletions src/components/Board/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ interface LocalBoardProps extends BoardProps {
G: G;
}

/** Render the game board. */
const Board = ({ G, ctx, moves, isActive }: LocalBoardProps) => {
const player = ctx.currentPlayer as Player;
const gameover = ctx.gameover as Result;
Expand Down Expand Up @@ -38,7 +37,7 @@ const Board = ({ G, ctx, moves, isActive }: LocalBoardProps) => {
isActive={isActive}
cells={G.cells}
hand={G.hands[player]}
history={G.history}
events={G.events}
player={player}
placePiece={moves.placePiece}
movePiece={moves.movePiece}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Link } from "react-router-dom";
import React from "react";

/** Opens the How to Play page in a new tab. */
const ShowHelp = () => (
const HelpButton = () => (
<div className="row flex-center">
<div className="col no-padding">
<Link
Expand All @@ -17,4 +16,4 @@ const ShowHelp = () => (
</div>
);

export default ShowHelp;
export default HelpButton;
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";

/** Render the basics. */
const Basics = () => (
<div className="row flex-center">
<div
className="col no-padding"
style={{ textAlign: "center", wordWrap: "break-word" }}
>
<h2>The Basics</h2>

<p>Thinktank is a 2-player strategy game inspired by Conundrum.</p>
<p>
On your turn, you can <b>place</b> a piece, <b>move</b> a piece, or{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import React from "react";
import { Token } from "../../logic";
import TokenIcon from "../Board/TokenIcon";

/** Render the cheatsheet. */
const Cheatsheet = () => (
<div className="row flex-center">
<div
className="col no-padding"
style={{ textAlign: "center", wordWrap: "break-word" }}
>
<h2>Cheatsheet</h2>

<table>
<thead>
<th>Name</th>
<th>Piece</th>
<th>Icon</th>
<th>Description</th>
<th>Movement</th>
Expand All @@ -24,7 +24,7 @@ const Cheatsheet = () => (
<td>
<TokenIcon token={Token.Blocker} />
</td>
<td>Protects your pieces from enemy tanks.</td>
<td>Blocks shots from enemy tanks.</td>
<td>1 space</td>
<td>
<TokenIcon token={Token.OrthogonalInfiltrator} />
Expand All @@ -39,7 +39,7 @@ const Cheatsheet = () => (
/<TokenIcon token={Token.LeftTank} />
/<TokenIcon token={Token.RightTank} />
</td>
<td>Shoots enemy pieces (in a single direction).</td>
<td>Shoots enemy pieces in a single direction.</td>
<td>1 horizontal/vertical space</td>
<td>
<TokenIcon token={Token.UpTank} />
Expand All @@ -49,7 +49,7 @@ const Cheatsheet = () => (
</td>
</tr>
<tr>
<td>Infiltrator (+)</td>
<td>Infiltrator</td>
<td>
<TokenIcon token={Token.OrthogonalInfiltrator} />
</td>
Expand All @@ -61,7 +61,7 @@ const Cheatsheet = () => (
</td>
</tr>
<tr>
<td>Infiltrator (X)</td>
<td>Infiltrator</td>
<td>
<TokenIcon token={Token.DiagonalInfiltrator} />
</td>
Expand All @@ -77,7 +77,7 @@ const Cheatsheet = () => (
<td>
<TokenIcon token={Token.Mine} />
</td>
<td>Explodes adjacent enemy (and friendly) pieces.</td>
<td>Explodes adjacent pieces.</td>
<td>2 spaces (can jump)</td>
<td>
<TokenIcon token={Token.UpTank} />
Expand All @@ -98,6 +98,36 @@ const Cheatsheet = () => (
</tr>
</tbody>
</table>

<table className="margin-top-large">
<thead>
<th>Action</th>
<th>Controls</th>
</thead>
<tbody>
<tr>
<td>Place a piece</td>
<td>
Click a piece in your hand, then click one of the highlighted
spaces.
</td>
</tr>
<tr>
<td>Move a piece</td>
<td>
Click a piece on the board, then click one of the highlighted
spaces.
</td>
</tr>
<tr>
<td>Rotate a tank</td>
<td>
Click a tank in your hand, then click one of the highlighted tanks
on the board.
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
Expand Down
Loading

0 comments on commit 6b9c190

Please sign in to comment.