diff --git a/Gemfile b/Gemfile index 63415039a7..c1efede913 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,9 @@ source 'https://rubygems.org' -ruby '3.0.2' +#ruby '3.0.2' gem 'sinatra' +gem 'sinatra-contrib' group :test do gem 'capybara' diff --git a/Gemfile.lock b/Gemfile.lock index 5afab6d697..cdd0e1ff8b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,6 +17,7 @@ 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) nokogiri (1.12.3) @@ -76,6 +77,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) @@ -93,9 +100,7 @@ DEPENDENCIES simplecov simplecov-console sinatra - -RUBY VERSION - ruby 3.0.2p107 + sinatra-contrib BUNDLED WITH - 2.2.26 + 2.3.13 diff --git a/README.md b/README.md index 3bd26e2d7d..34deadde95 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # RPS Challenge -Instructions -------- - -* Feel free to use google, your notes, books, etc. but work on your own -* If you refer to the solution of another coach or student, please put a link to that in your README -* If you have a partial solution, **still check in a partial solution** -* You must submit a pull request to this repo with your code by 9am Monday morning - Task ---- @@ -15,14 +7,14 @@ Knowing how to build web applications is getting us almost there as web develope The Makers Academy Marketing Array ( **MAMA** ) have asked us to provide a game for them. Their daily grind is pretty tough and they need time to steam a little. -Your task is to provide a _Rock, Paper, Scissors_ game for them so they can play on the web with the following user stories: +The task was to provide a _Rock, Paper, Scissors_ game for them so they can play on the web with the following user stories: ``` -As a marketeer +1) As a marketeer So that I can see my name in lights I would like to register my name before playing an online game -As a marketeer +2) As a marketeer So that I can enjoy myself away from the daily grind I would like to be able to play rock/paper/scissors ``` @@ -35,41 +27,28 @@ Hints on functionality - the game will choose a random option - a winner will be declared - -As usual please start by - -* Forking this repo -* TEST driving development of your app - -[You may find this guide to setting up a new Ruby web project helpful.](https://github.com/makersacademy/course/blob/main/pills/ruby_web_project_setup_list.md) - -## Bonus level 1: Multiplayer - -Change the game so that two marketeers can play against each other ( _yes there are two of them_ ). - -## Bonus level 2: Rock, Paper, Scissors, Spock, Lizard - -Use the _special_ rules ( _you can find them here http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock_ ) - ## Basic Rules - Rock beats Scissors - Scissors beats Paper - Paper beats Rock -In code review we'll be hoping to see: - -* All tests passing -* High [Test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) (>95% is good) -* The code is elegant: every class has a clear responsibility, methods are short etc. +## Progress so far -Reviewers will potentially be using this [code review rubric](docs/review.md). Referring to this rubric in advance may make the challenge somewhat easier. You should be the judge of how much challenge you want this at this moment. +User Story 1) is complete. The user is greeted at the start of the game and can submit their name. When they've submitted their name, they are invited to play with a "Let's play " message. + +Progress made on User Story 2). The player submits their choice for the game - Rock, Paper or Scissors. The computer's choice is randomly generated and shown on the screen. + +The game logic is built using if/elsif statements. I know it would be better to do this using a hash - I need to work on updating the code to use this instead. + +I need to build the feature tests for declaring the winner and finish the game. + +All tests currently passing. Notes on test coverage ---------------------- -Please ensure you have the following **AT THE TOP** of your spec_helper.rb in order to have test coverage stats generated -on your pull request: +Spec_helper.rb includes the following in order to have test coverage stats generated: ```ruby require 'simplecov' @@ -83,4 +62,4 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov.start ``` -You can see your test coverage when you run your tests. If you want this in a graphical form, uncomment the `HTMLFormatter` line and see what happens! +You can see your test coverage when you run your tests. If you want this in a graphical form, uncomment the `HTMLFormatter` line and see what happens! \ No newline at end of file diff --git a/app.rb b/app.rb new file mode 100644 index 0000000000..a14c602180 --- /dev/null +++ b/app.rb @@ -0,0 +1,41 @@ +require 'sinatra/base' +require 'sinatra/reloader' +require_relative 'lib/computer_choice' +require_relative 'lib/game' + +class RockPaper < Sinatra::Base + configure :development do + register Sinatra::Reloader + end + + enable :sessions + + get '/' do + erb :index + end + + post '/name' do + session[:player_name] = params[:player_name] + redirect '/play' + end + + get '/play' do + @player_name = session[:player_name] + erb :play + end + + post '/choice' do + session[:player_choice] = params[:player_choice] + redirect '/show_choice' + end + + get '/show_choice' do + @player_choice = session[:player_choice] + @computer_choice = ComputerChoice.new.get_choice + @game = Game.new(@player_choice, @computer_choice) + erb :choice + end + + run! if app_file == $0 +end + diff --git a/capybara-202206051331115181734402.html b/capybara-202206051331115181734402.html new file mode 100644 index 0000000000..e7be1c3608 --- /dev/null +++ b/capybara-202206051331115181734402.html @@ -0,0 +1,3 @@ +

