diff --git a/Gemfile b/Gemfile index 63415039..4020a46f 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index b5673894..8b0ecbbb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) @@ -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) @@ -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) @@ -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 diff --git a/app.rb b/app.rb index 4abb71ec..71cda559 100644 --- a/app.rb +++ b/app.rb @@ -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 + + 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 diff --git a/lib/game.rb b/lib/game.rb new file mode 100644 index 00000000..0e9552a4 --- /dev/null +++ b/lib/game.rb @@ -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 + +end diff --git a/lib/player.rb b/lib/player.rb new file mode 100644 index 00000000..0c74ed47 --- /dev/null +++ b/lib/player.rb @@ -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 diff --git a/spec/features/choose_ai_or_pvp_spec.rb b/spec/features/choose_ai_or_pvp_spec.rb new file mode 100644 index 00000000..a4f688b1 --- /dev/null +++ b/spec/features/choose_ai_or_pvp_spec.rb @@ -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("

Homer, make your choice

") + 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("

Marge, make your choice

") + end +end diff --git a/spec/features/play_game_spec.rb b/spec/features/play_game_spec.rb new file mode 100644 index 00000000..83dd2c68 --- /dev/null +++ b/spec/features/play_game_spec.rb @@ -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("

Game result

") + 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("

Welcome to the game, Homer

") + end +end diff --git a/spec/features/register_name_spec.rb b/spec/features/register_name_spec.rb new file mode 100644 index 00000000..da2bf38c --- /dev/null +++ b/spec/features/register_name_spec.rb @@ -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("

Homer, make your choice

") + end +end diff --git a/spec/features/web_helpers.rb b/spec/features/web_helpers.rb new file mode 100644 index 00000000..4766ad3e --- /dev/null +++ b/spec/features/web_helpers.rb @@ -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 diff --git a/spec/game_spec.rb b/spec/game_spec.rb new file mode 100644 index 00000000..599d53a9 --- /dev/null +++ b/spec/game_spec.rb @@ -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 diff --git a/spec/player_spec.rb b/spec/player_spec.rb new file mode 100644 index 00000000..39702de5 --- /dev/null +++ b/spec/player_spec.rb @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2177ec6a..cef686d8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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 diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 00000000..aebff95b --- /dev/null +++ b/views/index.erb @@ -0,0 +1,7 @@ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/views/play.erb b/views/play.erb new file mode 100644 index 00000000..3261cc28 --- /dev/null +++ b/views/play.erb @@ -0,0 +1,16 @@ +

<%= @player_one.name %>, make your choice

+
+
+ + +
+ +
+ + +
+ +
+ + +
\ No newline at end of file diff --git a/views/pvp_names.erb b/views/pvp_names.erb new file mode 100644 index 00000000..09729537 --- /dev/null +++ b/views/pvp_names.erb @@ -0,0 +1,5 @@ +
+ + + +
\ No newline at end of file diff --git a/views/pvp_play.erb b/views/pvp_play.erb new file mode 100644 index 00000000..aa0d8ee6 --- /dev/null +++ b/views/pvp_play.erb @@ -0,0 +1,16 @@ +

<%= @player_one.name %>, make your choice

+
+
+ + +
+ +
+ + +
+ +
+ + +
diff --git a/views/pvp_play_two.erb b/views/pvp_play_two.erb new file mode 100644 index 00000000..77c3c65c --- /dev/null +++ b/views/pvp_play_two.erb @@ -0,0 +1,16 @@ +

<%= @player_two.name %>, make your choice

+
+
+ + +
+ +
+ + +
+ +
+ + +
diff --git a/views/result.erb b/views/result.erb new file mode 100644 index 00000000..b6bbdb1d --- /dev/null +++ b/views/result.erb @@ -0,0 +1,10 @@ +

Game result

+ +

You chose <%= @player_one.choice%>

+

The AI chose <%= @game.ai_choice%>

+ +

<%= @result %>

+ +
+ +
\ No newline at end of file diff --git a/views/vs_ai_name.erb b/views/vs_ai_name.erb new file mode 100644 index 00000000..a85d667f --- /dev/null +++ b/views/vs_ai_name.erb @@ -0,0 +1,5 @@ +
+ + + +
\ No newline at end of file