Parcourir la source

Refactoring Game logic to use some proper state transitions

Kirk Trombley il y a 5 ans
Parent
commit
c6b25f77ec
2 fichiers modifiés avec 57 ajouts et 81 suppressions
  1. 55 79
      ui/src/App.js
  2. 2 2
      ui/src/components/player-scores.component.jsx

+ 55 - 79
ui/src/App.js

@@ -7,64 +7,53 @@ import RoundSummary from './components/round-summary.component';
 import './App.css';
 import PreGame from './components/pre-game.component';
 
+const LOADING    = "LOADING";
+const PRE_GAME   = "PREGAME";
+const IN_ROUND   = "INROUND";
+const POST_ROUND = "POSTROUND";
+const POST_GAME  = "POSTGAME";
 
 class Game extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
+      gameState: PRE_GAME,
       playerName: "testing", // TODO mechanism for setting this
       loading: false,
       gameId: null, // TODO mechanism for joining game
       currentRound: null,
       targetPoint: null,
       selectedPoint: null,
-      betweenRounds: false,
       lastScore: null,
       totalScore: null,
-      playerScores: null,
+      players: null,
     }
   }
 
   async handleGameCreate() {
-    this.setState({loading: true});
+    this.setState({ gameState: LOADING });
     const { playerName } = this.state;
     const gameId = await createGame(playerName, 300);
     this.setState({ gameId });
     await this.updateRoundState();
   }
 
-  handleRoundEnd(coords, currentRound) {
-    const targetPoint = coords[currentRound];
-    this.setState({
-      loading: false,
-      currentRound,
-      targetPoint,
-      selectedPoint: null,
-      betweenRounds: false,
-    });
-  }
-
-  handleGameEnd(playerScores) {
-    this.setState({
-      loading: false,
-      gameId: null,
-      currentRound: null,
-      targetPoint: null,
-      selectedPoint: null,
-      betweenRounds: false,
-      playerScores,
-    });
-  }
-
   async updateRoundState() {
-    this.setState({ loading: true })
+    this.setState({ gameState: LOADING })
     const { gameId, playerName } = this.state;
     const { currentRound } = await getGuesses(gameId, playerName);
     const { coords, players } = await gameInfo(gameId);
     if (currentRound) {
-      this.handleRoundEnd(coords, currentRound);
+      const targetPoint = coords[currentRound];
+      this.setState({
+        gameState: IN_ROUND,
+        currentRound,
+        targetPoint,
+        selectedPoint: null,
+        players,
+      });
     } else {
-      this.handleGameEnd(players);
+      this.setState({ gameState: POST_GAME, players });
     }
   }
 
@@ -75,65 +64,52 @@ class Game extends React.Component {
       currentRound,
       selectedPoint
     } = this.state;
-    this.setState({ loading: true });
+    this.setState({ gameState: LOADING });
     const { score, totalScore } = await sendGuess(gameId, playerName, currentRound, selectedPoint);
     this.setState({
-      loading: false,
-      betweenRounds: true,
+      gameState: POST_ROUND,
       lastScore: score,
       totalScore
     });
   }
 
   render() {
-    const {
-      loading,
-      currentRound,
-      selectedPoint,
-      targetPoint,
-      betweenRounds,
-      lastScore,
-      totalScore,
-      playerScores,
-    } = this.state;
-
-    // TODO eventually make state transitions more clear
-
-    if (loading) {
-      return <p>Loading...</p>
-    }
-
-    if (betweenRounds) {
-      return <RoundSummary
-        roundNum={currentRound}
-        score={lastScore}
-        totalScore={totalScore}
-        onAdvanceState={() => this.updateRoundState()}
-        buttonText={currentRound === "5" ? "View Summary" : "Next Round"}
-      />
-    }
-
-    if (playerScores) {
-      return <PlayerScores
-        scores={playerScores}
-        onReturnToStart={() => this.setState({ playerScores: null })}
-      />
-    }
-
-    if (!targetPoint) {
-      return <PreGame
-        onGameCreate={() => this.handleGameCreate()}
-      />
-    }
-
-    return <GamePanel
-      onSelectPoint={latLng => this.setState({selectedPoint: latLng})}
-      onSubmitGuess={() => this.handleSubmitGuess()}
-      streetViewPoint={targetPoint}
-      selectedPoint={selectedPoint}
-    />
+    const { gameState } = this.state;
+
+    switch (gameState) {
+      case LOADING:
+        return <p>Loading...</p>
+      case PRE_GAME:
+        return <PreGame
+          onGameCreate={() => this.handleGameCreate()}
+        />
+      case IN_ROUND:
+        const { targetPoint, selectedPoint } = this.state;
+        return <GamePanel
+          onSelectPoint={latLng => this.setState({selectedPoint: latLng})}
+          onSubmitGuess={() => this.handleSubmitGuess()}
+          streetViewPoint={targetPoint}
+          selectedPoint={selectedPoint}
+        />
+      case POST_ROUND:
+        const { currentRound, lastScore, totalScore } = this.state;
+        return <RoundSummary
+          roundNum={currentRound}
+          score={lastScore}
+          totalScore={totalScore}
+          onAdvanceState={() => this.updateRoundState()}
+          buttonText={currentRound === "5" ? "View Summary" : "Next Round"}
+        />
+      case POST_GAME:
+        const { players } = this.state;
+        return <PlayerScores
+          players={players}
+          onReturnToStart={() => this.setState({ gameState: PRE_GAME })}
+        />
+      default:
+        return <p>Application state is inconsistent, please refresh and rejoin your previous game.</p>
+    } 
   }
-
 }
 
 const App = () => {

+ 2 - 2
ui/src/components/player-scores.component.jsx

@@ -2,10 +2,10 @@ import React from 'react';
 
 // TODO render this as a nice score page
 
-const PlayerScores = ({ scores, onReturnToStart }) => (
+const PlayerScores = ({ players, onReturnToStart }) => (
   <div>
     <p>Previous Game:</p>
-    <p>{JSON.stringify(scores)}</p>
+    <p>{JSON.stringify(players)}</p>
     <button
       onClick={onReturnToStart}>
       Return to Start