diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..e146a8b --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' +gem 'mechanize', '~>2.7.2', '<2.7.3' +gem 'pry' # because you'll probably need it +gem 'sinatra' +gem 'sinatra-contrib' +gem 'httparty' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8812b57 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,73 @@ +GEM + remote: https://rubygems.org/ + specs: + backports (3.6.8) + coderay (1.1.1) + domain_name (0.5.20160615) + unf (>= 0.0.5, < 1.0.0) + http-cookie (1.0.2) + domain_name (~> 0.5) + httparty (0.13.7) + json (~> 1.8) + multi_xml (>= 0.5.2) + json (1.8.3) + mechanize (2.7.2) + domain_name (~> 0.5, >= 0.5.1) + http-cookie (~> 1.0.0) + mime-types (~> 1.17, >= 1.17.2) + net-http-digest_auth (~> 1.1, >= 1.1.1) + net-http-persistent (~> 2.5, >= 2.5.2) + nokogiri (~> 1.4) + ntlm-http (~> 0.1, >= 0.1.1) + webrobots (>= 0.0.9, < 0.2) + method_source (0.8.2) + mime-types (1.25.1) + mini_portile2 (2.1.0) + multi_json (1.12.1) + multi_xml (0.5.5) + net-http-digest_auth (1.4) + net-http-persistent (2.9.4) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + ntlm-http (0.1.1) + pkg-config (1.1.7) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.6.4) + rack-protection (1.5.3) + rack + rack-test (0.6.3) + rack (>= 1.0) + sinatra (1.4.7) + rack (~> 1.5) + rack-protection (~> 1.4) + tilt (>= 1.3, < 3) + sinatra-contrib (1.4.7) + backports (>= 2.0) + multi_json + rack-protection + rack-test + sinatra (~> 1.4.0) + tilt (>= 1.3, < 3) + slop (3.6.0) + tilt (2.0.5) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + webrobots (0.1.2) + +PLATFORMS + ruby + +DEPENDENCIES + httparty + mechanize (~> 2.7.2, < 2.7.3) + pry + sinatra + sinatra-contrib + +BUNDLED WITH + 1.12.5 diff --git a/README.md b/README.md index 3f18110..b955460 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Leo, Mike, Phil + # assignment_blackjack Hit me baby one more time? diff --git a/app.rb b/app.rb new file mode 100644 index 0000000..25b680c --- /dev/null +++ b/app.rb @@ -0,0 +1,60 @@ +require 'sinatra' +require 'sinatra/reloader' if development? +require 'pry' +require './classes/blackjack' +require './helpers/blackjack_helper' +# also_reload './views' + +helpers BlackjackHelper +enable :sessions + +get '/' do + "

Welcome!


