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

Jon Clarke - RPS challenge #232

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
source 'https://rubygems.org'

ruby '3.0.2'

gem 'sinatra'
gem 'webrick'
gem 'selenium-webdriver'
gem 'webdrivers', '~> 5.0', require: false

group :test do
gem 'capybara'
Expand Down
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (4.1.0)
diff-lcs (1.4.4)
docile (1.4.0)
mini_mime (1.1.1)
Expand Down Expand Up @@ -63,6 +64,11 @@ GEM
parser (>= 3.0.1.1)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
selenium-webdriver (4.1.0)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand All @@ -82,6 +88,11 @@ GEM
unicode-display_width (>= 1.1.1, < 3)
tilt (2.0.10)
unicode-display_width (1.6.1)
webdrivers (5.0.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webrick (1.7.0)
xpath (3.2.0)
nokogiri (~> 1.8)

Expand All @@ -93,9 +104,12 @@ DEPENDENCIES
capybara
rspec
rubocop (= 1.20)
selenium-webdriver
simplecov
simplecov-console
sinatra
webdrivers (~> 5.0)
webrick

RUBY VERSION
ruby 3.0.2p107
Expand Down
48 changes: 48 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,56 @@
require 'sinatra/base'
require_relative 'lib/player'
require_relative 'lib/game'

class RockPaperScissors < Sinatra::Base
enable :sessions

get '/test' do
'test page'
end

get '/' do
erb :index
end

get '/names' do
$player_one = Player.new(params[:player_one])
$player_two = Player.new(params[:player_two])
redirect to('/play')
end

get '/pvp-names' do
erb :pvp_names
end

get '/vs-ai-name' do
erb :vs_ai_name
end

get '/play' do
@player_one = $player_one
@player_two = $player_two
if @player_two.name == 'computer'
erb :play
else
erb :pvp_play
end
end
Comment on lines +30 to +38
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic would be better in the model.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the feedback, really useful :)


get '/pvp-play-2' do
$player_one.choose(params)
@player_two = $player_two
erb :pvp_play_two
end

# need to get this working with a second player's choices now
get '/result' do
@player_one = $player_one
@player_one.choose(params)
@game = Game.new(@player_one)
@result = @game.run_vs_ai
erb :result
end

run! if app_file == $0
end
27 changes: 27 additions & 0 deletions lib/game.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Game
attr_reader :player_one, :ai_choice

def initialize(player_one)
@player_one = player_one
@ai_choice = ["rock", "paper", "scissors"].sample
end

def self.run_vs_ai(player_one)
new(player_one).run_vs_ai
end

def run_vs_ai
if @player_one.choice == @ai_choice
return "It's a draw!"
elsif @player_one.choice == "rock" && @ai_choice == "scissors"
return "#{@player_one.name} wins!"
elsif @player_one.choice == "paper" && @ai_choice == "rock"
return "#{@player_one.name} wins!"
elsif @player_one.choice == "scissors" && @ai_choice == "paper"
return "#{@player_one.name} wins!"
else
return "You lose!"
end
end
Comment on lines +13 to +25
Copy link
Contributor

Choose a reason for hiding this comment

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

You are mixing presentation (the sentence used) and logic (who wins) here. It would be better to have the model/this file just handle the logic, and let the view handle the presentation.


end
11 changes: 11 additions & 0 deletions lib/player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Player
def initialize(name)
@name = name
end

def choose(choice)
choice.each { |_key, value| @choice = value }
end

attr_reader :name, :choice
end
19 changes: 19 additions & 0 deletions spec/features/choose_ai_or_pvp_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
feature 'choose to play vs AI or another player' do
scenario 'the player chooses to play vs AI' do
visit('/')
click_button 'Play vs AI'
fill_in 'player_one', with: 'Homer'
click_button 'Submit'
expect(page.html).to include("<h1>Homer, make your choice</h1>")
end

scenario 'the player chooses to play vs another player' do
visit('/')
click_button 'Player vs Player'
fill_in 'player_one', with: 'Homer'
fill_in 'player_one', with: 'Marge'
click_button 'Submit'
click_button 'rock'
expect(page.html).to include("<h1>Marge, make your choice</h1>")
end
end
14 changes: 14 additions & 0 deletions spec/features/play_game_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
feature 'play the game' do
scenario 'both players can make a choice' do
sign_in_and_play_vs_ai
click_button 'rock'
expect(page.html).to include("<h1>Game result</h1>")
end

