-
Notifications
You must be signed in to change notification settings - Fork 0
/
blackjack.rb
124 lines (124 loc) Β· 5.67 KB
/
blackjack.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class Player
attr_accessor :name, :hand
def initialize (name="Player")
@name = name
@hand = nil
# Note: I practiced YAGNI here, and I decided it wasn't necessary to implement the 'bankroll' property since the game ends after a single round.
end
end
class Computer
attr_accessor :name, :hand
def initialize (name="House")
@name = name
@hand = nil
end
end
class GameState
def initialize
@game_running = true
# Note: Due to YAGNI, it made more sense to just hardcode a numbers array from 2-11.
# Note: This approach made more sense because the 'face' cards Jack, Queen, and King are values of '10' anyways, so it made more logical sense to just hard code them into the deck array.
@deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
# This creates Player class.
@player = Player.new
# This assigns the Player.hand property to an array of two cards.
@player.hand = draws_two_cards
# This does the same for the Computer class.
@house = Computer.new
@house.hand = draws_two_cards
assign_player_name
# This game_start 'while-loop' is called inside constructor method once the GameState class is initialized at the very bottom of the file.
game_start
end
def assign_player_name
# This assigns player's name.
p "πππ Welcome to Ruby BlackJack Console Game! πππ"
p "Please input your desired BlackJack player name in the console: "
@player.name = gets.chomp
p "Your name is #{@player.name}!"
end
# This prints the current hand sum for the player and the house.
def print_current_hands
p "#{@player.name}'s current hand: #{@player.hand}, and the sum is #{get_hand_sum(@player.hand)}"
p "#{@house.name} current hand: #{@house.hand}, and the sum is #{get_hand_sum(@house.hand)}"
end
# This starts the game and continues looping until the user's input is 'stay'.
def game_start
# Default-value for user_input to start game.
user_input = false
while user_input != 'stay'
p "#{@player.name} please choose to 'hit' or 'stay'?"
print_current_hands
if get_hand_sum(@player.hand) > 21
p "β Sorry #{@player.name} you Busted! #{@house.name} has won! Game Over! Please Play Again! β"
# This is an explicit return that doesn't need need a ';'.
return
end
user_input = gets.chomp
# This checks if the player's input was 'hit' or 'stay'.
if user_input == 'hit'
add_card_to_hand(@player.hand)
elsif user_input == 'stay'
p "#{@player.name} has chosen to stay!"
# This prints when the user types something else other than 'hit' or 'stay' inside the terminal.
else
p "Sorry, #{@player.name}! That's an invalid input! Please type in 'hit' or 'stay'!"
end
end
# Once the while loop stops, the 'house_hits_loop' runs until one of the "win/lose conditions is met."
house_hits_loop
# This checks the game winning conditions.
check_winning_state
end
def house_hits_loop
# The 'house' player continues to 'hit', but won't go over a sum 'value' of 17.
while get_hand_sum(@house.hand) < 17
p "#{@house.name} hits!"
add_card_to_hand(@house.hand)
print_current_hands
end
end
def check_winning_state
print_current_hands
# This checks first if player sum is greater than 21...
if get_hand_sum(@player.hand) > 21
p "β Sorry #{@player.name} you Busted! #{@house.name} has won! Game Over! Please Play Again! β"
# then it checks if house sum is greater than 21...
elsif get_hand_sum(@house.hand) > 21
p "π Congratulations #{@player.name}! You Won! #{@house.name} busted! Please Play Again! π"
# then it checks if there's been a tie...
elsif get_hand_sum(@player.hand) == get_hand_sum(@house.hand)
p "πππ There was a draw! Game Over! πππ"
# then it checks if player's hand is greater than house's hand...
elsif get_hand_sum(@player.hand) > get_hand_sum(@house.hand)
p "π Congratulations #{@player.name}! You Won! #{@house.name} busted! Please Play Again! π"
# then it checks if house's hand is greater than player's hand...
elsif get_hand_sum(@player.hand) < get_hand_sum(@house.hand)
p "β Sorry #{@player.name} you Busted! #{@house.name} has won! Game Over! Please Play Again! β"
# This is a catch all print statement for an error in the game logic.
else
p "Something went wrong with the BlackJack game logic!"
end
end
# Adds a card to either player's hand array.
def add_card_to_hand(curr_hand)
curr_hand.push(get_rand_card)
end
# This sums the hand array.
def get_hand_sum(curr_hand)
curr_hand.inject(0) { |sum, card| sum + card }
end
# This initially generates two random numbers from the deck array and creates a two element array of cards.
def draws_two_cards
[get_rand_card, get_rand_card]
end
# This grabs a random number element from the @deck array as a random card value.
def get_rand_card
@deck[rand(@deck.length)]
end
end
# Main Driver Method Starts Game
GameState.new