-
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
Stevie Spiegl RPS #2115
base: main
Are you sure you want to change the base?
Stevie Spiegl RPS #2115
Changes from 15 commits
4359d10
1a24ee3
cea74c9
43edfb8
e071a99
392b36c
b136975
3be0405
0736433
8bfb302
23d4805
c1a4456
0a48d3e
af14b6c
7fc16b4
f0c7b17
6ced6bc
598460d
d7f237f
b331630
0162508
737ec52
e8cacd9
82d354a
06a966c
633c77b
ddb2463
5dcf235
c5a6c4f
bb949f7
9d44f07
88bf62a
1353f7a
dae923e
6f8e164
177486c
1c2215f
06e98e2
f3b1de1
1cb42bb
d143894
da77118
db0dba3
2eab430
63b1b62
2d23f71
508234a
a74ace6
66baab1
64d1602
a34292f
10ba08e
b7773b9
1a95f63
72c4d4f
63bb33e
cebb680
852c43f
c252626
0401afd
e0db0da
2d98a80
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,42 @@ | ||
require 'sinatra/base' | ||
require 'sinatra/reloader' | ||
require './lib/player' | ||
require './lib/game' | ||
|
||
class RockPaperScissors < Sinatra::Base | ||
configure :development do | ||
register Sinatra::Reloader | ||
end | ||
|
||
enable :sessions | ||
|
||
get '/' do | ||
erb :form | ||
end | ||
|
||
post '/play' do | ||
session[:player] = params[:player] | ||
$player = Player.new(params[:player]) | ||
@player_name = $player.name | ||
erb :play | ||
end | ||
|
||
post '/play_again' do | ||
session[:player] = params[:player] | ||
$player = Player.new(params[:player]) | ||
@player_name = $player.name | ||
erb :play_again | ||
end | ||
|
||
post '/battle' do | ||
@player = $player | ||
@player_weapon = @player.select_weapon(params[:player_choice]) | ||
game = Game.new(@player_weapon) | ||
@message = game.engine | ||
@computer_weapon = game.computer_weapon | ||
erb :battle | ||
end | ||
|
||
# Start the server if this file is executed directly (don't change the line below) | ||
run! if app_file == $0 | ||
end | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require_relative 'app' | ||
run RockPaperScissors |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require_relative 'game' | ||
|
||
class Computer | ||
def weapon | ||
Game::WEAPONS.sample | ||
# syntax for referring to a constant in another class | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require_relative 'computer' | ||
|
||
class Game | ||
|
||
WEAPONS = [:rock, :paper, :scissors] | ||
attr_reader :player, :engine, :computer_weapon, :computer, :player_weapon | ||
|
||
def initialize(player_weapon, computer = Computer.new) | ||
@player_weapon = player_weapon.to_sym | ||
@computer = computer | ||
@computer_weapon = computer.weapon | ||
end | ||
|
||
def engine | ||
if @player_weapon == @computer_weapon | ||
"draw" | ||
elsif @player_weapon == :rock && @computer_weapon == :scissors | ||
"You chose wisely." | ||
elsif @player_weapon == :rock && @computer_weapon == :paper | ||
"You did not choose wisely." | ||
elsif @player_weapon == :scissors && @computer_weapon == :paper | ||
"You chose wisely." | ||
elsif @player_weapon == :scissors && @computer_weapon == :rock | ||
"You did not choose wisely." | ||
elsif @player_weapon == :paper && @computer_weapon == :rock | ||
"You chose wisely." | ||
elsif @player_weapon == :paper && @computer_weapon == :scissors | ||
"You did not choose wisely." | ||
end | ||
end | ||
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. Good to see the creation of a WEAPONS constant in this file. Could the |
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Player | ||
|
||
attr_reader :name, :weapon | ||
|
||
def initialize(name) | ||
@name = name | ||
end | ||
|
||
def select_weapon(weapon) | ||
@weapon = weapon | ||
end | ||
|
||
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 WEAPONS constant be used in this file too? |
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require 'computer' | ||
|
||
describe Computer do | ||
it 'can choose rock' do | ||
dbl_cpu = double("rock") | ||
allow(dbl_cpu).to receive(:weapon).and_return(:rock) | ||
srand(2) | ||
expect(subject.weapon).to eq(:rock) | ||
end | ||
|
||
it 'can choose paper' do | ||
dbl_cpu = double("paper") | ||
allow(dbl_cpu).to receive(:weapon).and_return(:paper) | ||
srand(1) | ||
expect(subject.weapon).to eq(:paper) | ||
end | ||
it 'can choose scissors' do | ||
dbl_cpu = double("scissors") | ||
allow(dbl_cpu).to receive(:weapon).and_return(:scissors) | ||
srand(3) | ||
expect(subject.weapon).to eq(:scissors) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
require 'capybara/rspec' | ||
require_relative '../../app' | ||
|
||
Capybara.app = RockPaperScissors | ||
|
||
feature 'allows player to enter their name' do | ||
scenario 'player is able to enter their name' do | ||
visit('/') | ||
expect(page).to have_field('player') | ||
expect(page).to have_button('Submit name') | ||
end | ||
|
||
scenario 'player is taken to a new page to start the game' do | ||
sign_in | ||
expect(current_path).to eq('/play') | ||
end | ||
|
||
scenario 'player can see their name on the play page' do | ||
sign_in | ||
expect(current_path).to eq('/play') | ||
expect(page).to have_content('Alien') | ||
end | ||
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. Clear, concise, good indentation |
||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
require 'capybara/rspec' | ||
require_relative '../../app' | ||
|
||
Capybara.app = RockPaperScissors | ||
|
||
feature 'allows player to play a game of RockPaperScissors' do | ||
scenario 'the player can choose from three buttons' do | ||
sign_in | ||
expect(page).to have_xpath('/html/body/form[1]/input[1]') | ||
expect(page).to have_xpath('/html/body/form[2]/input[1]') | ||
expect(page).to have_xpath('/html/body/div/form/input[1]') | ||
end | ||
|
||
scenario 'a player can return to the play screen to have another go' do | ||
sign_in | ||
click_on(id='rock') | ||
expect(page).to have_button('Have another go?') | ||
end | ||
|
||
|
||
scenario 'clicking a button takes the player to the winner page' do | ||
sign_in | ||
click_on(id='rock') | ||
expect(current_path).to eq '/battle' | ||
end | ||
|
||
scenario 'rock beats scissors' do | ||
allow_any_instance_of(Computer).to receive(:weapon).and_return(:scissors) | ||
sign_in | ||
click_on(id='rock') | ||
expect(page).to have_content "You chose wisely." | ||
end | ||
|
||
scenario 'paper beats rock' do | ||
allow_any_instance_of(Computer).to receive(:weapon).and_return(:paper) | ||
sign_in | ||
click_on(id='rock') | ||
expect(page).to have_content "You did not choose wisely." | ||
end | ||
|
||
scenario 'scissors beats paper' do | ||
allow_any_instance_of(Computer).to receive(:weapon).and_return(:paper) | ||
sign_in | ||
click_on(id='scissors') | ||
expect(page).to have_content "You chose wisely." | ||
end | ||
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. Really clear test scenarios, really enjoyed reading these if I'm honest. Good takeaway for my tests in the future, thank you! 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. Agreed, good testing, well done for using stubs effectively here |
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
require 'capybara/rspec' | ||
require_relative '../../app' | ||
|
||
Capybara.app = RockPaperScissors | ||
|
||
feature 'confirms that the testing infrastructure is working' do | ||
scenario 'the home page returns a successful status code' do | ||
visit('/') | ||
expect(page.status_code).to eq(200) | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
def sign_in | ||
visit('/') | ||
fill_in 'player', with: 'Alien' | ||
click_on('Submit name!') | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
require 'game' | ||
|
||
describe Game do | ||
end | ||
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. Empty file? I think you left the spec for this somewhere else? Then maybe you could delete this file 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. Perhaps it would be good to consider what you might have tested in here if you had the time - you could even comment some ideas and come back to it at a later stage when you want to make improvements, especially the logic in Game is an important one. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require 'player' | ||
|
||
describe Player do | ||
let(:player) { described_class.new('Clodius') } | ||
it "should return player's name" do | ||
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. much better indentation here. Clear class names and tests. Nice one man! |
||
expect(player.name).to eq('Clodius') | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<style> | ||
body { | ||
<!-- margin: 0 auto; --> | ||
text-align: center; | ||
width: 100vw; | ||
background-image: url("https://source.unsplash.com/h4elZPxUXLU"); | ||
background-attachment: fixed; | ||
background-repeat: no-repeat; | ||
background-size: 100vw; | ||
} | ||
h1 {font-family: arial; | ||
text-align: center;} | ||
</style> | ||
<body> | ||
|
||
<h1>You chose <%= @player_weapon %>...<br></h1> | ||
<h1>Computer chose <%= @computer_weapon %>...<br><h1> | ||
<h1><%= @message %><h1> | ||
<form action='/play_again' method='post'> | ||
<button type="submit" style="padding: 5px 10px">Have another go?</button> | ||
</form> | ||
</body> | ||
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 again. Takes maybe a day or two to write the code, but people would have to read it an unspecified amount of time |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<style> form { | ||
text-align: center; | ||
font-family: arial; | ||
padding-bottom: 10px; | ||
} | ||
input {border-radius: 7px;} | ||
button {border-radius: 7px;} | ||
h1 {text-align: center; font-family: arial; padding-top: 20px} | ||
</style> | ||
|
||
<h1>Enter Name</h1> | ||
<form action='/play' method='post'> | ||
<input type="text" name="player" style="padding: 5px 15px"><br><br> | ||
<button type="submit" style="padding: 5px 10px">Submit name!</button> | ||
</form> | ||
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. Indentation.. naughty naughty! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<html> | ||
<head> | ||
<style> | ||
h1 {text-align: center; font-family: arial; margin: 0} | ||
h2 {text-align: center; font-family: arial;} | ||
div {text-align: center;} | ||
form {text-align: center;} | ||
form:hover {opacity: 0.7;} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h1>Welcome, <%= @player_name %></h1><br> | ||
<h2>Choose wisely.</h2> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/QxjEi8Fs9Hg' width='400' | ||
border='2' name='player_choice' type='submit' id='rock'></> | ||
<input type="hidden" name="player_choice" value="rock" /> | ||
</form> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/RyrFRsVoe2Q' width='400' | ||
border='2' name='player_choice' type='submit' id='paper'></> | ||
<input type="hidden" name="player_choice" value="paper" /> | ||
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. Don't forget to indent everything! Makes it easier to read for others ;) Maybe even have blank lines between the parts that don't relate i.e. After each form to show where one stops and the other starts (this is only when you know a code review will be done) |
||
</form> | ||
<div style="margin: 0px auto; width: 400; height: 267; overflow: hidden; border: 2px solid black"> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/c18q3myyHLU' width='400' | ||
name='player_choice' type='submit' id='scissors'></> | ||
<input type="hidden" name="player_choice" value="scissors" /> | ||
</form> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<html> | ||
<head> | ||
<style> | ||
h1 {text-align: center; font-family: arial} | ||
h2 {text-align: center; font-family: arial} | ||
h3 {text-align: center; font-family: arial} | ||
div {text-align: center;} | ||
form {text-align: center;} | ||
form:hover {opacity: 0.7;} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h3>Insanity is doing the same thing over and over again and expecting a different result.</h3> | ||
<h3>Except when it comes to rock, paper, scissors.</h3> | ||
<h3>Choose wisely.</h3> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/QxjEi8Fs9Hg' width='400' | ||
border='2' name='player_choice' type='submit' id='rock'></> | ||
<input type="hidden" name="player_choice" value="rock" /> | ||
</form> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/RyrFRsVoe2Q' width='400' | ||
border='2' name='player_choice' type='submit' id='paper'></> | ||
<input type="hidden" name="player_choice" value="paper" /> | ||
</form> | ||
<div style="margin: 0px auto; width: 400; height: 267; overflow: hidden; border: 2px solid black"> | ||
<!-- margin: 0px auto saved me here, nothing else would center the div --> | ||
<form action='/battle' method='post'> | ||
<input type='image' src='https://source.unsplash.com/c18q3myyHLU' width='400' | ||
name='player_choice' type='submit' id='scissors'></> | ||
<input type="hidden" name="player_choice" value="scissors" /> | ||
</form> | ||
</div> |
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.
Great file, concise, good use of class names and instance and global variables