Changeset 189cd8f for pages/api/poker
- Timestamp:
- 07/06/22 00:11:47 (2 years ago)
- Branches:
- main
- Children:
- aac3b2b
- Parents:
- 3a783f2
- Location:
- pages/api/poker
- Files:
-
- 3 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pages/api/poker/index.js
r3a783f2 r189cd8f 5 5 import { v4 as uuidv4 } from 'uuid'; 6 6 7 const sampleTable = { 8 id: '', 9 name: '', 10 status: '_1_just_created', 11 creator: '', 12 started: false, 13 ended: false, 14 round: 0, 15 turnIdx: -1, 16 pot: 0, 17 lastBet: 0, 18 turnsSinceLastBet: 0, 19 players: [], 20 deck: [], 21 cardsOnTable: [], 22 winners: [], 23 splitWinners: false, 24 turnTimeout: null, 25 } 26 27 const samplePlayer = { 28 id: '', 29 table: '', 30 status: '_1_just_entered', 31 displayName: '', 32 cards: [], 33 hand: { 34 hand: '', 35 highCard: 0, 36 }, 37 betAmount: 0, 38 isSatDown: false, 39 isCoordinator: false, 40 isFolded: false, 41 isGhost: false, 42 credits: 0, 43 } 44 45 let tables = [] 46 // contures -> { status, round, turnIdx, lastBet, turnsSinceLastBet, 47 // 48 // players -> { id, table, status, displayName, cards, 49 // betAmount, isSatDown, isCoordinator }, 50 // 51 // cardsOnTable } 52 53 const singleDeck = ["SA", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "SX", "SJ", "SQ", "SK", 54 "HA", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "HX", "HJ", "HQ", "HK", 55 "CA", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CX", "CJ", "CQ", "CK", 56 "DA", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DX", "DJ", "DQ", "DK" ]; 57 58 const deck = [...singleDeck]; 59 60 /* We are using 5 decks */ 61 // const deck = singleDeck.concat(singleDeck).concat(singleDeck).concat(singleDeck).concat(singleDeck); 62 63 /** 64 * Replace deck if empty 65 */ 66 function checkDeckSize(tableId) { 67 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 68 69 if (tables[tableIdx] !== undefined) { 70 if (tables[tableIdx].deck.length === 0) { 71 tables[tableIdx].deck = [...deck]; 72 } 73 } 74 } 75 76 /** 77 * Draw a SINGLE random card 78 */ 79 function drawASingleCard(tableId) { 80 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 81 82 if (tables[tableIdx] !== undefined) { 83 checkDeckSize(tableId); 84 85 let idx = Math.floor(Math.random() * tables[tableIdx].deck.length); 86 let card = tables[tableIdx].deck[idx]; 87 88 tables[tableIdx].deck.splice(idx, 1); 89 90 return card; 91 } 92 93 return undefined; 94 } 95 96 function getMaxBet(tableId) { 97 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 98 99 if (tables[tableIdx] !== undefined) { 100 const table = tables[tableIdx]; 101 102 let maxBet = 0; 103 table.players.forEach(player => { 104 if (player.betAmount > maxBet) { 105 maxBet = player.betAmount; 106 } 107 }) 108 109 return maxBet; 110 } 111 112 return 0; 113 } 114 115 function setNextPlayerIdx(tableId) { 116 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 117 118 if (tables[tableIdx] !== undefined) { 119 const table = tables[tableIdx]; 120 121 if (table.turnTimeout !== null) clearTimeout(table.turnTimeout); 122 123 let counter = 10; 124 125 while (true) { 126 counter--; 127 128 table.turnIdx++; 129 table.turnIdx %= table.players.length; 130 131 if (table.players[table.turnIdx] !== undefined && table.players[table.turnIdx].isSatDown && !table.players[table.turnIdx].isFolded) { 132 if (table.round >= 2 && table.players[table.turnIdx].credits === 0) continue; 133 134 let prevTurnIdx = table.turnIdx; 135 table.turnTimeout = setTimeout(() => { 136 if (prevTurnIdx === table.turnIdx) { 137 if (table.players[table.turnIdx] !== undefined) { 138 table.players[table.turnIdx].isFolded = true; 139 140 setNextPlayerIdx(table.id); 141 } 142 } 143 }, 30000); 144 145 table.lastBet = getMaxBet(table.id) - table.players[table.turnIdx].betAmount; 146 if (table.round === 1 && getMaxBet(table.id) <= 20) table.lastBet = 20; 147 148 return ; 149 } 150 151 if (counter <= 0) return ; 152 } 153 } 154 } 155 156 function getCardsOnTable(tableId) { 157 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 158 159 if (tables[tableIdx] !== undefined) { 160 const table = tables[tableIdx]; 161 162 if (table.round === 2) { 163 for (let i = 0; i < 3; i++) { 164 const card = drawASingleCard(table.id); 165 166 if (card !== undefined) { 167 table.cards.push(card); 168 } 169 } 170 } 171 else if (table.round > 2) { 172 const card = drawASingleCard(table.id); 173 174 if (card !== undefined) { 175 table.cards.push(card); 176 } 177 } 178 } 179 } 180 181 function resetGame(tableId) { 182 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 183 184 if (tables[tableIdx] !== undefined) { 185 const table = tables[tableIdx]; 186 187 table.started = false; 188 table.ended = false; 189 table.round = 0; 190 table.turnIdx = 0; 191 table.turnTimeout = null; 192 table.pot = 0; 193 table.lastBet = 20; 194 table.turnsSinceLastBet = 0; 195 table.deck = [...deck]; 196 197 table.players = table.players.filter(e=>e.isGhost === false); 198 199 table.players.forEach(player => { 200 player.credits = 0; 201 player.cards = []; 202 player.isFolded = false; 203 player.betAmount = 0; 204 player.wonAmount = 0; 205 player.hand = { 206 hand: '', 207 highCard: 0, 208 } 209 }) 210 table.winners = []; 211 table.splitWinners = false; 212 table.cards = []; 213 } 214 } 215 216 function giveMoneyToTheWinners(tableId) { 217 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 218 219 if (tables[tableIdx] !== undefined) { 220 const table = tables[tableIdx]; 221 222 const satDownPlayers = table.players.filter(e => e.isSatDown === true); 223 const satDownCount = satDownPlayers.length; 224 225 table.players.forEach(player => { 226 let winnings = 0; 227 if (table.winners.indexOf(player) !== -1) { 228 // winner 229 winnings = 0; 230 table.players.forEach(tmpPlayer => { 231 winnings += Math.min(tmpPlayer.betAmount, player.betAmount); 232 }) 233 234 axios.get(`${process.env.HOME_URL}/api/postgre/?action=add_credits&session_id=${player.id}&credits=${winnings}&game=poker&outcome=won`).then(postgreRes => { 235 if (postgreRes.data?.success) { 236 player.credits = postgreRes.data?.credits; 237 } 238 }); 239 } 240 else { 241 // loser 242 winnings = player.betAmount; 243 table.players.forEach(tmpPlayer => { 244 if (table.winners.indexOf(tmpPlayer) !== -1) { 245 winnings -= tmpPlayer.betAmount; 246 } 247 }) 248 249 axios.get(`${process.env.HOME_URL}/api/postgre/?action=add_credits&session_id=${player.id}&credits=${winnings}&game=poker&outcome=lost`).then(postgreRes => { 250 if (postgreRes.data?.success) { 251 player.credits = postgreRes.data?.credits; 252 } 253 }); 254 } 255 256 player.wonAmount = winnings; 257 }) 258 259 setTimeout(() => { 260 resetGame(table.id); 261 }, 15000); 262 } 263 } 264 265 function setWinner(tableId) { 266 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 267 268 if (tables[tableIdx] !== undefined) { 269 const table = tables[tableIdx]; 270 271 table.turnIdx = -1; 272 273 table.players.forEach(player => { 274 if (player.isSatDown && !player.isFolded) { 275 player.hand = getHandDetails(player.cards.concat(table.cards)) 276 } 277 }) 278 279 hands.forEach(hand => { 280 const playerHands = table.players.filter(e=>e.hand.hand === hand); 281 282 if (table.winners.length === 0) { 283 if (playerHands.length === 1) { 284 table.winners.push(playerHands[0]) 285 } 286 else if (playerHands.length > 1) { 287 let tmp = playerHands[0].hand.highCard; 288 let tmpWinners = []; 289 290 playerHands.forEach(player => { 291 if (player.hand.highCard > tmp) { 292 tmp = player.hand.highCard; 293 } 294 }) 295 296 playerHands.forEach(player => { 297 if (player.hand.highCard === tmp) { 298 tmpWinners.push(player); 299 } 300 }) 301 302 if (tmpWinners.length > 1) table.splitWinners = true; 303 table.winners = [...tmpWinners]; 304 } 305 } 306 }) 307 308 giveMoneyToTheWinners(table.id); 309 } 310 } 311 312 function progressRoundIfNeeded(tableId) { 313 const tableIdx = tables.map(e=>e.id).indexOf(tableId); 314 315 if (tables[tableIdx] !== undefined) { 316 const table = tables[tableIdx]; 317 318 const satDownPlayers = table.players.filter(e=>e.isSatDown === true); 319 const remainingPlayers = satDownPlayers.filter(e=>e.isFolded === false); 320 321 if (table.turnsSinceLastBet === remainingPlayers.length) { 322 table.round++; 323 table.lastBet = 0; 324 table.turnsSinceLastBet = 0; 325 326 if (table.round <= 4) { 327 getCardsOnTable(table.id); 328 } 329 else { 330 table.ended = true; 331 } 332 333 if (table.ended && table.winners.length === 0) { 334 setWinner(table.id); 335 } 336 } 337 } 338 } 7 import { tables, deck, sampleTable, samplePlayer } from './gameStates' 8 9 import { drawASingleCard, setNextPlayerIdx, progressRoundIfNeeded } from './tableSpecific' 339 10 340 11 /** … … 425 96 426 97 function getRestrictedTableArray(tableId, session_id) { 427 let result = {...sampleTable};98 let result = undefined; 428 99 429 100 let tableIdx = tables.map(e=>e.id).indexOf(tableId); … … 505 176 return { 506 177 success: false, 507 table: sampleTable,508 player: samplePlayer,178 table: {...sampleTable}, 179 player: {...samplePlayer}, 509 180 }; 510 181 } … … 696 367 if (table !== undefined && !table.started) { 697 368 table.players.push({ 698 ...samplePlayer,699 369 id: req.query.session_id, 700 370 table: req.query.tableId, 701 displayName: req.query.displayName 371 credits: 0, 372 status: '_1_just_entered', 373 displayName: req.query.displayName, 374 cards: [], 375 betAmount: 0, 376 wonAmount: 0, 377 isSatDown: false, 378 isCoordinator: false, 379 isFolded: false, 380 isGhost: false, 381 hand: { 382 hand: '', 383 highCard: 0, 384 }, 702 385 }) 703 386 } … … 735 418 const session_id = req.query.session_id; 736 419 737 const { table, player } = getTableAndPlayer(session_id);420 const { success, table, player } = getTableAndPlayer(session_id); 738 421 739 422 res.json({ … … 778 461 * ********************* END OF REQUEST HANDLER ********************* 779 462 */ 780 781 const hands = [782 'Royal Flush',783 'Straight Flush',784 'Four of a Kind',785 'Full House',786 'Flush',787 'Straight',788 'Three of a Kind',789 'Two Pairs',790 'Pair',791 'High Card',792 ]793 794 const order = "23456789TJQKA"795 function getHandDetails(hand) {796 const cards = hand797 const faces = cards.map(a => String.fromCharCode([77 - order.indexOf(a[1])])).sort()798 const suits = cards.map(a => a[0]).sort()799 const counts = faces.reduce(count, {})800 const duplicates = Object.values(counts).reduce(count, {})801 const flush = suits[0] === suits[4]802 const first = faces[0].charCodeAt(1)803 const straight = faces.every((f, index) => f.charCodeAt(1) - first === index)804 let rank =805 (flush && straight && 1) ||806 (duplicates[4] && 2) ||807 (duplicates[3] && duplicates[2] && 3) ||808 (flush && 4) ||809 (straight && 5) ||810 (duplicates[3] && 6) ||811 (duplicates[2] > 1 && 7) ||812 (duplicates[2] && 8) ||813 9;814 815 return { hand: hands[rank], highCard: faces.sort(byCountFirst).join("") }816 817 function byCountFirst(a, b) {818 //Counts are in reverse order - bigger is better819 const countDiff = counts[b] - counts[a]820 if (countDiff) return countDiff // If counts don't match return821 return b > a ? -1 : b === a ? 0 : 1822 }823 824 function count(c, a) {825 c[a] = (c[a] || 0) + 1826 return c827 }828 }829 830 function getCardCombinations(playerCards, tableCards) {831 let combinations = [];832 833 combinations.push([playerCards[0], tableCards[0], tableCards[1], tableCards[2], tableCards[3]])834 combinations.push([playerCards[0], tableCards[0], tableCards[1], tableCards[2], tableCards[4]])835 836 combinations.push([playerCards[0], tableCards[0], tableCards[1], tableCards[4], tableCards[3]])837 combinations.push([playerCards[0], tableCards[0], tableCards[4], tableCards[2], tableCards[3]])838 combinations.push([playerCards[0], tableCards[4], tableCards[1], tableCards[2], tableCards[3]])839 840 841 combinations.push([playerCards[1], tableCards[0], tableCards[1], tableCards[2], tableCards[3]])842 combinations.push([playerCards[1], tableCards[0], tableCards[1], tableCards[2], tableCards[4]])843 844 combinations.push([playerCards[1], tableCards[0], tableCards[1], tableCards[4], tableCards[3]])845 combinations.push([playerCards[1], tableCards[0], tableCards[4], tableCards[2], tableCards[3]])846 combinations.push([playerCards[1], tableCards[4], tableCards[1], tableCards[2], tableCards[3]])847 848 849 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[1], tableCards[2]])850 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[1], tableCards[3]])851 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[1], tableCards[4]])852 853 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[2], tableCards[3]])854 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[2], tableCards[4]])855 combinations.push([playerCards[0], playerCards[1], tableCards[0], tableCards[3], tableCards[4]])856 857 combinations.push([playerCards[0], playerCards[1], tableCards[1], tableCards[2], tableCards[3]])858 combinations.push([playerCards[0], playerCards[1], tableCards[1], tableCards[2], tableCards[4]])859 combinations.push([playerCards[0], playerCards[1], tableCards[1], tableCards[3], tableCards[4]])860 861 combinations.push([playerCards[0], playerCards[1], tableCards[2], tableCards[3], tableCards[4]])862 863 864 return combinations;865 }
Note:
See TracChangeset
for help on using the changeset viewer.