# Overview

In this project, you will be implementing a rock-paper-scissors game! Rock-paper-scissors is a hand game played between two people, in which each player simultaneously forms one of three shapes with an outstretched hand. These shapes are “rock” (a simple fist), “paper” (a flat hand), and “scissors” (a fist with the index and middle fingers extended, forming a V).

A player who plays rock will beat another player who has chosen scissors, but will lose to one who has played paper; a play of paper will lose to a play of scissors. If both players choose the same shape, the game is tied.

This project is significantly more difficult than Project 1 and you can expect it to take 2 to 3 times longer to complete.

See the image below for a visual representation of the rules of rock-paper-scissors:

## Objectives

By completing this project, you will learn to:

• Develop programs that are divided into functions
• Compile programs that are not yet complete by using stubs
• Verify the correctness of functions by writing test cases
• Implement functions based on a specification and RME comment
• Use existing operators to perform interactive I/O using C++
• Write logical expressions and selection statements in C++
• Create algorithms that use conditionals and loops
• An important objective is to have fun!

You will apply the following skills you learned in lecture:

• Lecture 3
• Call math functions like floor() and ceil().
• Lecture 4
• Call functions with multiple parameters
• Use return statements to provide a result from a function
• Lecture 5
• Create function declarations to allow calls to a function before its code is provided in a function definition
• Use the iterative development cycle for writing your functions
• Lecture 6
• Use if, else, and else if to conditionally execute code
• Execute the cin algorithm to determine how a given user input will be stored into variables
• Lecture 7
• Write event-controlled loops using while
• Combine loops with cin to continue reading until the user is finished
• Lecture 8
• Write count-controlled loops using for

# Getting Started

## Starter Files

The IDE setup tutorials for Visual Studio and XCode include a video about how to set up a project using the starter files. You can access the tutorals here:

Make sure there are 3 files in your project: rps.cpp, test.cpp, and start.cpp.

Submit your code to the autograder here. You receive 4 submits each day and your best overall submission counts as your score. You can find where the files you need to submit are on your computer using these steps from Project 1. You will submit two files, which must be called rps.cpp and test.cpp.

This project must be completed individually, i.e., no partners.

• 60 points: correctness. Implement functions in rps.cpp and play the game of rock, paper, scissors. To what extent does your code implement the features required by our specification? To what extent is your code consistent with our specifications and free of bugs?
• 10 points: testing. To what extent is your code tested? Implement the testing functions and submit them via the test.cpp file. See the Testing section for more details.
• 10 points: style. To what extent is your code written well? To what extent is your code readable? We will only look at your rps.cpp when determining your style grade. Consult EECS 183 Style Guide and check the Style Checklist at the end of this project’s specification for some tips!

The deadline is Friday, February 26 at 11:59PM Eastern. To encourage you to take advantage of the Wellness Day on Wednesday, February 24, the 5% bonus deadline will NOT be on Wednesday, Feb. 24 but instead will be on Thursday, Feb 25. If your last submission is on Thursday, February 25 by 11:59PM, you will receive a 5% bonus. There is no 2.5% bonus day for this project. If your last submission is on Wednesday, February 24 by 11:59PM, you will receive a 5% bonus. If your last submission is on Thursday, February 25 by 11:59PM, you will receive a 2.5% bonus.

You have 3 late days that you can use any time during the semester for projects. There are 3 late days total, not 3 per project. To use a late day, submit to the autograder after the deadline. It will prompt you about using one of your late day tokens. There are more details about late days in the syllabus.

Remember that we grade your BEST submission for style. If multiple submissions are tied in score, we take the last of those.

WARNING: Beware the autograder’s ability to detect cheating! See Collaboration Policy for further information.

## Understanding the Distribution Code

• rps.cpp: Starter code for the application you will write in this project. Holds the definitions of required functions and the implementations of a couple functions. We have stubbed all required functions for you.

• test.cpp: Testing functions for your rps.cpp implementation. Holds the declarations of required testing functions. We have stubbed all required functions for you.

• start.cpp: This file contains the main() function for your program, which allows you to run either the rps application or your test suite. You do not need to modify this file or submit it to the autograder.

Stubbing functions means adding the minimal necessary code to make a function compile. For example, some of the functions in rps.cpp have return types of bool. We have added return false in those functions so that they will compile even if you have not implemented all the functions yet. Be sure to remove our return statements when you write your own implementation of the function.

Once you have created a project, you should be able to compile and run the distribution code. We have included a main() function in start.cpp which will allow you to run either your tests or the rps application.

  -------------------------------
