From 3e5c16d487592721d6f30257e30777c18a455891 Mon Sep 17 00:00:00 2001 From: milo Date: Mon, 30 Jun 2025 18:57:59 +0200 Subject: [PATCH 1/2] poker beta: playing with coins and elo for real --- game.js | 42 +++++++++++++- index.js | 139 ++++++++++++++++++++++++++++++++++++++++++++++- init_database.js | 4 +- 3 files changed, 178 insertions(+), 7 deletions(-) diff --git a/game.js b/game.js index ff15086..c5c11cb 100644 --- a/game.js +++ b/game.js @@ -237,10 +237,46 @@ export async function pokerEloHandler(room) { } }) - room.winners.forEach(winnerId => { - if (DBplayers.find((player) => player.id === winnerId)) { - // update elo + const winnerIds = new Set(room.winners) + const baseK = 5 + const playerCount = Object.keys(room.players).length + const K = baseK * Math.log2(playerCount) + DBplayers.forEach(player => { + const others = DBplayers.filter(p => p.id !== player.id) + const avgOppElo = others.reduce((sum, p) => sum + p.elo, 0) / others.length + + const expectedScore = 1 / (1 + Math.pow(10, (avgOppElo - player.elo) / 400)) + let actualScore; + + if (winnerIds.has(player.id)) { + if (winnerIds.size === DBplayers.length) { + actualScore = 0.5 + } else { + actualScore = 1 + } + } else { + actualScore = 0 } + + const delta = K * (actualScore - expectedScore) + const newElo = Math.max(Math.floor(player.elo + delta), 0) + + console.log(`${player.id} elo update : ${player.elo} -> ${newElo} (K: ${K})`) + updateElo.run({ id: player.id, elo: newElo }) + + insertGame.run({ + id: player.id + '-' + Date.now().toString(), + p1: player.id, + p2: null, + p1_score: actualScore, + p2_score: null, + p1_elo: player.elo, + p2_elo: avgOppElo, + p1_new_elo: newElo, + p2_new_elo: null, + type: 'POKER_ROUND', + timestamp: Date.now(), + }) }) } \ No newline at end of file diff --git a/index.js b/index.js index d9694ac..ae3ed08 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ import { getFirstActivePlayerAfterDealer, getNextActivePlayer, checkEndOfBettingRound, initialCards, checkRoomWinners, pruneOldLogs } from './utils.js'; -import {channelPointsHandler, eloHandler, pokerTest, slowmodesHandler} from './game.js'; +import {channelPointsHandler, eloHandler, pokerEloHandler, pokerTest, slowmodesHandler} from './game.js'; import { Client, GatewayIntentBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; import cron from 'node-cron'; import Database from "better-sqlite3"; @@ -3714,6 +3714,40 @@ app.post('/poker-room/start', async (req, res) => { pokerRooms[roomId].players[pokerRooms[roomId].bb].last_played_turn = pokerRooms[roomId].current_turn + if (!pokerRooms[roomId].fakeMoney) { + const DB_SBplayer = await getUser.get(Object.keys(pokerRooms[roomId].players)[1]) + const DB_BBplayer = await getUser.get(Object.keys(pokerRooms[roomId].players)[2 % Object.keys(pokerRooms[roomId].players).length]) + if (DB_SBplayer) { + updateUserCoins.run({ + id: DB_SBplayer.id, + coins: pokerRooms[roomId].players[DB_SBplayer.id].bank, + }) + insertLog.run({ + id: DB_SBplayer.id + '-' + Date.now(), + user_id: DB_SBplayer.id, + action: 'POKER_SMALL_BLIND', + target_user_id: DB_SBplayer.id, + coins_amount: -10, + user_new_amount: DB_SBplayer.coins - 10, + }) + } + if (DB_BBplayer) { + updateUserCoins.run({ + id: DB_BBplayer.id, + coins: pokerRooms[roomId].players[DB_BBplayer.id].bank, + }) + insertLog.run({ + id: DB_BBplayer.id + '-' + Date.now(), + user_id: DB_BBplayer.id, + action: 'POKER_BIG_BLIND', + target_user_id: DB_BBplayer.id, + coins_amount: -20, + user_new_amount: DB_BBplayer.coins - 20, + }) + } + io.emit('data-updated', {table: 'users', action: 'update'}); + } + pokerRooms[roomId].playing = true pokerRooms[roomId].last_move_at = Date.now() @@ -3761,6 +3795,40 @@ async function handleRoomStart(roomId, dealerId = 0) { pokerRooms[roomId].players[pokerRooms[roomId].bb].last_played_turn = pokerRooms[roomId].current_turn + if (!pokerRooms[roomId].fakeMoney) { + const DB_SBplayer = await getUser.get(Object.keys(pokerRooms[roomId].players)[(dealerId + 2) % Object.keys(pokerRooms[roomId].players).length]) + const DB_BBplayer = await getUser.get(Object.keys(pokerRooms[roomId].players)[(dealerId + 3) % Object.keys(pokerRooms[roomId].players).length]) + if (DB_SBplayer) { + updateUserCoins.run({ + id: DB_SBplayer.id, + coins: pokerRooms[roomId].players[DB_SBplayer.id].bank, + }) + insertLog.run({ + id: DB_SBplayer.id + '-' + Date.now(), + user_id: DB_SBplayer.id, + action: 'POKER_SMALL_BLIND', + target_user_id: DB_SBplayer.id, + coins_amount: -10, + user_new_amount: DB_SBplayer.coins - 10, + }) + } + if (DB_BBplayer) { + updateUserCoins.run({ + id: DB_BBplayer.id, + coins: pokerRooms[roomId].players[DB_BBplayer.id].bank, + }) + insertLog.run({ + id: DB_BBplayer.id + '-' + Date.now(), + user_id: DB_BBplayer.id, + action: 'POKER_BIG_BLIND', + target_user_id: DB_BBplayer.id, + coins_amount: -20, + user_new_amount: DB_BBplayer.coins - 20, + }) + } + io.emit('data-updated', {table: 'users', action: 'update'}); + } + pokerRooms[roomId].playing = true pokerRooms[roomId].last_move_at = Date.now() @@ -4030,10 +4098,30 @@ app.post('/poker-room/winner', async (req, res) => { pokerRooms[roomId].winners.forEach((winner) => { pokerRooms[roomId].players[winner].bank += Math.floor(pool / winnerIds.length) + if (!pokerRooms[roomId].fakeMoney) { + const DBplayer = getUser.get(winner) + if (DBplayer) { + updateUserCoins.run({ + id: winner, + coins: pokerRooms[roomId].players[winner].bank, + }) + insertLog.run({ + id: winner + '-' + Date.now(), + user_id: winner, + action: 'POKER_WIN', + target_user_id: winner, + coins_amount: Math.floor(pool / winnerIds.length), + user_new_amount: pokerRooms[roomId].players[winner].bank, + }) + } + io.emit('data-updated', {table: 'users', action: 'update'}); + } }); pokerRooms[roomId].waiting_for_restart = true + io.emit('player-winner', { roomId: roomId, playerIds: winnerIds, amount: Math.floor(pool / winnerIds.length) }) + await pokerEloHandler(pokerRooms[roomId]) io.emit('new-poker-room') @@ -4068,6 +4156,8 @@ async function handleWinner(roomId, winnerIds) { pokerRooms[roomId].waiting_for_restart = true + io.emit('player-winner', { roomId: roomId, playerIds: pokerRooms[roomId].winners, amount: Math.floor(pool / winnerIds.length) }) + await pokerEloHandler(pokerRooms[roomId]) io.emit('new-poker-room') @@ -4135,6 +4225,8 @@ app.post('/poker-room/action/fold', async (req, res) => { pokerRooms[roomId].players[playerId].folded = true pokerRooms[roomId].players[playerId].last_played_turn = pokerRooms[roomId].current_turn + io.emit('player-fold', { roomId: roomId, playerId: playerId, playerName: pokerRooms[roomId].players[playerId].globalName }) + await checksAfterPokerAction(roomId) io.emit('new-poker-room') @@ -4157,6 +4249,8 @@ app.post('/poker-room/action/check', async (req, res) => { try { pokerRooms[roomId].players[playerId].last_played_turn = pokerRooms[roomId].current_turn + io.emit('player-check', { roomId: roomId, playerId: playerId, playerName: pokerRooms[roomId].players[playerId].globalName }) + await checksAfterPokerAction(roomId) io.emit('new-poker-room') @@ -4187,6 +4281,26 @@ app.post('/poker-room/action/call', async (req, res) => { pokerRooms[roomId].players[playerId].last_played_turn = pokerRooms[roomId].current_turn if (Object.values(pokerRooms[roomId].players).find(p => p.allin)) pokerRooms[roomId].players[playerId].allin = true + if (!pokerRooms[roomId].fakeMoney) { + const DBplayer = await getUser.get(playerId) + if (DBplayer) { + updateUserCoins.run({ + id: playerId, + coins: pokerRooms[roomId].players[playerId].bank, + }) + insertLog.run({ + id: playerId + '-' + Date.now(), + user_id: playerId, + action: 'POKER_CALL', + target_user_id: playerId, + coins_amount: -diff, + user_new_amount: pokerRooms[roomId].players[playerId].bank, + }) + } + io.emit('data-updated', { table: 'users', action: 'update' }); + } + + io.emit('player-call', { roomId: roomId, playerId: playerId, playerName: pokerRooms[roomId].players[playerId].globalName }) await checksAfterPokerAction(roomId) @@ -4221,6 +4335,27 @@ app.post('/poker-room/action/raise', async (req, res) => { pokerRooms[roomId].players[playerId].is_last_raiser = true pokerRooms[roomId].highest_bet = pokerRooms[roomId].players[playerId].bet + if (!pokerRooms[roomId].fakeMoney) { + const DBplayer = await getUser.get(playerId) + if (DBplayer) { + updateUserCoins.run({ + id: playerId, + coins: DBplayer.coins - amount, + }) + insertLog.run({ + id: playerId + '-' + Date.now(), + user_id: playerId, + action: 'POKER_RAISE', + target_user_id: playerId, + coins_amount: -amount, + user_new_amount: DBplayer.coins - amount, + }) + } + io.emit('data-updated', { table: 'users', action: 'update' }); + } + + io.emit('player-raise', { roomId: roomId, playerId: playerId, amount: amount, playerName: pokerRooms[roomId].players[playerId].globalName }) + await checksAfterPokerAction(roomId) io.emit('new-poker-room') @@ -4263,7 +4398,7 @@ async function updatePokerPlayersSolve(roomId) { for (const playerId in pokerRooms[roomId].players) { const player = pokerRooms[roomId].players[playerId] let fullHand = pokerRooms[roomId].tapis - player.solve = Hand.solve(fullHand.concat(player.hand), 'standard', false).descr + player.solve = Hand.solve(fullHand.concat(player.hand), 'standard', false)?.descr } } diff --git a/init_database.js b/init_database.js index e38b59c..dc3dbad 100644 --- a/init_database.js +++ b/init_database.js @@ -41,8 +41,8 @@ export const updateUser = flopoDB.prepare('UPDATE users SET warned = @warned, wa export const queryDailyReward = flopoDB.prepare(`UPDATE users SET dailyQueried = 1 WHERE id = ?`); export const resetDailyReward = flopoDB.prepare(`UPDATE users SET dailyQueried = 0 WHERE id = ?`); export const updateUserCoins = flopoDB.prepare('UPDATE users SET coins = @coins WHERE id = @id'); -export const getUser = flopoDB.prepare('SELECT * FROM users WHERE id = ?'); -export const getAllUsers = flopoDB.prepare('SELECT * FROM users ORDER BY coins DESC'); +export const getUser = flopoDB.prepare('SELECT *,elos.elo FROM users JOIN elos ON elos.id = users.id WHERE users.id = ?'); +export const getAllUsers = flopoDB.prepare('SELECT *,elos.elo FROM users JOIN elos ON elos.id = users.id ORDER BY coins DESC'); export const insertSkin = flopoDB.prepare('INSERT INTO skins (uuid, displayName, contentTierUuid, displayIcon, user_id, tierRank, tierColor, tierText, basePrice, currentLvl, currentChroma, currentPrice, maxPrice) VALUES (@uuid, @displayName, @contentTierUuid, @displayIcon, @user_id, @tierRank, @tierColor, @tierText, @basePrice, @currentLvl, @currentChroma, @currentPrice, @maxPrice)'); export const updateSkin = flopoDB.prepare('UPDATE skins SET user_id = @user_id, currentLvl = @currentLvl, currentChroma = @currentChroma, currentPrice = @currentPrice WHERE uuid = @uuid'); From 9abd1c976eaf4b3a5db0a38151cf1672ea61264b Mon Sep 17 00:00:00 2001 From: milo Date: Mon, 30 Jun 2025 18:59:42 +0200 Subject: [PATCH 2/2] removed hydrate advice message --- index.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/index.js b/index.js index ae3ed08..b7706bc 100644 --- a/index.js +++ b/index.js @@ -682,26 +682,6 @@ client.once('ready', async () => { } }); - cron.schedule(todaysHydrateCron, async () => { - const guild = await client.guilds.fetch(process.env.GUILD_ID); - - try { - const generalChannel = guild.channels.cache.find( - ch => ch.name === 'général' || ch.name === 'general' - ); - - if (generalChannel && generalChannel.isTextBased()) { - generalChannel.send( - `${getRandomHydrateText()} ${getRandomEmoji(1)}` - ); - } - - console.log(`Message hydratation`); - } catch (err) { - console.error('Message hydratation:', err); - } - }); - // users/skins dayly fetch at 7am cron.schedule('0 7 * * *', async() => { // fetch eventual new users/skins