forked from spacebetween/labs-frontend-exercise
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgameStore.js
160 lines (136 loc) · 4.01 KB
/
gameStore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import fs from "fs";
import got from "got";
import { v4 as uuidv4 } from "uuid";
var Hand = require('pokersolver').Hand;
const chunk = (arr, len) => {
const chunks = [];
const n = arr.length;
let i = 0;
while (i < n) {
chunks.push(arr.slice(i, (i += len)));
}
return chunks;
};
const readFromFile = () => {
try {
return JSON.parse(fs.readFileSync("game_store.json"));
} catch (err) {
return {};
}
};
const writeToFile = (gameStore) =>
fs.writeFileSync("game_store.json", JSON.stringify(gameStore));
const fetchNewDeck = async () => {
const { deck_id } = await got(
"https://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=5",
{ responseType: "json", resolveBodyOnly: true }
);
return deck_id;
};
const dealInitialCards = async (game) => {
const { cards } = await got(
`https://deckofcardsapi.com/api/deck/${game.deck}/draw/?count=${
5 * game.numPlayers
}`,
{ responseType: "json", resolveBodyOnly: true }
);
const hands = chunk(cards, 5);
return {
...game,
players: Object.keys(game.players).reduce((acc, key, index) => {
acc[key] = { ...game.players[key], cards: hands[index] };
return acc;
}, {}),
};
};
export const exchangeCards = async (gameId, playerId, discardedCardIndexes) => {
const game = await getGame(gameId);
const { cards: newCards } = await got(
`https://deckofcardsapi.com/api/deck/${game.deck}/draw/?count=${discardedCardIndexes.length}`,
{ responseType: "json", resolveBodyOnly: true }
);
let playerHand = game.players[playerId].cards;
discardedCardIndexes.forEach(
(discardIndex, i) => (playerHand[discardIndex] = newCards[i])
);
return updateGame(gameId, {
...game,
players: {
...game.players,
[playerId]: { cards: playerHand, exchanged: true },
},
});
};
export const createNewGame = async (numPlayers, firstPlayerId) => {
const gameId = uuidv4();
const deck = await fetchNewDeck();
const newGameState = {
deck,
numPlayers,
players: { [firstPlayerId]: { cards: [], exchanged: false } },
};
updateGame(gameId, newGameState);
return gameId;
};
export const getGame = (gameId) => {
const games = readFromFile();
if (!games.hasOwnProperty(gameId)) {
throw new Error(`Could not find game with id ${gameId}`);
}
return games[gameId];
};
export const updateGame = (gameId, newGameState) => {
const games = readFromFile();
writeToFile({ ...games, [gameId]: newGameState });
return newGameState;
};
export const allPlayersJoined = (game) =>
Object.keys(game.players).length === game.numPlayers;
export const addPlayer = async (gameId, playerId) => {
const game = getGame(gameId);
if (allPlayersJoined(game)) {
throw new Error("That game is already full");
}
let newGameState = {
...game,
players: { ...game.players, [playerId]: { cards: [], exchanged: false } },
};
if (allPlayersJoined(newGameState)) {
newGameState = await dealInitialCards(newGameState);
}
return updateGame(gameId, newGameState);
};
export const allPlayersExchanged = (gameId) => {
const { players } = getGame(gameId);
return (
Object.keys(players).filter((pk) => players[pk].exchanged === true)
.length === Object.keys(players).length
);
};
export const pokerSolver = (game) => {
let hands = {}
let handsArray = []
// get all cards from current game and solve them
Object.entries(game).map(([key, value]) => {
const cards = value.cards
let hand = []
Object.entries(cards).map(([key, value]) => {
hand.push(value.code)
})
const solvedHand = Hand.solve(hand)
hands[key] = solvedHand
handsArray.push(solvedHand)
})
// determine a winner
//TODO sometimes pokersolver library returns error 'Duplicate cards at new Hand'
const winnerHand = Hand.winners(handsArray);
let winnerId;
winnerHand.map((winnerValue, winnerKey) => {
Object.entries(hands).map(([key, value]) => {
if (JSON.stringify(winnerValue) == JSON.stringify(value)) {
winnerId = key
}
})
})
return winnerId
}