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

RPS Challenge #2125

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ source 'https://rubygems.org'
ruby '3.0.2'

gem 'sinatra'
gem 'sinatra-contrib'

group :test do
gem 'capybara'
Expand Down
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -93,6 +100,7 @@ DEPENDENCIES
simplecov
simplecov-console
sinatra
sinatra-contrib

RUBY VERSION
ruby 3.0.2p107
Expand Down
6 changes: 6 additions & 0 deletions Views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h1>ROCK! PAPER! SCISSORS!</h1>
<form action='/names' method="post">
<input type='text' name="player_1_name" placeholder="Enter your name">
<input type='text' name="player_2_name" placeholder="Enter your name">
<input type="submit" value="Submit">
</form>
Empty file added Views/move.erb
Empty file.
8 changes: 8 additions & 0 deletions Views/play.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1><%= @game.player_1.name %> vs. <%= @game.player_2.name %></h1>

<h3>Rock, paper or scissors? Make your choice:</h3>
<form action='/result' method="post">
<input type='text' name='player_1_choice' placeholder='Player 1 choice'>
<input type='text' name='player_2_choice' placeholder='Player 2 choice'>
<input type="submit" value="Play">
</form>
18 changes: 18 additions & 0 deletions Views/result.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<h3><%= @game.player_1.name %> chose <%= @game.get_player_1_choice %></h3>
<h3><%= @game.player_2.name %> chose <%= @game.get_player_2_choice %></h3>

<% if @game.get_player_1_choice == @game.get_player_2_choice %>

Choose a reason for hiding this comment

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

This logic in the view could be moved to a class. So, the view doesn't have to do too much work.

<h3>It's a draw!</h3>
<% elsif @game.get_player_1_choice == 'rock' && @game.get_player_2_choice == 'scissors' %>
<h3>Player 1 wins</h3>
<% elsif @game.get_player_1_choice == 'scissors' && @game.get_player_2_choice == 'paper' %>
<h3>Player 1 wins</h3>
<% elsif @game.get_player_1_choice == 'paper' && @game.get_player_2_choice == 'rock' %>
<h3>Player 1 wins</h3>
<% else %>
<h3><%= @game.player_2.name %> wins!</h3>
<% end %>

<form action='/play'>
<input type='submit' value='Play again'>
</form>
40 changes: 40 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'sinatra/base'
require 'sinatra/reloader'
require './lib/game'
require './lib/player'

class RPS < Sinatra::Base
enable :sessions
configure :development do
register Sinatra::Reloader
end

get '/' do
erb :index
end

post '/names' do
player_1 = Player.new(params[:player_1_name])
player_2 = Player.new(params[:player_2_name])
$game = Game.new(player_1, player_2)
redirect '/play'
end

get '/play' do
@game = $game
erb :play
end

post '/result' do
@game = $game
player_1_choice = params[:player_1_choice]
player_2_choice = params[:player_2_choice]
@game.player_1.make_choice(player_1_choice)
@game.player_2.make_choice(player_2_choice)

erb :result
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
29 changes: 29 additions & 0 deletions lib/game.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class Game

Choose a reason for hiding this comment

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

I really like this! It makes your code easy to follow and keeps the app.rb concise!

attr_reader :p1_choice, :player_1, :current_player, :p2_choice

def initialize(player_1, player_2)
@players = [player_1, player_2]
@current_player = player_1
end

def player_1
@players.first
end

def player_2
@players.last
end

def ai_choice
# 1 = Rock, 2 = Paper, 3 = Scissors
@comp_choice = ['rock', 'paper', 'scissors'].sample
end

def get_player_1_choice
player_1.choice
end

def get_player_2_choice
player_2.choice
end
end
12 changes: 12 additions & 0 deletions lib/player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Player
attr_reader :name, :choice

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

def make_choice(choice)
@choice = choice
end
end
81 changes: 81 additions & 0 deletions plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{{RPS Challenge}} Class Design Recipe
1. Describe the Problem
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
So that I can enjoy myself away from the daily grind
I would like to be able to play rock/paper/scissors

2. Design the Class Interface
Enter name before the game

Get shown a choice of Rock, Paper or Scissors

User can only choose 1 option

The game will choose make 1 other choice

Winner gets declared
Rock beats Scissors
Scissors beats Paper
Paper beats Rock

MODELS
- Player
- attr_reader :name
- def make_choice
- Game (current_turn, )

VIEWS
- index
- play
- Shows player 3 choices, buttons.
- result
- Shows the result of the game

CONTROLLER
- app.rb
'/'
'/play'
'/result'

# EXAMPLE

class Reminder
def initialize(name) # name is a string
# ...
end

def remind_me_to(task) # task is a string
# No return value
end

