Bots Home
|
Create an App
BlackJack21
Author:
harry241
Description
Source Code
Launch Bot
Current Users
Created by:
Harry241
/************************************************************* ** ** Title: Black Jack ** Author: harry241 ** Version: 1.0 ** Description: Tip to play a game of BlackJack against the model (the bank) and make the model perform goals. ** ** ** TODO: ** ===== ** ** - hide model commands ?? ** - model commands: show_players, show_winners ** - use of 3 different colors ?? change colors !! ** - display certain messages (to the model) only once per session: ** -- if a player is added and the round doesnt start automatically, msg the model to start with !bj_start ** - ** - keep track of points scored per player (add cmd for model to show list) ** *************************************************************/ var botVersion = "1.0"; var botCredits = "BlackJack v" + botVersion + " - created by harry241"; var privateFgColor = '#A52A2A'; var privateBgColor = '#F5F5DC'; var publicFgColor = '#000000'; var publicBgColor = '#FFA07A'; var bjRoundStarted = false; var bjPlayers = []; var bjPlayerNames = []; var bjCurrPlayer = 0; var bjBankCards; var bjCards = [ {card: '2', value: 2}, {card: '3', value: 3}, {card: '4', value: 4}, {card: '5', value: 5}, {card: '6', value: 6}, {card: '7', value: 7}, {card: '8', value: 8}, {card: '9', value: 9}, {card: '10', value: 10}, {card: 'J', value: 10}, {card: 'Q', value: 10}, {card: 'K', value: 10}, {card: 'A', value: 1} ]; var bjStack; var bjStats = {'ptsPlayers': 0, 'rndsPlayed': 0, 'startTime': 'now()'}; var bjActionText = 'Type "!hitme" if you want another card or "!stay" to stay.'; var bjWaitTurnText = 'It is not your turn.'; var bjBankWinsText = 'The bank wins this round!'; var bjEndRoundText = 'This round has ended, thank you for playing.'; cb.settings_choices = [ { name: 'bjTipAmount', label: 'Tip amount required to play a round of blackjack (for 1 point)', type: 'int', minValue: 1, maxValue: 999, required: true, defaultValue: 25 }, { name: 'bjGoalText', type: 'str', label: 'What is the goal you will perform when the players reach X points', defaultValue: '' }, { name: 'bjWinsNeeded', label: 'Number of points needed to perform goal', type: 'int', minValue: 1, maxValue: 999, required: true, defaultValue: 5 }, { name: 'bjAllowMultiples', label: 'Allow players to tip double, triple or more for additional points', type: 'choice', choice1:'Yes', choice2:'No', defaultValue: 'Yes' }, { name: 'bjAutoPlay', label: 'Enable auto-play feature for the bank (the model) (hit on 16 or lower, stay on 17 or higher)', type: 'choice', choice1:'Yes', choice2:'No', defaultValue: 'Yes' }, { name: 'bjWinLoseOn21', label: 'Who wins if both the bank and the player reach a total of 21', type: 'choice', choice1:'Bank', choice2:'Player', defaultValue: 'Player' }, { name: 'bjMaxPlayers', label: 'Maximum number of players allowed for 1 round of play', type: 'int', minValue: 1, maxValue: 5, required: true, defaultValue: 5 }, ]; cb.onMessage(function(message) { name = message['user']; msg = message['m']; var params; var isModel = (name == cb.room_slug); var isFan = message['in_fanclub']; var isMod = message['is_mod']; var hasTokens = message['has_tokens']; var isGrey = !(hasTokens || isMod || isModel || isFan); if (isModel) { // ** TEST VERSION: MANUAL TIP ** if (msg.search(/^ *!bj_tip +\S+ *$/) > -1) { params = msg.match(/^ *!bj_tip +(\S+) *$/); params['amount'] = params[1]; params['from_user'] = name; params['message'] = params[2]; debugMsg('** MANUAL TIP (TEST FEATURE) **'); manualTip(params); } // if the model wants to manually add a player if (msg.search(/^ *!bj_add +\S+ *(\d+)?$/) > -1) { // if the round hasnt started yet if (!bjRoundStarted) { params = msg.match(/^ *!bj_add +(\S+) *(\d+)?$/); debugMsg(params); params[2] = parseInt(params[2]); if (isNaN(params[2])) { params[2] = 1; } publicMsg('The bank added ' + params[1] + ' as a player for the next round of BlackJack.'); addPlayer(params[1],params[2]); } else { privateMsg('You cannot add players when a round of play is active.',name); } // if the model wants to manually start the round } else if (msg.search(/^ *!bj_start *?$/) > -1) { debugMsg('Command: manually start the round'); // if there are any players, start round if (bjPlayerNames.length > 0) { startRound(); } // if the model wants to manually start the round } else if (msg.search(/^ *!bj_stop *?$/) > -1) { debugMsg('Command: manually stop the round'); // if a round is active, end round if (bjRoundStarted) { endRound(); } // if the model wants to manually skip the current player } else if (msg.search(/^ *!bj_next *?$/) > -1) { debugMsg('Command: manually skip the current player'); // if a player is active if ((bjRoundStarted) && (bjCurrPlayer < bjPlayerNames.length)) { nextPlayer(); } // if the model wants to display the bot info } else if (msg.search(/^ *!bj_info *?$/) > -1) { debugMsg('Command: display bot info'); botInfo(); // if the model wants to display the bot statistics } else if (msg.search(/^ *!bj_stats *?$/) > -1) { debugMsg('Command: display bot statistics'); botStats(); // if the model wants to display the bot help } else if (msg.search(/^ *!bj_help *?$/) > -1) { debugMsg('Command: display bot help'); botHelp(); } // if it is the bank's turn if ((bjRoundStarted) && (bjCurrPlayer == bjPlayerNames.length)) { // if the bank wants another card if (msg.search(/^ *!hitme *$/) > -1) { actionHitMe(''); // if the bank wants to stay } else if (msg.search(/^ *!stay *$/) > -1) { actionStayBank(); } } } // if this is a player if (name in bjPlayers) { // if the player wants another card if (msg.search(/^ *!hitme *$/) > -1) { if (name == bjPlayerNames[bjCurrPlayer]) { actionHitMe(name); message['X-Spam'] = true; } else { privateMsg(bjWaitTurnText,name); } // if the player wants to stay } else if (msg.search(/^ *!stay *$/) > -1) { if (name == bjPlayerNames[bjCurrPlayer]) { actionStay(); message['X-Spam'] = true; } else { privateMsg(bjWaitTurnText,name); } } } return message; }); function manualTip(tip) { var tipAmount = parseInt(tip['amount']); var name = tip['from_user']; var msgText = tip['message']; var r = tipAmount%cb.settings.bjTipAmount; if (r==0) { var p = tipAmount/cb.settings.bjTipAmount; if (!bjRoundStarted) { publicMsg(name + ' tipped for a round of BlackJack.'); } addPlayer(name,p); } }; cb.onTip(function (tip) { manualTip(tip); }); function addPlayer(name,pts) { debugMsg('** ADD PLAYER (' + name + ' | ' + pts + ') **'); // if there is an active round if (bjRoundStarted) { privateMsg('You cannot tip for a round of play when a round is currently being played.',name) } else { if (cb.settings.bjAllowMultiples == "No") { pts = 1; } bjPlayers[name] = {'cards': [], 'points': pts}; bjPlayerNames.push(name); if (bjPlayerNames.length == cb.settings.bjMaxPlayers) { startRound(); } else { publicMsg('Players that tipped for a round of BlackJack:\n' + bjPlayerNames + '\n' + (cb.settings.bjMaxPlayers-bjPlayerNames.length) + ' more player(s) needed to start the round..'); // // send pvt msg to model about starting the round manually (once per session?) // } } } function clearPlayers() { debugMsg('** CLEAR PLAYERS **'); bjPlayers = []; bjPlayerNames = []; bjCurrPlayer = 0; } function startRound() { publicMsg('Starting a new round of BlackJack, dealing cards...'); bjRoundStarted = true; prepareCards(); var i = 1; for (p in bjPlayers) { debugMsg('PLAYER(' + i + '): ' + p); dealCards(p,false); i++; } dealCards(cb.room_slug,true); bjCurrPlayer = -1; nextPlayer(); } function endRound() { debugMsg('** END ROUND **'); clearPlayers(); bjStats.rndsPlayed++; bjRoundStarted = false; publicMsg(bjEndRoundText); botStats(); } function prepareCards() { bjBankCards = []; bjStack = bjCards; for (c in bjStack) { bjStack[c].count = 4; } } function dealCards(name,isModel) { var tot; if (!isModel) { debugMsg('** DEAL CARDS (' + name + ') **'); dealCard(name,true,false); dealCard(name,false,false); tot = countCards(bjPlayers[name].cards); privateMsg('Your cards are ' + bjPlayers[name].cards + ' for a total of ' + tot,name); } else { debugMsg('** DEAL BANK CARDS **'); dealCard(name,true,true); dealCard(name,false,true); tot = countCards(bjBankCards); publicMsg('The bank shows ' + (((bjBankCards[1]=='8')||(bjBankCards[1]=='A'))?'an ':'a ') + bjBankCards[1]); } } function dealCard(name,first,isModel) { var rnd = Math.floor(Math.random() * bjStack.length); //if (first) { rnd = 10; } else { rnd = 12; } bjStack[rnd].count--; //debugMsg('rnd: ' + rnd + ' (' + bjStack.length + ')'); if (!isModel) { bjPlayers[name].cards.push(bjStack[rnd].card); } else { bjBankCards.push(bjStack[rnd].card); } if (bjStack[rnd].count == 0) { bjStack.splice(rnd,1); } } function countCards(cards) { var tot = [0]; var val,max; //debugMsg(cards); for (c in cards) { switch (cards[c]) { case 'J': case 'Q': case 'K': val = 10; break; case 'A': val = 1; break; default: val = cards[c]*1; break; } for (i=0;i<tot.length;i++) { tot[i] += val; } if (val == 1) { tot[i] = tot[i-1] + 10; } } max = tot[0]; for (i=1;i<tot.length;i++) { if (tot[i]<=21) { max = tot[i]; } } //debugMsg('Total(s): ' + tot); return max; } function actionHitMe(name) { debugMsg('** HITME **'); var isModel = false; if (name == '') { name = cb.room_slug; isModel = true; } // deal extra card dealCard(name,false,isModel); if (isModel) { var c = bjBankCards[bjBankCards.length-1]; publicMsg("The bank's " + ordinal_suffix_of(bjBankCards.length) + ' card is ' + (((c=='8')||(c=='A'))?'an ':'a ') + c); actionCheckBank(); } else { var tot = countCards(bjPlayers[name].cards); //debugMsg('Total: ' + tot); var c = bjPlayers[name].cards[bjPlayers[name].cards.length-1]; publicMsg(name + "'s " + ordinal_suffix_of(bjPlayers[name].cards.length) + ' card is ' + (((c=='8')||(c=='A'))?'an ':'a ') + c); privateMsg('Your cards are ' + bjPlayers[name].cards + ' for a total of ' + tot,name); if (tot > 21) { publicMsg('Player ' + name + ' is bust!'); nextPlayer(); } else if (tot == 21) { // dont display this message, show something else ?? //publicMsg('Player ' + name + ' has 21!'); nextPlayer(); } else { // display card total and action msg to current player actionMsg(name,bjPlayers[name].cards); } } } function actionStay() { debugMsg('** STAY **'); publicMsg('Player ' + bjPlayerNames[bjCurrPlayer] + ' stays..'); nextPlayer(); } function actionStayBank() { var tot = countCards(bjBankCards); //debugMsg('Total: ' + tot); if (tot > 21) { publicMsg('The bank is bust!'); checkResults(tot); } else { // check the results and display scores checkResults(tot); } // end this round of play endRound(); } function actionCheckBank(tot) { var tot = countCards(bjBankCards); publicMsg('The bank is showing ' + bjBankCards + ' for a total of ' + tot); if (tot >= 21) { actionStayBank(); } else { if (cb.settings.bjAutoPlay == "Yes") { if (tot < 17) { actionHitMe(''); } else { publicMsg('The bank stays..'); actionStayBank(); } } else { // display card total and action msg to the model actionMsg(cb.room_slug,bjBankCards); } } } function checkResults(tot) { var p,t,pts = 0; for (p in bjPlayers) { t = countCards(bjPlayers[p].cards); if (t <= 21) { // if the bank hasnt busted if (tot <= 21) { // show the cards the player is holding publicMsg('Player ' + p + ' is showing ' + bjPlayers[p].cards + ' for a total of ' + t); } // if the player wins this round if ((t>tot) || (tot>21) || ((tot==21) && (t==21) && (cb.settings.bjWinLoseOn21=="Player"))) { publicMsg('Player ' + p + ' wins this round! (' + bjPlayers[p].points + ')',true); pts += bjPlayers[p].points; } else { publicMsg('Player ' + p + ' loses this round.'); } } } if (pts>0) { publicMsg('The player(s) scored a total of ' + pts + ' point' + ((pts==1)?'':'s') + ' this round.'); // calculate the number of times the goal was met var g1 = Math.floor(bjStats.ptsPlayers/cb.settings.bjWinsNeeded); // set the new total player points bjStats.ptsPlayers += pts; // calculate the number of times the goal should be met var g2 = Math.floor(bjStats.ptsPlayers/cb.settings.bjWinsNeeded); // if the goal was met if (g2 > g1) { var s = 'The model has to perform the goal: "' + cb.settings.bjGoalText + '"'; // if the goal has to be performed more than once if ((g2-g1) > 1) { s += ' (' + (g2-g1) + ' times)'; } publicMsg(s,true); } } } function nextPlayer() { debugMsg('** NEXT PLAYER **'); bjCurrPlayer++; if (bjCurrPlayer < bjPlayerNames.length) { var tot = countCards(bjPlayers[bjPlayerNames[bjCurrPlayer]].cards); if (tot == 21) { publicMsg('Player ' + bjPlayerNames[bjCurrPlayer] + ' stays..'); nextPlayer(); } else { publicMsg('It is ' + bjPlayerNames[bjCurrPlayer] + "'s turn, waiting for a response.."); // send card total and action msg to next player actionMsg(bjPlayerNames[bjCurrPlayer],bjPlayers[bjPlayerNames[bjCurrPlayer]].cards); } } else { var busted = true; for (p in bjPlayers) { if (countCards(bjPlayers[p].cards) <= 21) { busted = false; break; } } cb.log('busted: ' + busted); if (busted) { publicMsg(bjBankWinsText); endRound(); } else { actionCheckBank(); } } } function ordinal_suffix_of(i) { var j = i % 10, k = i % 100; if (j == 1 && k != 11) { return i + "st"; } if (j == 2 && k != 12) { return i + "nd"; } if (j == 3 && k != 13) { return i + "rd"; } return i + "th"; } function actionMsg(name,cards) { privateMsg(bjActionText,name); } function privateMsg(msg,name) { cb.sendNotice(msg,name,privateBgColor,privateFgColor); } function publicMsg(msg,bold) { cb.sendNotice(msg,'',publicBgColor,publicFgColor,(bold)?'bold':''); } function debugMsg(msg) { cb.log(msg); } function repeatChar(count,ch) { var txt = ""; for (var i = 0; i < count; i++) { txt += ch; } return txt; } function botStats() { var s = ''; s += botCredits + '\n\n'; s += 'This bot was started on ' + bjStats.startTime.toUTCString() + '\n'; s += 'So far there '+ ((bjStats.rndsPlayed==1)?'has':'have') + ' been ' + bjStats.rndsPlayed + ' round' + ((bjStats.rndsPlayed==1)?'':'s') + ' of play\n'; s += 'The players scored a total of ' + bjStats.ptsPlayers + ' point' + ((bjStats.ptsPlayers==1)?'':'s'); cb.sendNotice(s,'',privateBgColor,privateFgColor); } function botInfo() { var s = ''; s += botCredits + '\n'; s += repeatChar(botCredits.length,'*') + '\n'; s += 'Tip ' + cb.settings.bjTipAmount + ' to play a round of BlackJack (for 1 point)\n'; if (cb.settings.bjAllowMultiples == "Yes") { s += 'Tip double, triple or more to play for 2, 3 or more points per round\n'; } s += 'At every ' + cb.settings.bjWinsNeeded + ' points for the players, the model has to perform the goal:\n'; s += '"' + cb.settings.bjGoalText + '"'; cb.sendNotice(s,'',publicBgColor,publicFgColor); } function botHelp() { var s = ''; s += '\n'; s += 'Type "!bj_add <player_name> <points>" to manually add a player (points are optional)\n'; s += 'Type "!bj_start" to manually start the round of BlackJack\n'; s += 'Type "!bj_stop" to manually stop the round of BlackJack\n'; s += 'Type "!bj_next" to manually skip to the next player (in case of inactivity)\n'; s += '\n'; s += 'Type "!bj_info" to display the bot info\n'; s += 'Type "!bj_stats" to display the bot statistics\n'; s += 'Type "!bj_help" to display this help message\n'; cb.sendNotice(s,cb.room_slug,privateBgColor,privateFgColor); } function loadSettings() { bjStats.startTime = new Date(); botInfo(); botHelp(); } loadSettings();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.