Part 3: Implementing the Game Logic
The Resources folder structure should look something like this.
resources
βββ images
β βββ .gitkeep
βββ scripts
++β βββ rock_paper_scissors.js
β βββ index.js
βββ styles
βββ styles.css
The marked file is the file you'll be using in the part of the assignment.
SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible, and maintainable. It stands for:
- Single responsibility
- Openβclosed
- Liskov substitution
- Interface segregation
- Dependency inversion
In this exercise, we will introduce the first principle which states that "every class should have only one responsibility". We will do this by separating the code that controls the game logic from the code that controls and manipulates the DOM.
In the scripts/rock_paper_scissors.js
, we will make a RockPaperScissors
class that will contain all "logic" for the game (properties and methods). and in the scripts/index.js
file, we will handle the user input and call methods from the RockPaperScissors
class as needed.
This file, we will use JavaScript Classes.
RockPaperScissors
Classβ
The class will include a few properties:
- username
- score:
{user: 0, cpu: 0}
- gameHistoryLog: []
This class will only contain 4 methods:
constructor(username)
generateCPUResponse()
determineWinner(userSelection, cpuSelection)
play(userSelection)
class RockPaperScissors {
constructor(username) {
...
}
generateCPUResponse() {
...
}
determineWinner(userSelection, cpuSelection){
...
}
play(userSelection) {
...
}
}
Let's start with one function at a time...
constructor(username)
β
This function will take in the username
as a parameter and set it as a property to the class. In the constructor, we will also defined all our variables and set them to some initial values/
class RockPaperScissors {
constructor(username) {
this.username = username;
this.score = {
user: 0,
cpu:0
},
this.gameHistoryLog = [];
}
...
}
Note:β
- class property are declared with the
this
keyword.
generateCPUResponse()
β
For this function:
- Create an array with the following values
const acceptedValues = [ `rock`, `paper`, `scissors` ]
- Using both Math.random and Math.floor() methods, generate a random index number (0,1,2)
- return the value of acceptedValue at the random index generated in the previous step.
determineWinner(userSelection, cpuSelection)
β
This function will take 2 parameters userSelection
and cpuSelection
and will return one of the following values (win
, lose
, tie
).
- it would return (tie) if the user selection is the same as the cpu random selection.
- it would return (win) if:
- user selection is
rock
and cpu selection isscissors
- OR
- user selection is
paper
and cpu selection isrock
- OR
- user selection is
scissors
and cpu selection ispaper
- user selection is
- it would return (lose) in any other case.
play(userSelection)
β
This method takes in 1 parameter: the userSelection
. It will:
- Get the CPU Random selection using the
generateCPUResponse()
- Determine the winner using the
determineWinner(userSelection, cpuSelection)
- update the score tally
this.score
OR// if the user won the round
this.score.user ++;
// if the user cpu the round
this.score.cpu ++;this.score = {
user: NEW_SCORE,
cpu: NEW_SCORE
} - Add another historyLog entry to the game history array.
- the log entry should look something like this
Yahya selected Scissors, CPU selected Paper: Yahya wins wins
this.gameHistoryLog.push(`Yahya selected Scissors, CPU selected Paper: Yahya wins wins`);
- the log entry should look something like this
Resultβ
Running the unit tests should pass
Testingβ
- Run the tests with
npm run test:logic
. This will run the Unit tests for the logic component only of this assignment.