I have written a header file, candyCrush.hpp and a program candyCrushTest.cpp that uses the class/methods defined in that header file. Your job is to create the file candyCrush.cpp, which implements the methods defined in candyCrush.hpp.
You are allowed to add additional protected methods to candyCrush.hpp but you may not change the function prototypes of the existing methods nor may you delete any of them. You are not allowed to modify candyCrushTest.cpp. You will turn in candyCrush.hpp and candyCrush.cpp, and the TA's will compile and test them with the candyCrushTest.cpp that is in the lab directory.
One of the possible matches would be the two yellow-colored toffee candies at the beginning of the first row of the diagram and another would be the two purple-colored candies at the end of the first row of the diagram. There are other matches you could make in the columns, but for this lab we are going to focus on row matches. Specifically you are going to use an STL list to implement a single row of a simplified Candy Crush like game.
It would be too complicated to create fancy graphics for this lab assignment, so instead you will be using a list of strings to represent flavors of candy. In Part A you will write code to randomly generate the first candy sequence, put it in the list, and print out the portion of the list that you filled. In Part B you will generate enough candy sequences to completely fill a 12 item row of candies. In Part B you will also write code to allow the user to select a sequence of candies and assign points based on the length of the sequence. Finally in Part C you will remove the candy sequence selected by the user from the row, slide the remaining candies to the left, and fill the right side of the row with new candies.
Your program will read from stdin. Here is some sample input and how to interpret it:
256 10 // Seed for the random number generator and length of a candy crush row grape cherry orange lemon toffee // The candy flavors 20 10 // The probability for each possible candy sequence length 10 20 25 30 20 50 15 70 15 120 0 150 0 180 0 210 0 300You will be using a random number generator for this lab so the first input is the seed you will use to the random number generator. It must be an integer.
The second input on the first line is the length of the candy crush row and must be a non-negative integer between 1 and 100.
The second line of the input will be a list of the candy flavors that will be used in the game.
The remaining lines of the input will be the probabilities of generating a flavor sequence of a particular length and the points they are worth. The sequence lengths are not explicitly given. Your program should assume they begin with 1. Hence in the above input there is a 20% chance of generating a sequence of length 1 and it is worth 10 points if a player selects a sequence of length 1. Similarly there is a 25% chance of generating a sequence of length 3 and it is worth 30 points when a player selects it. You must provide a probability and point value for every sequence length up to the row length, since it is possible to have a row that consists only of one flavor. Note that there is no chance of generating a sequence of length 7-10. However, suppose you generate a "toffee" sequence of length 4 and then generate a "toffee" sequence of length 5. You will end up with a contiguous "toffee" sequence of length 9.
The probabilities must add up to 100 and must be non-negative integers.
Take a look at the header file candyCrush.hpp:
class candyCrush { public: candyCrush(const string &inputFile); int getRowLength() const; int getScore() const; void printCandy() const; int play(int choice); protected: list<string> candy; vector<string> flavors; vector<int> points; vector<int> probabilities; int score; int rowLength; }; |
You must minimally implement this public API. You are free to add additional protected methods and instance variables to help with your implementation. The method descriptions are as follows:
candyCrush(const string &inputFile): This constructor function sets up your initial game state. In this constructor you will generate a random sequence of candies and assign them to your candy list. You will do this as follows:
0: grape 1: cherry 2: orange 3: lemon 4: toffee
0: 20 1: 30 2: 55 3: 75 4: 90 5: 100and your random number is 90. Then the index you will choose is 5, not 4, and your sequence length will be 6. If you want to make life easier on yourself, you can start storing your probabilities at index location 1 rather than 0, so that you don't have to remember to add 1 to the index to get your sequence length.
int getRowLength() const: Returns the length of the candy crush row.
void printCandy() const: Prints the candy crush row as 8 flavors per row, left justified, in fields 10 characters wide.
int play(int choice): choice is an integer from 0 to rowLength-1 indicating which candy flavor the player selected. The test program error checks rowLength so you do not have to do so yourself. The return value is the number of points scored by the player on this turn. This method must:
play() does not print anything. There are commands you can use in the test program to print the candy crush row or the player's current score.
int getScore(): Returns the players current score.
I've written a main() procedure in candyCrushTest.cpp. It needs to be compiled with your implementation of candyCrush.cpp. You run it as follows:
./candyCrushTest inputFile |
Then it accepts commands on standard input:
The gradescript is in an incremental format. The test cases are laid out as follows:
The grading programs are in /home/ssmit285/public/gradescripts/cs140_bvz/lab6 as gradeall and gradescript, like usual. Your executable must be named candyCrushTest for you to run it, and it will flag you wrong if it doesn't find that file.
Don't go assuming that the test cases are error-free either. I've purposefully hidden a few faulty/bad examples (14 in total) in the gradescripts from 31 to 100. Just like the previous lab assignments, you can use the gradescripts and solution example to debug until you match outputs. If you run into an infinite loop, the gradescript will auto-fail that particular test case after 2 seconds of run time.
The following example interaction with the test program uses this input file:
157 10 grape cherry orange lemon toffee 20 10 10 20 25 30 20 50 15 70 10 120 0 150 0 180 0 210 0 300Here is a series of sample interactions with the test program and the output the test program will produce. In each case I have highlighted the flavor that the user has chosen:
UNIX> ./candyCrushTest input.txt PRINT lemon grape grape grape grape grape grape orange orange cherry CHOOSE 0 you scored 10 pointsThe player chose index location 0, which corresponds to "lemon". There is a sequence of 1 lemon flavors here so the player receives 10 points (note that in the input file, a sequence of length 1 is worth 10 points).
PRINT grape grape grape grape grape grape orange orange cherry grape CHOOSE 3 you scored 120 pointsNotice that after the user chooses the lemon sequence in the above example, that the lemon has been deleted and the remaining entries have been "moved over" one element. Finally a new flavor, cherry, has been added at the end of the row.
The user now chooses a grape candy. This grape candy is in the middle of a sequence of 6 grape candies so the user scores 120 points. The program then deletes this 6 candy sequence, moves the remaining 4 candies to the left, and adds 4 candies at the end of the row to get the following sequence:
PRINT orange orange cherry grape lemon lemon lemon lemon orange orange CHOOSE 9 you scored 20 pointsThe user now chooses the last candy in the sequence, which is an orange candy. This candy belongs to a sequence of two orange candies and hence the user scores 20 points. The program deletes this sequence of two candies and adds two new candies to the end of the row to get the following sequence:
PRINT orange orange cherry grape lemon lemon lemon lemon lemon lemon SCORE current score = 150 QUITNote that two lemon candies were added at the end of the sequence, so the lemon sequence that was previously 4 candies long is now 6 candies long. Hence it is possible for candy sequences to increase in length, either because additional candies of the same flavor are added at the end of a row, or because candies with the same flavor are both before and after a chosen candy sequence. For example, suppose that you had the following row (I have arbitrarily chosen this row as an example--it was not generated by my candyCrush executable):
PRINT toffee toffee toffee grape grape toffee toffee toffee toffee toffee CHOOSE 4 you scored 20 pointsThe player chose index location 4, which corresponds to "grape". When the grape sequence is deleted, the two toffee sequences on either side of the grape sequence are concatenated, resulting in a toffee sequence that is 8 candies long:
PRINT toffee toffee toffee toffee toffee toffee toffee toffee lemon orange
In order to generate to same output as my sample executable, you will need to do two things:
As always you should strive to break the program into parts and code up and test each part before moving to the next part. I coded the constructor, printCandy, and rowLength functions first, then the play and getScore functions, and finally I inserted error checking code. There are a fair number of error checks you need to perform. In order to use the test editor to test your constructor and printCandy functions (use the PRINT command), you will need to provide empty stubs for the remaining methods in the public API.
In lab you will be asked to try to enumerate these error checks. You can run my test executable to see the exact error message that your program should generate.