trucoshi 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +3 -2
  2. package/build/lib/classes/Hand.js +87 -29
  3. package/build/lib/classes/Match.d.ts +2 -2
  4. package/build/lib/classes/Match.js +2 -3
  5. package/build/lib/classes/Play.js +6 -12
  6. package/build/lib/classes/Player.js +12 -0
  7. package/build/lib/classes/Round.d.ts +1 -1
  8. package/build/lib/classes/Round.js +5 -1
  9. package/build/lib/classes/Table.d.ts +2 -2
  10. package/build/lib/classes/Table.js +3 -10
  11. package/build/lib/classes/Team.js +8 -0
  12. package/build/lib/classes/Truco.d.ts +2 -0
  13. package/build/lib/classes/Truco.js +110 -0
  14. package/build/lib/constants.d.ts +6 -0
  15. package/build/lib/constants.js +8 -1
  16. package/build/lib/index.d.ts +13 -6
  17. package/build/lib/index.js +83 -10
  18. package/build/lib/types.d.ts +50 -5
  19. package/build/lib/types.js +2 -0
  20. package/build/lib/utils.d.ts +2 -2
  21. package/build/lib/utils.js +1 -18
  22. package/build/server/match.d.ts +0 -0
  23. package/build/server/match.js +1 -0
  24. package/build/test/autoplay.js +11 -2
  25. package/build/test/play.js +70 -51
  26. package/package.json +1 -1
  27. package/src/lib/classes/Hand.ts +82 -26
  28. package/src/lib/classes/Match.ts +3 -4
  29. package/src/lib/classes/Play.ts +9 -17
  30. package/src/lib/classes/Player.ts +13 -1
  31. package/src/lib/classes/Round.ts +5 -1
  32. package/src/lib/classes/Table.ts +8 -13
  33. package/src/lib/classes/Team.ts +7 -0
  34. package/src/lib/classes/Truco.ts +72 -0
  35. package/src/lib/constants.ts +8 -0
  36. package/src/lib/index.ts +95 -17
  37. package/src/lib/types.ts +51 -5
  38. package/src/lib/utils.ts +1 -22
  39. package/src/server/match.ts +0 -0
  40. package/src/test/autoplay.ts +12 -2
  41. package/src/test/play.ts +64 -55
@@ -6,17 +6,18 @@ import {
6
6
  IHand,
7
7
  IHandCommands,
8
8
  IMatch,
9
- IPlayer,
10
9
  } from "../types"
11
10
  import { checkHandWinner } from "../utils"
12
11
  import { PlayInstance } from "./Play"
13
12
  import { Round } from "./Round"
13
+ import { Truco } from "./Truco"
14
14
 
