diff --git a/ui/source/css/basics/headings.css b/ui/source/css/basics/headings.css
index 657b08d..25020bd 100644
--- a/ui/source/css/basics/headings.css
+++ b/ui/source/css/basics/headings.css
@@ -25,4 +25,8 @@ h6 {
.site-title {
font-size: 1.75rem;
font-weight: var(--font-weight-bold);
+}
+
+.lobby__title {
+ font-size: 1.5rem;
}
\ No newline at end of file
diff --git a/ui/source/css/basics/icons.css b/ui/source/css/basics/icons.css
index 2779fe1..4af4133 100644
--- a/ui/source/css/basics/icons.css
+++ b/ui/source/css/basics/icons.css
@@ -1,13 +1,17 @@
.icon {
- display: inline-block;
- width: 1em;
- height: 1em;
- stroke-width: 0;
- stroke: currentColor;
- fill: currentColor;
- transition: transform var(--anim-duration-fast) var(--anim-easing);
- svg {
- max-width: 100%;
- max-height: 100%;
+ &::after {
+ content: '';
+ display: inline-block;
+ margin-left: 0.5rem;
+ width: 1rem;
+ height: 1rem;
+ vertical-align: -2px;
}
+}
+
+.icon--master {
+ &::after {
+ background: transparent url('../images/eye.svg') 50% 50% no-repeat;
+ background-size: 1rem 1rem;
+ }
}
\ No newline at end of file
diff --git a/ui/source/css/basics/inputs.css b/ui/source/css/basics/inputs.css
index a3ffd62..03076b6 100644
--- a/ui/source/css/basics/inputs.css
+++ b/ui/source/css/basics/inputs.css
@@ -1,5 +1,12 @@
.input {
+ display: inline-block;
+ appearance: none;
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
font-family: var(--font-family-primary);
+ box-shadow: 0 0.25rem 0.25rem 0 rgba(0,0,0,0.15);
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius);
}
.input--select {
diff --git a/ui/source/css/basics/labels.css b/ui/source/css/basics/labels.css
index ddc5592..3af836f 100644
--- a/ui/source/css/basics/labels.css
+++ b/ui/source/css/basics/labels.css
@@ -2,6 +2,11 @@ legend {
}
-.label {
+label[for] {
+ cursor: pointer;
+}
+.label {
+ font-size: 0.8rem;
+ font-weight: var(--font-weight-light);
}
\ No newline at end of file
diff --git a/ui/source/css/basics/switch.css b/ui/source/css/basics/switch.css
index 1356b64..f1f51fa 100644
--- a/ui/source/css/basics/switch.css
+++ b/ui/source/css/basics/switch.css
@@ -1,36 +1,69 @@
-.switch {
+.switch,
+.switch-toggle {
+ margin: 0.5rem auto 1rem auto;
+ border: 2px solid var(--color-border);
+ border-radius: var(--border-radius);
+}
+
+.switch-toggle {
display: flex;
}
-.switch__item {
- &:first-child {
- .switch__label {
- border-radius: 0.5rem 0 0 0.5rem;
- }
- }
- &:last-child {
- .switch__label {
- border-radius: 0 0.5rem 0.5rem 0;
- }
- }
- & + .switch__item {
- .switch__label {
- border-left: 0;
+.switch {
+ display: block;
+ position: relative;
+ text-align: center;
+}
+
+.switch__label,
+.switch-toggle__label {
+ display: block;
+ color: var(--color-text);
+ background-color: transparent;
+ transition: background-color var(--anim-duration);
+}
+
+.switch__control,
+.switch-toggle__control {
+ display: none;
+ overflow: hidden;
+ height: 0;
+ width: 0;
+ visibility: hidden;
+}
+
+.switch__control {
+ &:checked {
+ & + .switch__label {
+ background-color: var(--color-white);
}
}
}
-.switch__label {
- padding: 0.25rem 1rem;
- box-shadow: 0.25rem 0.25rem rgba(0, 0, 0, 0.25);
- border: 1px solid var(--color-gray-30);
- background: linear-gradient(to bottom, var(--color-gray-40) 0%, var(--color-gray-50) 100%);
+.switch-toggle__item {
+ flex-grow: 1;
+ text-align: center;
+ & + & {
+ border-left: 1px solid var(--color-border);
+ }
+ &:first-child {
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
+ }
+ &:last-child {
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
+ }
}
-.switch__input:checked + .switch__label {
- color: var(--color-white);
- background: linear-gradient(to bottom, var(--color-green-10) 0%, var(--color-green-20) 100%);
- .sub-label {
- font-weight: var(--font-weight-normal);
+.switch-toggle__control {
+ &:checked {
+ & + .switch-toggle__label {
+ color: var(--color-white);
+ &.switch--blue {
+ background-color: var(--color-team-blue);
+ }
+ &.switch--red {
+ background-color: var(--color-team-red);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/ui/source/css/basics/text.css b/ui/source/css/basics/text.css
index fae60e7..1a76829 100644
--- a/ui/source/css/basics/text.css
+++ b/ui/source/css/basics/text.css
@@ -8,4 +8,8 @@ body {
p {
margin: 0 0 var(--spacing-vertical) 0;
+}
+
+.text-center {
+ text-align: center;
}
\ No newline at end of file
diff --git a/ui/source/css/components/frame/sidebar.css b/ui/source/css/components/frame/sidebar.css
index d2e464f..9a0bfbc 100644
--- a/ui/source/css/components/frame/sidebar.css
+++ b/ui/source/css/components/frame/sidebar.css
@@ -3,6 +3,15 @@
margin: 1rem 0;
border: solid;
background-color: rgba(255,255,255,0.5);
+ .team-list {
+ & + .team-list {
+ margin-top: 1rem;
+ }
+ }
+ .switch__label,
+ .switch-toggle__label {
+ background-color: var(--color-gray-30);
+ }
}
@media (--large) {
diff --git a/ui/source/css/components/lobby/entry.css b/ui/source/css/components/lobby/entry.css
new file mode 100644
index 0000000..5781d4e
--- /dev/null
+++ b/ui/source/css/components/lobby/entry.css
@@ -0,0 +1,31 @@
+.entry-prompt__form {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-gap: 1rem;
+ max-width: 45rem;
+ & > * {
+ display: block;
+ }
+ .label {
+ align-self: center;
+ }
+
+}
+
+@media (--small) {
+ .entry-prompt__form {
+ grid-template-columns: 1fr 1fr;
+ }
+}
+
+@media (--medium) {
+ .entry-prompt__form {
+ grid-template-columns: 1fr 2fr 1fr;
+ input[type='submit'] {
+ grid-column: 1 / 4;
+ }
+ input[name='nameInput'] {
+ grid-column: 2/4;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/source/css/components/lobby/lobby.css b/ui/source/css/components/lobby/lobby.css
new file mode 100644
index 0000000..3ba1a55
--- /dev/null
+++ b/ui/source/css/components/lobby/lobby.css
@@ -0,0 +1,15 @@
+.lobby-prompt__form {
+
+}
+
+@media (--medium) {
+ .lobby-prompt__form {
+ .teams-list {
+ display: flex;
+ justify-content: center;
+ }
+ .team-list {
+ margin: 0 1rem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/source/css/components/player/team-list.css b/ui/source/css/components/player/team-list.css
index bb3270a..bd93e43 100644
--- a/ui/source/css/components/player/team-list.css
+++ b/ui/source/css/components/player/team-list.css
@@ -2,16 +2,6 @@
margin: 1rem 0;
}
-.team-list {
- & + & {
- margin-top: 1rem;
- }
-}
-
-.team-list__item {
-
-}
-
.team-list__item--title {
font-weight: var(--font-weight-light);
border-bottom: 1px dotted var(--color-text);
@@ -40,4 +30,15 @@
background: transparent url('../images/eye.svg') 50% 50% no-repeat;
background-size: 1rem 1rem;
}
+}
+
+.team-list__item--ready {
+ &::before {
+ content: '✓';
+ color: var(--color-positive);
+ }
+}
+
+.team-list__item--current-player {
+ font-weight: var(--font-weight-bold);
}
\ No newline at end of file
diff --git a/ui/source/css/components/status/status-list.css b/ui/source/css/components/status/status-list.css
index 683ba37..a71f523 100644
--- a/ui/source/css/components/status/status-list.css
+++ b/ui/source/css/components/status/status-list.css
@@ -25,4 +25,8 @@
.text-outline {
text-shadow: 1px 1px 0 rgba(255,255,255,1), 1px 1px 0 rgba(0,0,0,1);
+}
+
+.display-score {
+ font-size: 1.8rem;
}
\ No newline at end of file
diff --git a/ui/source/css/utilities/00-variables.css b/ui/source/css/utilities/00-variables.css
index bddfd5e..af7572d 100644
--- a/ui/source/css/utilities/00-variables.css
+++ b/ui/source/css/utilities/00-variables.css
@@ -1,11 +1,21 @@
:root {
--color-black: #000;
--color-white: #fff;
+ --color-gray-10: #333;
+ --color-gray-20: #666;
+ --color-gray-30: #999;
+ --color-gray-40: #ccc;
- --color-team-blue: rgb(0,0,255);
- --color-team-red: rgb(255,0,0);
+ --color-team-blue: rgb(10,10,255);
+ --color-team-red: rgb(255,10,10);
+
+ --color-green: rgb(25,150,25);
+ --color-positive: var(--color-green);
+ --color-red: rgb(255,0,0);
+ --color-negative: var(--color-red);
--color-text: var(--color-black);
+ --color-border: var(--color-gray-30);
--font-family-primary: 'Montserrat', sans-serif;
--font-size-base: 1rem;
diff --git a/ui/source/js/components/app.js b/ui/source/js/components/app.js
new file mode 100644
index 0000000..80f8a97
--- /dev/null
+++ b/ui/source/js/components/app.js
@@ -0,0 +1,87 @@
+import React, {Component} from 'react';
+import Start from './start.js';
+import Lobby from './lobby.js';
+import Game from './game.js';
+
+import {setSeed} from '../helpers/seedUtilities.js';
+import {setPlayerIsMaster} from '../helpers/teamUtilities.js';
+import router from '../helpers/router.js';
+
+class App extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ page: 'start',
+ seed: null,
+ teams: null,
+ currentPlayerId: null,
+ currentPlayerName: null,
+ currentLobbyName: null
+ };
+ this.handleEntrySubmit = this.handleEntrySubmit.bind(this);
+ this.handleLobbySubmit = this.handleLobbySubmit.bind(this);
+ this.updateTeams = this.updateTeams.bind(this);
+ }
+
+ updateTeams(newTeams) {
+ this.setState({ teams: newTeams });
+ }
+
+ getPage(pageId) {
+ let pageRoute;
+ switch(pageId) {
+ case 'start':
+ pageRoute = ;
+ break;
+ case 'lobby':
+ pageRoute = ;
+ break;
+ case 'game':
+ pageRoute = ;
+ break;
+ default:
+ console.error('Invalid Page Id');
+ }
+ return pageRoute;
+ }
+
+ handleEntrySubmit(currentPlayerName, currentLobbyName) {
+ setSeed(currentLobbyName);
+ this.setState({
+ page: 'lobby',
+ currentPlayerName: currentPlayerName,
+ currentLobbyName: currentLobbyName,
+ seed: currentLobbyName
+ });
+ }
+
+ handleLobbySubmit(lobbyTeams, currentPlayerId) {
+ this.setState({
+ page: 'game',
+ teams: lobbyTeams,
+ currentPlayerId: currentPlayerId
+ });
+ }
+
+ render() {
+ return (
+
+ { this.getPage(this.state.page) }
+
+ );
+ }
+}
+
+export default App;
\ No newline at end of file
diff --git a/ui/source/js/components/board.js b/ui/source/js/components/board.js
index c6c4fc2..1e7a441 100644
--- a/ui/source/js/components/board.js
+++ b/ui/source/js/components/board.js
@@ -5,7 +5,8 @@ function Board(props) {
function renderPiece(i) {
return props.onClick(i)}
/>;
diff --git a/ui/source/js/components/changePlayer.js b/ui/source/js/components/changePlayer.js
new file mode 100644
index 0000000..47e53c2
--- /dev/null
+++ b/ui/source/js/components/changePlayer.js
@@ -0,0 +1,67 @@
+import React from 'react';
+import {getPlayerTeam, setPlayerTeam, getPlayerIsMaster, setPlayerIsMaster} from '../helpers/teamUtilities.js';
+
+function ChangePlayer(props) {
+
+ let playerIsMaster = getPlayerIsMaster(props.teams, props.currentPlayerId);
+ let masterIcon = generateMasterIcon();
+
+ function generateMasterIcon() {
+ return playerIsMaster ? Master : Player;
+ }
+
+ function updatePlayerTeam(players, currentPlayerId, teamId) {
+ const updatedTeams = setPlayerTeam(players, currentPlayerId, teamId);
+ props.updateTeams(updatedTeams);
+ }
+
+ function togglePlayerIsMaster(players, currentPlayerId, toggleStatus) {
+ const updatedTeams = setPlayerIsMaster(players, currentPlayerId, toggleStatus);
+ props.updateTeams(updatedTeams);
+ }
+
+ return (
+
+ );
+}
+
+export default ChangePlayer;
\ No newline at end of file
diff --git a/ui/source/js/components/controls.js b/ui/source/js/components/controls.js
index 47da6a0..6dd47c9 100644
--- a/ui/source/js/components/controls.js
+++ b/ui/source/js/components/controls.js
@@ -1,58 +1,40 @@
import React from 'react';
+import ChangePlayer from './changePlayer.js';
+
+import {getPlayerTeam, getPlayerIsMaster} from '../helpers/teamUtilities.js';
function Controls(props) {
- function getViewerState(viewerId, controlId) {
- return viewerId === controlId;
+ let playerIsMaster = getPlayerIsMaster(props.teams, props.playerId);
+ let masterIcon = generateMasterIcon();
+
+ function isOtherTeamsTurn(teamArray, playerId, isBlueTurn) {
+ return getPlayerTeam(teamArray, playerId) === 1 ? !isBlueTurn : true;
+ }
+
+ function isGameOver(winnerName) {
+ return winnerName !== null ? true : false;
}
- function isWinner(winnerName) {
- if (winnerName !== null) {
- return true;
- }
- return false;
+ function generateMasterIcon() {
+ return playerIsMaster ? Master : Player;
}
return (
);
diff --git a/ui/source/js/components/game.js b/ui/source/js/components/game.js
index 594f508..cad7feb 100644
--- a/ui/source/js/components/game.js
+++ b/ui/source/js/components/game.js
@@ -2,9 +2,10 @@ import React, {Component} from 'react';
import Board from './board.js';
import Stats from './stats.js';
import Controls from './controls.js';
+import {getSeed} from '../helpers/seedUtilities.js';
import getWordlist from '../helpers/generateWordList.js';
import getOwnershipList from '../helpers/generateOwners.js';
-import generateTeams from '../helpers/teams.js';
+import {generateTeams, setPlayerTeam, setPlayerIsMaster} from '../helpers/teamUtilities.js';
import switchTurns from '../helpers/switchTurns.js';
import keepScore from '../helpers/keepScore.js';
import calculateWinner from '../helpers/winner.js';
@@ -36,26 +37,23 @@ class Game extends React.Component {
super(props);
this.state = {
isBlueTurn: true,
+ seed: this.props.seed,
score: {
black: blackPieceCount,
blue: bluePiecesCount,
red: redPiecesCount
},
pieces: buildPieceArray(),
- viewer: 0,
winner: null,
- teams: generateTeams()
+ teams: this.props.teams,
+ currentPlayerId: this.props.currentPlayerId
};
}
- switchTeamsClick() {
+ switchTeamTurnClick() {
this.setState({ isBlueTurn: !this.state.isBlueTurn });
}
- setViewer(i) {
- this.setState({ viewer: i });
- }
-
pieceChosenClick(i) {
if (this.state.winner === null) {
let updatedPieces = Array.from(this.state.pieces);
@@ -84,6 +82,7 @@ class Game extends React.Component {
newGame() {
this.setState({
+ seed: getSeed(),
winner: null,
isBlueTurn: true,
pieces: buildPieceArray()
@@ -103,25 +102,25 @@ class Game extends React.Component {
this.pieceChosenClick(i)}
/>
this.switchTeamsClick()}
- onClickViewMaster={() => this.setViewer(0)}
- onClickViewBlue={() => this.setViewer(1)}
- onClickViewRed={() => this.setViewer(2)}
+ teams={this.state.teams}
+ playerId={this.state.currentPlayerId}
+ isBlueTurn={this.state.isBlueTurn}
+ onClickSwitchTeams={() => this.switchTeamTurnClick()}
onClickPromptNewGame={() => this.promptNewGame()}
+ updateTeams={this.props.updateTeams}
/>
);
diff --git a/ui/source/js/components/lobby.js b/ui/source/js/components/lobby.js
new file mode 100644
index 0000000..7f22b59
--- /dev/null
+++ b/ui/source/js/components/lobby.js
@@ -0,0 +1,90 @@
+import React, {Component} from 'react';
+import TeamList from './teamList.js';
+import ChangePlayer from './changePlayer.js';
+
+import {generateTeams, getPlayerPositionInArray, getAllPlayersReady} from '../helpers/teamUtilities.js';
+
+const maxPlayers = 16;
+const currentPlayerId = 1;
+
+class Lobby extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ teams: this.populateTeams(),
+ currentPlayerId: currentPlayerId,
+ currentPlayerIsReady: false,
+ allPlayersReady: false
+ };
+ }
+
+ togglePlayerReady(currentTeams, playerId) {
+ const playerIndex = getPlayerPositionInArray(currentTeams, playerId);
+ if (playerIndex >= 0) {
+ currentTeams[playerIndex].isReady = !currentTeams[playerIndex].isReady;
+ const isAllPlayersReady = getAllPlayersReady(currentTeams);
+ this.setState({
+ teams: currentTeams,
+ currentPlayerIsReady: currentTeams[playerIndex].isReady,
+ allPlayersReady: isAllPlayersReady
+ });
+ } else {
+ console.error('Player not found');
+ }
+ }
+
+ populateTeams() {
+ const players = generateTeams();
+ if (players.length < maxPlayers) {
+ const currentPlayer = {
+ id: currentPlayerId,
+ name: this.props.currentPlayerName,
+ isMaster: false,
+ team: 1,
+ isReady: false
+ };
+ players.push(currentPlayer);
+ return players;
+ }
+ console.error('Too many people');
+ return players;
+ }
+
+ render() {
+ const buttonReadyText = this.state.currentPlayerIsReady ? 'Ready' : 'Unready';
+
+ return (
+
+ );
+ }
+}
+
+export default Lobby;
\ No newline at end of file
diff --git a/ui/source/js/components/piece.js b/ui/source/js/components/piece.js
index ccdb771..ff2ef8e 100644
--- a/ui/source/js/components/piece.js
+++ b/ui/source/js/components/piece.js
@@ -1,9 +1,11 @@
import React from 'react';
+import {getPlayerIsMaster} from '../helpers/teamUtilities.js';
function Piece(props) {
function getVisibleClass() {
- return (props.isChosen || props.viewer === 0) ? `piece--${props.owner}` : 'piece--neutral';
+ return (props.isChosen || getPlayerIsMaster(props.teams, props.playerId) === true)
+ ? `piece--${props.owner}` : 'piece--neutral';
}
return (
diff --git a/ui/source/js/components/player.js b/ui/source/js/components/player.js
index 4bd78b9..556812f 100644
--- a/ui/source/js/components/player.js
+++ b/ui/source/js/components/player.js
@@ -1,10 +1,35 @@
import React from 'react';
function Player(props) {
+ function playerIsCurrentPlayer() {
+ if (props.player.id === props.currentPlayerId) {
+ return 'team-list__item--current-player '
+ }
+ return '';
+ }
+
+ function playerIsReady() {
+ if (props.player.isReady === true) {
+ return 'team-list__item--ready '
+ }
+ return '';
+ }
+
+ function playerIsMaster() {
+ if (props.player.isMaster) {
+ return 'team-list__item--master ';
+ }
+ return '';
+ }
+
return (
{props.player.name}
diff --git a/ui/source/js/components/start.js b/ui/source/js/components/start.js
new file mode 100644
index 0000000..42c6e81
--- /dev/null
+++ b/ui/source/js/components/start.js
@@ -0,0 +1,77 @@
+import React, {Component} from 'react';
+import {getSeed, createSeed, setSeed} from '../helpers/seedUtilities.js';
+import {getPlayerName, setPlayerName} from '../helpers/playerUtilities.js';
+import {stripSpecialCharacters} from '../helpers/stringUtilities.js';
+
+class Start extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ currentPlayerName: getPlayerName(),
+ currentLobbyName: getSeed()
+ };
+ this.handleLobbyChange = this.handleLobbyChange.bind(this);
+ this.handleNameChange = this.handleNameChange.bind(this);
+ this.handleRandomClick = this.handleRandomClick.bind(this);
+ }
+
+ handleLobbyChange(event) {
+ this.setState({ currentLobbyName: event.target.value.toLowerCase().substr(0,20) });
+ }
+
+ handleNameChange(event) {
+ this.setState({ currentPlayerName: stripSpecialCharacters(event.target.value).substr(0,20) });
+ }
+
+ handleRandomClick(event) {
+ this.setState({ currentLobbyName: createSeed() });
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+export default Start;
\ No newline at end of file
diff --git a/ui/source/js/components/stats.js b/ui/source/js/components/stats.js
index e9cff79..89f55e1 100644
--- a/ui/source/js/components/stats.js
+++ b/ui/source/js/components/stats.js
@@ -1,32 +1,29 @@
import React from 'react';
import TeamList from './teamlist.js';
-import {getActiveTeamColorCSS, getViewerColorCSS, getViewerName} from '../helpers/decodeViewersAndWinners.js';
-import capitalizeFirstLetter from '../helpers/stringFunctions.js';
+import {getActiveTeamColorCSS} from '../helpers/classNames.js';
+import {capitalizeFirstLetter} from '../helpers/stringUtilities.js';
function Stats(props) {
function getStatus(winner, isBlueTurn) {
if (winner === null) {
- return `Current Turn: ${(isBlueTurn ? 'Blue' : 'Red')}`;
+ return `${(isBlueTurn ? 'Blue' : 'Red')} Turn`;
}
winner = capitalizeFirstLetter(winner);
- return `${winner} team wins.`;
+ return `${winner} Wins`;
}
return (
diff --git a/ui/source/js/components/teamlist.js b/ui/source/js/components/teamlist.js
index 813dd29..8c12834 100644
--- a/ui/source/js/components/teamlist.js
+++ b/ui/source/js/components/teamlist.js
@@ -7,24 +7,29 @@ function TeamList(props) {
return ;
}
- function generateList(teamArray) {
+ function generateList(teamArray, teamId) {
let listItemsArray = [];
- teamArray.forEach((player,i) => listItemsArray.push(renderPlayer(player, i)));
- return listItemsArray;
+ if (teamArray) {
+ return teamArray.filter(player => player.team === teamId)
+ .map((player,i) => (renderPlayer(player, i)));
+ }
+ console.error('No team array provided');
+ return Error;
}
return (
- Blue
- {generateList(props.teams.blue)}
+ {generateList(props.teams, 1)}
- Red
- {generateList(props.teams.red)}
+ {generateList(props.teams, 2)}
);
diff --git a/ui/source/js/helpers/decodeViewersAndWinners.js b/ui/source/js/helpers/classNames.js
similarity index 100%
rename from ui/source/js/helpers/decodeViewersAndWinners.js
rename to ui/source/js/helpers/classNames.js
diff --git a/ui/source/js/helpers/generateWordList.js b/ui/source/js/helpers/generateWordList.js
index e1f4121..5516587 100644
--- a/ui/source/js/helpers/generateWordList.js
+++ b/ui/source/js/helpers/generateWordList.js
@@ -2,20 +2,70 @@ import {shuffleArray} from './random.js';
function getWordlist(count) {
const wordList = [
- 'press', 'fan', 'pyramid', 'torch', 'fall',
- 'Himalayas', 'staff', 'pupil', 'drop', 'cotton',
- 'bottle', 'belt', 'stadium', 'glove', 'robot',
- 'glass', 'concert', 'bill', 'dress', 'pilot',
- 'green', 'turkey', 'ketchup', 'crown', 'cliff',
- 'bed', 'mass', 'Washington', 'box', 'dice',
- 'honey', 'hole', 'olive', 'star', 'litter',
- 'opera', 'shot', 'scientist', 'horn', 'time',
- 'apple', 'Olympus', 'telescope', 'snow', 'pan',
- 'princess', 'ivory', 'death', 'bugle', 'bark',
- 'duck', 'dinosaur', 'paste', 'orange', 'bow',
- 'straw', 'bug', 'doctor', 'cover', 'crane',
- 'point', 'pool', 'pirate', 'eagle', 'teacher',
- 'tie', 'cap', 'check', 'vacuum', 'shadow'
+ 'air', 'ambulance', 'ammonia', 'apple', 'appendix', 'archipelago',
+
+ 'ball', 'banana', 'bark', 'baron', 'barrier', 'bed', 'belt', 'bill', 'bingo', 'blackberry', 'bonus',
+ 'bottle', 'bow', 'box', 'broccoli', 'brunch', 'bug', 'bugle',
+
+ 'cap', 'cartridge', 'cassette', 'catfish', 'cemetery', 'check', 'Chihuahua', 'cilantro', 'circus',
+ 'cliff', 'coaster', 'coconut', 'code', 'command', 'concert', 'cover', 'conflict', 'cotton', 'coyote',
+ 'cracker', 'crane', 'crown', 'curfew', 'cursor',
+
+ 'dad', 'dawn', 'death', 'demon', 'dentist', 'diagnosis', 'dice', 'dinosaur', 'discovery', 'doctor',
+ 'donkey', 'dress', 'drop', 'duchess', 'duck',
+
+ 'Easter', 'eagle', 'editor', 'epilepsy', 'equator', 'error', 'espionage',
+
+ 'fall', 'fan', 'flask', 'flora', 'fox', 'fries', 'fundraiser', 'fusion',
+
+ 'glass', 'glove', 'glucose', 'google', 'green', 'gun',
+
+ 'hallway', 'hamburger', 'hammock', 'hand', 'head', 'heart', 'Himalayas', 'hole', 'honey', 'horn',
+ 'horseman', 'hurricane', 'hydra',
+
+ 'iceberg', 'illness', 'intersection', 'ivory',
+
+ 'Jabberwocky', 'jack', 'jerky', 'joker', 'juror',
+
+ 'kangaroo', 'ketchup', 'kingdom',
+
+ 'leopard', 'ligament', 'litter', 'logic', 'lookout',
+
+ 'mango', 'mass', 'matrix', 'medic', 'mirth', 'molasses', 'morale', 'motto', 'murder',
+
+ 'network', 'nexus', 'nightmare', 'noodle',
+
+ 'oasis', 'offense', 'olive', 'Olympus', 'opera', 'oracle', 'orange', 'oxygen',
+
+ 'pan', 'panther', 'pasta', 'paste', 'patriotism', 'pilot', 'pirate', 'plaza', 'point', 'poker',
+ 'pool', 'potassium', 'pottery', 'poultry', 'press', 'princess', 'prisoner', 'privacy', 'processor',
+ 'protein', 'prototype', 'puberty', 'pupil', 'pyramid',
+
+ 'quart', 'quartz', 'queen',
+
+ 'racism', 'ranger', 'recipe', 'recreation', 'refrigerator', 'reins', 'repository', 'republic', 'restaurant', 'roadblock',
+ 'robber', 'robot', 'rodeo', 'rocks',
+
+ 'saloon', 'Saturday', 'scenario', 'scholarship', 'scientist', 'scissors', 'scrum', 'seduction', 'senator', 'sesame',
+ 'setup', 'shadow', 'shop', 'shot', 'siding', 'sister', 'skate', 'snack', 'snail', 'snapshot',
+ 'snow', 'soccer', 'spaghetti', 'spoiler', 'squad', 'staff', 'stadium', 'stage', 'stairway', 'straw',
+ 'statement', 'star', 'stocks', 'subscription', 'suburb', 'success', 'sweater', 'syndrome', 'syntax',
+
+ 'tavern', 'teacher', 'technology', 'telescope', 'telephone', 'terror', 'theater', 'therapy', 'thunder', 'tie',
+ 'tiger', 'time', 'today', 'touchdown', 'torch', 'tourist', 'tractor', 'transmission', 'trauma', 'treadmill',
+ 'trilogy', 'trout', 'turkey', 'tyrant',
+
+ 'underdog', 'underwear', 'university',
+
+ 'vaccination', 'vacuum', 'vampire', 'vanguard', 'victory', 'viewpoint', 'villa', 'vista', 'vocalist', 'volcano',
+ 'voltage',
+
+ 'waistcoat', 'waitress', 'wardrobe', 'warmth', 'Washington', 'watchdog', 'wealth', 'werewolf', 'whisky', 'widget',
+ 'width', 'windfall', 'wiring', 'witchcraft', 'words', 'workman',
+
+ 'yak', 'yogurt', 'youngster',
+
+ 'Zanzibar', 'zibra', 'zoo'
];
return shuffleArray(wordList).slice(0, count);
}
diff --git a/ui/source/js/helpers/playerUtilities.js b/ui/source/js/helpers/playerUtilities.js
new file mode 100644
index 0000000..72d75ad
--- /dev/null
+++ b/ui/source/js/helpers/playerUtilities.js
@@ -0,0 +1,13 @@
+function getPlayerName() {
+ const playerName = window.localStorage.getItem('playerName');
+ return playerName ? playerName : '';
+}
+
+function setPlayerName(playerName) {
+ console.log(playerName);
+ if (playerName) {
+ window.localStorage.setItem('playerName', playerName);
+ }
+}
+
+export {getPlayerName, setPlayerName};
\ No newline at end of file
diff --git a/ui/source/js/helpers/router.js b/ui/source/js/helpers/router.js
new file mode 100644
index 0000000..54d9071
--- /dev/null
+++ b/ui/source/js/helpers/router.js
@@ -0,0 +1,7 @@
+import React from 'react';
+
+function router(route) {
+ console.log("Router online", route);
+}
+
+export default router;
\ No newline at end of file
diff --git a/ui/source/js/helpers/seedUtilities.js b/ui/source/js/helpers/seedUtilities.js
new file mode 100644
index 0000000..8fb609e
--- /dev/null
+++ b/ui/source/js/helpers/seedUtilities.js
@@ -0,0 +1,25 @@
+import getWordlist from './generateWordList.js';
+import {stripSpecialCharacters} from './stringUtilities.js';
+
+function getSeed() {
+ let seed = stripSpecialCharacters(window.location.hash).toLowerCase().substr(0,20);
+ if (!seed) {
+ seed = createSeed();
+ }
+ setSeed(seed);
+ return seed;
+}
+
+function createSeed(newSeed) {
+ if (!newSeed) {
+ return getWordlist(2).join('-').toLowerCase();
+ } else {
+ return newSeed.toLowerCase();
+ }
+}
+
+function setSeed(newSeed) {
+ window.location.hash = newSeed;
+}
+
+export {getSeed, setSeed, createSeed};
\ No newline at end of file
diff --git a/ui/source/js/helpers/stringFunctions.js b/ui/source/js/helpers/stringFunctions.js
deleted file mode 100644
index 6206bfa..0000000
--- a/ui/source/js/helpers/stringFunctions.js
+++ /dev/null
@@ -1,5 +0,0 @@
-function capitalizeFirstLetter(string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
-}
-
-export default capitalizeFirstLetter;
\ No newline at end of file
diff --git a/ui/source/js/helpers/stringUtilities.js b/ui/source/js/helpers/stringUtilities.js
new file mode 100644
index 0000000..eb0a38d
--- /dev/null
+++ b/ui/source/js/helpers/stringUtilities.js
@@ -0,0 +1,9 @@
+function capitalizeFirstLetter(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+}
+
+function stripSpecialCharacters(string) {
+ return string.replace(/[^a-zA-Z-]/g, '');
+}
+
+export {capitalizeFirstLetter, stripSpecialCharacters};
\ No newline at end of file
diff --git a/ui/source/js/helpers/teamUtilities.js b/ui/source/js/helpers/teamUtilities.js
new file mode 100644
index 0000000..b582cd9
--- /dev/null
+++ b/ui/source/js/helpers/teamUtilities.js
@@ -0,0 +1,76 @@
+function setPlayerTeam(playerArray, playerId, newPlayerTeam) {
+ const position = getPlayerPositionInArray(playerArray, playerId);
+ playerArray[position].team = newPlayerTeam;
+ return playerArray;
+}
+
+function setPlayerIsMaster(playerArray, playerId, newPlayerIsMaster) {
+ const position = getPlayerPositionInArray(playerArray, playerId);
+ playerArray[position].isMaster = newPlayerIsMaster;
+ return playerArray;
+}
+
+function getPlayerPositionInArray(playerArray, playerId) {
+ if (!playerArray) {
+ console.error('No team array');
+ }
+ return playerArray.map(player => player.id).indexOf(playerId);
+}
+
+function getPlayerTeam(playerArray, playerId) {
+ const position = getPlayerPositionInArray(playerArray, playerId);
+ return playerArray[position].team;
+}
+
+function getPlayerIsMaster(playerArray, playerId) {
+ const position = getPlayerPositionInArray(playerArray, playerId);
+ return playerArray[position].isMaster;
+}
+
+function getAllPlayersReady(playerArray) {
+ const readyPlayersArray = playerArray.filter(player => player.isReady);
+ const allPlayersReady = (playerArray.length === readyPlayersArray.length);
+ return allPlayersReady;
+}
+
+function generateTeams() {
+ return [
+ {
+ id: 2,
+ name: 'Jac',
+ isMaster: false,
+ team: 1,
+ isReady: true
+ },
+ {
+ id: 3,
+ name: 'Jeff',
+ isMaster: false,
+ team: 1,
+ isReady: true
+ },
+ {
+ id: 4,
+ name: 'Aaron',
+ isMaster: true,
+ team: 2,
+ isReady: true
+ },
+ {
+ id: 5,
+ name: 'Anna',
+ isMaster: false,
+ team: 2,
+ isReady: true
+ },
+ {
+ id: 6,
+ name: 'Andy',
+ isMaster: false,
+ team: 2,
+ isReady: true
+ }
+ ];
+}
+
+export {generateTeams, setPlayerTeam, setPlayerIsMaster, getPlayerTeam, getPlayerIsMaster, getPlayerPositionInArray, getAllPlayersReady};
\ No newline at end of file
diff --git a/ui/source/js/helpers/teams.js b/ui/source/js/helpers/teams.js
deleted file mode 100644
index 5894c40..0000000
--- a/ui/source/js/helpers/teams.js
+++ /dev/null
@@ -1,34 +0,0 @@
-function generateTeams() {
- return {
- blue: [
- {
- name: 'Joseph',
- isMaster: true
- },
- {
- name: 'Jac',
- isMaster: false
- },
- {
- name: 'Jeff',
- isMaster: false
- }
- ],
- red: [
- {
- name: 'Aaron',
- isMaster: true
- },
- {
- name: 'Anna',
- isMaster: false
- },
- {
- name: 'Andy',
- isMaster: false
- }
- ]
- };
-}
-
-export default generateTeams;
\ No newline at end of file
diff --git a/ui/source/js/main.js b/ui/source/js/main.js
index a00b355..0b1fcae 100644
--- a/ui/source/js/main.js
+++ b/ui/source/js/main.js
@@ -1,10 +1,10 @@
import React from 'react';
import {render} from 'react-dom';
-import Game from './components/game.js';
+import App from './components/app.js';
const rootEl = document.getElementById('app');
render(
- ,
+ ,
rootEl
);
\ No newline at end of file