EECS 183 Project 2 Menu Options
-------------------------------
1) Execute testing functions in test.cpp
2) Execute rps() function to play game
Choice --> 1

Now testing function isMoveGood()
'r': Expected: 1, Actual: 1
'q': Expected: 0, Actual: 1
...


The second test case currently fails because the isMoveGood() function is not fully implemented yet.

## How to get help

Most students in EECS 183 need help from staff and faculty multiple times each project. We’re here for you! Many more people need help with Project 2 than with Project 1.

If your question is about the specification or about something about the project in general, Piazza is the fastest place to get help.

Office Hours: All office hours and instructions for signing up/attending can be found under the Office Hours tab on the course website.

Group office hours: Group Office Hours are a great way to clear up commonly confused topics for projects. See this Piazza post for full details.

Individual office hours: You can get 1-1 help over a video call by signing up for office hours at eecsoh.org. You can find instructions here.

## Collaboration Policy and the Honor Code

All students in the class are presumed to be decent and honorable, and all students in the class are bound by the College of Engineering Honor Code.

We want students to learn from and with each other, and we encourage you to collaborate. We also want to encourage you to reach out and get help when you need it.

### You are encouraged to:

• Give or receive help in understanding course concepts covered in lecture or lab.
• Practice and study with other students to prepare for assessments or exams.
• Consult with other students to better understand project specifications.
• Discuss general design principles or ideas as they relate to projects.
• Help others understand compiler errors or how to debug parts of their code.

To clarify the last item, you are permitted to look at another student’s code to help them understand what is going on with their code. You are not allowed to tell them what to write for their code, and you are not allowed to copy their work to use in your own solution. If you are at all unsure whether your collaboration is allowed, please contact the course staff via the admin form before you do anything. We will help you determine if what you’re thinking of doing is in the spirit of collaboration for EECS 183.

### The following are considered Honor Code violations:

• Submitting others’ work as your own.
• Copying or deriving portions of your code from others’ solutions.
• Collaborating to write your code so that your solutions are identifiably similar.
• Sharing your code with others to use as a resource when writing their code.
• Receiving help from others to write your code.
• Sharing test cases with others if they are turned in as part of your solution.
• Sharing your code in any way, including making it publicly available in any form (e.g. a public GitHub repository or personal website).

The full collaboration policy can be found in the syllabus.

We run every submission against every other submission and determine similarities. All projects that are “too similar” are forwarded to the Engineering Honor Council. This happened to numerous students last semester. Also know that it takes months to get a resolution from the Honor Council. Discussing the project with other students will NOT be an issue. Sharing code between students, even if it’s just one function, will likely cause the cheating detector to identify both programs as “too similar”. We also search the web for solutions that may be posted online and add these into the mix of those checked for similarities. Searching the web, by the way, is something that we are very good at.

Any violation of the honor policies appropriate to each piece of course work will be reported to the Honor Council, and if guilt is established, penalties may be imposed by the Honor Council and Faculty Committee on Discipline. Such penalties can include, but are not limited to, letter grade deductions or expulsion from the University.

Also note that on all cases forwarded to the Engineering Honor Council the LSA Dean of Academic Affairs is also notified. Furthermore, the LSA rule is students involved in honor violations cannot withdraw from nor drop the course.

# Problem Statement

Your task for this project is to create a program for playing a game of rock-paper-scissors between two players. The game will consist of exactly three rounds of rock-paper-scissors. A player will need to win more of the three rounds than their opponent to win the game. The game will result in a tie if no player wins more rounds than the other player. For example: if Player 1 wins the first round while rounds 2 and 3 both result in a draw, Player 1 would win the game since they have won more rounds than Player 2.

IMPORTANT: So that we can automate the testing of your code, the output messages for the rock-paper-scissors game must be exactly the same as presented in this specification and the function RMEs. Making sure they are exact is critical to passing the autograder. Check the Sample Output below for the exact prompts. To avoid spelling errors, simply copy/paste the appropriate prompt into your code. Note that a spelling error will cause you to fail almost every test case from the autograder. Use of a diffchecker can easily catch such errors.

Here is an example of what the execution of your final application will look like:


----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

Player 1, enter your name: Rana Makki

Player 2, enter your name: David Cao

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 1

Rana Makki, enter your move: r

David Cao, enter your move: p

David Cao wins the round!

Rana Makki, enter your move: r

David Cao, enter your move: r

This round is a draw!

Rana Makki, enter your move: p

David Cao, enter your move: s

David Cao wins the round!

Congratulations David Cao!
You won EECS 183 Rock-Paper-Scissors!

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 3

