trucoshi 0.0.2 → 0.0.4
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.
- package/.prettierrc.json +4 -0
- package/LICENSE +674 -0
- package/README.md +36 -0
- package/build/lib/classes/Deck.d.ts +2 -0
- package/build/lib/classes/Deck.js +27 -0
- package/build/lib/classes/Hand.d.ts +2 -0
- package/build/lib/classes/Hand.js +175 -0
- package/build/lib/classes/Match.d.ts +2 -0
- package/build/lib/classes/Match.js +116 -0
- package/build/lib/classes/Play.d.ts +2 -0
- package/build/lib/classes/Play.js +45 -0
- package/build/lib/classes/Player.d.ts +2 -0
- package/build/lib/classes/Player.js +26 -0
- package/build/lib/classes/Round.d.ts +2 -0
- package/build/lib/classes/Round.js +29 -0
- package/build/lib/classes/Table.d.ts +2 -0
- package/build/lib/classes/Table.js +37 -0
- package/build/lib/classes/Team.d.ts +2 -0
- package/build/lib/classes/Team.js +34 -0
- package/build/lib/constants.d.ts +30 -28
- package/build/lib/constants.js +90 -12
- package/build/lib/index.d.ts +11 -0
- package/build/lib/index.js +88 -0
- package/build/lib/types.d.ts +75 -29
- package/build/lib/types.js +22 -12
- package/build/lib/utils.d.ts +3 -3
- package/build/lib/utils.js +29 -19
- package/build/server/index.js +13 -5
- package/build/server/types.d.ts +11 -0
- package/build/server/types.js +15 -0
- package/build/test/autoplay.js +43 -31
- package/build/test/play.js +127 -81
- package/package.json +5 -4
- package/src/lib/classes/Deck.ts +25 -0
- package/src/lib/classes/Hand.ts +151 -0
- package/src/lib/classes/Match.ts +80 -0
- package/src/lib/classes/Play.ts +48 -0
- package/src/lib/classes/Player.ts +25 -0
- package/src/lib/classes/Round.ts +26 -0
- package/src/lib/classes/Table.ts +37 -0
- package/src/lib/classes/Team.ts +34 -0
- package/src/lib/constants.ts +97 -11
- package/src/lib/index.ts +57 -0
- package/src/lib/types.ts +140 -80
- package/src/lib/utils.ts +70 -52
- package/src/server/index.ts +34 -22
- package/src/server/types.ts +12 -0
- package/src/test/autoplay.ts +47 -41
- package/src/test/play.ts +113 -70
- package/build/lib/trucoshi.d.ts +0 -10
- package/build/lib/trucoshi.js +0 -363
- package/build/test/legacy.d.ts +0 -1
- package/build/test/legacy.js +0 -146
- package/src/lib/trucoshi.ts +0 -342
- package/src/test/legacy.ts +0 -68
package/src/lib/constants.ts
CHANGED
|
@@ -1,14 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EEnvidoCommand,
|
|
3
|
+
ESayCommand,
|
|
4
|
+
IEnvidoCalculator,
|
|
5
|
+
IEnvidoCalculatorArgs,
|
|
6
|
+
ITeam,
|
|
7
|
+
TeamPoints,
|
|
8
|
+
} from "./types"
|
|
9
|
+
import { getMaxNumberIndex } from "./utils"
|
|
10
|
+
|
|
1
11
|
export const CARDS = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
"1e": 14,
|
|
13
|
+
"1b": 13,
|
|
14
|
+
"7e": 12,
|
|
15
|
+
"7o": 11,
|
|
16
|
+
"3e": 10,
|
|
17
|
+
"3o": 10,
|
|
18
|
+
"3b": 10,
|
|
19
|
+
"3c": 10,
|
|
20
|
+
"2e": 9,
|
|
21
|
+
"2o": 9,
|
|
22
|
+
"2b": 8,
|
|
23
|
+
"2c": 8,
|
|
24
|
+
"1o": 7,
|
|
25
|
+
"1c": 7,
|
|
26
|
+
re: 6,
|
|
27
|
+
ro: 6,
|
|
28
|
+
rb: 6,
|
|
29
|
+
rc: 6,
|
|
30
|
+
ce: 5,
|
|
31
|
+
co: 5,
|
|
32
|
+
cb: 5,
|
|
33
|
+
cc: 5,
|
|
34
|
+
pe: 4,
|
|
35
|
+
po: 4,
|
|
36
|
+
pb: 4,
|
|
37
|
+
pc: 4,
|
|
38
|
+
"7b": 3,
|
|
39
|
+
"7c": 3,
|
|
40
|
+
"6e": 2,
|
|
41
|
+
"6o": 2,
|
|
42
|
+
"6b": 2,
|
|
43
|
+
"6c": 2,
|
|
44
|
+
"5e": 1,
|
|
45
|
+
"5o": 1,
|
|
46
|
+
"5b": 1,
|
|
47
|
+
"5c": 1,
|
|
48
|
+
"4e": 0,
|
|
49
|
+
"4o": 0,
|
|
50
|
+
"4b": 0,
|
|
51
|
+
"4c": 0,
|
|
12
52
|
}
|
|
13
53
|
|
|
14
|
-
export const COLORS = [
|
|
54
|
+
export const COLORS = [
|
|
55
|
+
"#9b111",
|
|
56
|
+
"#17c6c6",
|
|
57
|
+
"#8c1d1d",
|
|
58
|
+
"#9f9b9b",
|
|
59
|
+
"#a5a5a5",
|
|
60
|
+
"#f5a623",
|
|
61
|
+
"#f44336",
|
|
62
|
+
"#c2185b",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
export const EnvidoCalculator: IEnvidoCalculator = {
|
|
66
|
+
[EEnvidoCommand.ENVIDO]: () => ({
|
|
67
|
+
accept: 2,
|
|
68
|
+
decline: 1,
|
|
69
|
+
next: [EEnvidoCommand.ENVIDO_ENVIDO, EEnvidoCommand.REAL_ENVIDO, EEnvidoCommand.FALTA_ENVIDO],
|
|
70
|
+
}),
|
|
71
|
+
[EEnvidoCommand.ENVIDO_ENVIDO]: () => ({
|
|
72
|
+
accept: 4,
|
|
73
|
+
decline: 2,
|
|
74
|
+
next: [EEnvidoCommand.REAL_ENVIDO, EEnvidoCommand.FALTA_ENVIDO],
|
|
75
|
+
}),
|
|
76
|
+
[EEnvidoCommand.REAL_ENVIDO]: () => ({
|
|
77
|
+
accept: 3,
|
|
78
|
+
decline: 1,
|
|
79
|
+
next: [EEnvidoCommand.FALTA_ENVIDO],
|
|
80
|
+
}),
|
|
81
|
+
[EEnvidoCommand.FALTA_ENVIDO]: (args) => {
|
|
82
|
+
if (!args || !args.teams || !args.matchPoint) {
|
|
83
|
+
return {
|
|
84
|
+
accept: 1,
|
|
85
|
+
decline: 1,
|
|
86
|
+
next: [],
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const { teams, matchPoint } = args
|
|
90
|
+
const totals = teams.map((team) => team.points.malas + team.points.buenas)
|
|
91
|
+
const higher = getMaxNumberIndex(totals)
|
|
92
|
+
const points = teams[higher].points
|
|
93
|
+
const accept = points.buenas > 0 ? matchPoint - points.buenas : matchPoint - points.malas
|
|
94
|
+
return {
|
|
95
|
+
accept,
|
|
96
|
+
decline: 2,
|
|
97
|
+
next: [],
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
}
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Match } from "./classes/Match"
|
|
2
|
+
import { Player } from "./classes/Player"
|
|
3
|
+
import { Team } from "./classes/Team"
|
|
4
|
+
import { IMatch, IPlayInstance, ITeam } from "./types"
|
|
5
|
+
|
|
6
|
+
export type IWinnerCallback = (winner: ITeam, teams: [ITeam, ITeam]) => Promise<void>
|
|
7
|
+
export type ITurnCallback = (match: IPlayInstance) => Promise<void>
|
|
8
|
+
|
|
9
|
+
export interface IGameLoop {
|
|
10
|
+
_onTurn: (match: IPlayInstance) => Promise<void>
|
|
11
|
+
_onWinner: (winner: ITeam, teams: [ITeam, ITeam]) => Promise<void>
|
|
12
|
+
onTurn: (callback: ITurnCallback) => IGameLoop
|
|
13
|
+
onWinner: (callback: IWinnerCallback) => IGameLoop
|
|
14
|
+
start: () => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const GameLoop = (match: IMatch) => {
|
|
18
|
+
let gameloop: IGameLoop = {
|
|
19
|
+
_onTurn: () => Promise.resolve(),
|
|
20
|
+
_onWinner: () => Promise.resolve(),
|
|
21
|
+
onTurn: (callback: ITurnCallback) => {
|
|
22
|
+
gameloop._onTurn = callback
|
|
23
|
+
return gameloop
|
|
24
|
+
},
|
|
25
|
+
onWinner: (callback: IWinnerCallback) => {
|
|
26
|
+
gameloop._onWinner = callback
|
|
27
|
+
return gameloop
|
|
28
|
+
},
|
|
29
|
+
async start() {
|
|
30
|
+
while (!match.winner) {
|
|
31
|
+
const play = match.play()
|
|
32
|
+
|
|
33
|
+
if (!play || !play.player) {
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await gameloop._onTurn(play)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await gameloop._onWinner(match.winner, match.teams)
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return gameloop
|
|
45
|
+
}
|
|
46
|
+
|
|
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))
|
|
57
|
+
}
|
package/src/lib/types.ts
CHANGED
|
@@ -3,108 +3,168 @@ import { CARDS } from "./constants"
|
|
|
3
3
|
export type ICard = keyof typeof CARDS
|
|
4
4
|
|
|
5
5
|
export interface IDeck {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
cards: Array<ICard>
|
|
7
|
+
usedCards: Array<ICard>
|
|
8
|
+
takeCard(): ICard
|
|
9
|
+
shuffle(): IDeck
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface IPlayedCard {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
player: IPlayer
|
|
14
|
+
card: ICard
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export interface IPlayer {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
teamIdx: number
|
|
19
|
+
id: string
|
|
20
|
+
hand: Array<ICard>
|
|
21
|
+
usedHand: Array<ICard>
|
|
22
|
+
setHand(hand: Array<ICard>): Array<ICard>
|
|
23
|
+
useCard(idx: number): ICard | null
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface ITeam {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
addPoints(points: number): number
|
|
27
|
+
_players: Map<string, IPlayer>
|
|
28
|
+
players: Array<IPlayer>
|
|
29
|
+
points: TeamPoints
|
|
30
|
+
addPoints(matchPoint: number, points: number): TeamPoints
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
export interface IMatch {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
34
|
+
teams: [ITeam, ITeam]
|
|
35
|
+
hands: Array<IHand>
|
|
36
|
+
winner: ITeam | null
|
|
37
|
+
currentHand: IHand | null
|
|
38
|
+
table: ITable
|
|
39
|
+
play(): IPlayInstance | null
|
|
40
|
+
addPoints(points: HandPoints): [ITeam, ITeam]
|
|
41
|
+
pushHand(hand: IHand): void
|
|
42
|
+
setCurrentHand(hand: IHand | null): IHand | null
|
|
43
|
+
setWinner(winner: ITeam): void
|
|
44
|
+
getNextTurn(): IteratorResult<IMatch | null, IMatch | null | void>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TeamPoints {
|
|
48
|
+
buenas: number
|
|
49
|
+
malas: number
|
|
50
|
+
winner: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface HandPoints {
|
|
54
|
+
0: number
|
|
55
|
+
1: number
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface RoundPoints {
|
|
59
|
+
0: number
|
|
60
|
+
1: number
|
|
61
|
+
ties: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export enum ESayCommand {
|
|
65
|
+
TRUCO = "TRUCO",
|
|
66
|
+
MAZO = "MAZO",
|
|
67
|
+
FLOR = "FLOR",
|
|
68
|
+
CONTRAFLOR = "CONTRAFLOR",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export enum EEnvidoCommand {
|
|
72
|
+
ENVIDO = "ENVIDO",
|
|
73
|
+
ENVIDO_ENVIDO = "ENVIDO_ENVIDO",
|
|
74
|
+
REAL_ENVIDO = "REAL_ENVIDO",
|
|
75
|
+
FALTA_ENVIDO = "FALTA_ENVIDO",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type ECommand = ESayCommand | EEnvidoCommand
|
|
79
|
+
|
|
80
|
+
export interface TrucoState {
|
|
81
|
+
state: 1 | 2 | 3 | 4
|
|
82
|
+
teamIdx: 0 | 1 | null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface EnvidoState {
|
|
86
|
+
accept: number
|
|
87
|
+
decline: number
|
|
88
|
+
teamIdx: 0 | 1 | null
|
|
65
89
|
}
|
|
66
90
|
|
|
67
91
|
export interface IPlayInstance {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
teams: [ITeam, ITeam]
|
|
93
|
+
handIdx: number
|
|
94
|
+
roundIdx: number
|
|
95
|
+
state: EHandState
|
|
96
|
+
truco: TrucoState
|
|
97
|
+
envido: EnvidoState
|
|
98
|
+
player: IPlayer | null
|
|
99
|
+
commands: Array<ECommand> | null
|
|
100
|
+
rounds: Array<IRound> | null
|
|
101
|
+
use(idx: number): ICard | null
|
|
102
|
+
say(command: ECommand): ECommand | null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export enum EHandState {
|
|
106
|
+
WAITING_PLAY = "WAITING_PLAY",
|
|
107
|
+
WAITING_FOR_TRUCO_ANSWER = "WAITING_FOR_TRUCO_ANSWER",
|
|
108
|
+
WAITING_ENVIDO_ANSWER = "WAITING_ENVIDO_ANSWER",
|
|
109
|
+
FINISHED = "FINISHED",
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type IHandCommands = {
|
|
113
|
+
[key in ECommand]: (player: IPlayer) => void
|
|
75
114
|
}
|
|
76
115
|
|
|
77
116
|
export interface IHand {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
117
|
+
idx: number
|
|
118
|
+
state: EHandState
|
|
119
|
+
turn: number
|
|
120
|
+
points: HandPoints
|
|
121
|
+
truco: TrucoState
|
|
122
|
+
envido: EnvidoState
|
|
123
|
+
rounds: Array<IRound>
|
|
124
|
+
currentPlayer: IPlayer | null
|
|
125
|
+
currentRound: IRound | null
|
|
126
|
+
disabledPlayerIds: Array<string>
|
|
127
|
+
commands: IHandCommands
|
|
128
|
+
finished: () => boolean
|
|
129
|
+
play(): IPlayInstance | null
|
|
130
|
+
pushRound(round: IRound): IRound
|
|
131
|
+
setTurn(turn: number): IPlayer
|
|
132
|
+
addPoints(team: 0 | 1, points: number): void
|
|
133
|
+
disablePlayer(player: IPlayer): void
|
|
134
|
+
setCurrentRound(round: IRound | null): IRound | null
|
|
135
|
+
setCurrentPlayer(player: IPlayer | null): IPlayer | null
|
|
136
|
+
setState(state: EHandState): EHandState
|
|
137
|
+
getNextPlayer(): IteratorResult<IHand, IHand | void>
|
|
93
138
|
}
|
|
94
139
|
|
|
95
140
|
export interface ITable {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
141
|
+
forehandIdx: number
|
|
142
|
+
cards: Array<Array<IPlayedCard>>
|
|
143
|
+
players: Array<IPlayer>
|
|
144
|
+
nextTurn(): IPlayer
|
|
145
|
+
player(idx?: number): IPlayer
|
|
146
|
+
getPlayerPosition(id: string): number
|
|
102
147
|
}
|
|
103
148
|
|
|
104
149
|
export interface IRound {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
150
|
+
tie: boolean
|
|
151
|
+
winner: IPlayer | null
|
|
152
|
+
highest: number
|
|
153
|
+
cards: Array<IPlayedCard>
|
|
154
|
+
use(playedCard: IPlayedCard): ICard
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export type IEnvidoCalculatorResult = {
|
|
158
|
+
accept: number
|
|
159
|
+
decline: number
|
|
160
|
+
next: Array<ECommand>
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export type IEnvidoCalculatorArgs = {
|
|
164
|
+
teams: [ITeam, ITeam]
|
|
165
|
+
matchPoint: number
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export type IEnvidoCalculator = {
|
|
169
|
+
[key in EEnvidoCommand]: (args?: IEnvidoCalculatorArgs) => IEnvidoCalculatorResult
|
|
110
170
|
}
|
package/src/lib/utils.ts
CHANGED
|
@@ -1,69 +1,87 @@
|
|
|
1
|
-
import { CARDS } from "./constants"
|
|
2
|
-
import { ICard,
|
|
1
|
+
import { CARDS } from "./constants"
|
|
2
|
+
import { ICard, IRound, ITeam, RoundPoints } from "./types"
|
|
3
|
+
|
|
4
|
+
export function getMaxNumberIndex<T = number>(array: Array<T>) {
|
|
5
|
+
return array.reduce((accumulator, current, index) => {
|
|
6
|
+
return current > array[accumulator] ? index : accumulator
|
|
7
|
+
}, 0)
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
export function getCardValue(card: ICard) {
|
|
5
|
-
|
|
11
|
+
return CARDS[card] || -1
|
|
6
12
|
}
|
|
7
13
|
|
|
8
|
-
export function shuffleArray<T =
|
|
9
|
-
|
|
14
|
+
export function shuffleArray<T = unknown>(array: Array<T>) {
|
|
15
|
+
let currentIndex = array.length,
|
|
16
|
+
randomIndex
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
18
|
+
while (currentIndex != 0) {
|
|
19
|
+
randomIndex = Math.floor(Math.random() * currentIndex)
|
|
20
|
+
currentIndex--
|
|
21
|
+
;[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]
|
|
22
|
+
}
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
return array as Array<T>
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
export function checkHandWinner(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
export function checkHandWinner(
|
|
28
|
+
rounds: Array<IRound>,
|
|
29
|
+
forehandTeamIdx: 0 | 1,
|
|
30
|
+
disabledPlayerIds: Array<string>,
|
|
31
|
+
teams: [ITeam, ITeam]
|
|
32
|
+
): null | 0 | 1 {
|
|
33
|
+
let winningTeamIdx = null
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (round.winner?.teamIdx === 0) {
|
|
37
|
-
roundsWon[0] += 1;
|
|
38
|
-
}
|
|
39
|
-
if (round.winner?.teamIdx === 1) {
|
|
40
|
-
roundsWon[1] += 1;
|
|
41
|
-
}
|
|
35
|
+
// End hand if all players in one team go MAZO
|
|
36
|
+
if (disabledPlayerIds.length) {
|
|
37
|
+
const disabledTeams = teams.map((team) => {
|
|
38
|
+
const forfeited = team.players.filter((player) => disabledPlayerIds.includes(player.id))
|
|
39
|
+
return forfeited.length === team.players.length
|
|
40
|
+
})
|
|
41
|
+
if (disabledTeams[0] && disabledTeams[1]) {
|
|
42
|
+
return forehandTeamIdx
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if ((roundsWon[0] > 2 && roundsWon[1] > 2) || (rounds.length > 2 && ties > 0)) {
|
|
47
|
-
return forehandTeamIdx
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (roundsWon[0] >= 2 && roundsWon[1] < 2) {
|
|
51
|
-
return 0
|
|
44
|
+
if (disabledTeams[0]) {
|
|
45
|
+
return 1
|
|
52
46
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return 1
|
|
47
|
+
if (disabledTeams[1]) {
|
|
48
|
+
return 0
|
|
56
49
|
}
|
|
50
|
+
}
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
const roundsWon: RoundPoints = {
|
|
53
|
+
0: 0,
|
|
54
|
+
1: 0,
|
|
55
|
+
ties: 0,
|
|
56
|
+
}
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
for (let i = 0; i < rounds.length; i++) {
|
|
59
|
+
const round = rounds[i]
|
|
60
|
+
if (round.tie) {
|
|
61
|
+
roundsWon[0] += 1
|
|
62
|
+
roundsWon[1] += 1
|
|
63
|
+
roundsWon.ties = roundsWon.ties + 1
|
|
64
|
+
continue
|
|
64
65
|
}
|
|
65
|
-
if (
|
|
66
|
-
|
|
66
|
+
if (round.winner?.teamIdx === 0) {
|
|
67
|
+
roundsWon[0] += 1
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
if (round.winner?.teamIdx === 1) {
|
|
70
|
+
roundsWon[1] += 1
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if ((roundsWon[0] > 2 && roundsWon[1] > 2) || (rounds.length > 2 && roundsWon.ties > 0)) {
|
|
75
|
+
return forehandTeamIdx
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (roundsWon[0] >= 2 && roundsWon[1] < 2) {
|
|
79
|
+
return 0
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (roundsWon[1] >= 2 && roundsWon[0] < 2) {
|
|
83
|
+
return 1
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null
|
|
69
87
|
}
|
package/src/server/index.ts
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import { createServer } from "http"
|
|
2
|
-
import { Server } from "socket.io"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import { createServer } from "http"
|
|
2
|
+
import { Server } from "socket.io"
|
|
3
|
+
import { EClientEvent, EServerEvent } from "./types"
|
|
4
|
+
|
|
5
|
+
const PORT = 4001
|
|
6
|
+
|
|
7
|
+
const httpServer = createServer()
|
|
8
|
+
const io = new Server(httpServer, {
|
|
9
|
+
cors: {
|
|
10
|
+
origin: "http://localhost:3000",
|
|
11
|
+
methods: ["GET", "POST"],
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const sessions = new Map<string, string>()
|
|
16
|
+
|
|
17
|
+
io.on("connection", (socket) => {
|
|
18
|
+
socket.on(EClientEvent.PING, (msg) => {
|
|
19
|
+
io.emit(EServerEvent.PONG, msg)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
socket.on(EClientEvent.CREATE_MATCH, (msg) => {
|
|
23
|
+
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
socket.on(EClientEvent.SET_PLAYER_ID, (msg) => {
|
|
27
|
+
if (typeof msg === 'string' && msg.length < 32) {
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
httpServer.listen(PORT)
|
|
33
|
+
|
|
34
|
+
console.log("Listening on port", PORT)
|
package/src/server/types.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export enum EClientEvent {
|
|
2
|
+
PING = "PING",
|
|
3
|
+
CREATE_MATCH = "CREATE_MATCH",
|
|
4
|
+
JOIN_MATCH = "JOIN_MATCH",
|
|
5
|
+
START_MATCH = "START_MATCH",
|
|
6
|
+
SET_PLAYER_ID = "SET_PLAYER_ID",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export enum EServerEvent {
|
|
10
|
+
SET_SESSION_ID = "SET_SESSION_ID",
|
|
11
|
+
PONG = "PONG",
|
|
12
|
+
}
|