During this activity:
This activity helps students develop the following skills, values and attitudes: ability to analyze and synthesize, capacity for identifying and solving problems, and efficient use of computer systems.
This activity can be developed individually or in pairs.
Create a directory called dsl
and a subdirectory src
within it. Inside the src
folder create two files called: jankenpon.rb
and jankenpon_test.rb
.
All Ruby source files must start with a comment containing the lab’s title, date, and the authors’ personal information. For example:
# Domain-Specific Language Pattern # Date: 25-Mar-2019 # Authors: # A00456654 Thursday Rubinstein # A01160611 Anthony Stark
In the jankenpon.rb
source file, implement an internal Domain-Specific Language (DSL) that allows you to see the results of a
Rock-Paper-Scissors-Lizard-Spock (a.k.a. Jan-ken-pon five-weapon expansion) hand game.
The rules of this game are as follows:
These rules are summarized in the following image:
And this is how Sheldon Cooper explains the game on The Big Bang Theory (Season 2, episode 8, “The Lizard–Spock Expansion”):
Your DSL should support five “literal” values: Rock
, Paper
, Scissors
, Lizard
, and Spock
. These values can be combined with the plus (+), minus (-) and parenthesis operators to conform complex expressions. Let A and B be expressions. The expression “A + B” returns the winner between A and B, while “A - B” returns the loser. Additionally, whenever the + and - operators execute the rule being applied is displayed on the standard output. Precedence and associativity of the operators follow Ruby’s rules.
For example, this DSL code:
show Spock - (Lizard + Paper)
should display the following:
Lizard eats Paper (winner Lizard) Lizard poisons Spock (loser Spock) Result = Spock
The show
command is responsible for the last line of the output, showing the result of the expression it takes as input.
Notice that the result and effect of “A + B” are the same as “B + A”. The same is true for “A - B” and “B - A”.
It’s possible to have a tie. This code:
show Spock + Spock
should generate this output:
Spock tie (winner Spock) Result = Spock
The following unit tests verify the correct behavior of your
DSL. Place the test class in the jankenpon_test.rb
source file.
# File: jankenpon_test.rb require 'minitest/autorun' require 'stringio' require 'jankenpon' class JakenponTest < Minitest::Test def setup @old_stdout = $stdout @out = $stdout = StringIO.new end def teardown $stdout = @old_stdout end def test_simple_cases_plus assert_equal Scissors, (Scissors + Paper) assert_equal Scissors, (Paper + Scissors) assert_equal Paper, (Paper + Rock) assert_equal Paper, (Rock + Paper) assert_equal Rock, (Rock + Lizard) assert_equal Rock, (Lizard + Rock) assert_equal Lizard, (Lizard + Spock) assert_equal Lizard, (Spock + Lizard) assert_equal Spock, (Spock + Scissors) assert_equal Spock, (Scissors + Spock) assert_equal Scissors, (Scissors + Lizard) assert_equal Scissors, (Lizard + Scissors) assert_equal Lizard, (Lizard + Paper) assert_equal Lizard, (Paper + Lizard) assert_equal Paper, (Paper + Spock) assert_equal Paper, (Spock + Paper) assert_equal Spock, (Spock + Rock) assert_equal Spock, (Rock + Spock) assert_equal Rock, (Rock + Scissors) assert_equal Rock, (Scissors + Rock) assert_equal Scissors, (Scissors + Scissors) assert_equal Paper, (Paper + Paper) assert_equal Rock, (Rock + Rock) assert_equal Lizard, (Lizard + Lizard) assert_equal Spock, (Spock + Spock) end def test_simple_cases_minus assert_equal Paper, (Scissors - Paper) assert_equal Paper, (Paper - Scissors) assert_equal Rock, (Paper - Rock) assert_equal Rock, (Rock - Paper) assert_equal Lizard, (Rock - Lizard) assert_equal Lizard, (Lizard - Rock) assert_equal Spock, (Lizard - Spock) assert_equal Spock, (Spock - Lizard) assert_equal Scissors, (Spock - Scissors) assert_equal Scissors, (Scissors - Spock) assert_equal Lizard, (Scissors - Lizard) assert_equal Lizard, (Lizard - Scissors) assert_equal Paper, (Lizard - Paper) assert_equal Paper, (Paper - Lizard) assert_equal Spock, (Paper - Spock) assert_equal Spock, (Spock - Paper) assert_equal Rock, (Spock - Rock) assert_equal Rock, (Rock - Spock) assert_equal Scissors, (Rock - Scissors) assert_equal Scissors, (Scissors - Rock) assert_equal Scissors, (Scissors - Scissors) assert_equal Paper, (Paper - Paper) assert_equal Rock, (Rock - Rock) assert_equal Lizard, (Lizard - Lizard) assert_equal Spock, (Spock - Spock) end def test_dsl_1 #--------- show Spock #--------- assert_equal \ "Result = Spock\n", @out.string end def test_dsl_2 #------------------ show Spock + Lizard #------------------ assert_equal \ "Lizard poisons Spock (winner Lizard)\n" \ "Result = Lizard\n", \ @out.string end def test_dsl_3 #------------------ show Spock - Lizard #------------------ assert_equal \ "Lizard poisons Spock (loser Spock)\n" \ "Result = Spock\n", \ @out.string end def test_dsl_4 #------------------------- show Spock + Lizard + Rock #------------------------- assert_equal \ "Lizard poisons Spock (winner Lizard)\n" \ "Rock crushes Lizard (winner Rock)\n" \ "Result = Rock\n", \ @out.string end def test_dsl_5 #--------------------------- show Spock + (Lizard + Rock) #--------------------------- assert_equal \ "Rock crushes Lizard (winner Rock)\n" \ "Spock vaporizes Rock (winner Spock)\n" \ "Result = Spock\n", \ @out.string end def test_dsl_6 #-------------------------------------------- show Rock + Paper + Scissors + Lizard + Spock #-------------------------------------------- assert_equal \ "Paper covers Rock (winner Paper)\n" \ "Scissors cut Paper (winner Scissors)\n" \ "Scissors decapitate Lizard (winner Scissors)\n" \ "Spock smashes Scissors (winner Spock)\n" \ "Result = Spock\n", \ @out.string end def test_dsl_7 #-------------------------------------------- show Rock - Paper - Scissors - Lizard - Spock #-------------------------------------------- assert_equal \ "Paper covers Rock (loser Rock)\n" \ "Rock crushes Scissors (loser Scissors)\n" \ "Scissors decapitate Lizard (loser Lizard)\n" \ "Lizard poisons Spock (loser Spock)\n" \ "Result = Spock\n", \ @out.string end def test_dsl_8 #------------------------------------------------- show((Rock + Paper) - (Scissors + Lizard) + Spock) #------------------------------------------------- assert_equal \ "Paper covers Rock (winner Paper)\n" \ "Scissors decapitate Lizard (winner Scissors)\n" \ "Scissors cut Paper (loser Paper)\n" \ "Paper disproves Spock (winner Paper)\n" \ "Result = Paper\n", \ @out.string end def test_dsl_9 #--------------------------------------------- show Paper + ((Spock + Paper) - Lizard + Rock) #--------------------------------------------- assert_equal \ "Paper disproves Spock (winner Paper)\n" \ "Lizard eats Paper (loser Paper)\n" \ "Paper covers Rock (winner Paper)\n" \ "Paper tie (winner Paper)\n" \ "Result = Paper\n", \ @out.string end end
Create a compressed tarball file with the full contents of the dsl
directory (including the generated HTML documentation in the doc subdirectory). Call this file dsl.tgz
. From a terminal, you can use the following command to create this file (make sure to run it at the same level where the dsl
folder resides):
tar czf dsl.tgz dsl
To deliver the dsl.tgz
file, please provide the following information:
Only one team member needs to upload the file.
Due date is Monday, March 25.
This activity will be evaluated using the following criteria:
50% | Implementation of program requirements. |
---|---|
50% | Documentation. |
1 | The program and/or documentation was plagiarized. |