Skip to content
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

Rewrite "rock paper scissors" project #26037

Merged
merged 23 commits into from
Apr 21, 2024
Merged
Changes from 20 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
86 changes: 60 additions & 26 deletions foundations/javascript_basics/project_rock_paper_scissors.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,78 @@
### Introduction

We're going to make an implementation of grade-school classic "rock paper scissors". If you don't know what that is check the [Wikipedia article](https://en.wikipedia.org/wiki/Rock%E2%80%93paper%E2%80%93scissors) or [this](https://www.wikihow.com/Play-Rock,-Paper,-Scissors) detailed step-by-step. For the moment we're just going to play the game from the browser console, but **we will revisit this project in a later lesson and add a Graphical User Interface with buttons and text,** so don't forget to keep the code on GitHub! You might notice some 'Live Preview' links in the student solutions that have a GUI - this is coming in a later lesson. When you get there don't forget to come back and add your link!
For this project, you will create the game [Rock Paper Scissors](https://www.wikihow.com/Play-Rock,-Paper,-Scissors). This game will be played entirely in the console.

### Quick exercises before starting
<div class="lesson-note">
Some of the student solutions below contain buttons, text, and other elements. These elements are part of what is called a graphical user interface (GUI). You'll create the GUI in a later lesson. In the meantime, remember to commit your code to GitHub.
</div>

### Problem solving approach

1. Identify three ways to include JavaScript in a page.
1. Test it out! Write `console.log("Hello World");` in JavaScript and check to see if it displays in the browser's console.
Since this is the first JavaScript project being built from scratch, it's important to remember the wise words from the [Problem Solving lesson](https://www.theodinproject.com/lessons/foundations-problem-solving). For each step in this project, be sure to do the following

Finally, this is your first JavaScript program built from scratch, so don't forget the previous lesson on problem solving. Plan your solution out before writing any code, and test each piece as you build to ensure it is working before moving on to the next!
1. Plan or pseudocode your solution.
1. Write the code.
1. Test your code to make sure it works.
Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is meant to echo the problem solving lesson, we probably want these items to be about understanding the problem, planning, writing pseudo code, and then dividing and conquering, no?

Maybe it's the wording leading into it, though. "Before you start this project" could maybe be removed, then just say, "For each step in this project, be sure to do the following:"


### Assignment

<div class="lesson-content__panel" markdown="1">
Don't forget to commit early & often! You can [reference the Commit Message lesson here](https://www.theodinproject.com/paths/foundations/courses/foundations/lessons/commit-messages)!
Remember to commit early and often! To refresh your memory, check out the [commit messages lesson](https://www.theodinproject.com/paths/foundations/courses/foundations/lessons/commit-messages).

#### Step 1: Initiate the project structure

1. Create a new Git repository for your project.
1. Create a blank HTML document with a script tag.
1. Check if the webpage includes JavaScript:
- Write `console.log("Hello World")` in JavaScript.
- Check if "Hello World" is logged in the browser console once you open your webpage.

It's best practice to link to an external JavaScript file inside this script tag. Using an external JavaScript file keeps your HTML file clean and organized.

You don't have to write additional code in the HTML file. This game is played entirely via the console.

#### Step 2: Write the logic to get the computer choice

Your game will be played against the computer. You will write a function that randomly returns "Rock", "Paper" or "Scissors".

1. Create a new function named `getComputerChoice`.
1. Write the code so that `getComputerChoice` will randomly `return` one of the following string values: "Rock", "Paper" or "Scissors".
- **Hint**: The [Math.random](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) method returns a random number that's greater than or equal to 0 and less than 1. Think about how you can use this to conditionally return one of the multiple choices.
cakegod marked this conversation as resolved.
Show resolved Hide resolved
thatblindgeye marked this conversation as resolved.
Show resolved Hide resolved
1. Test that your function returns what you expect using `console.log` or [the browser developer tools](https://www.theodinproject.com/lessons/foundations-javascript-developer-tools) before advancing to the next step.

#### Step 3: Write the logic to play a single round

Your game will be played round by round. You will write a function that takes the human and computer player choices as arguments, plays a single round and returns a winner announcement.

1. Create a new function named `playRound`.
1. Define two parameters for `playRound`: `playerChoice` and `computerChoice`. Use these two parameters to take the human and computer choices as arguments.
1. Make your function's `playerSelection` parameter case-insensitive so that players can input "rock", "ROCK", "RocK", or other variations.
1. Write the code for your `playRound` function to `return` a string value representing the round winner, such as: "You lose! Paper beats Rock".

Example code:

1. Start a new Git repo for your project.
1. Create a blank HTML document with a script tag (Hint: it is best practice to link an external .js file). This game is going to be played completely from the console, so don't worry about putting anything else in there.
1. Your game is going to play against the computer, so begin with a function called `getComputerChoice` that will randomly return either 'Rock', 'Paper' or 'Scissors'. We'll use this function in the game to make the computer's play. *Tip: use the console to make sure this is returning the expected output before moving to the next step!*
1. Write a function that plays a single round of Rock Paper Scissors. The function should take two parameters - the `playerSelection` and `computerSelection` - and then return a string that declares the winner or tie of the round like so: `"You Lose! Paper beats Rock"`
```javascript
function playRound(playerChoice, computerChoice) {
// your code here!
}

- Make your function's playerSelection parameter case-insensitive (so users can input `rock`, `ROCK`, `RocK` or any other variation).
const playerSelection = "rock";
const computerSelection = getComputerChoice();

1. **Important note:** you want to `return` the results of this function call, *not* `console.log()` them. You're going to use what you `return` later on, so let's test this function by using console.log to see the results:
console.log(playRound(playerSelection, computerSelection));
```

```javascript
function playRound(playerSelection, computerSelection) {
// your code here!
}
#### Step 4: Write the logic to entire the play the game
MaoShizhong marked this conversation as resolved.
Show resolved Hide resolved

const playerSelection = "rock";
const computerSelection = getComputerChoice();
console.log(playRound(playerSelection, computerSelection));
```
Your game will play 5 rounds. You will write a function named `playGame` that calls `playRound` to play 5 rounds, keeps score, and declares a winner at the end.

1. Write a NEW function called `playGame()`. Use the previous function *inside* of this one to play a five round game that keeps score and reports a winner or loser at the end.
- You have not officially learned how to "loop" over code to repeat function calls... if you already know about loops from somewhere else (or if you feel like doing some more learning) feel free to use them. If not, don't worry! Just call your `playRound` function 5 times in a row. Loops are covered in the next lesson.
- At this point you should be using `console.log()` to display the results of each round and the winner at the end.
- Use `prompt()` to get input from the user. [Read the docs here if you need to.](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt)
- Feel free to re-work your previous functions if you need to. Specifically, you might want to change the return value to something more useful.
- Feel free to create more "helper" functions if you think it would be useful.
1. Create a new function named `playGame`.
1. Get the human player choice using the `prompt` method. Read this [MDN article about the prompt method](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) learn more about it.
thatblindgeye marked this conversation as resolved.
Show resolved Hide resolved
1. Put the previous `playRound` function inside `playGame`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the intent with this line here that users should literally move their playRound declaration inside of playGame, or just that they should call playRound inside of playGame? The wording makes it sound like the former which we probably don't want users to do. We could honestly probably just remove this step since we're already telling users to call playRound 5x on the next line.

Copy link
Contributor Author

@cakegod cakegod Mar 27, 2024

Choose a reason for hiding this comment

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

This depends on where we want the user to declare the scores. If the scores are declared inside the playGame, we won't be able to increment the scores inside the playRound. We can use the return of playRound to conditionally increment the winner's score variable declared in playGame, but this makes the project much more complicated.

So, I thought about guiding the Oditinite to one of those two outcomes: https://gist.github.com/cakegod/2f5f63295ff606a1a729f67564cd7d43

Or we could keep the outcome return in playRound, but it becomes more messy and complicated without loops: https://gist.github.com/cakegod/269810a537de15cc427a0b35f4b8c39f

Copy link
Contributor

Choose a reason for hiding this comment

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

Another option would be declaring the scores as global variables, though yeah as the project is currently written and remains written here the intent seems to be that playGame houses the scores.

If you feel having the playRound moved inside of playGame is the better option I'm good with that. Maybe just tweak the verbiage of this instruction to, "Move your playRound function so that it's declared inside of the new playGame function"

1. Play 5 rounds by calling `playRound` 5 times.
- **Hint**: When you assign a function call to a variable, the return value of that function is assigned to the variable. Accessing the variable afterward will only provide the assigned value; it doesn't recall the function. You need to recall the choice functions to get new choices for each round.
thatblindgeye marked this conversation as resolved.
Show resolved Hide resolved
- Re-work your previous functions or create more helper functions if necessary. Specifically, you may want to change the return values to something more useful.
- If you already know about loops, you can use them. If not, don't worry! Loops will be covered in the next lesson.

</div>
<div class="lesson-note" markdown="1">
Expand Down
Loading