Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ end

group :development, :test do
gem 'rubocop', '1.20'
gem 'sinatra-contrib'
gem 'puma'
gem 'rack'
end
15 changes: 14 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ 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)
nio4r (2.5.8)
nokogiri (1.12.3)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
parallel (1.20.1)
parser (3.0.2.0)
ast (~> 2.4.1)
public_suffix (4.0.6)
puma (5.6.4)
nio4r (~> 2.0)
racc (1.5.2)
rack (2.2.3)
rack-protection (2.1.0)
Expand Down Expand Up @@ -76,6 +80,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 @@ -88,14 +98,17 @@ PLATFORMS

DEPENDENCIES
capybara
puma
rack
rspec
rubocop (= 1.20)
simplecov
simplecov-console
sinatra
sinatra-contrib

RUBY VERSION
ruby 3.0.2p107

BUNDLED WITH
2.2.26
2.3.12
119 changes: 69 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,48 @@
# RPS Challenge
# Rock, Paper, Scissors Challenge

Instructions
-------
## Instructions to install and play the game

* Feel free to use google, your notes, books, etc. but work on your own
* If you refer to the solution of another coach or student, please put a link to that in your README
* If you have a partial solution, **still check in a partial solution**
* You must submit a pull request to this repo with your code by 9am Monday morning
* Clone this repo in your desired directory by doing the following in the terminal:
```
git clone https://github.com/Farzan-I/rps-challenge.git
```
* Run `bundle` to install all the gemfiles
* Run `rackup` in the directory, then go to your desired browser and enter:
```
localhost:9292
```
* Enter your name (if you don't you can't continue), click on "Let's play!" and play until your heart desires!

Task
----
<br>

Knowing how to build web applications is getting us almost there as web developers!
## Task
-------

The Makers Academy Marketing Array ( **MAMA** ) have asked us to provide a game for them. Their daily grind is pretty tough and they need time to steam a little.
The Makers Academy Marketing Array ( **MAMA** ) have asked to provide a game for them. Their daily grind is pretty tough and they need time to steam a little.

Your task is to provide a _Rock, Paper, Scissors_ game for them so they can play on the web with the following user stories:
The task is to provide a _Rock, Paper, Scissors_ game for them so they can play on the web with the following 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
- the marketeer will be presented the choices (rock, paper and scissors)
- the marketeer can choose one option
- the game will choose a random option
- a winner will be declared


As usual please start by

* Forking this repo
* TEST driving development of your app

