BLACKJACK_MAX_BET=1000 BLACKJACK_MIN_BET=100 BLACKJACK_DEALER_AI=1 BLACKJACK_DEALER_RISK=20 BLACKJACK_DEALER_HIT=16 class Game_Deck #-------------------------------------------------------------------------- # * Constants #-------------------------------------------------------------------------- SUITS=["spades", "hearts", "diamonds", "clubs"] VALUES=['A','2','3','4','5','6','7','8','9','10','J','Q','K'] #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(num_decks = 1) # Setup Cards @cards = [] # Setup Deck @deck = [] # Setup Discarded @discard = [] # Setup In Play @in_play = [] # Setup Number of Decks @num_decks = num_decks # Setup Cards setup_cards # Shuffle shuffle end #-------------------------------------------------------------------------- # * Setup Cards #-------------------------------------------------------------------------- def setup_cards # Run Through number of decks times @num_decks.times do # Run Through Each Suit SUITS.each do |suit| # Run Through each value VALUES.each do |number| # Setup Card card = Game_Card.new(suit, number) # Push into cards array @deck.push(card) end end end end #-------------------------------------------------------------------------- # * Shuffle #-------------------------------------------------------------------------- def shuffle # Setup local variable cards cards = [] # Clear Discarded @discard.clear # Setup Cards to Deck @cards = [@deck].flatten! # Delete Cards already out delete_in_use_cards # Run through until cards are empty until @cards.empty? # Push a Random Card and Delete cards.push(@cards.delete_at(rand(@cards.size))) end # Set Cards to Cards @cards = cards end #-------------------------------------------------------------------------- # * Draw #-------------------------------------------------------------------------- def draw(number = 1) # Return if number is 1 if number == 1 # Shuffle if empty? shuffle if @cards.empty? # Get Card card = @cards.shift # Add Card to in play @in_play.push(card) # Return card return card end # Setup Array drawn = [] # Run Through number of times number.times do # Shuffle if empty? shuffle if @cards.empty? # Break if cards are still empty (all in play) break if @cards.empty? # Get Card card = @cards.shift # Add Card to in play @in_play.push(card) # Add to Drawn drawn.push(card) end # Return Drawn Cards return drawn end #-------------------------------------------------------------------------- # * Discard In Play #-------------------------------------------------------------------------- def discard # Add all in play cards to discard @discard += @in_play # Clear in play @in_play.clear end #-------------------------------------------------------------------------- # * Number #-------------------------------------------------------------------------- def number(*strings) # Setup Local Variable number = 0 # Run Through each card @cards.each do |card| # Run Through Each String Sent to this method strings.each do |string| # If A Suit if SUITS.include?(string) # Increase By 1 if suits are equal number += 1 if card.suit == string # If A Value elsif VALUES.include?(string) # Increase By 1 if values are equal number += 1 if card.value == string end end end return number end #-------------------------------------------------------------------------- # * Size #-------------------------------------------------------------------------- def size return @cards.size end #-------------------------------------------------------------------------- # * Delete Cards In Use #-------------------------------------------------------------------------- def delete_in_use_cards # Return if empty cards return if @in_play.empty? # Run Through each in play card and Delete Card from list @in_play.each {|card| @cards.delete(card)} # Clear In Play @in_play.clear end end class Game_Card #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :number attr_reader :suit attr_reader :value #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(suit, value, face10 = false, ace11 = false) @suit = suit @value = value @face10 = face10 @ace11 = ace11 @flipped = true setup_number end #-------------------------------------------------------------------------- # * Ace? #-------------------------------------------------------------------------- def ace? return @value == 'A' end #-------------------------------------------------------------------------- # * King? #-------------------------------------------------------------------------- def king? return @value == 'K' end #-------------------------------------------------------------------------- # * Queen? #-------------------------------------------------------------------------- def queen? return @value == 'Q' end #-------------------------------------------------------------------------- # * Jack? #-------------------------------------------------------------------------- def jack? return @value == 'J' end #-------------------------------------------------------------------------- # * Face? #-------------------------------------------------------------------------- def face? return ['J','Q','K'].include?(@value) end #-------------------------------------------------------------------------- # * Ten? #-------------------------------------------------------------------------- def ten? return @value == '10' || (self.face? and @face10) end def flipped return @flipped end def flipped=(value) @flipped=value end #-------------------------------------------------------------------------- # * To String (Returns card's value) #-------------------------------------------------------------------------- def to_s return self.value end #-------------------------------------------------------------------------- # * Setup Number (Private) #-------------------------------------------------------------------------- def setup_number case @value when 'A' @number = @ace11 ? 11 : 1 when 'J' @number = @face10 ? 10 : 11 when 'Q' @number = @face10 ? 10 : 12 when 'K' @number = @face10 ? 10 : 13 else @number = @value.to_i end end def self.createBack return _INTL("Graphics/Pictures/Cards/Backs/Pokemon") end def createBitmap if !@flipped return Game_Card.createBack end return sprintf("Graphics/Pictures/Cards/Normal/%s_%s",@suit,@value) end end class Game_CardHand #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize # Setup Cards @cards = [] end #-------------------------------------------------------------------------- # * Each (Runs Through Each Card in Hand) #-------------------------------------------------------------------------- def each @cards.each {|card| yield(card)} end #-------------------------------------------------------------------------- # * Cards #-------------------------------------------------------------------------- def cards return @cards.size end #-------------------------------------------------------------------------- # * Draw #-------------------------------------------------------------------------- def draw(*args) args.flatten! @cards.push(*args) @cards.each_with_index do |card, index| # Set Flipped Flag card.flipped = index != 0 end end #-------------------------------------------------------------------------- # * Discard #-------------------------------------------------------------------------- def discard @cards.clear end #-------------------------------------------------------------------------- # * To String (ex. A234K) #-------------------------------------------------------------------------- def to_s string = '' @cards.each {|card| string += card.to_s} return string end end class Game_BlackJackHand < Game_CardHand #-------------------------------------------------------------------------- # * Bust? #-------------------------------------------------------------------------- def bust? return self.total > 21 end #-------------------------------------------------------------------------- # * Black Jack #-------------------------------------------------------------------------- def blackjack? return ((@cards[0].ace? && @cards[1].ten?) || (@cards[1].ace? && @cards[0].ten?)) && @cards.size == 2 end #-------------------------------------------------------------------------- # * Double? #-------------------------------------------------------------------------- def double? return @cards.size == 2 end #-------------------------------------------------------------------------- # * Split #-------------------------------------------------------------------------- def split? return @cards[0].value == @cards[1].value && @cards.size == 2 end #-------------------------------------------------------------------------- # * Aces #-------------------------------------------------------------------------- def aces num = 0 @cards.each {|card| num += 1 if card.ace?} return num end #-------------------------------------------------------------------------- # * Total #-------------------------------------------------------------------------- def total(ace1 = false, countflipped=false) # Setup Number num = 0 # Add Up each {|card| num += card.number if card.flipped or countflipped} # Decrease ace value to 1 if over 21 self.aces.times { num -= 10 if num > 21 || ace1 } # Return total return num end #-------------------------------------------------------------------------- # * Value #-------------------------------------------------------------------------- def value return blackjack? ? 'BJ' : bust? ? 'Bust' : total.to_s end end class Blackjack_Scene def update pbUpdateSpriteHash(@sprites) pbDrawTable end def pbStart # Create sprite hash @sprites={} @deck=Game_Deck.new @playerhand=Game_BlackJackHand.new @dealerhand=Game_BlackJackHand.new @bet=0 @phase=0 # 0 = Bet, 1 = Game, 2 = End @viewport=Viewport.new(0,0,Graphics.width,Graphics.height) @viewport.z=99999 addBackgroundPlane(@sprites,"bg","Cards/background",@viewport) @sprites["overlay"]=BitmapSprite.new(Graphics.width,Graphics.height,@viewport) pbSetSystemFont(@sprites["overlay"].bitmap) pbDrawTable pbFadeInAndShow(@sprites) { update } end def pbReset if Kernel.pbConfirmMessage(_INTL("Would you like to play again?")) @deck=Game_Deck.new @playerhand=Game_BlackJackHand.new @dealerhand=Game_BlackJackHand.new @bet=0 @phase=0 # 0 = Bet, 1 = Game else @phase=2 end end def pbDrawTable overlay=@sprites["overlay"].bitmap overlay.clear baseColor=Color.new(248,248,248) shadowColor=Color.new(104,104,104) textPositions=[ [_INTL("Dealer's Hand"),38,58,0,baseColor,shadowColor], [_INTL("{1}",(@dealerhand.value rescue "N/A")),72,88,1,baseColor,shadowColor], [_INTL("{1}'s Hand",$Trainer.name),38,174,0,baseColor,shadowColor], [_INTL("{1}",(@playerhand.value rescue "N/A")),72,204,1,baseColor,shadowColor], [_INTL("BET: {1}",@bet),342,58,0,baseColor,shadowColor], [_INTL("COINS: {1}",$PokemonGlobal.coins),324,88,0,baseColor,shadowColor] ] pbDrawTextPositions(overlay,textPositions) imagePositions=[] x=170 for card in @playerhand imagePositions.push([card.createBitmap,x,174,0,0,-1,-1]) if @playerhand.cards<=3 x+=82 elsif @playerhand.cards<=7 x+=36 else x+=12 end end x=170 for card in @dealerhand imagePositions.push([card.createBitmap,x,80,0,0,-1,-1]) if @dealerhand.cards<=3 x+=82 elsif @dealerhand.cards<=7 x+=36 else x+=12 end end pbDrawImagePositions(overlay,imagePositions) end def pbMain loop do Graphics.update Input.update self.update case @phase when 0 params=ChooseNumberParams.new params.setRange(BLACKJACK_MIN_BET,BLACKJACK_MAX_BET) params.setInitialValue(BLACKJACK_MIN_BET) params.setCancelValue(0) qty=Kernel.pbMessageChooseNumber( _INTL("How much are you betting?"),params ) if qty>0 if $PokemonGlobal.coins>qty @phase=1 @bet=qty $PokemonGlobal.coins-=@bet @playerhand.draw(@deck.draw(2)) @playerhand.each{|card| card.flipped=true} @dealerhand.draw(@deck.draw(2)) else Kernel.pbMessage(_INTL("You don't have enough to bet that.")) end else Kernel.pbMessage(_INTL("Have a good day.")) break end when 1 commands=[_INTL("Hit"),_INTL("Stay")] commands.push(_INTL("Double")) if @playerhand.double? && !($PokemonGlobal.coins < @bet) action=Kernel.pbShowCommands(nil,commands) case action when 0 action_hit when 1 action_stay when 2 action_double end when 2 break end end end def action_hit player_draw if @playerhand.bust? start_cpu return end end def action_stay start_cpu end def action_double if $PokemonGlobal.coins < @bet return end $PokemonGlobal.coins-=@bet @bet*=2 player_draw start_cpu end def start_cpu if (@dealerhand.total(false,true) == 21 or @dealerhand.total(false,true) > @playerhand.total or @playerhand.blackjack? or @playerhand.bust?) # Start Checking Phase (Dealer Stands) start_check # Return return end case BLACKJACK_DEALER_AI when 0 # Hit 16 Stand 17 # If Less than or equal to 16 Draw Card Else Stand @dealerhand.total(false,false) <= 16 ? @dealerhand.draw(@deck.draw) : start_check when 1 # Hit When Advantageous # Get Total (All Aces are 1) amount = 21 - @dealerhand.total(true,true) # If Amount greater than or equal to 10 if amount >= 10 # Always Hit @dealerhand.draw(@deck.draw) # Return return end # Create Values values = ('2'..amount.to_s).to_a << 'A' # Get Number of Cards then won't make the dealer bust number = @deck.number(*values) # Get Size of Deck size = @deck.size # Get Chance of Not Busting if size != 0 chance = number * 100 / size else chance = 0 end # If chance is less than the riskiness or If value is less than minimum if (100 - chance <= BLACKJACK_DEALER_RISK || @dealerhand.total <= BLACKJACK_DEALER_HIT) # Hit Again @dealerhand.draw(@deck.draw) # Return return end # Else Dealer Stands start_check end end def player_draw @playerhand.draw(@deck.draw) @playerhand.each{|card| card.flipped=true} end def start_check self.update player, dealer = @playerhand.value, @dealerhand.value if @playerhand.bust? # Lose check_lose pbReset return end if @dealerhand.blackjack? and not @playerhand.blackjack? # Lose check_lose # Return pbReset return elsif @playerhand.blackjack? and not @dealerhand.blackjack? # Win check_win # Return pbReset return end if @playerhand.total > @dealerhand.total || @dealerhand.bust? # Win check_win # Return pbReset return # Push elsif @playerhand.total == @dealerhand.total # Push check_push # Return pbReset return # Lose else # Lose check_lose # Return pbReset return end end def check_lose Kernel.pbMessage(_INTL("\\me[Voltorb Flip Game Over]Oh no! You lost {1} Coins!\\wtnp[50]",@amount)) end def check_win winnings = (@bet * (@playerhand.blackjack? ? 2.5 : 2)).to_i Kernel.pbMessage(_INTL("\\me[Voltorb Flip Win]Congratulations! You won {1} Coins!\\wtnp[40]",winnings)) $PokemonGlobal.coins+=winnings end def check_push Kernel.pbMessage(_INTL("\\me[013-Gag02]It's a draw. You got a refund!\\wtnp[50]")) end def pbEnd pbFadeOutAndHide(@sprites) { update } pbDisposeSpriteHash(@sprites) @viewport.dispose end end class Blackjack_Screen def initialize(scene) @scene=scene end def pbStartScreen @scene.pbStart @scene.pbMain @scene.pbEnd end end def pbBlackJack if hasConst?(PBItems,:COINCASE) && $PokemonBag.pbQuantity(:COINCASE)<=0 Kernel.pbMessage(_INTL("You can't play unless you have a Coin Case.")) elsif $PokemonGlobal.coins==MAXCOINS Kernel.pbMessage(_INTL("Your Coin Case is full!")) else scene=Blackjack_Scene.new screen=Blackjack_Screen.new(scene) screen.pbStartScreen end end