----------------------------------------
Thanks for playing
Rock-Paper-Scissors!
----------------------------------------


## Development Cycle with Functions

In Project 1, you had to divide the program into pieces so you could test each part individually. In Project 2 and later, the program is already divided into functions in the starter code which you can use as the parts to work on. You should write, test, and debug one function at a time. See Lecture 5 for a recap of how to implement the iterative development cycle for functions.

The functions in a program call each other, and it is easiest to start with the functions that do not call any other functions. For example, in this project, getMove() will call isMoveGood(), so it makes sense to complete isMoveGood() before getMove(). We will be able to test isMoveGood() before we write the code that actually uses it in our program.

The order you write the functions will be different than the order they will appear in rps.cpp. We provide a suggested order for writing your functions in the Suggested Timeline.

## Solution Overview

• Your program will provide a menu, implemented using a loop, to obtain user input and play rock-paper-scissors games.

NOTE: Even though we are going over what happens in rps() early in the specification, this does NOT mean you should begin your implementation with rps(). Actually, you should write rps() last, after you have implemented all of the other functions, since rps() will work by calling all of the other functions.

• To begin, your program will call printInitialHeader(), which will print this heading:
----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

• Next, your program will obtain the two player names, which will not change for the duration of the program. First, Player 1 will be asked to input their name:
----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------



Once Player 1’s name is entered, the program will prompt Player 2 for their name:

----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

Player 1, enter your name: Rana Makki



Note that “Rana Makki” in the sample output above is user-entered text, and therefore is not included in the output prompt. Also note that player names can contain whitespace.

• Next, your program will call getMenuChoice(), which will print the menu (by calling another function that does this) and will obtain user input for menu selection.

Menu Options
------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice -->

• Depending upon the value the user enters for “Choice”, the program will either initiate a game of rock-paper-scissors, initiate a game of rock-paper-scissors-lizard-spock, or quit.

• Your program shall continue to play games and prompt the user for another choice until a user input of ‘Quit’ (user choice 3) is entered.

• When the user input indicates that they’ve had enough and want out of EECS 183 Rock-Paper-Scissors, your program will call printCloser(), which will print this heading:

----------------------------------------
Thanks for playing
Rock-Paper-Scissors!
----------------------------------------


and the program naturally finishes.

• There are many functions that assist in making all of this happen. Below is a brief overview of the functions you will use in this project. For in-depth descriptions of the functions’ behavior, please read the RME’s within rps.cpp.

IMPORTANT: For the functions you will implement, write their definitions below rps(), as indicated in rps.cpp.

• This function has been implemented for you.

• This function has been implemented for you.

### printErrorMessage()

• This function has been implemented for you.

### printCloser()

• This function has been implemented for you.

### getName()

• This function prompts a player for their name and handles the input accordingly.

• Make sure to print an extra newline before the function returns. This is so it can behave correctly on the autograder.

• This function utilizes the following function(s):

• printErrorMessage()

• This function will handle printing the menu and reading in the user’s menu choice from input.

• Make sure to print an extra newline right after every call to cin. This is so it can behave correctly on the autograder.

• This function utilizes the following function(s):

• printMenu()
• Invalid input: You cannot depend upon users to get the input within range. You also need to handle out of range input. If the user enters a menu option other than 1, 2, or 3 you need to

• print Invalid menu choice

• This needs to be repeated until a valid menu choice is entered.

• BE CAREFUL: this function’s purpose is solely to get a single menu choice from the user and return this choice. This function should not be for playing the actual game of rock-paper-scissors and should not call additional functions beyond printMenu().

### isMoveGood()

• This function determines whether or not a player’s move is valid. A valid move consists of an ‘r’, ‘p’ or ‘s’ character, corresponding to “rock”, “paper”, and “scissors”, respectively. The uppercase versions of these characters are also considered valid. Any other characters a user enters will be considered invalid.

IMPORTANT: Note that for this project you can assume user input will always be of the data type expected (which is char for moves). In other words, as the programmer, you only need to check that values entered are valid moves - you do not need to worry about users entering integers, doubles, strings, bools or any combination of these. Those are bad input and prohibited by the REQUIRES clause.

• This function utilizes no other functions.

### getMove()

• This function prompts a player to enter their move during a round, and handles the input accordingly.

• Make sure to print an extra newline before the function returns. This is so it can behave correctly on the autograder.

• This function utilizes the following function(s):

• printErrorMessage()

• isMoveGood()

There are two things that could happen depending on the character that the user inputs for their move:

• If valid move: The function returns the move.
David Cao, enter your move: p

