[Add-On] BlackJack NPC

Skilled Illusionist
Joined
Dec 16, 2010
Messages
304
Reaction score
164
I haven't coded much recently, so I decided to make and release a BlackJack NPC.

Why should you choose my BlackJack NPC when there are others?
I haven't seen the other BlackJack NPCs, but I can prettymuch guarantee they aren't made as well.
My NPC features:
  • Very thoroughly done and tested.
  • Emulates an actual BlackJack game (very realistically) with a full deck and card hands that are manipulated throughout the game.
  • Multi-Functional ~ You can learn how to play, Play the Game, and Redeem your chips in this one NPC.

Anyways, here's the script & methods, there's some screenshots and some last words below.
PHP:
/**
*
* @author Sharky
* @info BlackJack NPC
*/
importPackage(java.lang);
var debug = false; // set to true for debugging checks to appear in your .bat files
var status = 0, bet, selected;
var whichFunction = {"HowToPlay" : false, "PlayGame" : false, "SpendChips" : false};
var playingAction = {"Hit" : false, "Stay" : false};
var CardsInDeck = [[], []], CardsInPlayerHand = [[], []], CardsInDealerHand = [[], []];
var prizes = [[4001008], [10]]; // Item 4001008 (Pass) costs 10 Chips
// var prizes = [[enter, item, ids, here, like, so], [enter, amount, of, chips, needed, for, corresponding, item, here, like, so]];

function start() {
cm.sendSimple("Hello! I'm the #rBlackJack Dealer#k.#b \r\n\t#L0#How do I play BlackJack?#l \r\n\t#L1#I'd like to play Black Jack!#l \r\n\t#L2#I'd like to trade in my Black Jack Chips for prizes!#l");
}

function action(m,t,s) {
if(m == -1 || (m != 1 && whichFunction["PlayGame"])) {
cm.dispose();
return;
} else {
if(m == 1) {
status++;
} else {
status--;
}
if(!whichFunction["HowToPlay"] && !whichFunction["PlayGame"] && !whichFunction["SpendChips"]) {
whichFunction[s == 0 ? "HowToPlay" : s == 1 ? "PlayGame" : "SpendChips"] = true;
}
if(whichFunction["HowToPlay"]) {
HowToPlay();
} else if (whichFunction["PlayGame"]) {
PlayGame(s);
} else if (whichFunction["SpendChips"]) {
SpendChips(s);
}
}
}

function HowToPlay() {
if(status == 1) {
if(debug) {
System.out.println("HowToPlay() is progressing...");
}
cm.sendNext("Alright, I see we have a noob here! No worries, I'll gladly teach you how to play the game of #rBlackJack#k!");
} else if (status == 2) {
cm.sendNextPrev("You will be given #bchips#k to play the game. These #bchips#k are your betting money! Before you are dealt any cards, you will have to place a bet. If you win the round, your money is doubled, and if you win the round with a #bBlack Jack#k (or 21), your money is returned 2.5x!");
} else if (status == 3) {
cm.sendNextPrev("In the beginning of the game, you will be dealt 2 cards. Look at these cards and add up the values. #bThe goal of the game is to get 21 (or the closest to it) when you add up all the cards in your hand#k. After doing this, you can choose to either #bHit#k (which is to draw another card), or #bStay#k. If you choose to #bhit#k, remember that going over 21 will cause you to #rBUST#k, or lose the game to the dealer. If you think you are close to 21 and want to #bstay#k, you and the dealer will compare cards, and whoever is the closest to 21 wins!");
} else if (status == 4) {
cm.sendPrev("Remember, if you lose, you lose all of the #bchips#k you have bet to the dealer! Good luck!");
} else if (status == 5) {
cm.dispose();
}
}	

