Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finished BlackJack with Sinatra #56

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source 'https://rubygems.org'

gem 'sinatra'
gem 'json'

group :development do
gem 'pry-byebug'
gem 'sinatra-contrib'
end
46 changes: 46 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
GEM
remote: https://rubygems.org/
specs:
backports (3.8.0)
byebug (9.0.6)
coderay (1.1.1)
json (2.1.0)
method_source (0.8.2)
multi_json (1.12.1)
mustermann (1.0.0)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry-byebug (3.4.2)
byebug (~> 9.0)
pry (~> 0.10)
rack (2.0.3)
rack-protection (2.0.0)
rack
sinatra (2.0.0)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.0)
tilt (~> 2.0)
sinatra-contrib (2.0.0)
backports (>= 2.0)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.0.0)
sinatra (= 2.0.0)
tilt (>= 1.3, < 3)
slop (3.6.0)
tilt (2.0.7)

PLATFORMS
ruby

DEPENDENCIES
json
pry-byebug
sinatra
sinatra-contrib

BUNDLED WITH
1.15.1
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
Hit me baby one more time?

[A Blackjack game using the Ruby Sinatra web application framework which uses object oriented programming, cookies, sessions, and JSON from the Viking Code School](http://www.vikingcodeschool.com)
<br>
Mariah Schneeberger
97 changes: 97 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require 'sinatra'
require 'erb'
require 'json'
require 'pry-byebug'
require 'sinatra/reloader' if development?
require './helpers/blackjack_helpers.rb'


enable :sessions

helpers BlackJackHelpers

before do
@deck = Deck.new
end

get '/' do
erb :home
end

# starts bet before cards are dealt
get '/blackjack/bet' do
@user = HumanPlayer.new(@deck.deal_cards(2))
@dealer = Dealer.new(@deck.deal_cards(2))
save_variables
erb :betting_form
end

post '/blackjack/bet' do
restore_variables
@user.bet = params[:bet].to_i
@bet_string = params[:bet]
save_variables
if @user.bet > @user.bankroll || @bet_string =~ /\D/i || @bet_string =~ /[a-z]/i
erb :betting_form
else
redirect to('/blackjack/play')
end
end

# shuffles deck and deal hands to dealer and player
get '/blackjack/play' do
restore_variables
@user.bankroll -= @user.bet
get_scores(@user, @dealer)
save_variables
if @user_score == 21 || @dealer_score == 21
if @user_score == 21
@user.bankroll += (@user.bet * 2.5)
end
erb :blackjack_win
else
erb :blackjack
end
end


# adds a card to the players hand and re-renders the main page
# if hitting would bust player (over 21 total) redirect to get /blackjack/stay
post "/blackjack/hit" do
restore_variables
@user.hand << @deck.deal_cards(1).flatten
get_scores(@user, @dealer)
save_variables
if @user_score >= 21
redirect to('/blackjack/stay')
end
erb :blackjack
end


# gets dealer to play their hand - either hit or stay depending on if product is 17 or higher
# render main page with all cards revealed and describes the result
get '/blackjack/stay' do
restore_variables
get_scores(@user, @dealer)
if @user_score > 21
save_variables
erb :blackjack_stay
else
dealers_turn(@dealer)
@user.payout(@user_score, @dealer_score)
end
save_variables
erb :blackjack_stay
end

get '/blackjack/new_game' do
redirect to('/blackjack/bet')
end

get '/blackjack/play_again' do
@user = HumanPlayer.new(@deck.deal_cards(2), session[:user_bankroll])
@dealer = Dealer.new(@deck.deal_cards(2))
save_variables
erb :betting_form
end
54 changes: 54 additions & 0 deletions helpers/blackjack_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require_relative 'deck'
require_relative 'player'

module BlackJackHelpers


def save_variables
session[:dealer_hand] = @dealer.hand
session[:user_hand] = @user.hand
session[:user_bankroll] = @user.bankroll
session[:user_bet] = @user.bet
session[:deck] = @deck
end

def restore_variables
restore_user
restore_dealer
restore_deck
end


def get_scores(user, dealer)
@user_score = user.get_score
@dealer_score = dealer.get_score
end


def dealers_turn(dealer)
while @dealer_score <= 17
@dealer.hand << @deck.deal_cards(1).flatten
@dealer_score = @dealer.get_score
end
end


private


def restore_deck
@deck = session[:deck]
end


def restore_user
@user = HumanPlayer.new(session[:user_hand], session[:user_bankroll], session[:user_bet])
end


def restore_dealer
@dealer = Dealer.new(session[:dealer_hand])
end


end
17 changes: 17 additions & 0 deletions helpers/deck.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Deck

def initialize
face = [2,3,4,5,6,7,8,9,10,"J","Q","K","A"]
suit = ["hearts", "spades", "clubs", "diamonds"]
@deck = face.product(suit)
end

def deal_cards(num_of_cards)
hand = @deck.sample(num_of_cards)
hand.each do |card_in_hand|
@deck.delete_if { |card_in_deck| card_in_deck == card_in_hand }
end
hand
end

end
112 changes: 112 additions & 0 deletions helpers/player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
class Player

attr_accessor :hand

def initialize(hand)
@hand = hand
@scores = {
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'10' => 10,
'J' => 10,
'Q' => 10,
'K' => 10,
'A' => 11
}
end

def get_score
score = @hand.reduce(0) do |s, i|
s += @scores[i[0].to_s]
end
if score > 21 && @hand.any? {|x| x[0] == "A"}
score = score - 10
end
score
end

end


class HumanPlayer < Player

attr_accessor :hand, :bankroll, :bet

def initialize(hand, bankroll=1000, bet=0)
@hand = hand
@bankroll = bankroll
@bet = bet
@scores = {
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'10' => 10,
'J' => 10,
'Q' => 10,
'K' => 10,
'A' => 11
}
end


def payout(user_score, dealer_score)
if dealer_score > 21 ||
(dealer_score < 21 && dealer_score < user_score && user_score < 21) ||
user_score == 21
self.bankroll += (self.bet * 2)
elsif dealer_score == user_score
self.bankroll += self.bet
end
end


end


class Dealer < Player

attr_accessor :hand

def initialize(hand)
@hand = hand
@scores = {
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'10' => 10,
'J' => 10,
'Q' => 10,
'K' => 10,
'A' => 11
}
end

def partial_hand
[["HIDDEN"], self.hand.slice(1, self.hand.length).flatten]
end

def partial_hand_score(array)
array.shift
score = array.reduce(0) do |s, i|
s += @scores[i[0].to_s]
end
end


end
44 changes: 44 additions & 0 deletions views/betting_form.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<form class="navbar-form" action="/blackjack/bet" method="post">
<h1>Bankroll: $<%= @user.bankroll %> | Bet: $</h1>
<div class="form-group">
<input type="text" class="form-control" name="bet" placeholder="$ Place your Bet">
</div>
<input type="submit" name="submit_bet" class="btn btn-primary" value="HIT ME!">
</form>
</div>
</nav>

<div class="container-fluid">
<% if @user.bet.to_i > @user.bankroll %>
<div class="alert alert-danger">
<strong>*** ERROR ***</strong>
<br>
You cannot bet more than you have in your bankroll!!!
</div>
<% elsif @bet_string =~ /\D/ || @bet_string =~ /[a-z]/i %>
<div class="alert alert-danger">
<strong>*** ERROR ***</strong>
<br>
Bets may contain only numbers
</div>
<% end %>
</div>

<div class="container-fluid">
<div class="row">
<div class="col-sm-6">
<h1>Dealer:</h1>
<h3><strong>Hand:</h3>
<h3><strong>Total Points:</h3>
</div>

<div class="col-sm-6">
<h1>Player:</h1>
<h3><strong>Hand:</h3>
<h3><strong>Total Points:</h3>
</div>
</div>
</div>
Loading