1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- type PlayerOne = {
- kind: "playerOne";
- name: string;
- };
- type PlayerTwo = {
- kind: "playerTwo";
- name: string;
- };
- type Player = PlayerOne | PlayerTwo;
- type Point = "love" | "15" | "30";
- type Deuce = {
- kind: "deuce";
- };
- type PointsData = {
- kind: "points";
- playerOnePoint: Point;
- playerTwoPoint: Point;
- };
- type FortyData = {
- kind: "forty";
- player: Player;
- otherPlayerPoint: Point;
- };
- type Advantage = {
- kind: "advantage",
- player: Player
- };
- type Game = {
- kind: "game",
- player: Player
- // otherPlayerPoint: ? Not representable here.
- };
- type Score = Deuce | PointsData | FortyData | Advantage | Game;
- function scoreWhenDeuce(player: Player): Advantage {
- return {
- kind: "advantage",
- player,
- }
- }
- function scoreWhenAdvantage(score: Advantage, player: Player): Game | Deuce {
- return score.player.kind === player.kind ? {
- kind: "game",
- player,
- } :
- {
- kind: "deuce",
- };
- }
- function incrementPoints(point: Point): "15" | "30" | undefined {
- switch (point) {
- case "love":
- return "15";
- case "15":
- return "30";
- case "30":
- return undefined;
- }
- }
- function scoreWhenForty(score: FortyData, player: Player): Game | Deuce | FortyData {
- if (score.player.kind === player.kind) {
- return {
- kind: "game",
- player,
- }
- }
- else {
- // "15" | "30" | undefined is a subset of Point | undefined
- const newPoints: Point | undefined = incrementPoints(score.otherPlayerPoint);
- return newPoints === undefined ?
- { kind: "deuce" } :
- { ...score, otherPlayerPoint: newPoints };
- }
- }
|