function PlayGame(s) {
if(status == 1) {
if(debug) {
System.out.println("PlayGame() is progressing...");
}
if(cm.getPlayer().getBlackJackChips() == 0) {
cm.getPlayer().gainBlackJackChips(5);
}
cm.sendGetNumber("You currently have #b" + cm.getPlayer().getBlackJackChips() + " BlackJack Chips#k. How many #bchips#k would you like to bet this round?", 1, 1, cm.getPlayer().getBlackJackChips());
} else if (status == 2) {
if(s > 0 && s <= cm.getPlayer().getBlackJackChips()) { // packet edits
bet = s;
if(debug) {
System.out.println("Deck Initializing...");
}
InitializeGame();
var totP = GetTotalCardValue("Player"), totD = GetTotalCardValue("Dealer");
if(totD == 21 && CardsInDealerHand[0].length == 2 && totP == 21 && CardsInPlayerHand[0].length == 2) {
Finish("Tie");
} else if (totP == 21 && CardsInPlayerHand[0].length == 2) {
Finish("Player21");
} else if (totD == 21 && CardsInDealerHand[0].length == 2) {
Finish("Dealer21");
} else {
DisplayHandWithProgression();
}
}
} else if (status > 2) {
playingAction[s == 0 ? "Hit" : "Stay"] = true;
var totP, totD;
if(playingAction["Stay"]) {
if(debug) {
System.out.println("Player chose to Stay.");
}
if(totD < 16) {
CompleteDealer();
if(debug) {
System.out.println("Dealer was below 16 when the player chose to stay, Dealer was completed successfully.");
}
}
totP = GetTotalCardValue("Player"), totD = GetTotalCardValue("Dealer");
if(totP > 21 && totD > 21) {
Finish("DoubleBust");
} else if (totP > 21) {
Finish("PlayerBust");
} else if (totD > 21) {
Finish("DealerBust");
} else if(totP == totD) {
Finish("Tie");
} else if (totP == 21 && CardsInPlayerHand[0].length == 2) {
Finish("Player21");
} else if (totD == 21 && CardsInDealerHand[0].length == 2) {
Finish("Dealer21");
} else if (totP > totD) {
Finish("Win");
} else if (totP < totD) {
Finish("Lose");
}
} else if(playingAction["Hit"]) {
AddCardToHand();
totP = GetTotalCardValue("Player"), totD = GetTotalCardValue("Dealer");
if(totD == 21 && CardsInDealerHand[0].length == 2 && totP == 21 && CardsInPlayerHand[0].length == 2) {
Finish("Tie");
} else if (totP == 21 && CardsInPlayerHand[0].length == 2) {
Finish("Player21");
} else if (totD == 21 && CardsInDealerHand[0].length == 2) {
Finish("Dealer21");
} else if (totP > 21) {
Finish("PlayerBust");
} else if (totD > 21) {
Finish("DealerBust");
} else {
DisplayHandWithProgression();
}
}
}
}

function InitializeGame() {
var cardNames = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"];
var cardSuits = ["Hearts", "Spades", "Diamonds", "Clubs"];
for(var i = 0, a = 0; a < cardNames.length; i++) {
if(i == 4) {
a++;
i = 0;
}
CardsInDeck[0].push(cardNames[a]);
CardsInDeck[1].push(cardSuits[i]);
}
CardsInDeck[0].splice(-1);
CardsInDeck[1].splice(-1);
if(debug) {
for(var i = 0; i < CardsInDeck[0].length; i++) {
System.out.println(CardsInDeck[0][i] + " of " + CardsInDeck[1][i] + " pushed.");
}
}
AddCardToHand();
AddCardToHand();
}