Let's play Joe +

+ diff --git a/capybara-202206051334496713312562.html b/capybara-202206051334496713312562.html new file mode 100644 index 0000000000..cce182939c --- /dev/null +++ b/capybara-202206051334496713312562.html @@ -0,0 +1,4 @@ +

+Let's play Joe +

+ diff --git a/capybara-202206051354056527606077.html b/capybara-202206051354056527606077.html new file mode 100644 index 0000000000..b8dd3c5df1 --- /dev/null +++ b/capybara-202206051354056527606077.html @@ -0,0 +1,4 @@ +

+Let's play +

+ diff --git a/config.ru b/config.ru new file mode 100644 index 0000000000..dfe1deb51f --- /dev/null +++ b/config.ru @@ -0,0 +1,3 @@ +require_relative "./app" + +run RockPaper diff --git a/lib/computer_choice.rb b/lib/computer_choice.rb new file mode 100644 index 0000000000..d63921ef8a --- /dev/null +++ b/lib/computer_choice.rb @@ -0,0 +1,10 @@ +class ComputerChoice + def initialize + @choices = ["Rock", "Paper", "Scissors"] + end + + def get_choice + @choices.sample + end +end + diff --git a/lib/game.rb b/lib/game.rb new file mode 100644 index 0000000000..f3c0ef5ff6 --- /dev/null +++ b/lib/game.rb @@ -0,0 +1,27 @@ +class Game + + attr_reader :player_choice, :computer_choice + + def initialize(player_choice, computer_choice) + @player_choice = player_choice + @computer_choice = computer_choice + end + + def game_result + if @player_choice == "Rock" && @computer_choice == "Scissors" + return :win + elsif @player_choice == "Rock" && @computer_choice == "Paper" + return :lose + elsif @player_choice == "Paper" && @computer_choice == "Rock" + return :win + elsif @player_choice == "Paper" && @computer_choice == "Scissors" + return :lose + elsif @player_choice == "Scissors" && @computer_choice == "Paper" + return :win + elsif @player_choice == "Scissors" && @computer_choice == "Rock" + return :lose + else + return :draw + end + end +end \ No newline at end of file diff --git a/spec/features/computer_choice_spec.rb b/spec/features/computer_choice_spec.rb new file mode 100644 index 0000000000..b543a460d8 --- /dev/null +++ b/spec/features/computer_choice_spec.rb @@ -0,0 +1,8 @@ +feature 'Show computer choice' do + scenario 'computer makes a random choice of rock, paper or scissors' do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + visit('/show_choice') + expect(page).to have_content("Computer choice: Scissors") + end +end + diff --git a/spec/features/enter_name_spec.rb b/spec/features/enter_name_spec.rb new file mode 100644 index 0000000000..10ed7260c2 --- /dev/null +++ b/spec/features/enter_name_spec.rb @@ -0,0 +1,12 @@ +feature 'Enter player name' do + scenario 'submit name' do + visit('/') + fill_in :player_name, with: "Joe" + click_button "Submit" + + #save_and_open_page + + expect(page).to have_content "Let's play Joe" + end +end + diff --git a/spec/features/rps_choice_spec.rb b/spec/features/rps_choice_spec.rb new file mode 100644 index 0000000000..d026a538af --- /dev/null +++ b/spec/features/rps_choice_spec.rb @@ -0,0 +1,8 @@ +feature 'Enter player choice' do + scenario 'submit rock, paper or scissors' do + visit('/play') + fill_in :player_choice, with: "Rock" + click_button "Submit" + expect(page).to have_content "Your choice: Rock" + end +end diff --git a/spec/features/rps_winner_spec.rb b/spec/features/rps_winner_spec.rb new file mode 100644 index 0000000000..0edbd80c4d --- /dev/null +++ b/spec/features/rps_winner_spec.rb @@ -0,0 +1,35 @@ +feature 'Show the winner' do + scenario 'once both players have played, declare the winner' do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Rock") + visit('/') + fill_in :player_name, with: "Joe" + click_button "Submit" + fill_in :player_choice, with: "Paper" + click_button "Submit" + expect(page).to have_content "The result: win" + end +end + +feature 'Show the winner' do + scenario 'once both players have played, declare the winner' do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + visit('/') + fill_in :player_name, with: "Joe" + click_button "Submit" + fill_in :player_choice, with: "Paper" + click_button "Submit" + expect(page).to have_content "The result: lose" + end +end + +feature 'Show a draw' do + scenario 'when both players have played the same, declare a draw' do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + visit('/') + fill_in :player_name, with: "Joe" + click_button "Submit" + fill_in :player_choice, with: "Scissors" + click_button "Submit" + expect(page).to have_content "The result: draw" + end +end \ No newline at end of file diff --git a/spec/features/test_infrastructure_spec.rb b/spec/features/test_infrastructure_spec.rb new file mode 100644 index 0000000000..b32c0f6ae5 --- /dev/null +++ b/spec/features/test_infrastructure_spec.rb @@ -0,0 +1,6 @@ +# feature 'Testing infrastructure' do +# scenario 'Can run app and check page content' do +# visit('/') +# expect(page).to have_content 'Testing infrastructure working!' +# end +# end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 11a50a94e5..129a81b0d4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,17 @@ +# Set the environment to "test" +ENV['RACK_ENV'] = 'test' + +# Bring in the contents of the `app.rb` file. The below is equivalent to: require_relative '../app.rb' +require File.join(File.dirname(__FILE__), '..', 'app.rb') + +require 'capybara' require 'capybara/rspec' +require 'rspec' require 'simplecov' require 'simplecov-console' +Capybara.app = RockPaper + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::Console, # Want a nice code coverage website? Uncomment this next line! diff --git a/spec/units/computer_choice_spec.rb b/spec/units/computer_choice_spec.rb new file mode 100644 index 0000000000..93ff4c8706 --- /dev/null +++ b/spec/units/computer_choice_spec.rb @@ -0,0 +1,24 @@ +require 'computer_choice' + +RSpec.describe ComputerChoice do + context "give computer's choice for the game" do + it "returns Rock as a string" do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Rock") + + expect(ComputerChoice.new.get_choice).to eq "Rock" + end + + it "returns Paper as a string" do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Paper") + + expect(ComputerChoice.new.get_choice).to eq "Paper" + end + + it "returns Scissors as a string" do + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + + expect(ComputerChoice.new.get_choice).to eq "Scissors" + end + end +end + diff --git a/spec/units/game_spec.rb b/spec/units/game_spec.rb new file mode 100644 index 0000000000..fd8b366c86 --- /dev/null +++ b/spec/units/game_spec.rb @@ -0,0 +1,62 @@ +require 'game' + +RSpec.describe Game do + context "when the player chooses rock, and the computer choice is paper" do + it "shows computer as the winner" do + game = Game.new("Rock", "Paper") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Paper") + expect(game.game_result).to eq :lose + end + end + + context "when the player chooses rock, and the computer choice is scissors" do + it "shows player as the winner" do + game = Game.new("Rock", "Scissors") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + expect(game.game_result).to eq :win + end + end + + context "when the player chooses paper, and the computer choice is scissors" do + it "shows computer as the winner" do + game = Game.new("Paper", "Scissors") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + expect(game.game_result).to eq :lose + end + end + + context "when the player chooses paper, and the computer choice is rock" do + it "shows player as the winner" do + game = Game.new("Paper", "Rock") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Rock") + expect(game.game_result).to eq :win + end + end + + context "when the player chooses scissors, and the computer choice is rock" do + it "shows computer as the winner" do + game = Game.new("Scissors", "Rock") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Rock") + expect(game.game_result).to eq :lose + end + end + + context "when the player chooses scissors, and the computer choice is paper" do + it "shows player as the winner" do + game = Game.new("Scissors", "Paper") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Paper") + expect(game.game_result).to eq :win + end + end + + context "when the player chooses rock, and the computer choice is rock" do + it "is a draw" do + game = Game.new("Scissors", "Scissors") + allow_any_instance_of(ComputerChoice).to receive(:get_choice).and_return("Scissors") + expect(game.game_result).to eq :draw + end + end + end + + + diff --git a/views/choice.erb b/views/choice.erb new file mode 100644 index 0000000000..7358ae6da9 --- /dev/null +++ b/views/choice.erb @@ -0,0 +1,8 @@ +

+Your choice: <%= @player_choice %>
+ +Computer choice: <%= @computer_choice %>
+ +The result: <%= @game.game_result %> + +

\ No newline at end of file diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 0000000000..e20a6cafc5 --- /dev/null +++ b/views/index.erb @@ -0,0 +1,11 @@ +

+Welcome to Rock, Paper, Scissors! +

+

+Ready to play? +Enter your name below +

+
+ + +
diff --git a/views/play.erb b/views/play.erb new file mode 100644 index 0000000000..4195fd6ff1 --- /dev/null +++ b/views/play.erb @@ -0,0 +1,12 @@ +

+Let's play <%= @player_name %> +

+ +

+Make your choice, rock, paper or scissors? +Enter below. +

+
+ + +
\ No newline at end of file