Play blackjack!" +end + +get '/blackjack/bet' do + game = make_blackjack + save_game(game) + erb :bet +end + +post '/blackjack/bet' do + session["bet"] = params[:bet] + if enough_money?(get_bet) + redirect('blackjack') + else + redirect('blackjack/bet') + end +end + +post '/blackjack/reset' do + reset + redirect('blackjack/bet') +end + +get '/blackjack' do + winner = session[:condition] + game = make_blackjack + save_game(game) unless get_player_hand + if game.over? || winner + winner = game.end_game + game.update_bank(get_bet) + save_game(game) + end + erb :blackjack, locals: { player_hand: get_player_hand, dealer_hand: get_dealer_hand, condition: winner} +end + +post '/blackjack/hit' do + game = make_blackjack + game.give_card(game.player_hand) + save_game(game) + redirect('blackjack') +end + +post '/blackjack/stay' do + game = make_blackjack + game.dealer_play + session[:condition] = game.end_game + save_game(game) + redirect('blackjack') +end diff --git a/classes/blackjack.rb b/classes/blackjack.rb new file mode 100644 index 0000000..79a7cc4 --- /dev/null +++ b/classes/blackjack.rb @@ -0,0 +1,114 @@ +require_relative 'card' +require_relative 'hand' +require_relative 'dealer' + +class Blackjack + + attr_reader :player_hand, :dealer_hand + + SUITS = ["H", "S", "C", "D"] + + VALUES = { + "A": 11, + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "10": 10, + "J": 10, + "Q": 10, + "K": 10 + } + + def initialize(player_hand, dealer_hand, bank) + player_hand ||= [] + dealer_hand ||= [] + @deck = {} + @player_hand = Hand.new(player_hand, bank) + @dealer_hand = Dealer.new(dealer_hand) + build_deck() + start_game if player_hand.empty? + #@over = false + end + + def give_card(player) + face = @deck.keys.sample + suit = @deck[face].sample + delete(face, suit) + player.add_card(face, suit) + end + + def dealer_play + give_card(@dealer_hand) while @dealer_hand.decide_hit? + end_game + end + + def end_game + if win? + return "player" + elsif tie? + return "tie" + elsif lose? + return "dealer" + end + end + + def update_bank(bet) + if win? + @player_hand.make_bank(bet) + elsif lose? + @player_hand.lose_bank(bet) + end + end + + def over? + @player_hand.busted? || @player_hand.hand_value == 21 || @dealer_hand.busted? + end + + def save + save = {} + dealer = @dealer_hand.cards.map { |card| [card.face, card.suit] } + player = @player_hand.cards.map { |card| [card.face, card.suit] } + save["dealer"] = dealer + save["player"] = player + save + end + + + def start_game + 2.times do + give_card(@player_hand) + give_card(@dealer_hand) + end + end + + def build_deck + VALUES.keys.each do |key| + @deck[key] = SUITS.dup + end + + @player_hand.cards.each {|card| delete(card.face, card.suit)} + @dealer_hand.cards.each {|card| delete(card.face, card.suit)} + end + + def delete(face, suit) + @deck[face].delete(suit) + @deck.delete(face) if @deck[face].empty? + end + + def tie? + (@player_hand.busted? && @dealer_hand.busted?) || (@player_hand.hand_value == @dealer_hand.hand_value) + end + + def win? + ((@player_hand.hand_value > @dealer_hand.hand_value) || @dealer_hand.busted?) && !@player_hand.busted? + end + + def lose? + ((@player_hand.hand_value < @dealer_hand.hand_value) || @player_hand.busted?) && !@dealer_hand.busted? + end +end diff --git a/classes/card.rb b/classes/card.rb new file mode 100644 index 0000000..8c52f23 --- /dev/null +++ b/classes/card.rb @@ -0,0 +1,17 @@ +# suit, number, value + +class Card + + attr_reader :suit, :face + + def initialize(face, suit) + @face = face + @suit = suit + end + + def value + Blackjack::VALUES[@face] + end + + +end diff --git a/classes/dealer.rb b/classes/dealer.rb new file mode 100644 index 0000000..6ba1b2c --- /dev/null +++ b/classes/dealer.rb @@ -0,0 +1,9 @@ + + +class Dealer < Hand + + def decide_hit? + hand_value < 17 + end + +end diff --git a/classes/hand.rb b/classes/hand.rb new file mode 100644 index 0000000..783daed --- /dev/null +++ b/classes/hand.rb @@ -0,0 +1,54 @@ +class Hand + + attr_reader :cards, :bank + +# [[face, suit][face, suit]] + + def initialize(cards = [], bank = nil) + @cards = get_cards(cards) + bank ||= 1000 + @bank = bank + end + + # add_card, count value, see_cards, + # ace logic: 11, subtract until <21 + + def get_cards(cards) + cards.map { |card| Card.new(card[0], card[1])} + end + + def make_bank(bet) + @bank += bet + end + + def lose_bank(bet) + @bank -= bet + end + + def ace_logic(value, aces) + while value > 21 && aces > 0 + value -= 10 + aces -= 1 + end + value + end + + def hand_value + value = 0 + aces = 0 + cards.each do |card| + aces += 1 if card.value == 11 + value += card.value + end + value = ace_logic(value, aces) + end + + def add_card(face, suit) + @cards << Card.new(face, suit) + end + + def busted? + hand_value > 21 + end + +end diff --git a/helpers/blackjack_helper.rb b/helpers/blackjack_helper.rb new file mode 100644 index 0000000..a79165d --- /dev/null +++ b/helpers/blackjack_helper.rb @@ -0,0 +1,55 @@ +module BlackjackHelper + + def make_blackjack + if session["bank"].nil? + bank = nil + else + bank = get_bank + end + Blackjack.new(get_player_hand, get_dealer_hand, bank) + end + + def get_player_hand + session["player"] + end + + def get_dealer_hand + session["dealer"] + end + + def get_player_score + session["player_score"] + end + + def get_dealer_score + session["dealer_score"] + end + + def get_bet + session["bet"].to_i + end + + def get_bank + session["bank"].to_i + end + + def enough_money?(bet) + bet ||= 0 + session["bank"].to_i >= bet.to_i + end + + def reset + session["player"] = nil + session["dealer"] = nil + session["condition"] = nil + end + + def save_game(game) + state = game.save + session["player"] = state["player"] + session["dealer"] = state["dealer"] + session["bank"] = game.player_hand.bank + session["player_score"] = game.player_hand.hand_value + session["dealer_score"] = game.dealer_hand.hand_value + end +end diff --git a/views/bet.erb b/views/bet.erb new file mode 100644 index 0000000..dfe2045 --- /dev/null +++ b/views/bet.erb @@ -0,0 +1,13 @@ +What's your bet? +
+ + +
+ +You have $<%= get_bank %> + +<%unless enough_money?(get_bet)%> + +

Not enough money!

+ +<%end%> diff --git a/views/blackjack.erb b/views/blackjack.erb new file mode 100644 index 0000000..cf6ac63 --- /dev/null +++ b/views/blackjack.erb @@ -0,0 +1,34 @@ +Player:<%= player_hand %>
+Total:<%= get_player_score %> +
+ +<% if condition %> +Dealer: <%= dealer_hand %>
+Total:<%= get_dealer_score %> +<% else %> +Dealer: <%= dealer_hand[1] %>
+<% end %> +
+Bank: <%= get_bank %> +Bet: <%= get_bet %> +

+<%= condition %> +

+<% if condition%> + +
+ +
+ +<% else %> + +
+ +
+
+
+ +
+ + +<% end %> diff --git a/views/layout.erb b/views/layout.erb new file mode 100644 index 0000000..d00358c --- /dev/null +++ b/views/layout.erb @@ -0,0 +1,11 @@ + + + + + + Sinatra Blackjack + + + <%= yield %> + + \ No newline at end of file