diff --git a/exec/ircbots/poker/poker_commands.js b/exec/ircbots/poker/poker_commands.js new file mode 100644 index 0000000000000000000000000000000000000000..eae7df6a2a1194b6586256cb007ba9ac716db596 --- /dev/null +++ b/exec/ircbots/poker/poker_commands.js @@ -0,0 +1,152 @@ +this.Bot_Commands["DEAL"] = new Bot_Command(0,false,false); +this.Bot_Commands["DEAL"].command = function (target,onick,ouh,srv,lvl,cmd) { + cmd.shift(); + if (!poker_games[target]) { + srv.o(target, onick + " just started a new poker hand. To get " + + "in on the action, type '" + get_cmd_prefix() + "DEAL'"); + srv.o(target, "Seats will remain open for the next 60 seconds, " + + "or until someone types '" + get_cmd_prefix() + "GO'"); + poker_games[target] = new Poker_Game(); + poker_games[target].users[onick.toUpperCase()]=new Poker_Player(); + } else if (poker_games[target].users[onick.toUpperCase()]) { + srv.o(target, onick + ", you're already in the hand. Relax, don't do it."); + } else { + poker_games[target].users[onick.toUpperCase()]=new Poker_Player(); + srv.o(target, onick + " has been dealt in for this hand."); + } + return; +} + +this.Bot_Commands["GO"] = new Bot_Command(0,false,false); +this.Bot_Commands["GO"].command = function (target,onick,ouh,srv,lvl,cmd) { + cmd.shift(); + if (!poker_games[target]) { + srv.o(target, "No poker game to 'GO' with. Type '" + get_cmd_prefix() + "DEAL' to " + + "start a new one."); + return; + } else if(poker_games[target].round>0) { + srv.o(target, "This hand has already started."); + return; + } + if(true_array_len(poker_games[target].users)==1) { + srv.o(target, "At least two players are necessary to start the game."); + return; + } + poker_init_hand(target); + poker_deal_hole_cards(target,srv); + poker_prompt_player(target,srv); + return; +} + +this.Bot_Commands["FOLD"] = new Bot_Command(0,false,false); +this.Bot_Commands["FOLD"].command = function (target,onick,ouh,srv,lvl,cmd) { + if (!poker_games[target]) { + srv.o(target, onick + ", there is no game in progress."); + return; + } else if (!poker_games[target].users[onick.toUpperCase()]) { + srv.o(target, onick + ", you aren't playing this game."); + return; + } else if(poker_games[target].round<1) { + srv.o(target, onick + ", the game hasn't started yet."); + return; + } + + delete poker_games[target].users[onick.toUpperCase()]; + srv.o(target, onick + " folded their hand."); + poker_next_turn(target,srv); + return; +} + +this.Bot_Commands["CHECK"] = new Bot_Command(0,false,false); +this.Bot_Commands["CHECK"].command = function (target,onick,ouh,srv,lvl,cmd) { + if(!poker_verify_game_status(target,srv,onick)) return; + srv.o(target,onick + " checks."); + poker_next_turn(target,srv); + return; +} + +this.Bot_Commands["BET"] = new Bot_Command(0,false,false); +this.Bot_Commands["BET"].command = function (target,onick,ouh,srv,lvl,cmd) { + if(!poker_verify_game_status(target,srv,onick)) return; + if(!cmd[1]) { + srv.writeout("NOTICE " + p + " :" + "You must specify an amount to bet!"); + return; + } + var poker=poker_games[target]; + if(cmd[1]>poker.users[onick.toUpperCase()].money) { + srv.writeout("NOTICE " + p + " :" + "You don't have that much money!"); + srv.writeout("NOTICE " + p + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + return; + } + if(cmd[1]<poker.current_bet) { + srv.writeout("NOTICE " + p + " :" + "You must meet the minimum bet!"); + srv.writeout("NOTICE " + p + " :" + "Minimum bet: $" + poker.current_bet); + return; + } + srv.o(target,onick + " bets $" + cmd[1]); + poker.users[onick.toUpperCase()].money-=Number(cmd[1]); + poker.users[onick.toUpperCase()].bet+=Number(cmd[1]); + poker.current_bet=Number(cmd[1]); + srv.writeout("NOTICE " + onick + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + poker_next_turn(target,srv); + return; +} + +this.Bot_Commands["CALL"] = new Bot_Command(0,false,false); +this.Bot_Commands["CALL"].command = function (target,onick,ouh,srv,lvl,cmd) { + if(!poker_verify_game_status(target,srv,onick)) return; + var poker=poker_games[target]; + if(poker.current_bet>poker.users[onick.toUpperCase()].money) { + srv.writeout("NOTICE " + onick + " :" + "You don't have enough to call!"); + srv.writeout("NOTICE " + onick + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + return; + } + srv.o(target,onick + " calls the bet: $" + poker.current_bet); + poker.users[onick.toUpperCase()].money-=poker.current_bet; + poker.users[onick.toUpperCase()].bet+=poker.current_bet; + srv.writeout("NOTICE " + onick + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + poker_next_turn(target,srv); + return; +} + +this.Bot_Commands["RAISE"] = new Bot_Command(0,false,false); +this.Bot_Commands["RAISE"].command = function (target,onick,ouh,srv,lvl,cmd) { + if(!poker_verify_game_status(target,srv,onick)) return; + if(!cmd[1]) { + srv.writeout("NOTICE " + onick + " :" + "You must specify an amount to raise!"); + return; + } + var poker=poker_games[target]; + var bet=Number(cmd[1]); + if(poker.current_bet+bet>poker.users[onick.toUpperCase()].money) { + srv.writeout("NOTICE " + onick + " :" + "You don't have that much money!"); + srv.writeout("NOTICE " + onick + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + return; + } + srv.o(target,onick + " raises the bet to $" + poker.current_bet+bet); + poker.users[onick.toUpperCase()].money-=bet; + poker.users[onick.toUpperCase()].bet+=bet; + poker.current_bet+=bet; + srv.writeout("NOTICE " + onick + " :" + "Balance: $" + poker.users[onick.toUpperCase()].money); + poker_next_turn(target,srv); + return; +} + +this.Bot_Commands["STATUS"] = new Bot_Command(0,false,false); +this.Bot_Commands["STATUS"].command = function (target,onick,ouh,srv,lvl,cmd) { + return; +} + +this.Bot_Commands["LIST"] = new Bot_Command(0,false,false); +this.Bot_Commands["LIST"].command = function (target,onick,ouh,srv,lvl,cmd) { + if(!poker_games[target]) { + srv.o(target,"There is no active game."); + return; + } + var list=""; + for(u in poker_games[target].users) { + list+=" "+u; + } + srv.o(target,"Poker players:" + list); + return; +} \ No newline at end of file diff --git a/exec/ircbots/poker/poker_functions.js b/exec/ircbots/poker/poker_functions.js new file mode 100644 index 0000000000000000000000000000000000000000..49a38a41d57f0e380dd50f7e8360e9749486eb9e --- /dev/null +++ b/exec/ircbots/poker/poker_functions.js @@ -0,0 +1,169 @@ +/* IRC Bot Module - Server Commands + You would place all of your module functions in this file. */ + +this.Server_command=function(srv,cmdline,onick,ouh) +{ + var cmd=IRC_parsecommand(cmdline); + switch (cmd[0]) { + case "JOIN": + if (onick == srv.curnick) break; + + // Someone else joining? Let's send them a private welcome message! + srv.o(onick,"Welcome to Poker!"); + srv.o(onick,"This is a module for IRCBot - by Cyan"); + break; + case "PRIVMSG": + if ((cmd[1][0] == "#") || (cmd[1][0] == "&")) { + var chan = srv.channel[cmd[1].toUpperCase()]; + if (!chan) + break; + if (!chan.is_joined) + break; + if(srv.users[onick.toUpperCase()]) { + /* You can do special command processing here, if you like. + This is currently set up to parse public room messages for + things like trivia answers, or other responses that + are inconvenient for users to submit with a command prefix */ + } + } + break; + default: + break; + } +} + +//////////////////// Non-object Functions //////////////////// +function poker_deal_hole_cards(target,srv) { + var poker_game=poker_games[target]; + poker_game.round = 1; + for (p in poker_game.users) { + poker_game.users[p].cards[0] = poker_game.deck.deal(); + poker_game.users[p].cards[1] = poker_game.deck.deal(); + srv.writeout("NOTICE " + p + " :" + "Your hole cards: " + + poker_game.users[p].cards[0].color + "[ " + poker_game.users[p].cards[0].char + " ] " + + poker_game.users[p].cards[1].color + "[ " + poker_game.users[p].cards[1].char + " ]"); + } +} + +function poker_next_turn(target,srv) { + var poker=poker_games[target]; + poker.turn++; + if(poker.turn==poker.users_map.length) poker.turn=0; + + if(poker.deal_next) { + poker_load_pot(target,srv); + switch(++poker.round) { + case 1: + poker_deal_flop(target,srv); + break; + case 2: + poker_deal_turn(target,srv); + break; + case 3: + poker_deal_river(target,srv); + break; + } + poker.deal_next=false; + } else { + var turn_user=poker.users[poker.users_map[poker.turn]]; + if(poker.current_bet==turn_user.bet) poker.deal_next=true; + } + poker_prompt_player(target,srv); +} + +function poker_deal_flop(target,srv) { + var poker_game=poker_games[target]; + poker_game.round = 2; + poker_game.community_cards[0] = poker_game.deck.deal(); + poker_game.community_cards[1] = poker_game.deck.deal(); + poker_game.community_cards[2] = poker_game.deck.deal(); + srv.writeout("PRIVMSG " + target + " :The Flop: " + + poker_show_card(poker_game.community_cards[0]) + + poker_show_card(poker_game.community_cards[1]) + + poker_show_card(poker_game.community_cards[2])); +} + +function poker_deal_turn(target,srv) { + var poker_game=poker_games[target]; + poker_game.round = 3; + poker_game.community_cards[3] = poker_game.deck.deal(); + srv.writeout("PRIVMSG " + target + " :The Turn: " + + poker_show_card(poker_game.community_cards[0]) + + poker_show_card(poker_game.community_cards[1]) + + poker_show_card(poker_game.community_cards[2]) + + poker_show_card(poker_game.community_cards[3])); +} + +function poker_deal_river(target,srv) { + var poker_game=poker_games[target]; + poker_game.round = 4; + poker_game.community_cards[4] = poker_game.deck.deal(); + srv.writeout("PRIVMSG " + target + " :The River: " + + poker_show_card(poker_game.community_cards[0]) + + poker_show_card(poker_game.community_cards[1]) + + poker_show_card(poker_game.community_cards[2]) + + poker_show_card(poker_game.community_cards[3]) + + poker_show_card(poker_game.community_cards[4])); +} + +function poker_show_card(card) { + return(card.color + "[ " + card.char + " ]"); +} + +function poker_load_pot(target,srv) { + var poker=poker_games[target]; + for(var p in poker.users) { + poker.pot+=poker.users[p].bet; + poker.users[p].bet=0; + } + srv.o(target,"Current pot: $" + poker.pot); + return; +} + +function poker_prompt_player(target,srv) { + var poker=poker_games[target]; + var turn=poker.users_map[poker.turn]; + srv.writeout("NOTICE " + turn + " :" + "It is your turn. You may CHECK, CALL, BET, RAISE or FOLD"); + srv.writeout("NOTICE " + turn + " :" + "Minimum bet: $" + poker.current_bet); +} + +function poker_verify_game_status(target,srv,onick) { + var poker=poker_games[target]; + if (!poker) { + srv.o(target, "No poker game in progress. Type '" + get_cmd_prefix() + "DEAL' to " + + "start a new one."); + return false; + } + if(!poker.users[onick.toUpperCase()]) { + srv.o(onick, "You're not even in the hand!"); + return false; + } + var turn_player=poker.users_map[poker.turn]; + if (turn_player != onick.toUpperCase()) { + srv.o(target, "Acting out of turn?"); + return false; + } + return true; +} + +function poker_init_hand(target) { + poker_games[target].deck.shuffle(); + for(var u in poker_games[target].users) { + poker_games[target].users_map.push(u); + } +} + +function load_scores() +{ + var s_file=new File(poker_dir + "scores.ini"); + if(s_file.open(file_exists(s_file.name)?"r+":"w+")) { + writeln("reading scores from file: " + s_file.name); + var players=s_file.iniGetKeys(); + for(var p in players) { + writeln("loading player score: " + players[p]); + poker_scores[players[p]]=s_file.iniGetValue(null,players[p]); + } + s_file.close(); + } +} + diff --git a/exec/ircbots/poker/pokerbot.js b/exec/ircbots/poker/pokerbot.js new file mode 100644 index 0000000000000000000000000000000000000000..1a3cb9d2e34d47485bed9f206123ee447444040d --- /dev/null +++ b/exec/ircbots/poker/pokerbot.js @@ -0,0 +1,72 @@ +var poker_dir=this.dir; +var poker_scores=[]; +var notice_interval=10; //seconds +var activity_timeout=120; +var poker_games=[]; + +this.save=function() +{ + var s_file=new File(poker_dir + "scores.ini"); + if(!s_file.open(file_exists(s_file.name)?"r+":"w+")) return false; + writeln("writing scores to file: " + s_file.name); + for(s in poker_scores) { + s_file.iniSetValue(null,s,poker_scores[s]); + } + s_file.close(); +} +this.main=function(srv,target) +{ + var poker=poker_games[target]; + if(!poker || poker.paused) return; + var active_users=false; + for(var u in srv.users) { + if(poker.users[u]) { + if(time()-srv.users[u].last_spoke<activity_timeout){ + active_users=true; + break; + } else { + delete poker.users[u]; + srv.o(u,"You have been idle too long. Type 'DEAL' here to resume playing poker."); + } + } + } + if(!active_users) return; + + if(poker.cycle()) { + } +} + +function Poker_Game() +{ + this.last_update=0; + this.turn=0; + this.pot=0; + this.lg_blind=10; + this.sm_blind=5; + this.min_bet=this.sm_blind; + this.current_bet=this.min_bet; + this.round=0; + this.deck=new Deck(); + this.community_cards=new Array(); + this.paused=false; + this.users=[]; + this.users_map=[]; + + this.cycle=function() + { + if(time()-this.last_update>=notice_interval) { + this.last_update=time(); + return true; + } + return false + } + this.deck.shuffle(); +} +function Poker_Player() +{ + this.cards=[]; + this.money=100; + this.bet=0; +} + +load_scores();