• If invalid move: The program will print an error message as shown below, and the function will assign (and return) a “default” move for the user that entered invalid input. Note that the default move is ‘r’.
David Cao, enter your move: a

ERROR: Illegal move given, using default


### isRoundWinner()

• This function determines if the player made a winning move. Note: a move that results in a tie is not a winning move.

• This function utilizes no other functions.

### announceRoundWinner()

• This function announces the name of the round winner. If there is no round winner, it outputs that the round resulted in a draw.

• This function utilizes no other functions.

### doRound()

• This function will simulate one round of the game.

• This function utilizes the following function(s):

• getMove()

• isRoundWinner()

### announceWinner()

• This function announces the name of the game winner. If there is no winner of the game, it outputs that there was no winner.

• This function utilizes no other functions.

### doGame()

• This is the function that plays three rounds of rock-paper-scissors, announces round winners, and keeps track of the number of rounds each player has won. A player receives a point if they win a round. If the round is a draw, no player receives a point. The full game will always consist of three rounds. This means that even if the same player wins the first two rounds, the third round will always be played.

• Hint: Make use of the MAX_ROUNDS constant defined and initialized at the top of rps.cpp when implementing this function.

• This function utilizes the following function(s):

• doRound()

• announceRoundWinner()

• For the base project, if the game_type provided to this function is 2 (indicating that the user selected rock-paper-scissors-lizard-spock), the only thing this function needs to do is return an empty string after printing the following message:

Under Construction


Only the S’more version needs to handle a game_type of 2 and implement rock-paper-scissors-lizard-spock.

## Putting it Together: Writing rps()

• Once you have written and tested each of the above functions, it is time to combine everything in rps() and do further testing with your new debugging skills. Be sure that your program behaves as illustrated in the Sample Output.

• Now that you have a new project created and rps.cpp in front of you, it’s time to begin! The game is managed in the rps() function — but do not write code there before you have thought about the problem and implemented all of the other functions.

• You can find some starter pseudocode for implementing the rock-paper-scissors game below to help get you started:

// Print the header
// Get player 1 name
// Get player 2 name
// Repeat the following until the user quits the program:
//     Print the menu and get the menu choice, continuing to prompt until the user
//     chooses a valid menu choice
//     Play the game and announce the winner, or quit the program (according to user's menu choice)
// Print the closing message

• In programming, when you start by outlining the problem at hand, add in one small piece at a time, and test as you go, implementing a solution is much more manageable.

## Function Table

The table below provides an outline of which other functions each function should call, if any. You should not be using other functions if not specified.

Function Other functions it should call
getName() printErrorMessage()
getMenuChoice() printMenu()
isMoveGood() Does not utilize any other functions
getMove() printErrorMessage(), isMoveGood()
isRoundWinner() Does not utilize any other functions
announceRoundWinner() Does not utilize any other functions
doRound() getMove(), isRoundWinner()
announceWinner() Does not utilize any other functions
doGame() doRound(), announceRoundWinner()
rps() getName(), getMenuChoice(), doGame(), announceWinner()

Here is an example of how to read the table:

• getName() should call printErrorMessage()

# Suggested Timeline

Note: It’s common to not completely understand the project after reading through the spec. This is okay! You can start working on the project without fully understanding the spec. In fact, working on the project will likely help you better understand the spec.

As an approximate timeline, you will be on track if by:

• February 9: Starter code downloaded and new project set up in IDE. Starter code submitted to autograder. You’ve read through the spec.
• February 12: isMoveGood(), getMove(), isRoundWinner(), announceRoundWinner(), and announceWinner() implemented, fully tested, and passing autograder.
• February 16: getName(), getMenuChoice(), doRound() implemented, fully tested, and passing autograder.
• February 18: doGame() implemented, fully tested, and passing autograder. Start work on rps().
• February 21: rps() code “complete.” Debugging in progress, passing all individual function tests, 80% or higher on autograder
• February 23: Make last submission to autograder for 5% extra credit
• February 24: Wellness Day - relax! Due to the Wellness Day, the 5% extra credit deadline has been pushed to Thursday. There is no 2.5% extra credit day, and the project is still due on Friday.
• February 25: Make last submission to autograder for 5% extra credit
• February 26: Project due date.

# Creating a Project

If you haven’t done so already, read the Getting Started with Xcode guide or Getting Started with Visual Studio guide, depending on the operating system you’re using. They will walk you through creating a new project and basic editing.

Once you create a project, you’ll need to import rps.cpp, test.cpp, and start.cpp.

Xcode

