Skip to content
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/**/.DS_Store
/coverage
Gemfile.lock

# Local cache of Rubocop remote config
.rubocop-*

3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ source 'https://rubygems.org'
ruby '3.0.2'

gem 'sinatra'
gem 'sinatra-reloader'
gem 'puma'

group :test do
gem 'capybara'
gem 'rspec'
gem 'simplecov', require: false
gem 'simplecov-console', require: false
gem 'capybara-screenshot'
end

group :development, :test do
Expand Down
20 changes: 20 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,28 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
capybara-screenshot (1.0.26)
capybara (>= 1.0, < 4)
launchy
diff-lcs (1.4.4)
docile (1.4.0)
launchy (2.5.0)
addressable (~> 2.7)
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 +85,14 @@ 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)
sinatra-reloader (1.0)
sinatra-contrib
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
tilt (2.0.10)
Expand All @@ -88,11 +105,14 @@ PLATFORMS

DEPENDENCIES
capybara
capybara-screenshot
puma
rspec
rubocop (= 1.20)
simplecov
simplecov-console
sinatra
sinatra-reloader

RUBY VERSION
ruby 3.0.2p107
Expand Down
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
# RPS Challenge
# RPS Challenge - Tom Solution

## Instructions to user

This is a simple web app that allows the user to input a name and play rock paper scissors against the computer. The player chooses a move, the computer's move is randomly selected and the winner is calculated and the result displayed to the screen.

The player is then given the option to play again.

I have not had as much time as I would like to refactor the code and improve the aesthetics of the app but the functionality is there (I think).

I was unsure how to get buttons with a picture, I was able to follow a student from a previous cohort's code through finding him through a blogpost, his github code is here:

https://github.com/awye765/rps-challenge

I did not follow his code anywhere else.


Instructions
-------
Expand Down
49 changes: 49 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'sinatra/base'
require 'sinatra/reloader'
require './lib/player'
require './lib/computer'
require './lib/game'

class Rps < Sinatra::Base
enable :sessions

configure :development do
register Sinatra::Reloader
end

get '/' do
erb :home
end

post '/begin_single_player' do
p params
$player_1 = Player.new(params[:player_1])
$computer = Computer.new("Dwayne")
redirect '/single_player_game'
end

get '/single_player_game' do
@player_1_name = $player_1.name
@computer_name = $computer.name
erb :single_player
end

post '/calculate_results' do
$game = Game.new
$player_1.choose(params[:choice])
$computer.choose
$game.calculate_result($player_1.choice,$computer.choice)
redirect '/results'
end

get '/results' do
@result = $game.result
@player_1_name = $player_1.name
@computer_name = $computer.name
@player_1_choice = $player_1.choice
@computer_choice = $computer.choice
erb :results
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 './app'
run Rps
16 changes: 16 additions & 0 deletions lib/computer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Computer

attr_reader :name, :choice

ALLOWED_MOVES = ["rock", "paper", "scissors"]

def initialize(name)
@name = name
@choice = nil
end

def choose
@choice = ALLOWED_MOVES.sample
end

Choose a reason for hiding this comment

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

All of these .rb's are so CLEAN, so TIGHT, every function has a clear and distinct role. V tasty.

end
38 changes: 38 additions & 0 deletions lib/game.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class Game

attr_reader :result

ALLOWED_MOVES = ["rock", "paper", "scissors"]

def initialize
@result = nil
@outcomes = {
"rock rock" => nil,
"rock scissors" => true,
"rock paper" => false,
"scissors rock" => false,
"scissors scissors" => nil,
"scissors paper" => true,
"paper rock" => true,
"paper scissors" => false,
"paper paper" => nil,
}
end

def calculate_result(move1,move2)
check_move_allowed(move1)
check_move_allowed(move2)
@result = output_winner(move1,move2)
end

private

def check_move_allowed(move)
fail 'Incorrect move' unless ALLOWED_MOVES.include?(move)
end

Choose a reason for hiding this comment

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

So have you implemented this in such a way as it requires the player enters another choice?

def output_winner(move1,move2)
@outcomes["#{move1} #{move2}"]
end

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

attr_reader :name, :choice

def initialize(name)
@name = name
@choice = nil
end

def choose(choice)
@choice = choice
end

end
Binary file added public/Rock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/paper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/rock.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/scissors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions spec/Feature_tests/home_feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
feature "Going to the homepage, entering a player name" do