15
15
  export function Hand(match: IMatch, deck: IDeck, idx: number) {
16
16
  match.teams.forEach((team) => {
17
17
  team.players.forEach((player) => {
18
18
  const playerHand = [deck.takeCard(), deck.takeCard(), deck.takeCard()]
19
19
  player.setHand(playerHand)
20
+ player.enable()
20
21
  // player.setHand(["5c", "4c", "6c"])
21
22
  })
22
23
  })
@@ -26,9 +27,7 @@ export function Hand(match: IMatch, deck: IDeck, idx: number) {
26
27
  let forehandTeamIdx = match.table.player(hand.turn).teamIdx as 0 | 1
27
28
 
28
29
  while (currentRoundIdx < 3 && !hand.finished()) {
29
- let i = 0
30
-
31
- const round = Round()
30
+ const round = Round(0)
32
31
  hand.setCurrentRound(round)
33
32
  hand.pushRound(round)
34
33
 
@@ -42,30 +41,45 @@ export function Hand(match: IMatch, deck: IDeck, idx: number) {
42
41
  }
43
42
  }
44
43
 
45
- while (i < match.table.players.length) {
44
+ while (round.turn < match.table.players.length) {
45
+
46
+ while (hand.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
47
+ const { value } = hand.truco.getNextPlayer()
48
+ if (value && value.currentPlayer) {
49
+ console.log({ value: value.currentPlayer })
50
+ hand.setCurrentPlayer(value.currentPlayer)
51
+ yield hand
52
+ }
53
+ }
54
+
46
55
  const player = match.table.player(hand.turn)
47
56
  hand.setCurrentPlayer(player)
48
- if (hand.disabledPlayerIds.includes(player.id)) {
57
+ if (player.disabled) {
49
58
  hand.setCurrentPlayer(null)
50
59
  }
51
60
 
52
- if (hand.turn >= match.table.players.length - 1) {
53
- hand.setTurn(0)
54
- } else {
55
- hand.setTurn(hand.turn + 1)
56
- }
57
-
58
- i++
59
-
60
61
  yield hand
61
62
  }
62
63
 
63
- const teamIdx = checkHandWinner(hand.rounds, forehandTeamIdx, hand.disabledPlayerIds, match.teams)
64
+ if (match.teams[0].isTeamDisabled() && match.teams[1].isTeamDisabled()) {
65
+ hand.setState(EHandState.FINISHED)
66
+ break
67
+ }
68
+
69
+ let winnerTeamIdx = checkHandWinner(hand.rounds, forehandTeamIdx)
70
+
71
+ if (match.teams[0].isTeamDisabled()) {
72
+ winnerTeamIdx = 1
73
+ }
74
+ if (match.teams[1].isTeamDisabled()) {
75
+ winnerTeamIdx = 0
76
+ }
64
77
 
65
- if (teamIdx !== null) {
66
- hand.addPoints(teamIdx, hand.truco.state)
78
+ if (winnerTeamIdx !== null) {
79
+ hand.addPoints(winnerTeamIdx, hand.truco.state)
67
80
  hand.setState(EHandState.FINISHED)
68
81
  }
82
+
69
83
  currentRoundIdx++
70
84
  }
71
85
  yield hand
@@ -81,6 +95,19 @@ export function Hand(match: IMatch, deck: IDeck, idx: number) {
81
95
  const { teamIdx } = hand.truco
82
96
  if (teamIdx === null || teamIdx !== player.teamIdx) {
83
97
  hand.setState(EHandState.WAITING_FOR_TRUCO_ANSWER)
98
+ hand.truco.sayTruco(player.teamIdx as 0 | 1, match.teams[Number(!player.teamIdx)].players)
99
+ }
100
+ },
101
+ [ESayCommand.QUIERO]: () => {
102
+ if (hand.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
103
+ hand.truco.setAnswer(true)
104
+ hand.setState(EHandState.WAITING_PLAY)
105
+ }
106
+ },
107
+ [ESayCommand.NO_QUIERO]: (player) => {
108
+ if (hand.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
109
+ hand.truco.setAnswer(false)
110
+ hand.setState(EHandState.WAITING_PLAY)
84
111
  }
85
112
  },
86
113
  [ESayCommand.FLOR]: () => {},
@@ -96,28 +123,57 @@ export function Hand(match: IMatch, deck: IDeck, idx: number) {
96
123
  turn: Number(match.table.forehandIdx),
97
124
  state: EHandState.WAITING_PLAY,
98
125
  rounds: [],
99
- truco: {
100
- state: 1,
101
- teamIdx: null,
102
- },
126
+ truco: Truco(),
103
127
  envido: {
104
128
  accept: 1,
105
129
  decline: 2,
106
130
  teamIdx: null,
107
131
  },
108
132
  points: [0, 0],
109
- disabledPlayerIds: [],
110
133
  currentRound: null,
111
- currentPlayer: null,
134
+ _currentPlayer: null,
135
+ set currentPlayer(player) {
136
+ hand._currentPlayer = player
137
+ },
138
+ get currentPlayer() {
139
+ if (hand.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
140
+ return hand.truco.currentPlayer
141
+ }
142
+ return hand._currentPlayer
143
+ },
112
144
  commands,
113
145
  play() {
114
146
  return PlayInstance(hand, match.teams)
115
147
  },
148
+ use(idx: number) {
149
+ const player = hand.currentPlayer
150
+ const round = hand.currentRound
151
+ if (!player || !round) {
152
+ return null
153
+ }
154
+
155
+ const card = player.useCard(idx)
156
+ if (card) {
157
+ hand.nextTurn()
158
+ return round.use({ player, card })
159
+ }
160
+
161
+ return null
162
+ },
163
+ nextTurn() {
164
+ if (hand.turn >= match.table.players.length - 1) {
165
+ hand.setTurn(0)
166
+ } else {
167
+ hand.setTurn(hand.turn + 1)
168
+ }
169
+
170
+ hand.currentRound?.nextTurn()
171
+ },
116
172
  getNextPlayer() {
117
173
  return roundsGenerator.next()
118
174
  },
119
175
  disablePlayer(player) {
120
- hand.disabledPlayerIds.push(player.id)
176
+ match.teams[player.teamIdx].disable(player)
121
177
  },
122
178
  addPoints(team, points) {
123
179
  hand.points[team] = hand.points[team] + points
@@ -135,8 +191,8 @@ export function Hand(match: IMatch, deck: IDeck, idx: number) {
135
191
  return hand.currentRound
136
192
  },
137
193
  setCurrentPlayer(player) {
138
- hand.currentPlayer = player
139
- return hand.currentPlayer
194
+ hand._currentPlayer = player
195
+ return hand._currentPlayer
140
196
  },
141
197
  setState(state) {
142
198
  hand.state = state
@@ -1,9 +1,8 @@
1
- import { IHand, IMatch, ITeam } from "../types"
1
+ import { IHand, IMatch, ITable, ITeam } from "../types"
2
2
  import { Deck } from "./Deck"
3
3
  import { Hand } from "./Hand"
4
- import { Table } from "./Table"
5
4
 
6
- export function Match(teams: Array<ITeam> = [], matchPoint: number = 9): IMatch {
5
+ export function Match(table: ITable, teams: Array<ITeam> = [], matchPoint: number = 9): IMatch {
7
6
  const deck = Deck().shuffle()
8
7
 
9
8
  const size = teams[0].players.length
@@ -47,7 +46,7 @@ export function Match(teams: Array<ITeam> = [], matchPoint: number = 9): IMatch
47
46
  winner: null,
48
47
  teams: teams as [ITeam, ITeam],
49
48
  hands: [],
50
- table: Table(teams, size),
49
+ table,
51
50
  currentHand: null,
52
51
  play() {
53
52
  match.getNextTurn()
@@ -1,7 +1,6 @@
1
- import { EEnvidoCommand, ESayCommand, IHand, IPlayInstance, ITeam } from "../types"
1
+ import { EEnvidoCommand, EHandState, ESayCommand, IHand, IPlayInstance, ITeam } from "../types"
2
2
 
3
3
  export function PlayInstance(hand: IHand, teams: [ITeam, ITeam]) {
4
-
5
4
  const instance: IPlayInstance = {
6
5
  state: hand.state,
7
6
  teams,
@@ -13,30 +12,19 @@ export function PlayInstance(hand: IHand, teams: [ITeam, ITeam]) {
13
12
  commands: [],
14
13
  rounds: hand.rounds,
15
14
  use(idx) {
16
- const player = hand.currentPlayer
17
- const round = hand.currentRound
18
- if (!player || !round) {
19
- return null
20
- }
21
-
22
- const card = player.useCard(idx)
23
- if (card) {
24
- return round.use({ player, card })
25
- }
26
-
27
- return null
15
+ return hand.use(idx)
28
16
  },
29
17
  say(command) {
30
- if (!hand.currentPlayer || !instance.commands?.includes(command)) {
18
+ if (!hand._currentPlayer || !instance.commands?.includes(command)) {
31
19
  return null
32
20
  }
33
21
 
34
- hand.commands[command](hand.currentPlayer)
22
+ hand.commands[command](hand._currentPlayer)
35
23
 
36
24
  return command
37
25
  },
38
26
  }
39
-
27
+
40
28
  instance.commands?.push(ESayCommand.MAZO)
41
29
  instance.commands?.push(ESayCommand.TRUCO)
42
30
 
@@ -44,5 +32,9 @@ export function PlayInstance(hand: IHand, teams: [ITeam, ITeam]) {
44
32
  instance.commands?.push(EEnvidoCommand.ENVIDO)
45
33
  }
46
34
 
35
+ if (hand.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
36
+ instance.commands = [ESayCommand.TRUCO, ESayCommand.QUIERO, ESayCommand.NO_QUIERO]
37
+ }
38
+
47
39
  return instance
48
40
  }
@@ -1,11 +1,23 @@
1
- import { ICard, IPlayer } from "../types"
1
+ import { IPlayer } from "../types"
2
2
 
3
3
  export function Player(id: string, teamIdx: number) {
4
4
  const player: IPlayer = {
5
5
  id,
6
6
  teamIdx,
7
7
  hand: [],
8
+ commands: [],
8
9
  usedHand: [],
10
+ disabled: false,
11
+ ready: false,
12
+ enable() {
13
+ player.disabled = false
14
+ },
15
+ disable() {
16
+ player.disabled = true
17
+ },
18
+ setReady(ready) {
19
+ player.ready = ready
20
+ },
9
21
  setHand(hand) {
10
22
  player.hand = hand
11
23
  player.usedHand = []
@@ -1,12 +1,16 @@
1
1
  import { IRound } from "../types"
2
2
  import { getCardValue } from "../utils"
3
3
 
4
- export function Round(): IRound {
4
+ export function Round(turn: number): IRound {
5
5
  const round: IRound = {
6
+ turn,
6
7
  highest: -1,
7
8
  winner: null,
8
9
  cards: [],
9
10
  tie: false,
11
+ nextTurn() {
12
+ round.turn++
13
+ },
10
14
  use({ card, player }) {
11
15
  const value = getCardValue(card)
12
16
  if (value === round.highest && player.teamIdx !== round.winner?.teamIdx) {
@@ -1,12 +1,16 @@
1
- import { ITable, ITeam } from "../types"
1
+ import { GAME_ERROR, TEAM_SIZE_VALUES } from "../constants"
2
+ import { IPlayer, ITable, ITeam } from "../types"
3
+ import { Match } from "./Match"
4
+ import { Player } from "./Player"
5
+ import { Team } from "./Team"
2
6
 
3
- export function Table(teams: Array<ITeam>, size: number): ITable {
7
+ export function Table(players: Array<IPlayer>, teams: Array<ITeam>): ITable {
4
8
  const table: ITable = {
5
- players: [],
9
+ players,
6
10
  cards: [],
7
11
  forehandIdx: 0,
8
12
  nextTurn() {
9
- if (table.forehandIdx < size * 2 - 1) {
13
+ if (table.forehandIdx < table.players.length - 1) {
10
14
  table.forehandIdx++
11
15
  } else {
12
16
  table.forehandIdx = 0
@@ -24,14 +28,5 @@ export function Table(teams: Array<ITeam>, size: number): ITable {
24
28
  },
25
29
  }
26
30
 
27
- if (teams[0].players.length != size || teams[1].players.length != size) {
28
- throw new Error("Unexpected team size")
29
- }
30
-
31
- for (let i = 0; i < size; i++) {
32
- table.players.push(teams[0].players[i])
33
- table.players.push(teams[1].players[i])
34
- }
35
-
36
31
  return table
37
32
  }
@@ -11,6 +11,13 @@ export function Team(players: Array<IPlayer>) {
11
11
  malas: 0,
12
12
  winner: false,
13
13
  },
14
+ isTeamDisabled() {
15
+ return team.players.reduce((prev, curr) => prev && curr.disabled, true)
16
+ },
17
+ disable(player) {
18
+ team._players.get(player.id)?.disable()
19
+ return team.isTeamDisabled()
20
+ },
14
21
  addPoints(matchPoint, points) {
15
22
  const malas = team.points.malas + points
16
23
  const diff = malas - matchPoint
@@ -0,0 +1,72 @@
1
+ import { ITruco } from "../types"
2
+
3
+ export function Truco() {
4
+ function* trucoAnswerGeneratorSequence() {
5
+ let i = 0
6
+ while (i < truco.players.length && truco.answer === null) {
7
+ const player = truco.players[truco.turn]
8
+ truco.setCurrentPlayer(player)
9
+ if (player.disabled) {
10
+ truco.setCurrentPlayer(null)
11
+ }
12
+
13
+ if (truco.turn >= truco.players.length - 1) {
14
+ truco.setTurn(0)
15
+ } else {
16
+ truco.setTurn(truco.turn + 1)
17
+ }
18
+
19
+ i++
20
+
21
+ yield truco
22
+ }
23
+ yield truco
24
+ }
25
+
26
+ const truco: ITruco = {
27
+ turn: 0,
28
+ state: 1,
29
+ teamIdx: null,
30
+ answer: null,
31
+ currentPlayer: null,
32
+ generator: trucoAnswerGeneratorSequence(),
33
+ players: [],
34
+ sayTruco(teamIdx, players) {
35
+ truco.teamIdx = teamIdx
36
+ truco.answer = null
37
+ truco.players = players
38
+ truco.generator = trucoAnswerGeneratorSequence()
39
+ return truco
40
+ },
41
+ setPlayers(players) {
42
+ truco.players = players
43
+ },
44
+ setAnswer(answer) {
45
+ if (answer) {
46
+ truco.state++
47
+ }
48
+ if (answer !== null) {
49
+ truco.teamIdx = null
50
+ }
51
+ truco.answer = answer
52
+ return truco
53
+ },
54
+ setTeam(idx: 0 | 1) {
55
+ truco.teamIdx = idx
56
+ return truco.teamIdx
57
+ },
58
+ setTurn(turn) {
59
+ truco.turn = turn
60
+ return truco.turn
61
+ },
62
+ setCurrentPlayer(player) {
63
+ truco.currentPlayer = player
64
+ return truco.currentPlayer
65
+ },
66
+ getNextPlayer() {
67
+ return truco.generator.next()
68
+ },
69
+ }
70
+
71
+ return truco
72
+ }
@@ -62,6 +62,14 @@ export const COLORS = [
62
62
  "#c2185b",
63
63
  ]
64
64
 
65
+ export const TEAM_SIZE_VALUES = [1, 2, 3]
66
+
67
+ export enum GAME_ERROR {
68
+ UNEXPECTED_TEAM_SIZE = 'UNEXPECTED_TEAM_SIZE',
69
+ TEAM_NOT_READY = 'TEAM_NOT_READY',
70
+ TEAM_IS_FULL = 'TEAM_IS_FULL',
71
+ }
72
+
65
73
  export const EnvidoCalculator: IEnvidoCalculator = {
66
74
  [EEnvidoCommand.ENVIDO]: () => ({
67
75
  accept: 2,
package/src/lib/index.ts CHANGED
@@ -1,23 +1,33 @@
1
1
  import { Match } from "./classes/Match"
2
2
  import { Player } from "./classes/Player"
3
+ import { Table } from "./classes/Table"
3
4
  import { Team } from "./classes/Team"
4
- import { IMatch, IPlayInstance, ITeam } from "./types"
5
+ import { GAME_ERROR, TEAM_SIZE_VALUES } from "./constants"
6
+ import { EHandState, IMatch, IPlayInstance, IPrivateTrucoshi, ITeam, ITrucoshi } from "./types"
5
7
 
6
8
  export type IWinnerCallback = (winner: ITeam, teams: [ITeam, ITeam]) => Promise<void>
7
- export type ITurnCallback = (match: IPlayInstance) => Promise<void>
9
+ export type ITurnCallback = (play: IPlayInstance) => Promise<void>
10
+ export type ITrucoCallback = (play: IPlayInstance) => Promise<void>
8
11
 
9
12
  export interface IGameLoop {
10
- _onTurn: (match: IPlayInstance) => Promise<void>
11
- _onWinner: (winner: ITeam, teams: [ITeam, ITeam]) => Promise<void>
13
+ _onTruco: ITrucoCallback
14
+ _onTurn: ITurnCallback
15
+ _onWinner: IWinnerCallback
12
16
  onTurn: (callback: ITurnCallback) => IGameLoop
13
17
  onWinner: (callback: IWinnerCallback) => IGameLoop
14
- start: () => void
18
+ onTruco: (callback: ITrucoCallback) => IGameLoop
19
+ begin: () => void
15
20
  }
16
21
 
17
22
  const GameLoop = (match: IMatch) => {
18
23
  let gameloop: IGameLoop = {
24
+ _onTruco: () => Promise.resolve(),
19
25
  _onTurn: () => Promise.resolve(),
20
26
  _onWinner: () => Promise.resolve(),
27
+ onTruco: (callback: ITrucoCallback) => {
28
+ gameloop._onTruco = callback
29
+ return gameloop
30
+ },
21
31
  onTurn: (callback: ITurnCallback) => {
22
32
  gameloop._onTurn = callback
23
33
  return gameloop
@@ -26,7 +36,7 @@ const GameLoop = (match: IMatch) => {
26
36
  gameloop._onWinner = callback
27
37
  return gameloop
28
38
  },
29
- async start() {
39
+ async begin() {
30
40
  while (!match.winner) {
31
41
  const play = match.play()
32
42
 
@@ -34,7 +44,15 @@ const GameLoop = (match: IMatch) => {
34
44
  continue
35
45
  }
36
46
 
37
- await gameloop._onTurn(play)
47
+ if (play.state === EHandState.WAITING_FOR_TRUCO_ANSWER) {
48
+ await gameloop._onTruco(play)
49
+ continue
50
+ }
51
+
52
+ if (play.state === EHandState.WAITING_PLAY) {
53
+ await gameloop._onTurn(play)
54
+ continue
55
+ }
38
56
  }
39
57
 
40
58
  await gameloop._onWinner(match.winner, match.teams)
@@ -44,14 +62,74 @@ const GameLoop = (match: IMatch) => {
44
62
  return gameloop
45
63
  }
46
64
 
47
- export function Trucoshi(
48
- idsTeam0: Array<string>,
49
- idsTeam1: Array<string>,
50
- matchPoint: 9 | 12 | 15
51
- ) {
52
- const teams = [
53
- Team(idsTeam0.map((id) => Player(id, 0))),
54
- Team(idsTeam1.map((id) => Player(id, 1))),
55
- ]
56
- return GameLoop(Match(teams, matchPoint))
65
+ export function Trucoshi(teamSize?: 1 | 2 | 3) {
66
+ const trucoshi: IPrivateTrucoshi = {
67
+ lastTeamIdx: 1,
68
+ _players: new Map(),
69
+ get players() {
70
+ return Array.from(trucoshi._players.values())
71
+ },
72
+ teams: [],
73
+ table: null,
74
+ maxPlayers: teamSize ? teamSize * 2 : 6,
75
+ full: false,
76
+ ready: false,
77
+ calculateReady() {
78
+ trucoshi.ready = trucoshi.players.reduce((prev, curr) => prev && curr.ready, true)
79
+ return trucoshi.ready
80
+ },
81
+ calculateFull() {
82
+ trucoshi.full = trucoshi._players.size >= trucoshi.maxPlayers
83
+ return trucoshi.full
84
+ },
85
+ addPlayer(id, teamIdx) {
86
+ const maxSize = teamSize ? teamSize : 3
87
+ if (trucoshi.full || trucoshi.players.filter((p) => p.teamIdx === teamIdx).length > maxSize) {
88
+ throw new Error(GAME_ERROR.TEAM_IS_FULL)
89
+ }
90
+ const player = Player(id, teamIdx !== undefined ? teamIdx : Number(!trucoshi.lastTeamIdx))
91
+ trucoshi.lastTeamIdx = Number(!trucoshi.lastTeamIdx) as 0 | 1
92
+ trucoshi._players.set(id, player)
93
+ trucoshi.calculateFull()
94
+ trucoshi.calculateReady()
95
+ return player
96
+ },
97
+ removePlayer(id) {
98
+ trucoshi._players.delete(id)
99
+ trucoshi.calculateFull()
100
+ trucoshi.calculateReady()
101
+ return trucoshi
102
+ },
103
+ startMatch(matchPoint = 9) {
104
+ trucoshi.calculateReady()
105
+ const teamSize = trucoshi._players.size / 2
106
+
107
+ if (!TEAM_SIZE_VALUES.includes(teamSize)) {
108
+ throw new Error(GAME_ERROR.UNEXPECTED_TEAM_SIZE)
109
+ }
110
+
111
+ if (!trucoshi.ready) {
112
+ throw new Error(GAME_ERROR.TEAM_NOT_READY)
113
+ }
114
+
115
+ trucoshi.teams.push(Team(trucoshi.players.filter((p) => p.teamIdx === 0)))
116
+ trucoshi.teams.push(Team(trucoshi.players.filter((p) => p.teamIdx === 1)))
117
+
118
+ if (
119
+ trucoshi.teams[0].players.length !== teamSize ||
120
+ trucoshi.teams[1].players.length !== teamSize
121
+ ) {
122
+ throw new Error(GAME_ERROR.UNEXPECTED_TEAM_SIZE)
123
+ }
124
+
125
+ trucoshi.table = Table(trucoshi.players, trucoshi.teams)
126
+ return GameLoop(Match(trucoshi.table, trucoshi.teams, matchPoint))
127
+ },
128
+ }
129
+
130
+ return {
131
+ addPlayer: trucoshi.addPlayer,
132
+ removePlayer: trucoshi.removePlayer,
133
+ startMatch: trucoshi.startMatch,
134
+ }
57
135
  }