trucoshi 0.0.2 → 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 (61) hide show
  1. package/.prettierrc.json +4 -0
  2. package/LICENSE +674 -0
  3. package/README.md +37 -0
  4. package/build/lib/classes/Deck.d.ts +2 -0
  5. package/build/lib/classes/Deck.js +27 -0
  6. package/build/lib/classes/Hand.d.ts +2 -0
  7. package/build/lib/classes/Hand.js +233 -0
  8. package/build/lib/classes/Match.d.ts +2 -0
  9. package/build/lib/classes/Match.js +115 -0
  10. package/build/lib/classes/Play.d.ts +2 -0
  11. package/build/lib/classes/Play.js +39 -0
  12. package/build/lib/classes/Player.d.ts +2 -0
  13. package/build/lib/classes/Player.js +38 -0
  14. package/build/lib/classes/Round.d.ts +2 -0
  15. package/build/lib/classes/Round.js +33 -0
  16. package/build/lib/classes/Table.d.ts +2 -0
  17. package/build/lib/classes/Table.js +30 -0
  18. package/build/lib/classes/Team.d.ts +2 -0
  19. package/build/lib/classes/Team.js +42 -0
  20. package/build/lib/classes/Truco.d.ts +2 -0
  21. package/build/lib/classes/Truco.js +110 -0
  22. package/build/lib/constants.d.ts +36 -28
  23. package/build/lib/constants.js +97 -12
  24. package/build/lib/index.d.ts +18 -0
  25. package/build/lib/index.js +161 -0
  26. package/build/lib/types.d.ts +121 -30
  27. package/build/lib/types.js +24 -12
  28. package/build/lib/utils.d.ts +3 -3
  29. package/build/lib/utils.js +11 -18
  30. package/build/server/index.js +13 -5
  31. package/build/server/match.d.ts +0 -0
  32. package/build/server/match.js +1 -0
  33. package/build/server/types.d.ts +11 -0
  34. package/build/server/types.js +15 -0
  35. package/build/test/autoplay.js +52 -31
  36. package/build/test/play.js +146 -81
  37. package/package.json +5 -4
  38. package/src/lib/classes/Deck.ts +25 -0
  39. package/src/lib/classes/Hand.ts +207 -0
  40. package/src/lib/classes/Match.ts +79 -0
  41. package/src/lib/classes/Play.ts +40 -0
  42. package/src/lib/classes/Player.ts +37 -0
  43. package/src/lib/classes/Round.ts +30 -0
  44. package/src/lib/classes/Table.ts +32 -0
  45. package/src/lib/classes/Team.ts +41 -0
  46. package/src/lib/classes/Truco.ts +72 -0
  47. package/src/lib/constants.ts +105 -11
  48. package/src/lib/index.ts +135 -0
  49. package/src/lib/types.ts +186 -80
  50. package/src/lib/utils.ts +50 -53
  51. package/src/server/index.ts +34 -22
  52. package/src/server/match.ts +0 -0
  53. package/src/server/types.ts +12 -0
  54. package/src/test/autoplay.ts +57 -41
  55. package/src/test/play.ts +122 -70
  56. package/build/lib/trucoshi.d.ts +0 -10
  57. package/build/lib/trucoshi.js +0 -363
  58. package/build/test/legacy.d.ts +0 -1
  59. package/build/test/legacy.js +0 -146
  60. package/src/lib/trucoshi.ts +0 -342
  61. package/src/test/legacy.ts +0 -68
package/src/lib/utils.ts CHANGED
@@ -1,69 +1,66 @@
1
- import { CARDS } from "./constants";
2
- import { ICard, IPoints, IRound, ITeam } from "./types";
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
- return CARDS[card] || -1
11
+ return CARDS[card] || -1
6
12
  }
7
13
 
