|
@@ -19,7 +19,7 @@ type PointsData = {
|
|
|
type FortyData = {
|
|
|
kind: "forty";
|
|
|
player: Player;
|
|
|
- otherPlayerPoints: Point;
|
|
|
+ otherPlayerPoint: Point;
|
|
|
};
|
|
|
type Advantage = {
|
|
|
kind: "advantage",
|
|
@@ -28,28 +28,30 @@ type Advantage = {
|
|
|
type Game = {
|
|
|
kind: "game",
|
|
|
player: Player
|
|
|
- // otherPlayerPoints: ? Not representable here.
|
|
|
+ // otherPlayerPoint: ? Not representable here.
|
|
|
};
|
|
|
type Score = Deuce | PointsData | FortyData | Advantage | Game;
|
|
|
|
|
|
-function scoreWhenDeuce(player: Player): Advantage {
|
|
|
+// Add the ignored _score parameter to ensure a type check.
|
|
|
+function scoreWhenDeuce(_score: Deuce, player: Player): Advantage {
|
|
|
return {
|
|
|
kind: "advantage",
|
|
|
- player,
|
|
|
- }
|
|
|
+ player
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
function scoreWhenAdvantage(score: Advantage, player: Player): Game | Deuce {
|
|
|
- return score.player.kind === player.kind ? {
|
|
|
- kind: "game",
|
|
|
- player,
|
|
|
- } :
|
|
|
- {
|
|
|
- kind: "deuce",
|
|
|
- };
|
|
|
+ return score.player.kind === player.kind ?
|
|
|
+ {
|
|
|
+ kind: "game",
|
|
|
+ player: score.player // == player.
|
|
|
+ } :
|
|
|
+ {
|
|
|
+ kind: "deuce"
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
-function incrementPoints(point: Point): "15" | "30" | undefined {
|
|
|
+function incrementPoint(point: Point): "15" | "30" | undefined {
|
|
|
switch (point) {
|
|
|
case "love":
|
|
|
return "15";
|
|
@@ -64,15 +66,14 @@ function scoreWhenForty(score: FortyData, player: Player): Game | Deuce | FortyD
|
|
|
if (score.player.kind === player.kind) {
|
|
|
return {
|
|
|
kind: "game",
|
|
|
- player,
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
+ player: player
|
|
|
+ };
|
|
|
+ } else {
|
|
|
// "15" | "30" | undefined is a subset of Point | undefined
|
|
|
- const newPoints: Point | undefined = incrementPoints(score.otherPlayerPoints);
|
|
|
- return newPoints === undefined ?
|
|
|
+ const newPoints: Point | undefined = incrementPoint(score.otherPlayerPoint);
|
|
|
+ return (newPoints === undefined) ?
|
|
|
{ kind: "deuce" } :
|
|
|
- { ...score, otherPlayerPoints: newPoints };
|
|
|
+ {...score, otherPlayerPoint: newPoints};
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -81,9 +82,9 @@ function updatePointsData(score: PointsData, newPoints: Point, player: Player):
|
|
|
// union, and the switch the typeGuard.
|
|
|
switch (player.kind) {
|
|
|
case "playerOne":
|
|
|
- return { ...score, playerOnePoint: newPoints };
|
|
|
+ return {...score, playerOnePoint: newPoints};
|
|
|
case "playerTwo":
|
|
|
- return { ...score, playerTwoPoint: newPoints };
|
|
|
+ return {...score, playerTwoPoint: newPoints};
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -95,27 +96,28 @@ function createFortyData(score: PointsData, player: Player): FortyData {
|
|
|
return {
|
|
|
kind: "forty",
|
|
|
player,
|
|
|
- otherPlayerPoints: otherPlayerPoint,
|
|
|
- }
|
|
|
+ otherPlayerPoint
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
function scoreWhenPoints(score: PointsData, player: Player): PointsData | FortyData {
|
|
|
- const newPoints: Point | undefined = player.kind === "playerOne"
|
|
|
- ? incrementPoints(score.playerOnePoint)
|
|
|
- : incrementPoints(score.playerTwoPoint);
|
|
|
- return (newPoints === undefined)
|
|
|
- ? createFortyData(score, player)
|
|
|
- : updatePointsData(score, newPoints, player);
|
|
|
+ const newPoints: Point | undefined = player.kind === "playerOne" ?
|
|
|
+ incrementPoint(score.playerOnePoint) :
|
|
|
+ incrementPoint(score.playerTwoPoint);
|
|
|
+ return newPoints === undefined ?
|
|
|
+ createFortyData(score, player) :
|
|
|
+ updatePointsData(score, newPoints, player);
|
|
|
}
|
|
|
|
|
|
function score(score: Score, player: Player): Score {
|
|
|
+ // XXX: refactor to avoid the switch and just use a method map.
|
|
|
switch (score.kind) {
|
|
|
case "points":
|
|
|
return scoreWhenPoints(score, player);
|
|
|
case "forty":
|
|
|
return scoreWhenForty(score, player);
|
|
|
case "deuce":
|
|
|
- return scoreWhenDeuce(player);
|
|
|
+ return scoreWhenDeuce(score, player);
|
|
|
case "advantage":
|
|
|
return scoreWhenAdvantage(score, player);
|
|
|
case "game":
|