-
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
Sophie gilder RPS #2136
base: main
Are you sure you want to change the base?
Sophie gilder RPS #2136
Changes from all commits
abb6eac
c0c4e59
6ac1d1f
101f586
a607119
94d49f7
94c557b
d9df953
d076d26
9988c8b
6fd50a0
f3fffd8
64acac1
d071b2f
e3fea09
377681e
cd2e0a5
51bb778
e3bb0c6
9b015f1
32344eb
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,62 @@ | ||
require 'sinatra/base' | ||
require 'sinatra/reloader' | ||
require './lib/player.rb' | ||
require './lib/game.rb' | ||
require './lib/computer.rb' | ||
|
||
class RockPaperScissors < Sinatra::Base | ||
configure :development do | ||
register Sinatra::Reloader | ||
end | ||
|
||
get "/" do | ||
erb :index | ||
end | ||
|
||
get '/single' do | ||
erb :single | ||
end | ||
|
||
get '/multi' do | ||
erb :multi | ||
end | ||
|
||
post "/names_single" do | ||
player_1 = Player.new(params[:name]) | ||
player_2 = Computer.new | ||
$game = Game.new(player_1, player_2) | ||
redirect "/play" | ||
end | ||
|
||
post "/names_multi" do | ||
player_1 = Player.new(params[:name]) | ||
player_2 = Player.new(params[:name2]) | ||
$game = Game.new(player_1, player_2) | ||
redirect "/play" | ||
end | ||
|
||
get "/play" do | ||
@game = $game | ||
erb @game.select_type | ||
end | ||
|
||
post "/weapon" do | ||
@game = $game | ||
@game.player_1.weapon = params[:weapon] | ||
redirect '/result' | ||
end | ||
|
||
post "/weapon_multi" do | ||
@game = $game | ||
@game.player_1.weapon = params[:weapon] | ||
@game.player_2.weapon = params[:weapon2] | ||
redirect '/result' | ||
end | ||
|
||
get "/result" do | ||
@game = $game | ||
erb @game.result | ||
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. Same remark than above here — you could set the result in an instance variable and display something different in the view depending on this |
||
end | ||
|
||
run! if app_file == $0 | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require "./app" | ||
run RockPaperScissors |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
### 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 | ||
|
||
### Routes | ||
|
||
````ruby | ||
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. It's good you've designed the routes beforehand here — it probably helped a lot your decisions in terms of routing, and how the application would behave, HTTP-wise |
||
get "/" do | ||
# registration page | ||
end | ||
|
||
post "/name" do | ||
# processes the names and redirects | ||
end | ||
|
||
get "/play" do | ||
# user sees their name here | ||
# game play happens here | ||
# user selects their weapon | ||
end | ||
|
||
post "/result" do | ||
# takes the weapon choice that was selected | ||
# selects the correct erb dependng on the result | ||
end | ||
|
||
get "/win" do | ||
# winner page | ||
end | ||
|
||
get "/draw" do | ||
# page for draws | ||
end | ||
|
||
get "/lose" do | ||
# page for losing | ||
end | ||
|
||
```` | ||
|
||
### Classes | ||
|
||
````ruby | ||
class App | ||
# stores the routes etc | ||
end | ||
|
||
class Player | ||
attr_reader :name | ||
attr_accessor :weapon | ||
|
||
def initialize(name) | ||
@name = name | ||
@weapon = nil | ||
end | ||
end | ||
|
||
class Computer | ||
def weapon | ||
# sample from the GAMES::WEAPONS array | ||
end | ||
end | ||
|
||
class Game | ||
attr_reader :players | ||
def initialize(player_1, player_2) | ||
# weapons constant | ||
# rules constant | ||
# players array | ||
end | ||
|
||
def player_1 | ||
end | ||
|
||
def player_2 | ||
end | ||
|
||
def result | ||
# returns a symbol for selecting correct erb | ||
# based on the players weapons | ||
end | ||
end | ||
```` | ||
|
||
### Unit tests | ||
|
||
````ruby | ||
# Game | ||
describe Game do | ||
subject(:game) { described_class.new(player_1, player_2) } | ||
let(:player_1) { double :player } | ||
let(:player_2) { double :computer } | ||
|
||
it "returns the players" do | ||
expect(game.players).to eq [player_1, player_2] | ||
expect(game.player_1).to eq player_1 | ||
expect(game.player_1).to eq player_2 | ||
end | ||
|
||
it "returns win if player_1 wins" | ||
allow(player_1).to receive(weapon).and_return(:rock) | ||
allow(player_2).to receive(weapon).and_return(:scissors) | ||
expect(game.result).to eq :win | ||
end | ||
|
||
it "returns lose if player_1 wins" | ||
allow(player_1).to receive(weapon).and_return(:rock) | ||
allow(player_2).to receive(weapon).and_return(:paper) | ||
expect(game.result).to eq :lose | ||
end | ||
|
||
it "returns draw if a draw" | ||
allow(player_1).to receive(weapon).and_return(:rock) | ||
allow(player_2).to receive(weapon).and_return(:rock) | ||
expect(game.result).to eq :draw | ||
end | ||
|
||
# Player | ||
describe Player do | ||
subject(:player) { described_class.new("Rosie") } | ||
|
||
it "constructs and returns name" do | ||
expect(player.name).to eq "Rosie" | ||
end | ||
|
||
it "can have a weapon assigned to it" do | ||
game.weapon == :rock | ||
expect(game.weapon).to eq :rock | ||
end | ||
end | ||
|
||
# Computer | ||
describe Computer do | ||
subject(:computer) { described_class.new } | ||
|
||
it "randomly selects a weapon" do # not entirely sure this will work | ||
expect(computer.weapon).to eq :paper | ||
computer.weapon | ||
end | ||
end | ||
```` | ||
|
||
### Features tests | ||
|
||
````ruby | ||
# displays name | ||
|
||
# selects a weapon | ||
|
||
# shows the correct screen depending on who won | ||
```` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
class Computer | ||
attr_reader :name, :weapon, :type | ||
|
||
def initialize | ||
@weapon = Game::WEAPONS.sample | ||
@name = :Computer | ||
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. Minor one - usually symbol names are always lowercase |
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
class Game | ||
WEAPONS = [:rock, :paper, :scissors] | ||
RULES = {rock: :scissors, scissors: :paper, paper: :rock} | ||
|
||
attr_reader :players | ||
|
||
def initialize(player_1, player_2) | ||
@players = [player_1, player_2] | ||
same_name_setter if player_1.name == player_2.name | ||
end | ||
|
||
def player_1 | ||
@players.first | ||
end | ||
|
||
def player_2 | ||
@players.last | ||
end | ||
|
||
def select_type | ||
single_player ? :game : :game_multi | ||
end | ||
|
||
def result | ||
if player_2.weapon == RULES[player_1.weapon] | ||
:win | ||
elsif player_1.weapon == RULES[player_2.weapon] | ||
:lose | ||
else | ||
:draw | ||
end | ||
end | ||
|
||
def single_player | ||
player_2.name == :Computer | ||
end | ||
|
||
def same_name_setter | ||
player_2.name=("#{player_2.name} 2") | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Player | ||
attr_reader :weapon, :type | ||
attr_accessor :name | ||
|
||
def initialize(name) | ||
@name = name | ||
@weapon = nil | ||
end | ||
|
||
def weapon=(weapon) | ||
@weapon = weapon.downcase.to_sym | ||
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.
Usually it's best to enforce the view name to be something specific, rather than the return of a method that you might not fully control — for example, tomorrow you (or someone else) might modify
select_type
to return a different value, but might also forget to add a new view to cover this case here, which would break the program. Rather than coupling tightly the return value to the view name, it might be better to add some condition and specifically select the correct view — or better, to have a generic single view that is always used, but using an instance variable and some dynamic ERB tags to display a slightly different portion of the HTML, depending on the value