8
- export function shuffleArray<T = never>(array: Array<T>) {
9
- let currentIndex = array.length, randomIndex;
14
+ export function shuffleArray<T = unknown>(array: Array<T>) {
15
+ let currentIndex = array.length,
16
+ randomIndex
10
17
 
11
- while (currentIndex != 0) {
12
- randomIndex = Math.floor(Math.random() * currentIndex);
13
- currentIndex--;
14
- [array[currentIndex], array[randomIndex]] = [
15
- array[randomIndex], array[currentIndex]];
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
- return array as Array<T>;
24
+ return array as Array<T>
19
25
  }
20
26
 
21
- export function checkHandWinner(rounds: Array<IRound>, forehandTeamIdx: 0 | 1): null | 0 | 1 {
22
- const roundsWon: IPoints = {
23
- 0: 0,
24
- 1: 0,
25
- 2: 0 // tied rounds
26
- }
27
+ export function checkHandWinner(
28
+ rounds: Array<IRound>,
29
+ forehandTeamIdx: 0 | 1
30
+ ): null | 0 | 1 {
31
+ const roundsWon: RoundPoints = {
32
+ 0: 0,
33
+ 1: 0,
34
+ ties: 0,
35
+ }
27
36
 
28
- for (let i = 0; i < rounds.length; i++) {
29
- const round = rounds[i];
30
- if (round.tie) {
31
- roundsWon[0] += 1;
32
- roundsWon[1] += 1;
33
- roundsWon[2] = (roundsWon[2] || 0) + 1;
34
- continue;
35
- }
36
- if (round.winner?.teamIdx === 0) {
37
- roundsWon[0] += 1;
38
- }
39
- if (round.winner?.teamIdx === 1) {
40
- roundsWon[1] += 1;
41
- }
37
+ for (let i = 0; i < rounds.length; i++) {
38
+ const round = rounds[i]
39
+ if (round.tie) {
40
+ roundsWon[0] += 1
41
+ roundsWon[1] += 1
42
+ roundsWon.ties = roundsWon.ties + 1
43
+ continue
42
44
  }
43
-
44
- const ties = roundsWon[2] || 0
45
-
46
- if ((roundsWon[0] > 2 && roundsWon[1] > 2) || (rounds.length > 2 && ties > 0)) {
47
- return forehandTeamIdx
45
+ if (round.winner?.teamIdx === 0) {
46
+ roundsWon[0] += 1
48
47
  }
49
-
50
- if (roundsWon[0] >= 2 && roundsWon[1] < 2) {
51
- return 0
48
+ if (round.winner?.teamIdx === 1) {
49
+ roundsWon[1] += 1
52
50
  }
51
+ }
53
52
 
54
- if (roundsWon[1] >= 2 && roundsWon[0] < 2) {
55
- return 1
56
- }
53
+ if ((roundsWon[0] > 2 && roundsWon[1] > 2) || (rounds.length > 2 && roundsWon.ties > 0)) {
54
+ return forehandTeamIdx
55
+ }
57
56
 
58
- return null
59
- }
57
+ if (roundsWon[0] >= 2 && roundsWon[1] < 2) {
58
+ return 0
59
+ }
60
60
 
61
- export function checkMatchWinner(teams: Array<ITeam>, matchPoint: number): ITeam | null {
62
- if (teams[0].points >= matchPoint) {
63
- return teams[0]
64
- }
65
- if (teams[1].points >= matchPoint) {
66
- return teams[1]
67
- }
68
- return null
61
+ if (roundsWon[1] >= 2 && roundsWon[0] < 2) {
62
+ return 1
63
+ }
64
+
65
+ return null
69
66
  }
@@ -1,22 +1,34 @@
1
- import { createServer } from "http";
2
- import { Server } from "socket.io";
3
-
4
- const PORT = 4001
5
-
6
- const httpServer = createServer();
7
- const io = new Server(httpServer, {
8
- cors: {
9
- origin: "http://localhost:3000",
10
- methods: ["GET", "POST"]
11
- }
12
- });
13
-
14
- io.on("connection", (socket) => {
15
- socket.on('ping', (msg) => {
16
- io.emit('pong', msg);
17
- });
18
- });
19
-
20
- httpServer.listen(PORT);
21
-
22
- console.log('Listening on port', PORT)
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)
File without changes
@@ -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
+ }
@@ -1,41 +1,57 @@
1
- import { COLORS } from '../lib/constants';
2
- import { Match, Player, Team } from "../lib/trucoshi";
3
- import { ICard, IRound } from '../lib/types';
4
-
5
- (async () => {
6
- const player1 = Player('lukini', 0)
7
- const player2 = Player('guada', 0)
8
- const player3 = Player('denoph', 1)
9
- const player4 = Player('juli', 1)
10
- const player5 = Player('fran', 1)
11
- const player6 = Player('day', 0)
12
-
13
- const team1 = Team(COLORS[0], [player1, player2, player6])
14
- const team2 = Team(COLORS[1], [player3, player4, player5])
15
-
16
- const match = Match([team1, team2], 9);
17
-
18
- while(!match.winner) {
19
- const play = match.play()
20
-
21
- if (!play || !play.player) {
22
- break;
23
- }
24
-
25
- const name = play.player.id.toUpperCase()
26
- console.log(`=== Mano ${play.handIdx} === Ronda ${play.roundIdx} === Turno de ${name} ===`)
27
- match.teams.map((team, id) => console.log(`=== Team ${id} = ${team.points} Puntos ===`))
28
- console.log(play.rounds && play.rounds.length ? (play.rounds.map((round: IRound) => round.cards.length ? round.cards.map(c => [c.player.id, c.card]) : '')) : '')
29
-
30
- const randomIdx = Math.round(Math.random() * (play.player.hand.length - 1))
31
- const card = play.use(randomIdx)
32
-
33
- console.log(`\n${JSON.stringify(play.player.hand)}\nUsing ${card}`)
34
- console.log(play.rounds && play.rounds.length ? (play.rounds.map((round: IRound) => round.cards.length ? round.cards.map(c => [c.player.id, c.card]) : '')) : '')
35
- }
36
-
37
- console.log('\n')
38
- match.teams.map((t, i) => console.log(`Equipo ${i}: ${t.players.map(p => ` ${p.id}`)} === ${t.points} puntos`))
39
- console.log(`\nEquipo Ganador:${match.winner?.players.map(p => ` ${p.id}`)}`)
40
-
41
- })();
1
+ import { Trucoshi } from "../lib"
2
+ import { IRound } from "../lib/types"
3
+ ;(async () => {
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()
15
+ .onTurn(async (play) => {
16
+ if (!play.player) {
17
+ return
18
+ }
19
+ const name = play.player?.id.toUpperCase()
20
+ console.log(`=== Mano ${play.handIdx} === Ronda ${play.roundIdx} === Turno de ${name} ===`)
21
+ play.teams.map((team, id) =>
22
+ console.log(`=== Team ${id} = ${team.points.malas} malas ${team.points.buenas} buenas ===`)
23
+ )
24
+ console.log(
25
+ play.rounds && play.rounds.length
26
+ ? play.rounds.map((round: IRound) =>
27
+ round.cards.length ? round.cards.map((c) => [c.player.id, c.card]) : ""
28
+ )
29
+ : ""
30
+ )
31
+
32
+ const randomIdx = Math.round(Math.random() * (play.player.hand.length - 1))
33
+ const handString = JSON.stringify(play.player.hand)
34
+ const card = play.use(randomIdx)
35
+
36
+ console.log(`\n${handString}\nUsing ${card}`)
37
+ console.log(
38
+ play.rounds && play.rounds.length
39
+ ? play.rounds.map((round: IRound) =>
40
+ round.cards.length ? round.cards.map((c) => [c.player.id, c.card]) : ""
41
+ )
42
+ : ""
43
+ )
44
+ })
45
+ .onWinner(async (winner, teams) => {
46
+ console.log("\n")
47
+ teams.map((t, i) =>
48
+ console.log(
49
+ `Equipo ${i}: ${t.players.map((p) => ` ${p.id}`)} === ${t.points.malas} malas ${
50
+ t.points.buenas
51
+ } buenas`
52
+ )
53
+ )
54
+ console.log(`\nEquipo Ganador:${winner.players.map((p) => ` ${p.id}`)}`)
55
+ })
56
+ .begin()
57
+ })()
package/src/test/play.ts CHANGED
@@ -1,70 +1,122 @@
1
- import * as readline from 'readline'
2
- import { COLORS } from '../lib/constants';
3
- import { Match, Player, Team } from "../lib/trucoshi";
4
- import { IRound } from '../lib/types';
5
-
6
- (async () => {
7
- const player1 = Player('lukini', 0)
8
- const player2 = Player('guada', 0)
9
- const player3 = Player('denoph', 1)
10
- const player4 = Player('juli', 1)
11
-
12
- const team1 = Team(COLORS[0], [player1, player2])
13
- const team2 = Team(COLORS[1], [player3, player4])
14
-
15
- const match = Match([team1, team2], 9);
16
-
17
- while(!match.winner) {
18
-
19
- const play = match.play()
20
-
21
- if (!play || !play.player) {
22
- break;
23
- }
24
-
25
- const name = play.player.id.toUpperCase()
26
-
27
- process.stdout.write('\u001B[2J\u001B[0;0f');
28
- process.stdout.write('\u001B[0;0f');
29
-
30
- console.log(`=== Mano ${play.handIdx} === Ronda ${play.roundIdx} === Turno de ${name} ===`)
31
-
32
- process.stdout.write('\u001B[2;0f');
33
-
34
- match.teams.map((team, id) => console.log(`=== Team ${id} = ${team.points} Puntos ===`))
35
-
36
- process.stdout.write('\u001B[5;0f');
37
-
38
- console.log(play.rounds && play.rounds.length ? (play.rounds.map((round: IRound) => round.cards.length ? round.cards.map(c => [c.player.id, c.card]) : '')) : '')
39
-
40
- const prom = () => new Promise<void>((resolve) => {
41
- const rl = readline.createInterface(process.stdin, process.stdout);
42
- rl.setPrompt(`\n${play.player?.id} elije una carta [1, 2, 3]: ${JSON.stringify(play.player?.hand)}\n`);
43
- rl.prompt();
44
- rl.on('line', (idx: string) => {
45
- const playedCard = play.use(Number(idx) - 1)
46
- if (!playedCard) {
47
- rl.close();
48
- return (async () => {
49
- await prom()
50
- resolve()
51
- })();
52
- }
53
- process.stdout.write('\u001B[7;0f');
54
- console.log(`\n${JSON.stringify(play.player?.hand)}\nUsing ${playedCard}`)
55
- process.stdout.write('\u001B[10;0f');
56
- console.log(play.rounds && play.rounds.length ? (play.rounds.map((round: IRound) => round.cards.length ? round.cards.map(c => [c.player.id, c.card]) : '')) : '')
57
- rl.close();
58
- resolve()
59
- });
60
- });
61
-
62
- await prom()
63
-
64
- }
65
-
66
- process.stdout.write('\u001B[2J\u001B[2;0f');
67
- match.teams.map((t, i) => console.log(`Equipo ${i}: ${t.players.map(p => ` ${p.id}`)} === ${t.points} puntos`))
68
- console.log(`\nEquipo Ganador:${match.winner?.players.map(p => ` ${p.id}`)}`)
69
-
70
- })();
1
+ import * as readline from "readline"
2
+ import { Trucoshi } from "../lib"
3
+ import { IPlayInstance, IRound, ITeam } from "../lib/types"
4
+
5
+ const command = (
6
+ title: string,
7
+ onLine: (line: string, close: () => void) => Promise<void>
8
+ ): (() => Promise<void>) => {
9
+ const promise = () =>
10
+ new Promise<void>((resolve) => {
11
+ const rl = readline.createInterface(process.stdin, process.stdout)
12
+ rl.setPrompt(title)
13
+ rl.prompt()
14
+ rl.on("line", async (line) => {
15
+ try {
16
+ await onLine(line, () => rl.close())
17
+ rl.close()
18
+ resolve()
19
+ } catch (e) {
20
+ rl.close()
21
+ return (async () => {
22
+ await promise()
23
+ resolve()
24
+ })()
25
+ }
26
+ })
27
+ })
28
+
29
+ return promise
30
+ }
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
+
80
+ ;(async () => {
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) => {
94
+ const name = play.player?.id.toUpperCase()
95
+ console.log(`=== Mano ${play.handIdx} === Ronda ${play.roundIdx} === Turno de ${name} ===`)
96
+
97
+ play.teams.map((team, id) =>
98
+ console.log(`=== Team ${id} = ${team.points.malas} malas ${team.points.buenas} buenas`)
99
+ )
100
+
101
+ console.log(
102
+ play.rounds && play.rounds.length
103
+ ? play.rounds.map((round: IRound) =>
104
+ round.cards.length ? round.cards.map((c) => [c.player.id, c.card]) : ""
105
+ )
106
+ : ""
107
+ )
108
+
109
+ await sayCommand(play, true)()
110
+ })
111
+ .onWinner(async (winner: ITeam, teams: [ITeam, ITeam]) => {
112
+ teams.map((t, i) =>
113
+ console.log(
114
+ `Equipo ${i}: ${t.players.map((p) => ` ${p.id}`)} === ${t.points.malas} malas ${
115
+ t.points.buenas
116
+ } buenas`
117
+ )
118
+ )
119
+ console.log(`\nEquipo Ganador:${winner?.players.map((p) => ` ${p.id}`)}`)
120
+ })
121
+ .begin()
122
+ })()
@@ -1,10 +0,0 @@
1
- import { IMatch, IPlayer, ITeam } from "./types";
2
- export declare function Match(teams?: Array<ITeam>, matchPoint?: number): IMatch;
3
- export declare function Player(id: string, teamIdx: number): IPlayer;
4
- export declare function Team(color: string, players: Array<IPlayer>): {
5
- _players: Map<string, IPlayer>;
6
- readonly players: IPlayer[];
7
- color: string;
8
- points: number;
9
- addPoints(points: number): number;
10
- };