-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Aisha's RPS Challenge #2128
base: main
Are you sure you want to change the base?
Aisha's RPS Challenge #2128
Changes from all commits
04d1bf6
199d5f7
aa0a1da
b95fd6b
26ec4f5
ab0b489
23da11e
40fadf2
b7721c0
ae9d94f
a2e45a0
17b7a5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
require 'sinatra/base' | ||
require 'sinatra/reloader' | ||
require './lib/player' | ||
require './lib/computer' | ||
require './lib/final_result' | ||
|
||
class RockPaperScissors < Sinatra::Base | ||
configure :development do | ||
register Sinatra::Reloader | ||
end | ||
|
||
enable :sessions | ||
|
||
get '/' do | ||
erb :index | ||
end | ||
|
||
post '/name' do | ||
session[:username] = params[:names] | ||
redirect '/play' | ||
end | ||
|
||
get '/play' do | ||
@username = session[:username] | ||
@game = $game | ||
erb :play | ||
end | ||
|
||
post '/rock' do | ||
session[:player] = Player.new(params[:player_option]) | ||
redirect '/game' | ||
end | ||
|
||
post '/paper' do | ||
session[:player] = Player.new(params[:player_option]) | ||
redirect '/game' | ||
end | ||
|
||
post '/scissors' do | ||
session[:player] = Player.new(params[:player_option]) | ||
redirect '/game' | ||
end | ||
|
||
get '/game' do | ||
@username = session[:username] | ||
@player_option = session[:player].option | ||
session[:computer] = Computer.new(["Rock", "Paper", "Scissors"]) | ||
@computer_option = session[:computer].option | ||
|
||
$final_result = FinalResult.new | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the object final_result = FinalResult.new
final_result.calculate(@player_option, @computer_option)
@final_result = $final_result.winner Maybe the name of the class could be changed to |
||
$final_result.calculate(@player_option, @computer_option) | ||
@final_result = $final_result.winner | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could the @final_result variable go into a separate get route and have /game redirect to it (either as a post or get)? The global $final_result can stay in /game if needed? |
||
erb :game | ||
end | ||
|
||
run! if app_file == $0 | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
require_relative "./app" | ||
|
||
run RockPaperScissors |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
RPS (Rock, paper, scissors) Design Recipe | ||
1. Describe the Problem | ||
|
||
USER STORIES | ||
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 | ||
|
||
Hints on functionality | ||
|
||
the marketeer should be able to enter their name before the game - /index - name - field(capybara) | ||
the marketeer will be presented the choices (rock, paper and scissors) - click button rock, paper and scissors | ||
the marketeer can choose one option - move to page with their button | ||
the game will choose a random option - need random array | ||
a winner will be declared - result page, button play again takes them to index | ||
|
||
|
||
|
||
2. Design the Class System | ||
Consider diagramming out the classes and their relationships. Take care to focus on the details you see as important, not everything. The diagram below uses asciiflow.com but you could also use excalidraw.com, draw.io, or miro.com | ||
|
||
┌────────────────────────────┐ | ||
│ MusicPlayer │ | ||
│ │ | ||
│ - add(track) │ | ||
│ - all │ | ||
│ - search_by_title(keyword) │ | ||
│ => [tracks...] │ | ||
└───────────┬────────────────┘ | ||
│ | ||
│ owns a list of | ||
▼ | ||
┌─────────────────────────┐ | ||
│ Track(title, artist) │ | ||
│ │ | ||
│ - title │ | ||
│ - artist │ | ||
│ - format │ | ||
│ => "TITLE by ARTIST" │ | ||
└─────────────────────────┘ | ||
Also design the interface of each class in more detail. | ||
|
||
-------------------------------------------------------------------------------------- | ||
|
||
3. Create Examples as Integration Tests | ||
Create examples of the classes being used together in different situations and combinations that reflect the ways in which the system will be used. | ||
|
||
|
||
4. Create Examples as Unit Tests | ||
Create examples, where appropriate, of the behaviour of each relevant class at a more granular level of detail. | ||
# EXAMPLE | ||
|
||
# Constructs a track | ||
track = Track.new("Carte Blanche", "Veracocha") | ||
track.title # => "Carte Blanche" | ||
Encode each example as a test. You can add to the above list as you go. | ||
|
||
5. Implement the Behaviour | ||
After each test you write, follow the test-driving process of red, green, refactor to implement the behaviour. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Computer | ||
attr_reader :option | ||
|
||
def initialize(options) | ||
@option = options.sample | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
class FinalResult | ||
|
||
def initialize | ||
@rules = { | ||
Rock: { Rock: :draw, Paper: :lose, Scissors: :win }, | ||
Paper: { Rock: :win, Paper: :draw, Scissors: :lose }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really like this way of going about determining the rules of the game |
||
Scissors: { Rock: :lose, Paper: :win, Scissors: :draw } | ||
} | ||
|
||
@result = [] | ||
end | ||
|
||
def calculate(player_option, comp_option) | ||
player = player_option.to_sym | ||
comp = comp_option.to_sym | ||
@result = @rules[player][comp] | ||
end | ||
|
||
def winner | ||
return "Congratulations! You won, you beat the computer!" if @result == :win | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than having human-readable messages returned by this class, it might be better to let this responsibility to the view (in the .erb file) to have all the content / text displayed to the user. This way, it becomes easier to change it, if we want to change the text displayed, translate it in other languages, etc. The method |
||
return "Oh well, it's a draw!" if @result == :draw | ||
return "Oh no, you lost! Better luck next time!" if @result == :lose | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Player | ||
attr_reader :option | ||
|
||
def initialize(options) | ||
@option = options | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require 'computer' | ||
|
||
describe Computer do | ||
context "returns Rock, Paper, Scissor as an option for the computer" do | ||
it "it returns rock" do | ||
comp = Computer.new(["Rock", "Paper", "Scissors"]) | ||
allow(comp).to receive(:option).and_return("Rock") | ||
expect(comp.option).to eq "Rock" | ||
end | ||
|
||
it "it returns paper" do | ||
comp = Computer.new(["Rock", "Paper", "Scissors"]) | ||
allow(comp).to receive(:option).and_return("Paper") | ||
expect(comp.option).to eq "Paper" | ||
end | ||
|
||
it "it returns scissors" do | ||
comp = Computer.new(["Rock", "Paper", "Scissors"]) | ||
allow(comp).to receive(:option).and_return("Scissors") | ||
expect(comp.option).to eq "Scissors" | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
feature "Choose option" do | ||
scenario "when player chooses rock, return rock" do | ||
sign_in_and_play | ||
click_button 'Rock' | ||
expect(page).to have_content "Aisha played Rock" | ||
end | ||
|
||
scenario "when player chooses paper, return paper" do | ||
sign_in_and_play | ||
click_button 'Paper' | ||
expect(page).to have_content "Aisha played Paper" | ||
end | ||
|
||
scenario "when player chooses scissors, return scissors" do | ||
sign_in_and_play | ||
click_button 'Scissors' | ||
expect(page).to have_content "Aisha played Scissors" | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is $game variable used or needed?