• There are a couple of ways to import a file in Xcode. The easiest way, perhaps, is to drag and drop that file next to main.cpp in the Navigator area on the left side of the Xcode window.

Check the checkbox next to Destination: Copy items if needed, make sure that the checkbox next to Add to targets is checked and click Finish.

• Alternatively, you can choose File > Add Files to…​ in the menu bar, navigate to your file, select it and click Add (or press Option-Command-A). Make sure that the checkbox next to Add to targets is checked when you are adding .cpp files.

• Now there is a problem: there are two main() functions in your project: one in main.cpp that was automatically inserted by Xcode when you created a new project and another one written by the staff in start.cpp that you’ve just imported. Recall that a C++ program must have one and only one main() function, so your code will not compile. But not to worry! Just delete main.cpp that was automatically created by Xcode by right-clicking (or Control-clicking) on main.cpp in the Navigator area on the left side of the Xcode window and choose Delete.

Visual Studio

• To add a new file to your Visual Studio project, right-click on Source Files in the Solution Explorer and choose Add > Existing Item…​ (or press Shift-Alt-A).

Navigate to rps.cpp, select it and click Add.

• You should now see the contents of rps.cpp in the Code pane (editing area).

IMPORTANT: Repeat the process to add test.cpp and start.cpp to your project.

NOTE: Be sure to add your name, your uniqname and a small description of the program to the header comments at the top of rps.cpp and test.cpp.

## Running the Program

Once you have created a project, you should be able to compile and run the distribution code. We have included a main() function in start.cpp which will allow you to select exectuing your test cases or executing the game Rock Paper Scissors. When executing your project, you should see the following message:

• Enter 1 to select exectuing your test cases starting with the startTests() function in test.cpp, enter 2 to select executing your Rock Paper Scissors game starting with the rps() function in rps.cpp (red text represents your input)

Select 1 for test cases

    -------------------------------
EECS 183 Project 2 Menu Options
-------------------------------
1) Execute testing functions in test.cpp
2) Execute rps() function to play game
Choice --> 1

Now testing function isMoveGood()
'r': Expected: 1, Actual: 1
'q': Expected: 0, Actual: 1


# Testing

• As part of this project, you will also submit a test suite for testing some of the functions you implement in rps.cpp. It is important to note that you will only be testing your program for invalid input rather than bad input. For the purposes of this document, “bad input” will refer to input whose type (char, int, double, etc.) is different than what is expected by your program. So if your program is expecting that the user will input an integer — you are guaranteed to always receive input of type int and will not receive something like char, which would be considered bad input. On the other hand, you will be testing for “invalid input,” which has the correct type but is considered invalid given the program specification. The RMEs will be clear about what is considered to be invalid input for a specific function.

• To help you with writing your tests, you can take advantage of test.cpp and the autograder. You will write your test functions in test.cpp and submit it to the autograder. (See How to Submit section.) The autograder will run your test suite against buggy programs in order to see if your tests can expose enough bugs. The nature of the bugs will be hidden from you so you will have to think about how invalid input may affect your program and cause it to produce incorrect behavior given specifications.

• When thinking about writing tests, it is helpful to examine the RME for the functions and figure out what the function is actually supposed to do. Then, write tests that target each step in that process for potential bugs. One question you might have is: how do I know that I have enough tests? In practice, this question is usually not helpful and isn’t the correct way to think about writing tests. ?This is because a common pitfall for students is to write a lot of tests that all fundamentally test the same functionality of a function. This isn’t useful when trying to expose bugs in other parts of a function’s implementation, and so in this case more tests are not necessarily better.

• For example, if you are trying to test a function that divides two integers and returns the result, you could write an infinite number of test cases that divide positive integers by positive integers and never expose a bug with negative integers or dividing by zero.
• In Lab 4, you will be writing test cases for certain functions in this project. The test cases you come up with for lab are meant to help you with this project and you are meant to submit them along with your test cases for the remaining functions to the autograder. It is not an Honor Code violation to submit tests that you may have come up with in your group for the lab (but still is for functions not covered in lab).

NOTE: Remember, you only have to think about exposing bugs related to invalid input and not bad input.

## Testing Overview

• It is considered good practice to write the test suite BEFORE you implement a function. The idea is to know if you are correct or not without using a submit to the autograder. This is also a very good way to cut coding time by a significant amount.

NOTE: The basic idea of testing is you start small and build. Start with the obvious inputs needed then expand to the boundary conditions, and then expand further into the what else category.