function AddCardToHand() {
var random;
random = Math.floor(Math.random() * CardsInDeck[0].length);
CardsInPlayerHand[0].push(CardsInDeck[0][random]);
CardsInPlayerHand[1].push(CardsInDeck[1][random]);
if(debug) {
System.out.println("Card Added to Player Hand: " + CardsInDeck[0][random] + " of " + CardsInDeck[1][random]);
}
for(var i = 0; i < CardsInDeck[0].length; i++) {
if(CardsInPlayerHand[0][CardsInPlayerHand[0].length - 1] == CardsInDeck[0][i] && CardsInPlayerHand[1][CardsInPlayerHand[1].length - 1] == CardsInDeck[1][i]) {
if(debug) {
System.out.println("Card Spliced from Deck: " + CardsInDeck[0][i] + " of " + CardsInDeck[1][i]);
}
CardsInDeck[0].splice(i, 1);
CardsInDeck[1].splice(i, 1);
break;
}
}
if(GetTotalCardValue("Dealer") < 16) {
random = Math.floor(Math.random() * CardsInDeck[0].length);
CardsInDealerHand[0].push(CardsInDeck[0][random]);
CardsInDealerHand[1].push(CardsInDeck[1][random]);
if(debug) {
System.out.println("Card Added to Dealer Hand: " + CardsInDeck[0][random] + " of " + CardsInDeck[1][random]);
}
for(var i = 0; i < CardsInDeck[0].length; i++) {
if(CardsInDealerHand[0][CardsInDealerHand[0].length - 1] == CardsInDeck[0][i] && CardsInDealerHand[1][CardsInDealerHand[1].length - 1] == CardsInDeck[1][i]) {
if(debug) {
System.out.println("Card Spliced from Deck: " + CardsInDeck[0][i] + " of " + CardsInDeck[1][i]);
}
CardsInDeck[0].splice(i, 1);
CardsInDeck[1].splice(i, 1);
break;
}
}
}
}

function CompleteDealer() {
while (GetTotalCardValue("Dealer") < 16) {
var random = Math.floor(Math.random() * CardsInDeck[0].length);
CardsInDealerHand[0].push(CardsInDeck[0][random]);
CardsInDealerHand[1].push(CardsInDeck[1][random]);
if(debug) {
System.out.println("Card Added to Dealer Hand: " + CardsInDeck[0][random] + " of " + CardsInDeck[1][random]);
}
for(var i = 0; i < CardsInDeck[0].length; i++) {
if(CardsInDealerHand[0][CardsInDealerHand[0].length - 1] == CardsInDeck[0][i] && CardsInDealerHand[1][CardsInDealerHand.length - 1] == CardsInDeck[1][i]) {
if(debug) {
System.out.println("Card Spliced from Deck: " + CardsInDeck[0][i] + " of " + CardsInDeck[1][i]);
}
CardsInDeck[0].splice(i, 1);
CardsInDeck[1].splice(i, 1);
break;
}
}
}
}

function GetValueByName(name) {
var nums = [["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]];
for(var i = 0; i < nums[0].length; i++) {
if(name == nums[0][i]) {
return nums[1][i];
}
}
}

function DisplayHandWithProgression() {
var text = "#d#nCards in your hand:#k#e"
if(CardsInPlayerHand[0].length > 1) {
text += "\r\n#eFirst Card:#n #d" + CardsInPlayerHand[0][0] + "#k of " + (CardsInPlayerHand[1][0].equals("Hearts") || CardsInPlayerHand[1][0].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][0] + "#k") : CardsInPlayerHand[1][0]) +
"\r\n#eSecond Card:#n #d" + CardsInPlayerHand[0][1] + "#k of " + (CardsInPlayerHand[1][1].equals("Hearts") || CardsInPlayerHand[1][1].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][1] + "#k") : CardsInPlayerHand[1][1]);
}
if (CardsInPlayerHand[0].length > 2) {
text += "\r\n#eThird Card:#n #d" + CardsInPlayerHand[0][2] + "#k of " + (CardsInPlayerHand[1][2].equals("Hearts") || CardsInPlayerHand[1][2].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][2] + "#k") : CardsInPlayerHand[1][2]);
}
if (CardsInPlayerHand[0].length > 3) {
text += "\r\n#eFourth Card:#n #d" + CardsInPlayerHand[0][3] + "#k of " + (CardsInPlayerHand[1][3].equals("Hearts") || CardsInPlayerHand[1][3].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][3] + "#k") : CardsInPlayerHand[1][3]);
}
if (CardsInPlayerHand[0].length > 4) {
text += "\r\n#eFifth Card:#n #d" + CardsInPlayerHand[0][4] + "#k of " + (CardsInPlayerHand[1][4].equals("Hearts") || CardsInPlayerHand[1][4].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][4] + "#k") : CardsInPlayerHand[1][4]);
}
text += "\r\n\r\n#eTotal Card Value: #b" + GetTotalCardValue("Player");
if(CardsInPlayerHand[0].length > 4) {
text += "\r\nLooks like you'll have to #bstay#k and see how things turn out.#b \r\n\t#L1#Stay#l";
} else {
text += "\r\nWhat would you like to do?#b \r\n\t#L0#Hit#l \r\n\t#L1#Stay#l";
}
cm.sendSimple(text);
}