xscenario 'the player can click a button to play again' do
sign_in_and_play_vs_ai
click_button 'rock'
click_button 'Play again'
expect(page.html).to include("<h1>Welcome to the game, Homer</h1>")
end
end
9 changes: 9 additions & 0 deletions spec/features/register_name_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
feature 'adding player name vs ai' do
scenario 'the player can submit their name' do
visit('/')
click_button 'Play vs AI'
fill_in 'player_one', with: 'Homer'
click_button 'Submit'
expect(page.html).to include("<h1>Homer, make your choice</h1>")
end
end
11 changes: 11 additions & 0 deletions spec/features/web_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def sign_in_and_play_vs_ai
visit('/')
click_button 'Play vs AI'
fill_in 'player_one', with: 'Homer'
click_button 'Submit'
end

def randomise
srand(1)
srand(3)
end
35 changes: 35 additions & 0 deletions spec/game_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'game'

describe Game do
let(:player_one) { double :player, choice: "rock", name: "Homer" }
# let(:player_two) { double :player, choice: "scissors", name: "Marge" }

describe '#make_ai_choice returns a random choice' do
it 'returns a random choice' do
expect(["rock", "paper", "scissors"]).to include(Game.new(player_one).ai_choice)
end
end

describe 'player chooses rock, ai chooses scissors, ' do
it 'player wins' do
randomise
expect(Game.run_vs_ai(player_one)).to eq "#{player_one.name} wins!"
end
end

describe 'player chooses scissors, ai chooses scissors, ' do
let(:player_one) { double :player, choice: "scissors" }
it "it's a draw" do
randomise
expect(Game.run_vs_ai(player_one)).to eq "It's a draw!"
end
end

describe 'player chooses paper, ai chooses scissors, ' do
let(:player_one) { double :player, choice: "paper" }
it "it's a draw" do
randomise
expect(Game.run_vs_ai(player_one)).to eq "You lose!"
end
end
end
20 changes: 20 additions & 0 deletions spec/player_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'player'

describe Player do

describe '#name' do
it 'returns the name' do
player = Player.new('Homer')
expect(player.name).to eq 'Homer'
end
end

describe '#choose' do
it 'returns the choice of the player' do
player = Player.new('Homer')
choice = { rock: 'rock' }
player.choose(choice)
expect(player.choice).to eq "rock"
end
end
end
3 changes: 2 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
require 'capybara/rspec'
require 'simplecov'
require 'simplecov-console'
require 'features/web_helpers'

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
7 changes: 7 additions & 0 deletions views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<form action="/vs-ai-name">
<input type="submit" value="Play vs AI">
</form>

<form action="/pvp-names">
<input type="submit" value="Player vs Player">
</form>
16 changes: 16 additions & 0 deletions views/play.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h1><%= @player_one.name %>, make your choice</h1>
<br />
<form action='/result'>
<input type='hidden' name='rock' value='rock'>
<input type='submit' value='rock'>
</form>

<form action='/result'>
<input type='hidden' name='paper' value ='paper'>
<input type='submit' value='paper'>
</form>

<form action='/result'>
<input type='hidden' name='scissors' value='scissors'>
<input type='submit' value='scissors'>
</form>
5 changes: 5 additions & 0 deletions views/pvp_names.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<form action="/names">
<input type="text" name="player_one" placeholder="player one name">
<input type="text" name="player_two" placeholder="player two name">
<input type="submit" value="Submit">
</form>
16 changes: 16 additions & 0 deletions views/pvp_play.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h1><%= @player_one.name %>, make your choice</h1>
<br />
<form action='/pvp-play-2'>
<input type='hidden' name='rock' value='rock'>
<input type='submit' value='rock'>
</form>

<form action='/pvp-play-2'>
<input type='hidden' name='paper' value ='paper'>
<input type='submit' value='paper'>
</form>

<form action='/pvp-play-2'>
<input type='hidden' name='scissors' value='scissors'>
<input type='submit' value='scissors'>
</form>
16 changes: 16 additions & 0 deletions views/pvp_play_two.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h1><%= @player_two.name %>, make your choice</h1>
<br />
<form action='/result'>
<input type='hidden' name='rock' value='rock'>
<input type='submit' value='rock'>
</form>

<form action='/result'>
<input type='hidden' name='paper' value ='paper'>
<input type='submit' value='paper'>
</form>

<form action='/result'>
<input type='hidden' name='scissors' value='scissors'>
<input type='submit' value='scissors'>
</form>
10 changes: 10 additions & 0 deletions views/result.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Game result</h1>

<p>You chose <%= @player_one.choice%></p>
<p>The AI chose <%= @game.ai_choice%></p>

<p><%= @result %></p>

<form action='/play'>
<input type='submit' value='Play again'>
</form>
5 changes: 5 additions & 0 deletions views/vs_ai_name.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<form action="/names">
<input type="text" name="player_one" placeholder="enter your name">
<input type="hidden" name="player_two" value="computer">
<input type="submit" value="Submit">
</form>