=begin name: BlackJack v0.2 author: Dirk Meijer date: January 31st 2006 description: A simple BlackJack game using the Queen of Diamonds library, it uses a simple terminal window, until I have finished the graphic part. I'm probably about half-way through. =end require "Queen_Of_Diamonds" #addition to the Card class, an ace can only be degraded once, #otherwise certain situations would keep a player (or dealer) from losing class Card attr_accessor :ace_degraded end class Hand def calculate_score score=0 each do |card| if card.value == :A #if it's an ace score += 11 #add 11 points score -= 10 if card.ace_degraded elsif (2..10).include?(card.value) #if it's a 2 upto a 10 score += card.value #add that value else #if it's something else score += 10 #add 10 points end end if score>21 #if your hand is more than 21 each do |card| #each card if card.value == :A and card.ace_degraded != true #if an ace hasn't been degraded yet score-=10 if score>21 #turn 11 points from ace into 1 point if your score still > 21 card.ace_degraded = true #tell the ace that it has been degraded end end end score end end #the BlackJack class, which holds all the methods required to play blackjack class BlackJack attr_reader :player_score, :dealer_score, :player_hand, :dealer_hand, :winner, :money, :bet def initialize(money=50) @money=money end #the play methods, call this method to start a game def play loop do @deck = Deck.new.shuffle #create a new (and shuffled) deck @player_score=0 #your score is nullified @dealer_score=0 @turn=0 puts "---------------------------\n Money: #{@money}\n How much money would you like to bet?" bet=gets.to_i until (1..@money).include?(bet) puts "---------------------------\n Money: #{@money}\n How much money would you like to bet?" bet=gets.to_i end @bet=bet @money-=@bet @player_hand=@deck.stock(2).sort #you get two cards @player_score=@player_hand.calculate_score puts "---------------------------\n Player's hand:",@player_hand," Score: #{@player_score}" #show your score if @player_score==21 #if your score = 21 puts " Blackjack!" #tell player he has a blackjack @winner=:player #player wins @money+=(@bet*1.5).to_i next #tell game to end end option= :choose #the first option is choose loop do #until the game exits option=__send__(option) #each method will return a symbol that is a method name, which will be evaluated, when the game is supposed to end, this will be :exit break if option == :play end end end private #choose gives you four options, only the first two currently have effect def choose @turn+=1 puts "---------------------------\n Hit/Stand#{"/Double" if @turn==1 and ((9..11).include?(@player_score) or ([19,20].include?(@player_score) and (@player_hand[0].value==:A or @player_hand[1].value==:A))) and @money>=@bet}#{"/Split" if @turn==1 and @player_hand[0].value == @player_hand[1].value and @money>=@bet}#{"/Surrender" if @turn==1}?" #show options g=gets #get string if g=~/^h/i #if string starts with 'h' return :hit #tell program to hit elsif g=~/^st/i #if string starts with 'st' return :dealer_move #tell program your done elsif g=~/^d/i and @turn==1 and ((9..11).include?(@player_score) or ([19,20].include?(@player_score) and (@player_hand[0].value==:A or @player_hand[1].value==:A))) and @money>=@bet #if string starts with 'd' return :double #double elsif g=~/^sp/i and @turn==1 and @player_hand[0].value == @player_hand[1].value and @money>=@bet #if string starts with 'sp' return :split #split cards elsif g=~/^su/i and @turn==1 return :surrender else #if no option was chosen @turn-=1 return :choose #choose again end end #you get another card def hit card=@deck.stock(1) #pop a card from the deck (@player_hand+=card).sort! #add the popped card to hand @player_score=@player_hand.calculate_score puts "---------------------------\n Player's hand:",@player_hand," Score: #{@player_score}" #show your score if @player_score>21 #if the player's score > 21 puts " Bust!" #tell the player that @winner=:dealer #dealer wins return :stop #tell game to end end if @player_hand.size==5 #if player has 5 cards puts " Five cards!" #tell player @winner=:player #player wins return :stop #tell game to end end return :choose #if the game hasn't ended, tell the game you can choose again end #the dealers turn def dealer_move @dealer_score=0 #dealer score is nullified @dealer_hand=@deck.stock(2).sort #deal 2 cards @dealer_score=@dealer_hand.calculate_score puts "---------------------------\n Dealer's hand:",@dealer_hand," Score: #{@dealer_score}" #show dealer score if @dealer_score==21 #if blackjack puts " Blackjack!" #tell player @winner=:dealer #dealer wins return :stop #end the game end while @dealer_score<@player_score #dealer will continue to hit himself, until his score is no longer less than player score `pause` #game will pause, so the player can see what's going on card=@deck.stock(1) #pop a card @dealer_hand+=card #add the card to dealer hand @dealer_score=@dealer_hand.calculate_score puts "---------------------------\n Dealer's hand:",@dealer_hand," Score: #{@dealer_score}" #show dealers score if @dealer_score>21 #if dealer score exceeds 21 puts " Bust!" #tell player @winner=:player #player wins return :stop #end the game end if @dealer_hand.size==5 #if dealer holds 5 cards puts " Five cards!" #tell player @winner=:dealer #dealer wins return :stop #end game end end @winner=:dealer #when dealer score equal or is more than player score, dealer wins return :stop #end game end def double @money-=@bet @bet*=2 if @player_hand[0].value==:A @player_score-=10 @player_hand[0].ace_degraded=true elsif @player_hand[1].value==:A @player_score-=10 @player_hand[1].ace_degraded=true end card=@deck.stock(1) #pop a card from the deck (@player_hand+=card).sort! #add the popped card to hand @player_score=@player_hand.calculate_score puts "---------------------------\n Player's hand:",@player_hand," Score: #{@player_score}" #show your score if @player_score>21 #if the player's score > 21 puts " Bust!" #tell the player that @winner=:dealer #dealer wins return :stop #tell game to end end return :dealer_move end def split @money-=@bet hand1=@player_hand.stock(1) hand2=@player_hand.stock(1) [hand1,hand2].each do |hand| @player_hand=hand (@player_hand+=@deck.stock(1)).sort! #you get two cards @player_score=@player_hand.calculate_score puts "---------------------------\n Player's hand:",@player_hand," Score: #{@player_score}" #show your score option= :choose #the first option is choose loop do #until the game exits option=__send__(option) #each method will return a symbol that is a method name, which will be evaluated, when the game is supposed to end, this will be :exit break if option == :play end end :play end def surrender @money+=(@bet*0.5).to_i return :play end #what to do when the game ends def stop puts "---------------------------\n Player's score: #{@player_score}\n Dealer's score: #{@dealer_score}" #show scores if @winner==:player #tell player who's won puts " You win!" @money+=@bet*2 else puts " You lose!" end if @money>0 return :play else puts "---------------------------\n Game Over!\n No money left!\n---------------------------\n Blackjack\n Queen of Diamonds\n Dirk Meijer" #give credit to me return :exit end end end BlackJack.new(5000).play #call the game!!