• Remember, a computer does not interpret. If you misspell a word, you will fail all autograder test cases. If you omit punctuation, you will fail all autograder test cases. We strongly suggest you test your code. Use diff tools to compare the Sample Output against the output generated by your code using the same input. Some easy-to-use diff websites that we recommend are:

• To test getName() and getMenuChoice(), you do NOT need any of the other functions implemented. You should test these functions thoroughly now, so if something goes wrong with your code in the future you will know it is NOT these functions. This method of testing will save you mega-time.

• To test getName() and getMenuChoice(), you need to check them against good input and invalid input. Therefore, to test these functions, call them within startTests() and make sure you get the output and action you expect.

void test_getName();

void startTests() {
cout << "\nExecuting your test cases\n";

test_isMoveGood();
// TODO: call more test functions here
test_getName();

return;
}

void test_getName() {
cout << "Now testing function getName()\n";
cout << "testing good input" << endl;

// a valid input would be Rana
cout << getName(1) << endl;
cout << getName(2) << endl;

cout << "testing invalid input" << endl;

// an invalid input would be just pressing enter
cout << getName(1) << endl;
// more test cases...
}

cout << "Now testing function getMenuChoice()\n";
cout << "testing good input" << endl;

// good inputs would be 1, 2, or 3

cout << "testing invalid input" << endl;

// invalid input would be other numbers, like 5 or -1
// more test cases...
}

• For “good input” in getName(), you want to check valid player names. For “good input” in getMenuChoice(), you should try the valid menu choices 1, 2, and 3. Run your code. Make absolutely sure that the functions output the values you expect for the different inputs you provide.

• Now that we have laid out the testing approach for getName() and getMenuChoice(), take the concepts and apply them to the other functions. You can do this. Just follow the same line of thinking.

### Implementing Test Functions for Submission

• The file test.cpp includes function stubs for test_isMoveGood() and test_isRoundWinner(). Your task is to implement these functions, which should call isMoveGood() and isRoundWinner(), respectively, to test their behavior.

• The test functions you write should reveal incorrect implementations of isMoveGood() and isRoundWinner(). Your job is to create a thorough test suite, calling the RPS functions with a variety of valid and invalid inputs (not bad inputs, as noted above).

• Keep in mind that you should only test values that adhere to the Requires clauses of functions. For example, when testing isRoundWinner(), note that bool isRoundWinner(char move, char opponent_move) “Requires” that “both move and opponent_move are valid moves”.

What this means is you can — and should — test:

// because 'r' and 's' are valid moves
cout << "'r' and 's' Expected: 1, Actual: " << isRoundWinner('r', 's') << endl;


However, a move like ‘x’ is invalid. Therefore, even though it is “legal” within C++ to write

// INVALID test case - this would violate the RME of isRoundWinner()
cout << "'r' and 'x' Expected: 1, Actual: " << isRoundWinner('r', 'x') << endl;


It violates the Requires clause and the programmer should not do this. It is the responsibility of the coder to not violate the Requires clauses of the functions they call.

• Note that the functions stubbed in test.cpp are the only test functions you will need to submit to the autograder.

• However, you should still write tests for getName(), getMenuChoice(), and the functions involved in game play to ensure that your individual functions behave as expected before writing the main() function for your program. You can call these test functions in main() and remove them before submission. Do not include these functions when you submit to the autograder.

• When you submit test.cpp, we will compile and run it with our correct implementation of rps.cpp and with our buggy implementation of rps.cpp, so as to generate two different outputs. We’ll then compare two outputs. If there is any difference, you’ve successfully exposed a bug! The autograder does not go into the details of what the difference is, it only sees if there exists a difference.

• Remember that some functions don’t print anything on their own; we have to print their return value, as with the function isMoveGood():

    cout << "'r': Expected: 1, Actual: " << isMoveGood('r') << endl;
cout << "'q': Expected: 0, Actual: " << isMoveGood('q') << endl;


(Keep in mind that bool values are printed as 0 or 1.)

• After you submit your test suite, you might see output that looks like this:

That means that your test suite exposed 1 out of 8 bugs in the staff’s “buggy” implementations of rps.cpp and your score for the test suite is 1.5 out of 10 points.

### Bugs To Expose

There are a total of 8 unique bugs to find in our implementations. Your tests do not need to expose all of the bugs to receive full points for this part of the project. The autograder will tell you the names of the bugs that you have exposed, from the following set:

• CHECK_ISMOVEGOOD_1

• CHECK_ISMOVEGOOD_2

• CHECK_ANNOUNCEROUNDWINNER_1

• CHECK_ANNOUNCEROUNDWINNER_2