function GetTotalCardValue(name) {
var sum = 0;
if(name.equals("Player")) {
for(var i = 0; i < CardsInPlayerHand[0].length; i++) {
sum += GetValueByName(CardsInPlayerHand[0][i]);
}
} else if (name.equals("Dealer")) {
for(var i = 0; i < CardsInDealerHand[0].length; i++) {
sum += GetValueByName(CardsInDealerHand[0][i]);
}
}
return sum;
}

function Finish(action) {
if(action.equals("DoubleBust")) {
cm.sendOk("Looks like we both #rBUST#k! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + " \r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nI guess nobody wins here.");
} else if (action.equals("PlayerBust")) {
cm.sendOk("Hahaha, looks like you #rBUST#k! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + " \r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nSorry, but it looks like I'll be taking your #bchips#k!");
cm.getPlayer().gainBlackJackChips(-bet);
} else if (action.equals("DealerBust")) {
cm.sendOk("I can't believe it! I #rBUSTED#k! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + " \r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nLooks like you've won some #bchips#k!");
cm.getPlayer().gainBlackJackChips(bet);
} else if (action.equals("Tie")) {
cm.sendOk("We tied! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + "\r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nLooks like neither of us won...");
} else if (action.equals("Player21")) {
cm.sendOk("Wow! You have #rBlackJack#k! That means you got #r21 in Two Cards#k! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + " \r\nYou have won #b2.5x your Bet!#k");
cm.getPlayer().gainBlackJackChips(bet + (bet % 2 != 0 ? ((bet + 1) / 2) : (bet / 2)));
} else if (action.equals("Dealer21")) {
cm.sendOk("#rBLACKJACK!#k Haha, it looks like I won with #r21 in Two Cards#k! \r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nSorry, looks like I have to take your #bchips#k! Better luck next time!");
cm.getPlayer().gainBlackJackChips(-bet);
} else if (action.equals("Win")) {
cm.sendOk("I don't believe it. You won! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + "\r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nIt looks like you've won some #bchips#k!");
cm.getPlayer().gainBlackJackChips(bet);
} else if (action.equals("Lose")) {
cm.sendOk("Haha, looks like you lost! \r\n#bYour Hand:#k \r\n\t" + DisplayCardsInHand("Player") + "\r\n#rMy Hand:#k \r\n\t" + DisplayCardsInHand("Dealer") + " \r\nI'm sorry, but I'm going to have to take your #bchips#k! Better luck next time!");
cm.getPlayer().gainBlackJackChips(-bet);
}
if(debug) {
System.out.println("Finish() carried out with a " + action);
}
cm.dispose();
}

function DisplayCardsInHand(name) {
var cards = "";
if(name.equals("Player")) {
for(var i = 0; i < CardsInPlayerHand[0].length; i++) {
cards += ("#d" + CardsInPlayerHand[0][i] + "#k of " + (CardsInPlayerHand[1][i].equals("Hearts") || CardsInPlayerHand[1][i].equals("Diamonds") ? ("#r" + CardsInPlayerHand[1][i] + "#k") : CardsInPlayerHand[1][i]) + (i != (CardsInPlayerHand[0].length - 1) ? ", " : "."));
}
} else if (name.equals("Dealer")) {
for(var i = 0; i < CardsInDealerHand[0].length; i++) {
cards += ("#d" + CardsInDealerHand[0][i] + "#k of " + (CardsInDealerHand[1][i].equals("Hearts") || CardsInDealerHand[1][i].equals("Diamonds") ? ("#r" + CardsInDealerHand[1][i] + "#k") : CardsInDealerHand[1][i]) + (i != (CardsInDealerHand[0].length - 1) ? ", " : "."));
}
}
return cards;
}

function SpendChips(s) {
if(status == 1) {
if(debug) {
System.out.println("SpendChips() progressing...");
}
var text = "You currently have #b" + cm.getPlayer().getBlackJackChips() + " Black Jack Chips#k. What would you like to purchase?";
for(var i = 0; i < prizes[0].length; text += "\r\n#L" + i + "##i" + prizes[0][i] + "##b ~ #t" + prizes[0][i] + "##k for #r" + prizes[1][i] + " Black Jack Chips#k#l", i++);
cm.sendSimple(text);
} else if (status == 2) {
selected = s;
cm.sendYesNo("Are you sure you want to buy a #i" + prizes[0][s] + "##b ~ #t" + prizes[0][s] + "##k for #r" + prizes[0][s] + " Black Jack Chips#k?");
} else if (status == 3) {
if(cm.getPlayer().getBlackJackChips() >= prizes[1][selected]) {
cm.gainItem(prizes[0][selected]);
cm.getPlayer().gainBlackJackChips(-prizes[1][selected]);
cm.sendOk("Thanks for playing! Enjoy your prize, and come again!");
} else {
cm.sendOk("You need #r" + (prizes[1][selected] - cm.getPlayer().getBlackJackChips()) + " more Black Jack Chips#k for this prize!");
}
cm.dispose();
}
}

Put these in MapleCharacter.java: (IF you know how to save this to your database, it's a nice addition)
PHP:
private int blackjackchips;

public int getBlackJackChips() {
return blackjackchips;
}

public void gainBlackJackChips(int gain) {
blackjackchips += gain;
}

ScreenShots:
Sharky - [Add-On] BlackJack NPC - RaGEZONE Forums


Sharky - [Add-On] BlackJack NPC - RaGEZONE Forums


Sharky - [Add-On] BlackJack NPC - RaGEZONE Forums


Sharky - [Add-On] BlackJack NPC - RaGEZONE Forums


Sharky - [Add-On] BlackJack NPC - RaGEZONE Forums

There's a few things that could be improved, and I encourage anybody who thinks they can to shorten, optimize further, or improve this feature. Anyways, here's my list. People who give input may have their suggestion added to the list.
  • Aces have a value of strictly 11, whereas in BlackJack Aces can be interchangeably 11 or 1.
  • The cards are listed out, rather than displayed looking like a card (I tried this, but it was too boring, so I didn't finish).
  • It seems like the code is a bit excess in places and could be trimmed down.
  • Add wz images to make it look nicer. ~ iAkira

Thanks for reading :)
 
Last edited:
seems 'ok' I find it a bit plain if you ask me like you could use some images from wz for something to make it more creative somehow

The cards are listed out, rather than displayed looking like a card (I tried this, but it was too boring, so I didn't finish).

Still, if you wouldn't of gotten bored with images it would of been better.

Good npc though. :)
 
I believe there's a chip item. I'm not 100% positive on that, but I'm fairly sure. I'll look around if I have the time. I think it'd go great with this. Nice job on it.
If you can find it, I'll add it into the NPC, as well as something to make the Cards look nicer ;)
 
don't look so intresting .. don't get mad at me i'm just saying in my own perspective .. but anyway's keep up the good work..
 
Nice job on the NPC.

For variable aces, you could adapt some of this code:
Code:
function calcHandValue(cards) {
    if (cards.length == 2) { //Figure out BlackJack first =.=;;
        if (cards[0] == "A" && (cards[1] == "10" || cards[1] == "J" || cards[1] == "Q" || cards[1] == "K"))
            return "BlackJack";
        if (cards[1] == "A" && (cards[0] == "10" || cards[0] == "J" || cards[0] == "Q" || cards[0] == "K"))
            return "BlackJack";
    }
    var ret = 0;
    var numAces = 0; //Stupid variable aces....
    for (var i = 0;i < cards.length;i++)
        if (!isNaN(cards[i]))
            ret += Number(cards[i]);
        else {
            if (cards[i] == "A") {
                numAces++;
                ret += 11;
            } else
                ret += 10;
        }
    while (numAces > 0 && ret > 21) {
        numAces --;
        ret -= 10;
    }
    return ret;
}

(See http://forum.ragezone.com/5940283-post43.html for the above code in context)

For numbers/letters, you could use the standard Green or Red letters
3990000 - 3991051

For card suits, I think Osiris pointed out some in his post:
http://forum.ragezone.com/6308566-post7.html
 
Nice job on the NPC.

For variable aces, you could adapt some of this code:
Code:
function calcHandValue(cards) {
    if (cards.length == 2) { //Figure out BlackJack first =.=;;
        if (cards[0] == "A" && (cards[1] == "10" || cards[1] == "J" || cards[1] == "Q" || cards[1] == "K"))
            return "BlackJack";
        if (cards[1] == "A" && (cards[0] == "10" || cards[0] == "J" || cards[0] == "Q" || cards[0] == "K"))
            return "BlackJack";
    }
    var ret = 0;
    var numAces = 0; //Stupid variable aces....
    for (var i = 0;i < cards.length;i++)
        if (!isNaN(cards[i]))
            ret += Number(cards[i]);
        else {
            if (cards[i] == "A") {
                numAces++;
                ret += 11;
            } else
                ret += 10;
        }
    while (numAces > 0 && ret > 21) {
        numAces --;
        ret -= 10;
    }
    return ret;
}

(See http://forum.ragezone.com/5940283-post43.html for the above code in context)

For numbers/letters, you could use the standard Green or Red letters
3990000 - 3991051

For card suits, I think Osiris pointed out some in his post:
http://forum.ragezone.com/6308566-post7.html
Thanks a ton, this was really what I was looking for!
I may re-do the NPC with those items soon ;)

P.S. Had I known you made & publicly posted a BlackJack NPC, I would not have made this, because frankly, yours is every bit as good as mine, and probably better. I might make a Texas Holdem NPC, not sure if you already beat me to that? :mellow:
 
"
public void getBlackJackChips() {
return blackjackchips;
}
"
I'm sorry for saying that but when I'm getting this script into the MapleCharacter.Java
I'm getting a event over there "return blackjackchips;" If you know why is that could you help me over it please ?
CTRL + ALT says : "cannot return a value from method whose result type is void return blackjackchips;"
 
"
public void getBlackJackChips() {
return blackjackchips;
}
"
I'm sorry for saying that but when I'm getting this script into the MapleCharacter.Java
I'm getting a event over there "return blackjackchips;" If you know why is that could you help me over it please ?
CTRL + ALT says : "cannot return a value from method whose result type is void return blackjackchips;"

I would regularly delete post and give a warning / infraction for bumping old threads. But this is actually an useful comment that apparently no one noticed.

There is a mistake in Sharky's code. It should be:

PHP:
public int getBlackJackChips() {
    return blackjackchips;
}

Since obviously, void cannot return values.
 
I would regularly delete post and give a warning / infraction for bumping old threads. But this is actually an useful comment that apparently no one noticed.

There is a mistake in Sharky's code. It should be:

PHP:
public int getBlackJackChips() {
    return blackjackchips;
}

Since obviously, void cannot return values.
Shawn replaced the release from google cache (I assume), I'm pretty certain I edited it after I saw it. But thanks, edited again.
- back to hiding -
 
Back