
   /*****************************
   * Johnny's blackjack mod
   ******************************
   *
   * Try it out on my server! [DuDeS] - Freakin Sweet
   * 129.237.51.145:27015
   *
   ******************************
   *
   * And yes, I fully realize that there can be more than 4
   * of any card (aces, 2's, 3's), but I don't think anybody
   * really cares that much.
   *
   * CVARS:
   * amx_blackjack_enabled  -- 0 = off
   *                           1 = on
   *
   * amx_blackjack_deadonly -- 0 = off
   *                           1 = on
   * COMMANDS:
   * amx_blackjack  -- starts a fun fun game of blackjack.
   * say blackjack  -- also starts a fun fun game of blackjack.
   *
   *****************************/
   #include <amxmod>
   #include <amxmisc>
   /*********************************************************************
   *****/
   /***********************       DECLARATIONS         ******************
   *****/
   /*********************************************************************
   *****/
   #define MAX_CARDS 22
   #define MAX_MENU_CHARS 256
   // Each player's cards.
   new player_cards[32][MAX_CARDS]
   // The cards of the dealer (unique to each player of course).
   new dealer_cards[32][MAX_CARDS]
   // Each player's bet amount.
   new player_bet[32]
   /*********************************************************************
   *****/
   /***********************       THE ACTUAL
   CODE      ***********************/
   /*********************************************************************
   *****/
   public StartBlackJack(id)
   {
       new card_num
       if (get_cvar_num("amx_blackjack_enabled") == 0)
       {
           client_print(id,print_chat,"[BLKJK]    Sorry,   blackjack   is
   currently disabled.")
       }
       else if (is_user_alive(id) &&
   get_cvar_num("amx_blackjack_deadonly") == 1)
       {
           client_print(id,print_chat,"[BLKJK]  You  can't play blackjack
   while you're alive, dummy.")
       }
       else
       {
           // Reset the cards for this player (and their dealer)
           for(card_num=0; card_num < MAX_CARDS; card_num++)
           {
               player_cards[id][card_num] = 0
               dealer_cards[id][card_num] = 0
           }
           // Give this player (and their dealer) a couple random cards.
           player_cards[id][0] = random_num(1,13)
           player_cards[id][1] = random_num(1,13)
           dealer_cards[id][0] = random_num(1,13)
           dealer_cards[id][1] = random_num(1,13)

           // This player has bet no money yet, yo.
           player_bet[id] = 0
           // Show the betting menu.
           ShowBetMenu(id)
       }
       return PLUGIN_CONTINUE
   }
   ShowBetMenu(id)
   {
       new user_base_cash
       new user_money
       new menu_body[256]
       new menu_keys
       new View1000, View100, View10, View1
       /////////////////
       // Format the blackjack menu.
       /////////////////
       // Currently they can only press number 5 (for no money) or 0 (for
   exit)
       menu_keys = (1<<4)|(1<<9)
       // Get how much money they have available.
       user_base_cash = get_user_money(id)
       user_money = user_base_cash - player_bet[id]
       // Enable/disable menu commands according to funds.
       View1000 = View100 = View10 = View1 = 'd'
       if (user_money >= 1000)
       {
           View1000 = 'w'
           menu_keys |= (1<<0)
       }
       if (user_money >= 100)
       {
           View100 = 'w'
           menu_keys |= (1<<1)
       }
       if (user_money >= 10)
       {
           View10 = 'w'
           menu_keys |= (1<<2)
       }
       if (user_money >= 1)
       {
           View1 = 'w'
           menu_keys |= (1<<3)
       }

       // Put it all together in a big string.
       format(menu_body,256,"\y[BLKJK]  Set  your  bet:^n^nCurrent funds:
   %d^nCurrent  bet:  %d^n\%c1.  1000^n\%c2. 100^n\%c3. 10^n\%c4. 1^n\w5.
   Done^n^n\w0.  Nuts  to  this. (exit)", user_base_cash, player_bet[id],
   View1000, View100, View10, View1)

       // Send it to the player.
       show_menu(id,menu_keys,menu_body,10)
   }
   public SetBet(id,key){
       switch(key)
       {
           case 0:
           {
               // Add to their bet.
               player_bet[id] += 1000
               ShowBetMenu(id)
           }
           case 1:
           {
               // Add to their bet.
               player_bet[id] += 100
               ShowBetMenu(id)
           }
           case 2:
           {
               // Add to their bet.
               player_bet[id] += 10
               ShowBetMenu(id)
           }
           case 3:
           {
               // Add to their bet.
               player_bet[id] += 1
               ShowBetMenu(id)
           }
           case 4:
           {
               // They're done betting.
               ShowGameMenu(id, false)
           }
       }
       return PLUGIN_HANDLED
   }
   ShowGameMenu(id, game_done)
   {
       new player_total = 0 // Player's total (of card values).
       new dealer_total = 0 // Dealer's total (of card values).
       new card_num         // Card incrementer.
       new player_has_ace   // Does the player have an ace?
       new dealer_has_ace   // Does the dealer have an ace?
       new  player_cards_string[MAX_CARDS  *  3]   //  A  string  for the
   player's cards.
       new  dealer_cards_string[MAX_CARDS  *  3]   //  A  string  for the
   dealer's cards.
       new card_temp_player[3] // A temporary card string.
       new card_temp_dealer[3] // A temporary card string.
       new menu_body[MAX_MENU_CHARS]  // The menu body message.
       new menu_keys       // The menu keys.
       new user_money
       player_has_ace = false
       dealer_has_ace = false
       for (card_num = 0; card_num < MAX_CARDS; card_num++)
       {
           switch(player_cards[id][card_num])
           {
               case 0:
               {
                   // No card in this slot.
               }
               case 1:
               {
                   // An ace.
                   player_has_ace = true
                   player_total += 1
                   add(player_cards_string, MAX_CARDS * 3, "A ");
               }
               case 11:
               {
                   // A Jack.
                   player_total += 10
                   add(player_cards_string, MAX_CARDS * 3, "J ");
               }
               case 12:
               {
                   // A Queen.
                   player_total += 10
                   add(player_cards_string, MAX_CARDS * 3, "Q ");
               }
               case 13:
               {
                   // A King.
                   player_total += 10
                   add(player_cards_string, MAX_CARDS * 3, "K ");
               }
               case 10:
               {
                   // A Ten.
                   player_total += 10
                   add(player_cards_string, MAX_CARDS * 3, "10 ");
               }
               default:
               {
                   // Just a simple number.
                   player_total += player_cards[id][card_num]
                   format(card_temp_player,3,"%d
   ",player_cards[id][card_num])
                   add(player_cards_string,      MAX_CARDS      *      3,
   card_temp_player)
               }
           }
       }
       if (player_total > 21)
       {
           game_done = true
       }
       else if(game_done)
       {
           // Player didn't bust, and the game's over.
           // The dealer needs to play.
           if (player_has_ace && (player_total < 12))
           {
               DealerPlay(id, player_total + 10)
           }
           else
           {
               DealerPlay(id, player_total)
           }
       }
       for (card_num = 0; card_num < MAX_CARDS; card_num++)
       {
           switch(dealer_cards[id][card_num])
           {
               case 0:
               {
                   // No card in this slot.
               }
               case 1:
               {
                   // An ace.
                   dealer_has_ace = true
                   dealer_total += 1
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "A ");
                   }
               }
               case 11:
               {
                   // A Jack.
                   dealer_total += 10
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "J ");
                   }
               }
               case 12:
               {
                   // A Queen.
                   dealer_total += 10
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "Q ");
                   }
               }
               case 13:
               {
                   // A King.
                   dealer_total += 10
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "K ");
                   }
               }
               case 10:
               {
                   // A Ten.
                   dealer_total += 10
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "10 ");
                   }
               }
               default:
               {
                   // Just a simple number.
                   dealer_total += dealer_cards[id][card_num]
                   if(card_num==0 && !game_done)
                   {
                       add(dealer_cards_string, MAX_CARDS * 3, "# ");
                   }
                   else
                   {
                       format(card_temp_dealer,3,"%d
   ",dealer_cards[id][card_num])
                       add(dealer_cards_string,     MAX_CARDS     *    3,
   card_temp_dealer)
                   }
               }
           }
       }
       /////////////////
       // Format the game menu.
       /////////////////
       if (game_done)
       {
           if (player_has_ace && (player_total < 12))
           {
               player_total += 10
           }
           if (dealer_has_ace && (dealer_total < 12))
           {
               dealer_total += 10
           }
           // They can only restart or exit.
           menu_keys = (1<<8)|(1<<9)
           // Get how much money they have.
           user_money = get_user_money(id)
           if (player_total > 21)
           {
               //They busted!
               format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]            Game
   state:^n^nDealer's  cards:   \w%s^n\yDealer's  total:   \w%d^n^n\yYour
   cards:     \w%s^n\yYour     total:      \w%d^n^n\rYou    lost!    (You
   busted)^n^n\w9.    Play    again!^n0.    Exit",   dealer_cards_string,
   dealer_total, player_cards_string, player_total)
               set_user_money(id,user_money - player_bet[id])
           }
           else if (dealer_total > 21)
           {
               //Dealer busted!
               format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]            Game
   state:^n^nDealer's  cards:   \w%s^n\yDealer's  total:   \w%d^n^n\yYour
   cards:     \w%s^n\yYour    total:      \w%d^n^n\wYou    won!   (Dealer
   busted)^n^n\w9.    Play    again!^n0.    Exit",   dealer_cards_string,
   dealer_total, player_cards_string, player_total)
               set_user_money(id,user_money + player_bet[id])
           }
           else
           {
               if (player_total > dealer_total)
               {
                   //They won
                   format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]        Game
   state:^n^nDealer's  cards:   \w%s^n\yDealer's  total:   \w%d^n^n\yYour
   cards:     \w%s^n\yYour  total:      \w%d^n^n\wYou  won!^n^n\w9.  Play
   again!^n0.       Exit",       dealer_cards_string,       dealer_total,
   player_cards_string, player_total)
                   set_user_money(id,user_money + player_bet[id])
               }
               else if(player_total < dealer_total)
               {
                   //Dealer won.
                   format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]        Game
   state:^n^nDealer's  cards:   \w%s^n\yDealer's  total:   \w%d^n^n\yYour
   cards:     \w%s^n\yYour  total:      \w%d^n^n\rYou  lost!^n^n\w9. Play
   again!^n0.       Exit",       dealer_cards_string,       dealer_total,
   player_cards_string, player_total)
                   set_user_money(id,user_money - player_bet[id])
               }
               else
               {
                   //Tie game.
                   format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]        Game
   state:^n^nDealer's  cards:   \w%s^n\yDealer's  total:   \w%d^n^n\yYour
   cards:     \w%s^n\yYour  total:      \w%d^n^n\wTie  game!^n^n\w9. Play
   again!^n0.       Exit",       dealer_cards_string,       dealer_total,
   player_cards_string, player_total)
               }
           }
       }
       else
       {
           // They can hit or stand.
           menu_keys = (1<<0)|(1<<1)

           // Format the game board and stuff.
           if (player_has_ace && (player_total < 12))
           {
               format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]            Game
   state:^n^nDealer's   cards:   \w%s^n^n\yYour   cards:     \w%s^n\yYour
   total:      \w%d  (or %d)^n^n\w1. Hit^n2. Stand", dealer_cards_string,
   player_cards_string, player_total, player_total + 10)
           }
           else
           {
               format(menu_body,MAX_MENU_CHARS,"\y[BLKJK]            Game
   state:^n^nDealer's   cards:   \w%s^n^n\yYour   cards:     \w%s^n\yYour
   total:      \w%d^n^n\w1.    Hit^n2.    Stand",    dealer_cards_string,
   player_cards_string, player_total)
           }
       }
       // Send it to the player.
       show_menu(id,menu_keys,menu_body)
   }
   DealerPlay(id, player_total)
   {
       new has_ace
       new dealer_total
       new card_num
       new done_playing
       new empty_slot = 0
       done_playing = false
       while(!done_playing)
       {
           for (card_num = 0; card_num < MAX_CARDS; card_num++)
           {
               switch(dealer_cards[id][card_num])
               {
                   case 0:
                   {
                       // No card in this slot.
                       if (empty_slot == 0)
                       {
                           empty_slot = card_num;
                       }
                   }
                   case 1:
                   {
                       // An ace.
                       has_ace = true;
                       dealer_total += 1
                   }
                   case 11:
                   {
                       // A Jack.
                       dealer_total += 10
                   }
                   case 12:
                   {
                       // A Queen.
                       dealer_total += 10
                   }
                   case 13:
                   {
                       // A King.
                       dealer_total += 10
                   }
                   default:
                   {
                       // Just a simple number.
                       dealer_total += dealer_cards[id][card_num]
                   }
               }
           }
           if (dealer_total >= player_total)
           {
               //  Dealers  don't  attempt to go over the value they need
   to.
               done_playing = true
           }
           else
           {
               if (has_ace && (dealer_total < 12))
               {
                   // Dealer has a significant ambiguous ace.
                   if (dealer_total + 10 >= player_total)
                   {
                       //  Dealer  +  ace  value (as 11) is over player's
   value.
                       done_playing = true
                   }
                   else
                   {
                       // Dealer's gonna risk not using the ace.
                       dealer_cards[id][empty_slot] = random_num(1,13)
                   }
               }
               else
               {
                   // Dealer decides to hit.
                   dealer_cards[id][empty_slot] = random_num(1,13)
               }
           }
       }
   }
   public PlayGame(id,key){
       new card_num       // A card number incrementer.
       new empty_slot = 0 // An empty card slot (to add a card to).
       switch(key)
       {
           case 0:
           {
               // They're hitting.
               for (card_num = 0; card_num < MAX_CARDS; card_num++)
               {
                   if  (player_cards[id][card_num]  == 0 && empty_slot ==
   0)
                   {
                       empty_slot = card_num;
                   }
               }
               player_cards[id][empty_slot] = random_num(1,13)
               ShowGameMenu(id, false)
           }
           case 1:
           {
               // They're standing.
               ShowGameMenu(id, true)
           }
           case 8:
           {
               //They want to play again! :D
               StartBlackJack(id)
           }
       }
       return PLUGIN_HANDLED
   }
   public plugin_init()
   {
       // This registers my great plugin
       register_plugin("Johnnys Blackjack","1.0","Johnny")
       // Registers the client commands.
       register_clcmd("say blackjack", "StartBlackJack")
       register_clcmd("amx_blackjack", "StartBlackJack")

       // This registers the menus.
       register_menucmd(register_menuid("[BLKJK]         Set         your
   bet:"),1023,"SetBet")
       register_menucmd(register_menuid("[BLKJK]                     Game
   state:"),1023,"PlayGame")
       // This registers the CVARS used.
       register_cvar("amx_blackjack_enabled","1")
       register_cvar("amx_blackjack_deadonly","1")
       return PLUGIN_CONTINUE
   }
   /*********************************************************************
   *****/
   /*********************************************************************
   *****/
   /*********************************************************************
   *****/