[You may find this guide to setting up a new Ruby web project helpful.](https://github.com/makersacademy/course/blob/main/pills/ruby_web_project_setup_list.md)

## Bonus level 1: Multiplayer

Change the game so that two marketeers can play against each other ( _yes there are two of them_ ).

## Bonus level 2: Rock, Paper, Scissors, Spock, Lizard

Use the _special_ rules ( _you can find them here http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock_ )
- The marketeer should be able to enter their name before the game
- The marketeer will be presented the choices (rock, paper and scissors)
- The marketeer can choose one option
- The game will choose a random option
- A winner will be declared

## Basic Rules
-----

- Rock beats Scissors
- Scissors beats Paper
Expand All @@ -63,24 +54,52 @@ In code review we'll be hoping to see:
* High [Test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) (>95% is good)
* The code is elegant: every class has a clear responsibility, methods are short etc.

Reviewers will potentially be using this [code review rubric](docs/review.md). Referring to this rubric in advance may make the challenge somewhat easier. You should be the judge of how much challenge you want this at this moment.
Reviewers can potentially be using this [code review rubric](docs/review.md).

## Demo
-------
### Home page
![home_page](public/images/home.png)

Notes on test coverage
----------------------
### Home page error
![home_page_error](public/images/home_error.png)

Please ensure you have the following **AT THE TOP** of your spec_helper.rb in order to have test coverage stats generated
on your pull request:
### Battleground
![battleground](public/images/battle_ground.png)

```ruby
require 'simplecov'
require 'simplecov-console'
### Battleground win
![battleground_win](public/images/battleground_win.png)

### Battleground loss
![battleground_win](public/images/battleground_loss.png)

### Battleground draw
![battleground_draw](public/images/battleground_draw.png)

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::Console,
# Want a nice code coverage website? Uncomment this next line!
# SimpleCov::Formatter::HTMLFormatter
])
SimpleCov.start
```

You can see your test coverage when you run your tests. If you want this in a graphical form, uncomment the `HTMLFormatter` line and see what happens!
## Conclusion
-----
* I managed to make several files to be able to incorporate the classes and the tests that I needed
* These were split into features and unit test folders as well as a 'lib' folder to have all the game class as well as the player class
* The 'app.rb' file that has the specifications for the game is present in the parent folder to incorporate all of the spec and lib folder files in order to run the game
* I had difficulty trying to apply a gradient background on the home page and therefore made it a simple, slick white background
* I did however make the play page a gradient background and didn't apply an image
* I managed to make a button on the home page that is required to be filled in (name) in order for the player to access the battleground and select their weapon for Rock, Paper, Scissors
* On the play page, the buttons for the weapons I customised and would have preferred to have had more time to make them look slicker
* A message was given for when the player won, drew or lost to the computer - I would have tried to incorporate javascript to make the messages more dynamic and eye catching

## Improvements if not on a time constraint
-----
* Make the home page more eye catchy
* Allow the user to have a better experience i.e. see a better win/loss/draw message by using javascript and maybe CSS
* Make the buttons more appealing and less like 1990's/2000's style by using capybara properly and javascript with CSS
* Make the game two player by allowing two players to entrer their names on the home page and also select their weapons in the play area
* Incorporate the 'rock, paper, scissors, lizard, spock' and make the game more complicated and appealing

## Bonus level 1: Multiplayer - **_Did not complete_**

Change the game so that two marketeers can play against each other ( _yes there are two of them_ ).

## Bonus level 2: Rock, Paper, Scissors, Spock, Lizard - **_Did not complete_**

Use the _special_ rules ( _you can find them here http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock_ )
52 changes: 52 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'sinatra/base'
require 'sinatra/reloader'
require './lib/player'
require './lib/game'

class Rps < Sinatra::Base

configure :development do
register Sinatra::Reloader
end

get '/' do
erb :index
end

enable :sessions

post '/names' do
$game = Game.new(Player.new(params[:player]))
redirect to('/play')
end

get '/play' do
@game = $game
@message = session[:message]
erb :play
end

post '/rock' do
@game = $game
@game.rock
session[:message] = @game.message
redirect '/play'
end

post '/paper' do
@game = $game
@game.paper
session[:message] = @game.message
redirect '/play'
end

post '/scissors' do
@game = $game
@game.scissors
session[:message] = @game.message
redirect '/play'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Currently, you define a route for each player move option, and each of these routes uses mostly the same code. This is a duplication of code that could be refactored.

Another method of approach this logic is to pass in the player move as a parameter, calling the same route, and passing that param into the @GAMe instance.

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

attr_reader :player, :win

def initialize(player)
@player = player
@win = nil
@message = ""
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this feels like neat logic - very easy to read

def rock
case rpc_play
when "rock"
@win = nil
when "paper"
@win = false
when "scissors"
@win = true
end
end

def paper
case rpc_play
when "rock"
@win = true
when "paper"
@win = nil
when "scissors"
@win = false
end
end

def scissors
case rpc_play
when "rock"
@win = false
when "paper"
@win = true
when "scissors"
@win = nil
end
end

def message
case @win
when true
@message = "You've won! Well done!"
when false
@message = "You've lost! Try again!"
when nil
@message = "It's a tie! Try again!"
end
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This approach can be simplified to make this class more concise. Check out the following approach: https://github.com/makersacademy/rps-challenge/blob/main/docs/review.md#use-of-ifelsif-conditionals-for-business-logic


private

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You could consider keeping the computer in a separate class

def rpc_play
["rock", "paper", "scissors"].sample
end

end
9 changes: 9 additions & 0 deletions lib/player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Player

attr_reader :name

def initialize(name)
@name = name
end

end
Binary file added public/images/battle_ground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/battleground_draw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/battleground_loss.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/battleground_win.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/home_error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions spec/features/enter_names_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
feature "Enter names" do
scenario "submitting names" do
visit("/")
fill_in :player, with: "Farzan"
click_button "Submit"

save_and_open_page

expect(page).to have_content("Let's Play Farzan!\nRock, Paper, Scissors?\nRock\nPaper\nScissors")
end

scenario "display homepage" do
visit '/'
expect(page).to have_content("Welcome to: Rock, Paper, Scissors!")
expect(page).to have_content("Please enter your name to start:")
expect(page).to have_button("Let's play!")
end

end
15 changes: 15 additions & 0 deletions spec/features/play_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
feature "play" do

before do
visit ('/')
fill_in("player", with: "Farzan")
click_on("Let's play!")
end

scenario "displays rock paper scissor buttons" do
expect(page).to have_button("Rock")
expect(page).to have_button("Paper")
expect(page).to have_button("Scissors")
end

end
Loading