scenario "the home page returns a successful status code" do
visit("/")
expect(page.status_code).to eq(200)
end

Choose a reason for hiding this comment

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

Ahh nice to see an example of a test for this

scenario "page contains 'Please enter your name(s)'" do
visit("/")
expect(page).to have_content('Please enter your name(s)')
end

scenario "Page contains an option for single player mode" do
visit("/")
expect(page).to have_selector(:link_or_button, 'Single Player Mode')
end

end
36 changes: 36 additions & 0 deletions spec/Feature_tests/result_feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
feature "Game outcome screen" do

scenario "When the player picks rock, they are taken to a results page" do
sign_in_and_play_1p
click_on 'Rock'
expect(page).to have_content('The results are in')
end

scenario "The player picks rock, the computer picks scissors, the player wins" do
srand(3)
sign_in_and_play_1p
click_on 'Rock'
expect(page).to have_content('Mario wins')
end

scenario "The player picks scissors, the computer picks scissors, it's a draw" do
srand(3)
sign_in_and_play_1p
click_on 'Scissors'
expect(page).to have_content('draw')
end

scenario "The player picks paper, the computer picks scissors, the player loses" do
srand(3)
sign_in_and_play_1p
click_on 'Paper'
expect(page).to have_content('Mario loses')
end

scenario "There is an option to play again at the end of the game" do
sign_in_and_play_1p
click_on 'Rock'
expect(page).to have_selector(:link_or_button,'Play again?')
end

end
13 changes: 13 additions & 0 deletions spec/Feature_tests/single_player_feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
feature "Playing the game" do

scenario "When player names have been entered, they appear in the game" do
sign_in_and_play_1p
expect(page).to have_content("Mario vs. Dwayne")
end

scenario "Player can choose rock" do
sign_in_and_play_1p
expect(page).to have_selector(:link_or_button, 'Rock')
end

end
11 changes: 11 additions & 0 deletions spec/computer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'computer'

describe Computer do
subject(:ai) { Player.new('HAL 9000') }

describe '#name' do
it 'returns the name' do
expect(ai.name).to eq 'HAL 9000'
end
end
end
37 changes: 37 additions & 0 deletions spec/game_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'game'

describe Game do
subject(:game) { Game.new }

describe '#calculate_result' do
it 'responds to two arguments' do
expect(game).to respond_to(:calculate_result).with(2)
end

it 'fails if the first move is not rock, paper or scissors' do
expect { game.calculate_result('elephant','rock') }.to raise_error 'Incorrect move'
end

it 'fails if the first move is not rock, paper or scissors' do
expect { game.calculate_result('rock','octopus') }.to raise_error 'Incorrect move'
end

it 'outputs true for a winning game' do
expect(game.calculate_result('rock','scissors')).to eq true
expect(game.calculate_result('paper','rock')).to eq true
expect(game.calculate_result('scissors','paper')).to eq true
end

it 'outputs nil for a drawn game' do
expect(game.calculate_result('rock','rock')).to eq nil
expect(game.calculate_result('scissors','scissors')).to eq nil
expect(game.calculate_result('paper','paper')).to eq nil
end

it 'outputs false for a losing game' do
expect(game.calculate_result('rock','paper')).to eq false
expect(game.calculate_result('scissors','rock')).to eq false
expect(game.calculate_result('paper','scissors')).to eq false
end
end
end
11 changes: 11 additions & 0 deletions spec/player_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'player'

describe Player do
subject(:mario) { Player.new('Mario') }

describe '#name' do
it 'returns the name' do
expect(mario.name).to eq 'Mario'
end
end
end
12 changes: 12 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
require 'capybara/rspec'
require 'rspec'
require 'rack/test'
require 'capybara'
require 'sinatra'
require 'simplecov'
require 'simplecov-console'
# require 'capybara-screenshot/rspec'

ENV['RACK_ENV'] = 'test'

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::Console,
Expand All @@ -9,6 +16,11 @@
])
SimpleCov.start

require File.join(File.dirname(__FILE__), '..', 'app.rb')
require File.join(File.dirname(__FILE__), 'web_helpers.rb')

Capybara.app = Rps

# For accurate test coverage measurements, require your code AFTER 'SimpleCov.start'

RSpec.configure do |config|
Expand Down
5 changes: 5 additions & 0 deletions spec/web_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def sign_in_and_play_1p
visit("/")
fill_in 'player_1', with: 'Mario'
click_on 'Single Player Mode'
end
Loading