• CHECK_ANNOUNCEWINNER_1

• CHECK_ANNOUNCEWINNER_2

• CHECK_ISROUNDWINNER_1

• CHECK_ISROUNDWINNER_2

### Preparing your test.cpp for Submission

• You will write all your tests and execute them from startTests() in your test.cpp file. This will include:

• The function bodies the test functions (e.g., test_isMoveGood() and test_isRoundWinner()).

• The code you wrote in startTests() to call the test functions.

• At any time you can submit your test.cpp to the autograder (How to Submit) to see how many bugs your tests exposed. However, remember you only have four submissions each day with feedback.

# How to Submit

• Write your program using Visual Studio or Xcode as described in lecture and discussion section. Your program must be written and documented to comply with the Style Guidelines provided for EECS 183.

• You must submit both rps.cpp and test.cpp for grading.

If you’re using Xcode and don’t know where exactly rps.cpp is located on your computer, right-click (or click while holding down the Command key) on the file in the Navigator area on the left side of the Xcode window and choose Show in Finder.

If you’re using Visual Studio and would like to know where rps.cpp is on your computer, right-click on rps.cpp in the tab above the Code pane and choose Open Containing Folder.

• On the new page, click Choose file and navigate to your file. The files you submit to the autograder MUST be called rps.cpp and test.cpp.

• If confident that you’ve selected the correct file, click Submit to submit your code to the Autograder.

• For this project:

• You have 4 submissions with feedback per day.

• You also have one additional “wildcard” submission with feedback. This can be used once for an additional submit with feedback.

• We provide some information regarding the tests that you do not pass. However, it is our intent that you learn to develop code independently. It’s important to have tests to tell you whether or not your code works, but real life does not have an autograder. Providing complete feedback from our own tests will hurt your ability to learn to test.

• You technically have an infinite number of submits per day, but only the first four submits per day return autograder feedback and a score. Any additional submits are “blind submits,” which do not return autograder feedback — not even a score. Be very cautious with these or you may be surprised by your grade.

• Remember: your best submit is the one we grade. We do not accept submissions via email.

• You will soon develop a “love/hate” relationship with the autograder. You will “love” that you can check your code to see your score. You will “love” that it gives you feedback. You will “hate” that it tells you that you are not totally correct on the first submit.

## Where to Begin

• The best approach is always to start small and build your solution up one piece at a time. Never try and do the entire thing at once.

• First, start with writing out some logic on a piece of paper. What needs to happen first?

• Implement one function at a time, thinking about what this function needs as input, what it should return, and how it should be used.

• We suggest starting with pseudocode, remember Lecture 01. Pseudocode is a way to explain what needs to happen in English before having to figure out how to do it in code. It is a way to lay out what is needed logically without the overhead of C++ code.

• Only after writing out the pseudocode of what is described above is it time to then translate it to C++. This will save you hours when you start coding, trust us!

• If your code is not working as intended checkout the troubleshooting checklist

## Style Checklist

To maximize your style points, be sure to follow this non-exhaustive checklist:

• ❏ Review the EECS 183 Style Guide. Pay particular attention to Comments, Whitespace and Indentation and Variables and Constants.

• ❏ Be sure to use descriptive variable names. The more descriptive the variable names, the less you need to comment.

• ❏ Be sure to use consistent variable naming style. Use either camelCase or snake_case, but do not alternate between them. Do not change the case of the variable and function names provided.

• ❏ Be sure that your code is well-commented. It might at first seem that the algorithm is straight-forward and self-explanatory, but would you remember all the details a month from now? Pro Tip: It’s much easier for the staff to help you with your code if you have comments!

• ❏ Remember to avoid magic numbers.

• ❏ Don’t use global variables. However, global constants are OK and should be used.

• ❏ Remember that all lines must be 80 characters or less.

• ❏ Check out the Style Rubric to avoid any deductions. This is the rubric that will be used for style grading.

## Sample Output

Here are a few examples of the way your program output should look, wherein text in red represents some user’s input.

NOTE: The following sample runs do not include the menu selection detailed in Running the Program.

Sample Run 1


----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

Player 1, enter your name: Rana Makki

Player 2, enter your name: David Cao

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 1

Rana Makki, enter your move: r

David Cao, enter your move: p

David Cao wins the round!

Rana Makki, enter your move: r

David Cao, enter your move: r

This round is a draw!

Rana Makki, enter your move: p

David Cao, enter your move: s

David Cao wins the round!

Congratulations David Cao!
You won EECS 183 Rock-Paper-Scissors!

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 3

