fp-elevators
Game.cpp
#include <random> #include <sstream> bool Game::saveGame(ofstream& saveFile) const { return true; } bool Game::isValidPickupList(const string& pickupList, const int pickupFloorNum) const { return true; } void Game::playGame(bool isAIModeIn, ifstream &gameFile) { std::mt19937 gen(1); std::uniform_int_distribution<> floorDist(0, 9); std::uniform_int_distribution<> angerDist(0, 3); printGameStartPrompt(); initGame(gameFile); while (true) { int src = floorDist(gen); int dst = floorDist(gen); if (src != dst) { std::stringstream ss; ss << "0f" << src << "t" << dst << "a" << angerDist(gen); Person p(ss.str()); building.spawnPerson(p); } building.prettyPrintBuilding(cout); satisfactionIndex.printSatisfaction(cout, false); checkForGameEnd(); Move m = getMove(); update(m); } }
Overview
Game
is a class declared in the Game.h
. The Game
class is the engine behind the elevators project, and will be the main object used for how users interact with the program.
Member data
building
stores the internal building statesatisfactionIndex
stores the cumulative benchmark scoring data
Member Functions
Many member functions have been written for you. Please refer to their RME’s for use reference.
You will be writing the implementations for the following functions:
playGame
(Difficulty: ★★★★☆)isValidPickupList
(Difficulty: ★★★☆☆)saveGame
(Difficulty: ★★★★★)
playGame
/**
* Requires: nothing
* Modifies: cout, isAIMode, building, satisfactionIndex
* Effects: prints game start prompt
* if game input file is not open, exits with status 1
* else reads events from game input file
* if event is happening on current turn, updates building
* with event else prints building and checks if game has
* ended, if it hasn't yet, gets user (player or AI) move,
* and updates building with move.
*/
void playGame(bool isAIModeIn, ifstream &gameFile);
This function should set isAIMode based on the argument, then call 2 member functions (in the order below) of Game in order to set up the main game loop:
Game::printGameStartPrompt()
: This will alert the user that the game will begin, and will display the menu options available during theGame
.Game::initGame()
: This will initialize theGame
by loading in the initial data fromgameFile
.
The input file will have lines describing when people will be spawned. The user will play the game as these files are read and the people are spawned. After all the people have spawned, the user can continue playing the game. To do this:
- While there is another line in gameFile:
- Create a Person using that line
- Determine which tick the Person will be spawned
- Have the user play the game until that tick has finished
- Spawn the person
- Until the game is over:
- Have the user play the game
Here are the steps to have the user play the game:
- Make a call to
prettyPrintBuilding
on thebuilding
member variable withcout
as the parameter argument - Make a call to
printSatisfaction
on thesatisfactionIndex
member variable withcout
andfalse
as the parameter arguments - Check to see if the game has ended (we’ve given you the
checkForGameEnd()
function for this) - Ask the user for a
Move
(we’ve provided a member function for this) - Apply the inputted
Move
(we’ve provided a member function for this)
isValidPickupList
/**
* Requires: pickupFloorNum is the floor the pickup move was called on
* Modifies: nothing
* Effects: determines if pickupList is a valid
* list of people to pick up
*/
bool isValidPickupList(const string& pickupList, const int pickupFloorNum) const;
This function is called when the user decides to pick up people on a floor. The game gives the user an opportunity to select which people currently on that floor they would like to pick up, then calls this function to verify that the user’s selection is valid.
pickupList
is a string representing the user inputted list of indices. Because there are a maximum of 10 people per floor, every index will be a single digit.pickupFloorNum
is an int represented the floor the pickup action occurred on
An example pickupList
: "0135"
“I choose the people at indices 0, 1, 3, and 5 to pickup”
A pickupList
is valid if it meets the following conditions:
- There are no duplicate indices present in
pickupList
- Each element of
pickupList
is a non-negative digit - The length of the
pickupList
is less than or equal to the capacity of an elevator - The maximum value pointed to by an index of
pickupList
must be strictly less than the number of people on the floor pointed to bypickupFloorNum
- Each person represented by an index in
pickupList
must be going in the same direction relative topickupFloorNum
saveGame
/**
* Requires: saveFile is in good state
* Modifies: cout, saveFile
* Effects: prints "Saving game..."
* adds current state of game to saveFile
* reads remaining moves from game input file
* if game input file cannot be opened
* prints "Game input file could not be opened!"
* and returns false
* else
* adds remaining move to saveFile
* flushes saveFile buffer
* prints "Saved!" when finished and returns true
*
* Prompts: "Saving game..."
* "Saved!"
* "Game input file could not be opened!"
*/
bool saveGame(ofstream& saveFile) const;
This function saves the current state of the game to the stream saveFile
.
When the player started a new game, the times that people would spawn was loaded from the file game.in
. As the player plays, those people are spawned at the tick listed for them. When the game is saved, there may still be people in the input file that have not yet been spawned – for instance, it may currently be tick 10 in the game, but there are people left in the file that will spawn on tick 11 and 12. These future people need to be written into the saved game file so that when the user resumes the game, they will be spawned at the right time.
Here is a picture of this process. Make sure to review Reading and Writing for an explanation of the file format.
Here are the steps you will implement in your algorithm:
- Print the prompt
Saving Game...
- Write the current SatisfactionIndex, tick, and elevator states to
saveFile
. The elevators must be written in the order they are inBuilding::elevators
. - Write currently waiting people to
saveFile
. They must have spawn time0
. They must be written starting at the bottom floor (0), and in the same order they appear inFloor::people
. - Open the game input file (
GAME_INPUT_FILENAME
inUtility.h
). If it cannot be opened, printGame input file could not be opened!
and a newline, and returnfalse
- Transfer person spawns that occur after the current tick from the input file to
saveFile
- Print
Saved!
and a newline, and returntrue