199 lines
5.8 KiB
JavaScript
199 lines
5.8 KiB
JavaScript
import cuffeo from 'cuffeo';
|
|
import handranker from './inc/handranker.mjs';
|
|
import helper from './inc/helper.mjs';
|
|
|
|
const cfg = helper.config;
|
|
const bot = await new cuffeo(cfg.getFull().clients);
|
|
|
|
const env = {
|
|
gamestate: 'preflop', // [preflop,flop,turn,river]
|
|
hand: false,
|
|
board: false,
|
|
winchance: false,
|
|
joined: false,
|
|
callamount: 0,
|
|
pot: 0,
|
|
bank: 0,
|
|
lastaction: false // debug purpose
|
|
};
|
|
|
|
bot.on("notice", msg => {
|
|
if(msg.match(/^Your hand/)) {
|
|
env.hand = helper.parseCards(msg);
|
|
if(cfg.get('debug'))
|
|
console.log('hand:', env.hand);
|
|
}
|
|
});
|
|
|
|
bot.on("message", async e => {
|
|
if(e.channel !== '#poker') {
|
|
return;
|
|
}
|
|
if(e.message === '.schmirc help') {
|
|
await e.write(`PRIVMSG ${e.user.nick} I always say hirc schmirc, available commands are:`);
|
|
const commands = [
|
|
' .pj -- poker join',
|
|
' .pl -- poker leave',
|
|
' .bb -- bank balance',
|
|
' .bl -- bank loan',
|
|
' .d -- deal',
|
|
' .deb -- toggle debug',
|
|
' .aj -- toggle autojoin',
|
|
'While playing:',
|
|
' .s -- stack',
|
|
' .f -- fold',
|
|
];
|
|
|
|
for(const command of commands) {
|
|
await e.write(`PRIVMSG ${e.user.nick} ${command}`);
|
|
}
|
|
}
|
|
if(e.message.match(new RegExp(`^${e.self.me.nickname}: Your bank account`))) {
|
|
env.bank = +e.message.match(/is: (\d+) \(/)[1];
|
|
}
|
|
if(e.message === ".deb") {
|
|
const tmp = await cfg.set('debug', !cfg.get('debug'));
|
|
return e.reply(`${!tmp} -> ${tmp}`);
|
|
}
|
|
if(e.message === ".aj") {
|
|
const tmp = await cfg.set('autojoin', !cfg.get('autojoin'));
|
|
return e.reply(`${!tmp} -> ${tmp}`);
|
|
}
|
|
if(e.message === ".pj" || (e.message === "pj" && cfg.get('autojoin')) && !env.hand && !env.joined) {
|
|
env.joined = true;
|
|
//return e.reply("pj");
|
|
return e.reply("bb\npj");
|
|
|
|
}
|
|
if(e.message === ".pl" && !env.hand) {
|
|
env.joined = false;
|
|
return e.reply("pl");
|
|
}
|
|
if(e.message === ".bb" && !env.hand)
|
|
return e.reply("bb");
|
|
if(e.message === ".bl" && !env.hand)
|
|
return e.reply("bank loan");
|
|
if(e.message === ".s" && env.hand)
|
|
return e.reply("s");
|
|
if(e.message === ".f")
|
|
return e.reply("f");
|
|
if(e.message === ".d" && !env.hand)
|
|
return e.reply("d");
|
|
|
|
if(e.user.nick !== 'hirc' || !env.hand)
|
|
return;
|
|
|
|
// tracker
|
|
if(e.message.includes('raises the pot')) {
|
|
env.callamount = +e.message.match(/raises the pot by (\d+)/)[1];
|
|
env.pot += env.callamount;
|
|
if(e.message.includes(e.self.me.nickname))
|
|
env.bank -= env.callamount;
|
|
return;
|
|
}
|
|
if(e.message.includes('calls')) {
|
|
env.callamount = +e.message.match(/calls (\d+)\./)[1];
|
|
env.pot += env.callamount;
|
|
if(e.message.includes(e.self.me.nickname))
|
|
env.bank -= env.callamount;
|
|
return;
|
|
}
|
|
if(e.message.endsWith('blind).')) { // blinds
|
|
env.callamount = +e.message.match(/pays (\d+) \(/)[1];
|
|
env.pot += env.callamount;
|
|
env.gamestate = 'preflop';
|
|
if(e.message.includes(e.self.me.nickname))
|
|
env.bank -= env.callamount;
|
|
return;
|
|
}
|
|
|
|
// bot's turn
|
|
if(e.message.match(new RegExp(`Current player: ${e.self.me.nickname}( |$)`))) {
|
|
let action = 'c'; // default
|
|
if(env.gamestate === 'preflop' || !env.winchance) { // preflop
|
|
env.lastaction = action;
|
|
return e.reply(action); // checkcall
|
|
}
|
|
|
|
if(e.message.endsWith('to call)')) { // callphase
|
|
env.callamount = +e.message.match(/\((\d+) to call\)/)[1];
|
|
|
|
if(env.winchance < 6500) {
|
|
if(helper.rand(5) === 1 && env.callamount < 80) { // bad hand, call anyway
|
|
action = 'c';
|
|
}
|
|
else { // bad hand, fold
|
|
action = 'f';
|
|
}
|
|
}
|
|
else if(env.winchance > 7000) { // decent hand, raise
|
|
if(helper.rand(5) === 1) { // 20%
|
|
action = 'r ' + (env.callamount + helper.rand(5) * 10);
|
|
}
|
|
}
|
|
else if(env.winchance > 15000) { // good hand lol
|
|
if(helper.rand(2) === 1) { // 50%
|
|
action = 'r ' + (env.callamount + helper.rand(6) * 10);
|
|
}
|
|
}
|
|
else if(env.winchance > 20000) { // fuck them all
|
|
action = 'r ' + (env.callamount + helper.rand(7) * 10);
|
|
}
|
|
}
|
|
else { // checkphase
|
|
if(env.winchance > 7000) { // decend hand, raise
|
|
if(helper.rand(5) === 1) { // 20%
|
|
action = 'r ' + (env.callamount + helper.rand(5) * 10);
|
|
}
|
|
}
|
|
else if(env.winchance > 15000) { // good hand lol
|
|
if(helper.rand(2) === 1) { // 50%
|
|
action = 'r ' + (env.callamount + helper.rand(6) * 10);
|
|
}
|
|
}
|
|
else if(env.winchance > 20000) { // fuck them all
|
|
action = 'r ' + (env.callamount + helper.rand(7) * 10);
|
|
}
|
|
}
|
|
|
|
if(action) {
|
|
env.lastaction = action;
|
|
return e.reply(action);
|
|
}
|
|
}
|
|
|
|
// gamestate & board changes
|
|
if(e.message.match(/^(Flop|Turn|River)/)) {
|
|
env.board = helper.parseCards(e.message);
|
|
env.gamestate = e.message.match(/(\w+): /)[1].toLowerCase();
|
|
|
|
const rank = handranker.evalHand([...env.board, ...env.hand]);
|
|
env.winchance = rank.value;
|
|
}
|
|
|
|
// end of game
|
|
if(e.message.includes('wins the pot') || e.message.includes('Split pot')) {
|
|
if(e.message.includes(e.self.me.nickname)) {
|
|
if(e.message.includes('Split pot')) {
|
|
const tmp = e.message.match(/size (\d+) .*: (.*) \(/);
|
|
env.bank += ~~(tmp[1] / tmp[2].split(', ').length);
|
|
}
|
|
else {
|
|
env.bank += +e.message.match(/pot(: | of size )(\d+)/)[2];
|
|
}
|
|
}
|
|
|
|
env.gamestate = 'preflop';
|
|
env.hand = false;
|
|
env.board = false;
|
|
env.winchance = false;
|
|
env.joined = false;
|
|
env.pot = 0;
|
|
env.lastaction = false;
|
|
return;
|
|
}
|
|
|
|
if(cfg.get('debug'))
|
|
console.log(env);
|
|
});
|