def remind()
# Throws an exception if no task is set
# Otherwise, returns a string reminding the user to do the task
end
end
3. Create Examples as Tests
Make a list of examples of how the class will behave in different situations.

# EXAMPLE

# 1
reminder = Reminder("Kay")
reminder.remind_me_to("Walk the dog")
reminder.remind() # => "Walk the dog, Kay!"

# 2
reminder = Reminder("Kay")
reminder.remind() # fails with "No task set."

# 3
reminder = Reminder("Kay")
reminder.remind_me_to("")
reminder.remind() # => ", Kay!"
Encode each example as a test. You can add to the above list as you go.

4. Implement the Behaviour
After each test you write, follow the test-driving process of red, green, refactor to implement the behaviour.
7 changes: 7 additions & 0 deletions spec/features/enter_names_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
feature "Enter player name" do
scenario "submitting a name" do
sign_in_and_play
#save_and_open_page
expect(page).to have_content "Joe vs. Dan"
end
end
10 changes: 10 additions & 0 deletions spec/features/play_again_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
feature 'play again' do
scenario 'press play again to restart game' do
sign_in_and_play
player_1_rock_p2_scissors
click_button 'Play again'
expect(page).to have_content "Joe vs. Dan"
expect(page).not_to have_content "Dan wins!"
expect(page).not_to have_content "Joe wins!"
end
end
28 changes: 28 additions & 0 deletions spec/features/result_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
feature 'Result of choice' do
scenario 'Player 1 chooses Rock, player 2 scissors' do
sign_in_and_play
player_1_rock_p2_scissors
expect(page).to have_content "Joe chose rock"
expect(page).to have_content "Dan chose scissors"
expect(page).not_to have_content "Joe chose paper"
expect(page).not_to have_content "Joe chose scissors"
end

scenario 'Player 1 chooses paper, player 2 rock' do
sign_in_and_play
player_2_rock_p1_paper
expect(page).to have_content "Joe chose paper"
expect(page).to have_content "Dan chose rock"
expect(page).not_to have_content "Joe chose rock"
expect(page).not_to have_content "Dan chose scissors"
end

scenario 'Player 1 chooses scissors, player 2 paper' do
sign_in_and_play
player_2_paper_p1_scissors
expect(page).to have_content "Joe chose scissors"
expect(page).to have_content "Dan chose paper"
expect(page).not_to have_content "Joe chose paper"
expect(page).not_to have_content "Joe chose rock"
end
end
42 changes: 42 additions & 0 deletions spec/features/web_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
def sign_in_and_play
visit('/')
fill_in :player_1_name, with: 'Joe'
fill_in :player_2_name, with: 'Dan'
click_button 'Submit'
end

def player_1_rock_p2_scissors
fill_in :player_1_choice, with: 'rock'
fill_in :player_2_choice, with: 'scissors'
click_button 'Play'
end

def player_1_paper_p2_scissors
fill_in :player_1_choice, with: 'paper'
fill_in :player_2_choice, with: 'scissors'
click_button 'Play'
end

def player_1_scissors_p2_scissors
fill_in :player_1_choice, with: 'scissors'
fill_in :player_2_choice, with: 'scissors'
click_button 'Play'
end

def player_2_rock_p1_paper
fill_in :player_1_choice, with: 'paper'
fill_in :player_2_choice, with: 'rock'
click_button 'Play'
end

def player_2_paper_p1_scissors
fill_in :player_1_choice, with: 'scissors'
fill_in :player_2_choice, with: 'paper'
click_button 'Play'
end

def player_2_scissors_p1_rock
fill_in :player_1_choice, with: 'rock'
fill_in :player_2_choice, with: 'scissors'
click_button 'Play'
end
22 changes: 22 additions & 0 deletions spec/game_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'game'

describe Game do
subject(:game) { described_class.new(player_1, player_2) }
let(:player_1) { double :player }
let(:player_2) { double :player }


describe '#get_player_choice' do
it "it returns player 1 choice" do
allow(player_1).to receive(:make_choice).with('rock').and_return 'rock'
expect(game).to receive(:get_player_1_choice).and_return 'rock'
game.get_player_1_choice
end

it "it returns player 2 choice" do
allow(player_2).to receive(:make_choice).with('paper').and_return 'paper'
expect(game).to receive(:get_player_2_choice).and_return 'paper'
game.get_player_2_choice
end
end
end
13 changes: 13 additions & 0 deletions spec/player_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'player'

describe Player do
subject(:joe) { Player.new("Joe") }
subject(:dan) { Player.new("Dan") }

describe '#name' do
it 'returns the name' do
expect(joe.name).to eq "Joe"
expect(dan.name).to eq "Dan"
end
end
end