----------------------------------------
Thanks for playing
Rock-Paper-Scissors!
----------------------------------------


Sample Run 2


----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

Player 1, enter your name: Rana Makki

Player 2, enter your name: David Cao

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 4

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 2

Under Construction
No winner!

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 3

----------------------------------------
Thanks for playing
Rock-Paper-Scissors!
----------------------------------------



Sample Run 3


----------------------------------------
EECS 183
Rock-Paper-Scissors
----------------------------------------

ERROR: Illegal name given, using default

ERROR: Illegal name given, using default

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 1

Creed wins the round!

This round is a draw!

Rocky wins the round!

No winner!

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 1

Rocky wins the round!

ERROR: Illegal move given, using default
This round is a draw!

Rocky wins the round!

Congratulations Rocky!
You won EECS 183 Rock-Paper-Scissors!

------------
1) Play rock, paper, scissors
2) Play rock, paper, scissors, lizard, spock
3) Quit

Choice --> 3

----------------------------------------
Thanks for playing
Rock-Paper-Scissors!
----------------------------------------


# S’More Functionality

OPTIONAL: For more practice and fun, check out the S’More for Project 2. With this optional challenge you can update your project to play rock, paper, scissors, lizard, spock.

# Style

## Style Rubric

### Top Comment

Must have name, uniqname, program name, and project description at the top of the file.

If all or part of the top comment is missing, take 1 point off.

-1 for each of the following:

#### Indentations

• Not using a consistent number of spaces for each level of code indentation

• This includes using tabs on some lines and spaces on others
• Not indenting lines at all

• Failing to indent the blocks of code inside curly braces

#### Spacing

• Not putting a space around operators (e.g., 5*7 instead of 5 * 7 or count=0; instead of count = 0;)

• Includes stream insertion (<<) and extraction (>>) operators
• Not putting a space between if, while, or for and the condition to be evaluated

• Putting a space between a function name and the opening parenthesis

#### Bracing

• Using a mix of Egyptian-style and hanging braces

• Egyptian-style: ‘{‘ at the end of a statement

• Hanging: ‘{‘ on its own line

• Braces should always be used for conditionals, loops, and functions

• Examples:
 // good
if (x == 1) {
return false;
}
if (x == 2)
{
return true;
}

if (x == 1) return false;
if (x == 2)
return true;


#### Variables

• Variable names not meaningful

• Inconsistent variable naming style (camelCase vs. snake_case)

• Excluding const variables, which are always SNAKE_CASE
• Not declaring const variables as const

• Not using all uppercase SNAKE_CASE for const variable names

• Using variable types that do not make sense in context

• e.g. using double instead of int for number of people

#### Line limit

• Going over 80 characters on a line

• Includes lines of comments and lines of code

#### Statements

• More than one statement on a single line

• A statement ends in a semicolon

• Do not count off for multiple statements as part of a for loop declaration

• Commenting on the end of a line of code

 // A comment should be placed before a line of code
int count = 0; // not on the same line as the code


• Code should be thoroughly commented such that lines’ functionality is apparent from comments alone or from quickly glancing at code

• Example of appropriate comment:

 // convert cups of flour to bags of flour
int bagFlour = ceil((CUPS_FLOUR * numBatches) / CUPS_IN_LB_FLOUR);


 // declare variable
int bagFlour;

• Unneeded comments left in the code:

 // your code goes here
// TODO: implement
// this function doesn't work
// FIXED

• Commented out code:

 // int numBatches = people / 12;
int numBatches = ceil(people / NUM_IN_BATCH);


#### RMEs

• Missing RMEs for any of the defined functions, except for main. This includes functions from the distribution code and any functions created by the student

• Not having RMEs for tester functions is okay.
• Repeating RMEs for the same function.

## Coding quality

-2 for each of the following:

#### Global variables

• Global variables not declared as const

#### Magic numbers

• Integer and/or double literals used such that it is unclear to a reasonable reader what the literals represent

• If there is a comment explaining the number/calculation, then it is okay

• 0, 1, and 2 never count as magic numbers

#### Egregious code

• Logic that is clearly too involved or incorrect

• e.g. instead of basing numbers on conversions, writing:

 if (year >= 1700 && year < 1800) {
century = 17;
} else if (year >= 1800 && year < 1900) {
century = 18;
}


and so on

#### Function misuse

• Not calling helper functions where appropriate

• Not calling printMenu() inside getMenuChoice()

• Not calling isMoveGood() inside getMove()

• Having tester functions

#### bools

• Only deduct 1 point for this category

• Returning 0 and 1 instead of true and false for a bool functions