trucoshi 0.0.4 → 0.0.6
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/README.md +3 -2
- package/build/lib/classes/Hand.js +87 -29
- package/build/lib/classes/Match.d.ts +2 -2
- package/build/lib/classes/Match.js +2 -3
- package/build/lib/classes/Play.js +6 -12
- package/build/lib/classes/Player.js +12 -0
- package/build/lib/classes/Round.d.ts +1 -1
- package/build/lib/classes/Round.js +5 -1
- package/build/lib/classes/Table.d.ts +2 -2
- package/build/lib/classes/Table.js +3 -10
- package/build/lib/classes/Team.js +8 -0
- package/build/lib/classes/Truco.d.ts +2 -0
- package/build/lib/classes/Truco.js +110 -0
- package/build/lib/constants.d.ts +6 -0
- package/build/lib/constants.js +8 -1
- package/build/lib/index.d.ts +13 -6
- package/build/lib/index.js +83 -10
- package/build/lib/types.d.ts +50 -5
- package/build/lib/types.js +2 -0
- package/build/lib/utils.d.ts +2 -2
- package/build/lib/utils.js +1 -18
- package/build/server/match.d.ts +0 -0
- package/build/server/match.js +1 -0
- package/build/test/autoplay.js +11 -2
- package/build/test/play.js +70 -51
- package/package.json +3 -2
- package/src/lib/classes/Hand.ts +82 -26
- package/src/lib/classes/Match.ts +3 -4
- package/src/lib/classes/Play.ts +9 -17
- package/src/lib/classes/Player.ts +13 -1
- package/src/lib/classes/Round.ts +5 -1
- package/src/lib/classes/Table.ts +8 -13
- package/src/lib/classes/Team.ts +7 -0
- package/src/lib/classes/Truco.ts +72 -0
- package/src/lib/constants.ts +8 -0
- package/src/lib/index.ts +95 -17
- package/src/lib/types.ts +51 -5
- package/src/lib/utils.ts +1 -22
- package/src/server/match.ts +0 -0
- package/src/test/autoplay.ts +12 -2
- package/src/test/play.ts +64 -55
package/src/lib/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IGameLoop } from "."
|
|
1
2
|
import { CARDS } from "./constants"
|
|
2
3
|
|
|
3
4
|
export type ICard = keyof typeof CARDS
|
|
@@ -18,7 +19,13 @@ export interface IPlayer {
|
|
|
18
19
|
teamIdx: number
|
|
19
20
|
id: string
|
|
20
21
|
hand: Array<ICard>
|
|
22
|
+
commands: Array<ECommand>
|
|
21
23
|
usedHand: Array<ICard>
|
|
24
|
+
disabled: boolean
|
|
25
|
+
ready: boolean
|
|
26
|
+
enable(): void
|
|
27
|
+
disable(): void
|
|
28
|
+
setReady(ready: boolean): void
|
|
22
29
|
setHand(hand: Array<ICard>): Array<ICard>
|
|
23
30
|
useCard(idx: number): ICard | null
|
|
24
31
|
}
|
|
@@ -27,6 +34,8 @@ export interface ITeam {
|
|
|
27
34
|
_players: Map<string, IPlayer>
|
|
28
35
|
players: Array<IPlayer>
|
|
29
36
|
points: TeamPoints
|
|
37
|
+
isTeamDisabled(): boolean
|
|
38
|
+
disable(player: IPlayer): boolean
|
|
30
39
|
addPoints(matchPoint: number, points: number): TeamPoints
|
|
31
40
|
}
|
|
32
41
|
|
|
@@ -62,6 +71,8 @@ export interface RoundPoints {
|
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
export enum ESayCommand {
|
|
74
|
+
QUIERO = "QUIERO",
|
|
75
|
+
NO_QUIERO = "NO_QUIERO",
|
|
65
76
|
TRUCO = "TRUCO",
|
|
66
77
|
MAZO = "MAZO",
|
|
67
78
|
FLOR = "FLOR",
|
|
@@ -77,9 +88,21 @@ export enum EEnvidoCommand {
|
|
|
77
88
|
|
|
78
89
|
export type ECommand = ESayCommand | EEnvidoCommand
|
|
79
90
|
|
|
80
|
-
export interface
|
|
91
|
+
export interface ITruco {
|
|
81
92
|
state: 1 | 2 | 3 | 4
|
|
82
93
|
teamIdx: 0 | 1 | null
|
|
94
|
+
answer: boolean | null
|
|
95
|
+
turn: number
|
|
96
|
+
players: Array<IPlayer>
|
|
97
|
+
currentPlayer: IPlayer | null
|
|
98
|
+
generator: Generator<ITruco, void, unknown>
|
|
99
|
+
sayTruco(teamIdx: 0 | 1, players: Array<IPlayer>): ITruco
|
|
100
|
+
setPlayers(players: Array<IPlayer>): void
|
|
101
|
+
setAnswer(answer: boolean | null): ITruco
|
|
102
|
+
setTurn(turn: number): number
|
|
103
|
+
setTeam(idx: 0 | 1): 0 | 1
|
|
104
|
+
setCurrentPlayer(player: IPlayer | null): IPlayer | null
|
|
105
|
+
getNextPlayer(): IteratorResult<ITruco, ITruco | void>
|
|
83
106
|
}
|
|
84
107
|
|
|
85
108
|
export interface EnvidoState {
|
|
@@ -93,7 +116,7 @@ export interface IPlayInstance {
|
|
|
93
116
|
handIdx: number
|
|
94
117
|
roundIdx: number
|
|
95
118
|
state: EHandState
|
|
96
|
-
truco:
|
|
119
|
+
truco: ITruco
|
|
97
120
|
envido: EnvidoState
|
|
98
121
|
player: IPlayer | null
|
|
99
122
|
commands: Array<ECommand> | null
|
|
@@ -118,15 +141,18 @@ export interface IHand {
|
|
|
118
141
|
state: EHandState
|
|
119
142
|
turn: number
|
|
120
143
|
points: HandPoints
|
|
121
|
-
truco:
|
|
144
|
+
truco: ITruco
|
|
122
145
|
envido: EnvidoState
|
|
123
146
|
rounds: Array<IRound>
|
|
124
|
-
|
|
147
|
+
_currentPlayer: IPlayer | null
|
|
148
|
+
get currentPlayer(): IPlayer | null
|
|
149
|
+
set currentPlayer(player: IPlayer | null)
|
|
125
150
|
currentRound: IRound | null
|
|
126
|
-
disabledPlayerIds: Array<string>
|
|
127
151
|
commands: IHandCommands
|
|
128
152
|
finished: () => boolean
|
|
129
153
|
play(): IPlayInstance | null
|
|
154
|
+
nextTurn(): void
|
|
155
|
+
use(idx: number): ICard | null
|
|
130
156
|
pushRound(round: IRound): IRound
|
|
131
157
|
setTurn(turn: number): IPlayer
|
|
132
158
|
addPoints(team: 0 | 1, points: number): void
|
|
@@ -137,6 +163,24 @@ export interface IHand {
|
|
|
137
163
|
getNextPlayer(): IteratorResult<IHand, IHand | void>
|
|
138
164
|
}
|
|
139
165
|
|
|
166
|
+
export interface IPrivateTrucoshi {
|
|
167
|
+
lastTeamIdx: 0 | 1
|
|
168
|
+
_players: Map<string, IPlayer>
|
|
169
|
+
get players(): Array<IPlayer>
|
|
170
|
+
teams: Array<ITeam>
|
|
171
|
+
maxPlayers: number
|
|
172
|
+
table: ITable | null
|
|
173
|
+
ready: boolean
|
|
174
|
+
full: boolean
|
|
175
|
+
addPlayer(id: string, teamIdx?: 0 | 1): IPlayer
|
|
176
|
+
removePlayer(id: string): ITrucoshi
|
|
177
|
+
calculateReady(): boolean
|
|
178
|
+
calculateFull(): boolean
|
|
179
|
+
startMatch(matchPoint?: 9 | 12 | 15): IGameLoop
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface ITrucoshi extends Pick<IPrivateTrucoshi, 'addPlayer' | 'removePlayer' | 'startMatch'> {}
|
|
183
|
+
|
|
140
184
|
export interface ITable {
|
|
141
185
|
forehandIdx: number
|
|
142
186
|
cards: Array<Array<IPlayedCard>>
|
|
@@ -151,6 +195,8 @@ export interface IRound {
|
|
|
151
195
|
winner: IPlayer | null
|
|
152
196
|
highest: number
|
|
153
197
|
cards: Array<IPlayedCard>
|
|
198
|
+
turn: number,
|
|
199
|
+
nextTurn(): void
|
|
154
200
|
use(playedCard: IPlayedCard): ICard
|
|
155
201
|
}
|
|
156
202
|
|
package/src/lib/utils.ts
CHANGED
|
@@ -26,29 +26,8 @@ export function shuffleArray<T = unknown>(array: Array<T>) {
|
|
|
26
26
|
|
|
27
27
|
export function checkHandWinner(
|
|
28
28
|
rounds: Array<IRound>,
|
|
29
|
-
forehandTeamIdx: 0 | 1
|
|
30
|
-
disabledPlayerIds: Array<string>,
|
|
31
|
-
teams: [ITeam, ITeam]
|
|
29
|
+
forehandTeamIdx: 0 | 1
|
|
32
30
|
): null | 0 | 1 {
|
|
33
|
-
let winningTeamIdx = null
|
|
34
|
-
|
|
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
|
|
43
|
-
}
|
|
44
|
-
if (disabledTeams[0]) {
|
|
45
|
-
return 1
|
|
46
|
-
}
|
|
47
|
-
if (disabledTeams[1]) {
|
|
48
|
-
return 0
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
31
|
const roundsWon: RoundPoints = {
|
|
53
32
|
0: 0,
|
|
54
33
|
1: 0,
|
|
File without changes
|
package/src/test/autoplay.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { Trucoshi } from "../lib"
|
|
2
2
|
import { IRound } from "../lib/types"
|
|
3
3
|
;(async () => {
|
|
4
|
-
|
|
4
|
+
const trucoshi = Trucoshi()
|
|
5
|
+
|
|
6
|
+
trucoshi.addPlayer("lukini").setReady(true)
|
|
7
|
+
trucoshi.addPlayer("denoph").setReady(true)
|
|
8
|
+
trucoshi.addPlayer("guada").setReady(true)
|
|
9
|
+
trucoshi.addPlayer("juli").setReady(true)
|
|
10
|
+
trucoshi.addPlayer("day").setReady(true)
|
|
11
|
+
trucoshi.addPlayer("fran").setReady(true)
|
|
12
|
+
|
|
13
|
+
trucoshi
|
|
14
|
+
.startMatch()
|
|
5
15
|
.onTurn(async (play) => {
|
|
6
16
|
if (!play.player) {
|
|
7
17
|
return
|
|
@@ -43,5 +53,5 @@ import { IRound } from "../lib/types"
|
|
|
43
53
|
)
|
|
44
54
|
console.log(`\nEquipo Ganador:${winner.players.map((p) => ` ${p.id}`)}`)
|
|
45
55
|
})
|
|
46
|
-
.
|
|
56
|
+
.begin()
|
|
47
57
|
})()
|
package/src/test/play.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as readline from "readline"
|
|
2
2
|
import { Trucoshi } from "../lib"
|
|
3
|
-
import {
|
|
3
|
+
import { IPlayInstance, IRound, ITeam } from "../lib/types"
|
|
4
4
|
|
|
5
5
|
const command = (
|
|
6
6
|
title: string,
|
|
@@ -29,9 +29,68 @@ const command = (
|
|
|
29
29
|
return promise
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
const playCommand = (play: IPlayInstance) =>
|
|
33
|
+
command(
|
|
34
|
+
`${play.player?.id} elije una carta [${play.player?.hand.map(
|
|
35
|
+
(_c, i) => i + 1
|
|
36
|
+
)}]: ${JSON.stringify(play.player?.hand)}\n`,
|
|
37
|
+
async (idx) => {
|
|
38
|
+
const playedCard = play.use(Number(idx) - 1)
|
|
39
|
+
if (!playedCard) {
|
|
40
|
+
return Promise.reject()
|
|
41
|
+
}
|
|
42
|
+
const handString = JSON.stringify(play.player?.hand)
|
|
43
|
+
console.log(`\n${handString}\nUsing ${playedCard}`)
|
|
44
|
+
console.log(
|
|
45
|
+
play.rounds && play.rounds.length
|
|
46
|
+
? play.rounds.map((round: IRound) =>
|
|
47
|
+
round.cards.length ? round.cards.map((c) => [c.player.id, c.card]) : ""
|
|
48
|
+
)
|
|
49
|
+
: ""
|
|
50
|
+
)
|
|
51
|
+
return Promise.resolve()
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const sayCommand = (play: IPlayInstance, canPlay: boolean) =>
|
|
56
|
+
command(
|
|
57
|
+
`${play.player?.id} elije una accion [${canPlay ? "0," : ""}${play.commands?.map(
|
|
58
|
+
(_c, i) => i + 1
|
|
59
|
+
)}]: ${
|
|
60
|
+
canPlay ? JSON.stringify(["CARTA", ...(play.commands || [])]) : JSON.stringify(play.commands)
|
|
61
|
+
}\n`,
|
|
62
|
+
async (idx, close) => {
|
|
63
|
+
const selectedCommand = play.commands?.[Number(idx) - 1]
|
|
64
|
+
|
|
65
|
+
if (selectedCommand) {
|
|
66
|
+
play.say(selectedCommand)
|
|
67
|
+
return Promise.resolve()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (idx === "0" && canPlay) {
|
|
71
|
+
close()
|
|
72
|
+
await playCommand(play)()
|
|
73
|
+
return Promise.resolve()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return Promise.reject()
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
|
|
32
80
|
;(async () => {
|
|
33
|
-
|
|
34
|
-
|
|
81
|
+
const trucoshi = Trucoshi()
|
|
82
|
+
|
|
83
|
+
trucoshi.addPlayer("lukini", 0).setReady(true)
|
|
84
|
+
trucoshi.addPlayer("guada", 0).setReady(true)
|
|
85
|
+
trucoshi.addPlayer("denoph", 1).setReady(true)
|
|
86
|
+
trucoshi.addPlayer("juli", 1).setReady(true)
|
|
87
|
+
|
|
88
|
+
trucoshi
|
|
89
|
+
.startMatch()
|
|
90
|
+
.onTruco(async (play) => {
|
|
91
|
+
await sayCommand(play, false)()
|
|
92
|
+
})
|
|
93
|
+
.onTurn(async (play) => {
|
|
35
94
|
const name = play.player?.id.toUpperCase()
|
|
36
95
|
console.log(`=== Mano ${play.handIdx} === Ronda ${play.roundIdx} === Turno de ${name} ===`)
|
|
37
96
|
|
|
@@ -39,8 +98,6 @@ const command = (
|
|
|
39
98
|
console.log(`=== Team ${id} = ${team.points.malas} malas ${team.points.buenas} buenas`)
|
|
40
99
|
)
|
|
41
100
|
|
|
42
|
-
const canPlay = play.state === EHandState.WAITING_PLAY
|
|
43
|
-
|
|
44
101
|
console.log(
|
|
45
102
|
play.rounds && play.rounds.length
|
|
46
103
|
? play.rounds.map((round: IRound) =>
|
|
@@ -49,55 +106,7 @@ const command = (
|
|
|
49
106
|
: ""
|
|
50
107
|
)
|
|
51
108
|
|
|
52
|
-
|
|
53
|
-
`${play.player?.id} elije una accion [${canPlay ? "0," : ""}${play.commands?.map(
|
|
54
|
-
(_c, i) => i + 1
|
|
55
|
-
)}]: ${
|
|
56
|
-
canPlay
|
|
57
|
-
? JSON.stringify(["CARTA", ...(play.commands || [])])
|
|
58
|
-
: JSON.stringify(play.commands)
|
|
59
|
-
}\n`,
|
|
60
|
-
async (idx: string, close: () => void) => {
|
|
61
|
-
const selectedCommand = play.commands?.[Number(idx) - 1]
|
|
62
|
-
|
|
63
|
-
if (selectedCommand) {
|
|
64
|
-
play.say(selectedCommand)
|
|
65
|
-
return Promise.resolve()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (idx === "0" && canPlay) {
|
|
69
|
-
close()
|
|
70
|
-
await playCommand()
|
|
71
|
-
return Promise.resolve()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return Promise.reject()
|
|
75
|
-
}
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
const playCommand = command(
|
|
79
|
-
`${play.player?.id} elije una carta [${play.player?.hand.map(
|
|
80
|
-
(_c, i) => i + 1
|
|
81
|
-
)}]: ${JSON.stringify(play.player?.hand)}\n`,
|
|
82
|
-
async (idx: string) => {
|
|
83
|
-
const playedCard = play.use(Number(idx) - 1)
|
|
84
|
-
if (!playedCard) {
|
|
85
|
-
return Promise.reject()
|
|
86
|
-
}
|
|
87
|
-
const handString = JSON.stringify(play.player?.hand)
|
|
88
|
-
console.log(`\n${handString}\nUsing ${playedCard}`)
|
|
89
|
-
console.log(
|
|
90
|
-
play.rounds && play.rounds.length
|
|
91
|
-
? play.rounds.map((round: IRound) =>
|
|
92
|
-
round.cards.length ? round.cards.map((c) => [c.player.id, c.card]) : ""
|
|
93
|
-
)
|
|
94
|
-
: ""
|
|
95
|
-
)
|
|
96
|
-
return Promise.resolve()
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
await sayCommand()
|
|
109
|
+
await sayCommand(play, true)()
|
|
101
110
|
})
|
|
102
111
|
.onWinner(async (winner: ITeam, teams: [ITeam, ITeam]) => {
|
|
103
112
|
teams.map((t, i) =>
|
|
@@ -109,5 +118,5 @@ const command = (
|
|
|
109
118
|
)
|
|
110
119
|
console.log(`\nEquipo Ganador:${winner?.players.map((p) => ` ${p.id}`)}`)
|
|
111
120
|
})
|
|
112
|
-
.
|
|
121
|
+
.begin()
|
|
113
122
|
})()
|