Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ end

group :development, :test do
gem 'rubocop', '1.20'
gem 'sinatra-contrib'
gem 'puma'
gem 'rack'
end
15 changes: 14 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ GEM
docile (1.4.0)
mini_mime (1.1.1)
mini_portile2 (2.6.1)
multi_json (1.15.0)
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nio4r (2.5.8)
nokogiri (1.12.3)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
parallel (1.20.1)
parser (3.0.2.0)
ast (~> 2.4.1)
public_suffix (4.0.6)
puma (5.6.4)
nio4r (~> 2.0)
racc (1.5.2)
rack (2.2.3)
rack-protection (2.1.0)
Expand Down Expand Up @@ -76,6 +80,12 @@ GEM
rack (~> 2.2)
rack-protection (= 2.1.0)
tilt (~> 2.0)
sinatra-contrib (2.1.0)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.1.0)
sinatra (= 2.1.0)
tilt (~> 2.0)
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
tilt (2.0.10)
Expand All @@ -88,14 +98,17 @@ PLATFORMS

DEPENDENCIES
capybara
puma
rack
rspec
rubocop (= 1.20)
simplecov
simplecov-console
sinatra
sinatra-contrib

RUBY VERSION
ruby 3.0.2p107

BUNDLED WITH
2.2.26
2.3.12
51 changes: 51 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'sinatra/base'
require 'sinatra/reloader'
require './lib/player'
require './lib/game'

class Rps < Sinatra::Base
configure :development do
register Sinatra::Reloader
end

get '/' do
erb :index
end

enable :sessions

post '/names' do

$game = Game.new(Player.new(params[:player]))
redirect to('/play')
end

get '/play' do
@game = $game
@message = session[:message]
erb :play
end

post '/rock' do
@game = $game
@game.rock
session[:message] = @game.message
redirect '/play'
end

post '/paper' do
@game = $game
@game.paper
session[:message] = @game.message
redirect '/play'
end

post '/scissors' do
@game = $game
@game.scissors
session[:message] = @game.message
redirect '/play'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, you define a route for each player move option, and each of these routes uses mostly the same code. This is a duplication of code that could be refactored.

Another method of approach this logic is to pass in the player move as a parameter, calling the same route, and passing that param into the @GAMe instance.

end

run! if app_file == $0
end
2 changes: 2 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require_relative './app'
run Rps
19 changes: 19 additions & 0 deletions features/enter_names_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
feature "Enter names" do
scenario "submitting names" do
visit("/")
fill_in :player_1_name, with: "Farzan"
click_button "Submit"

save_and_open_page

expect(page).to have_content("Farzan Vs. Computer")
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, specific content requirements throughout the tests - I need to tighten mine up.

scenario "display homepage" do
visit '/'
expect(page).to have_content("Welcome to: Rock, Paper, Scissors!")
expect(page).to have_content("Please enter your name to start:")
expect(page).to have_button("Let's play!")
expect(page).to have_button("Reset")
end
end
61 changes: 61 additions & 0 deletions lib/game.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class Game

attr_reader :player, :win, :message

def initialize(player)
@player = player
@win = nil
@message = ""
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels like neat logic - very easy to read

def rock
case rpc_play
when "rock"
@win = nil
when "paper"
@win = false
when "scissors"
@win = true
end
end

def paper
case rpc_play
when "rock"
@win = true
when "paper"
@win = nil
when "scissors"
@win = false
end
end

def scissors
case rpc_play
when "rock"
@win = false
when "paper"
@win = true
when "scissors"
@win = nil
end
end

def message
case @win
when true
@message = "You've won! Well done!"
when false
@message = "You've lost! Try again!"
when nil
@message = "It's a tie! Try again!"
end
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach can be simplified to make this class more concise. Check out the following approach: https://github.com/makersacademy/rps-challenge/blob/main/docs/review.md#use-of-ifelsif-conditionals-for-business-logic


private

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could consider keeping the computer in a separate class

def rpc_play
["rock", "paper", "scissors"].sample
end

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

attr_reader :name

def initialize(name)
@name = name
end

end
14 changes: 13 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@


# Set environment to test
ENV['RACK_ENV'] = 'test'

# require File.join(File.dirname(__FILE__), '..', 'app.rb')
require 'capybara'
require 'capybara/rspec'
require 'simplecov'
require 'simplecov-console'
require 'rspec'
require './app'

# Capybara to interact with RockPaperScissors
Capybara.app = Rps

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::Console,
# Want a nice code coverage website? Uncomment this next line!
# SimpleCov::Formatter::HTMLFormatter
SimpleCov::Formatter::HTMLFormatter
])
SimpleCov.start

Expand Down
36 changes: 36 additions & 0 deletions views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang='en'>
<head>
<h1 style='text-align:center'>Welcome to: Rock, Paper, Scissors!</h1>
</head>

<body>

<form action="/names" style='text-align:center' method="post">

<label>
Please enter your name to start:
<input type="text" name="player" placeholder="Enter your name" required>
</label>

<input type="submit" value="Let's play!">
<input type="reset">

</form>

<br>
<br>

<style>
img {
display: block;
margin-left: auto;
margin-right: auto;
}
</style>


<img src='https://miro.medium.com/max/612/1*G9UfaUBS_VqtFILMe37fZw.jpeg' style="width:50%;">

</body>
</html>
20 changes: 20 additions & 0 deletions views/play.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<head>
<h1 style='text-align:center;color:rgb(4, 71, 76)'> Let's Play <%= @game.player.name %>!</h1>
</head>

<h3 style='text-align:center;color:rgb(185, 10, 10)'> Rock, Paper, Scissors? </h3>

<body style='background-image:linear-gradient(rgb(6, 238, 240),rgb(4, 159, 249))'>


<table style="width:30%;margin-left:auto;margin-right:auto">
<tr style="text-align:center">
<form action="/rock" method="post"><th><button style="background-color:red; border-color:blue; color:white">Rock</button></th></form>
<form action="/paper" method="post"><th><button style="background-color:red; border-color:blue; color:white">Paper</button></th></form>
<form action="/scissors" method="post"><th><button style="background-color:red; border-color:blue; color:white">Scissors</button></th></form>
</tr>
</table>

<h3 style='text-align:center;color:rgb(4, 57, 249)' name='message'><%= @message %></h3>

</body>