Project Three: Simple World
Due: Nov. 17, 2024
- Motivation
- To give you experience in using arrays, pointers, structs, enums, and different I/O streams anwriting program that takes arguments.
- To let you have fun with an application that is extremely captivating.
- IntroductionThe simple world program we will write for this project simulates a number of creatures runningaround in a simple square world. The world is an m-by-n two-dimensional grid of squares (Thenumber m represents the height of the grid and the number n represents the width of the grid.).
Each creature lives in one of the squares, faces in one of the major compass directions (north,east, south, or west) and belongs to a particular species, whichdetermineshow that creatureigure 1. A 4-by-4 grid, which contains five creatures. Two creatures belong to the species
flytrap (whose short name is “fl”), two belong to the species hop (whose short name is “ho”), andone belongs to the species landmine (whose short name is “la”). The direction of each creaturerepresented by the direction of the arrow.Figure 1 shows a 4-by-4 grid populated by five creatures. Two of them belong to the species
flytrap (whose short name is “fl”), two belong to the species hop (whose short name is “ho”), andone belongs to the species landmine (whose short name is “la”). The direction of each creature is represented by the direction of the arrow. For example, the flytrap at the top row is facing eastand the flytrap at the bottom row is facingwest.Table 1. The list of instructions and their explanations.hop The creature moves forward as long as the square it is facing is empty. Ifmoving forward would put the creature outside the boundaries of the grid orwould cause it to land on top of another creature, the hop instruction does
nothing.left The creature turns left 90 degrees to face in a new direction.right The creature turns right 90 degrees to face in a new direction.infect If the square immediately in front of this creature is occupied by a creature ofa different species (an “enemy”), that enemy creature is infected to becomethe same as the infecting pecies. When a creature is infected, it keeps itsposition and orientation, but changes its internal species indicator and beginsexecuting the same program as the infecting creature, starting at step 1. If thesquare immediately in front of this creature is empty, outside the grid, oroccupied by a creature of the same species, the infect instruction doesnothing.ifempty n f the square in front of the creature is inside the grid boundary and
unoccupied, jump to step n of the program; otherwise, go on with the nextinstruction in sequence.ifwall n If the creature is facing the border of the grid (which we imagine asconsisting of a huge wall) jump to step n of the program; otherwise, go onwith the next instruction in sequence. n If the square the creature is facing is occupied by a creature of the same species, jump to step n; otherwise, go on with the next instruction. n species, jump to step n; otherwise, go on with the next instruction.
go n
This instruction always jumps to step n, independent of any condition.Each species has an associated program which controls how each creature of that speciesbehaves.Programs are composed of a sequence of instructions. The instructionsthat can bepart of a program are listed in Table 1. There are nine legal instructions in total. The last five
instructions have an additional integer argument.Program is an attribute associated with species. Creatures of the same species have the sameprogram. However, differentspecies have different programs.For example, the program of the species flytrap is composed of the following five instructions:ifenemy 4leftchange.Each creature also maintains a variable called program counter which stores the index of theinstruction it is going to execute. On each turn of a creature, it executes of instructionsof its program, starting from the step indicated by the program counter. A program ordinarilycontinues with each new instruction in sequence, although this order can be changed by certaininstructions in the program such as the if*** instructions. In each turn, a creature can execute number of if*** or go instructions without relinquishing this turn. Its turn ends only whenthe creature executes one of the instructions: hop, left, right, or infect. After its turn ends, thecreature updates the programcounter to point to the next instruction, which will be executed atthe beginning of its next turn.Note that each creature maintains its own program counter, so that two different creaturesbelonging to the same species can have different program counters. The indices of the instructions start from one, i.e., the first instruction of each program is “step 1”. At the very of the simulation process, the program counters of all the creatures are set to their firststructions.III. Available Types
completing this project, you will have the following types available to you. They are defined
n the file world_type.h.
const unsigned int MAXSPECIES = 10; // Max number of species in the
All the species, the programs for all the species, and the initial layout of the creature world are
tored in files and these files will be read by your program to set up the simulation environment.
Note: when you read files, you must use input file stream ifstream. Otherwise, since the
files are read-only on our online judge, you may fail to read the files.As we described before, each species has an associated program. The program for each species isstored in a separate file whose name is just the name of that species. For example, the programfor the species flytrap is stored in a file called flytrap.A file describing a ogram contains all the instructions of that program in order. Each line listsjust one instruction. The first line lists the first instruction; the second line lists the second
nstruction; so on and so forth. Each instruction is one of the nine legal instructions described inTable 1. The program ends with the end of file or a blank line. Commentsmay appear after thelank line or at the end of each instruction line. For example, the program file for the flytrapspecies looks like: 4 If there is an enemy, go to step 4.left If no enemy, turn left.go 1infect
go 1The flytrap sits in one place and spins.It infects anything which comes in front.Flytraps do well when they clump.Note that in writing functions for reading these program files, you should handle the commentscorrectly, which means that you should ignore these comments when etting up the program for apecies.Sice there are many species, we stored all of their program files in a directory.
To help you get all the species and their program files, we also have a file telling the directorywhere the program files are stored and listing all the species. We call this file a species summary.e first line of this file shows the directory where all of the program files are stored. The next lines list all the species, with one species per line. For example, the following s speciessummary file:creaturesflytraphoplandmine
From this file, we can learn that the program files are stored in the directory called creatureslocated relative to the current working directory (i.e., where the program cates). We have threpecies to simulate, which are flytrap, hop, and landmine. By first reading the species summaryfile, you will know where to find the program file for ech species.nally, there is a file describing the initial state of the creature world. We call it a world file. Theirst line of this file gives the height of the two-dimensional grid (i.e., the number of rows) andhe second line gives the width of the grid (i.e., the number of columns). The remaining lines ofhis file describe all the creatures to simulate and their initial directions and locations, with onecreature per line. Each of these lines has the following format:<species><initial-direction> <initial-row> <initial-columnwher<species> is one of the species from the species summary file,<initial-direction> describes the initial direction and is one of the strings “east”,
“south”, “west”, and “north”. <initial-row> describes the initial row location of the
creature. We use the convention that the top-most row of the grid is row 0 and the row
number increases from top to bottom. <initial-column> describes the initial column
location of the creature. We use the convention that the left-most column of the grid is column
0 and the column number increases from left to right. An example of a world file looks like:4
4hop east 2 0flytrap east 2 2It says that the size of the grid is 4-by-4 and there are two creatures in the world. The firstcreature belongs to the species hop. It faces east andlives at point (2, 0) initially.The secondcreature belongs to the species flytrap. It faces east and lives at point (2, 2) initially.In the simulation, the order on the creatures to simulate is important. This order is determined by the order that these creatures appear in the world file.V. Program Arguments program will obtain the names of the species summary file and the world file via programarguments. Additionally, your program will be toldthenumber of rounds to simulate andwhether it should print the simulation result verbosely or not.The expected order of arguments is:<species-summary> <world-file> <rounds> [v|verbose]The first three arguments are mandatory. They give the name of the species summary file, thename of the world ile, and the number of simulation rounds, respectively. Tfourth argumentis optional. If the fourth argument is the string “v” or the string “verbose”, your program shouldprint the simulation result verbosely, which will be explained later. Otherwise, if it is omitted ors any other string, your program should print the result concisely, which will also be explainedter. If there are more than four arguments, your program should just read the first four andignore the remainingSuppose that you program is called p3. It may be invoked by typing in a terminal:./p3 species world 10 vThen your program should read the species summary from the filecalled “代寫Project Three: Simple World species” and the worldfile from the file called “world”. The number of simulation rounds is 10. Your program shouldprint the simulation information verbosely.VI. Error Checking and Error Message Your program should check for errors before it starts to simulate the moves ofthecreatures. Ifany error happens, your program should issue an error message and then exit. If there are noerrors happening, then the initial state of the creature world is legal and yourprogram can startsimulating the creature world.We require you to do the following error checking and print the error message in exactly thesame way as described below. Note that some of the output error message has two lines and eacherror message should be ended with a newline character. All error messages should be sent to the standard output stream cout; none to the standard error stream cerr.
- Check whether the number of arguments is less than three. If it is less than three, then one othe mandatory arguments is missing. You should print the following error messageror: Missing argumentsUsage: ./p3 <species-summary> <world-file> <rounds> [v|verboseCheck whether the value <rounds> supplied by the user is negative. If it is negative, youshould print the following error message: Number of simulation rounds is negative!
- Check whether file open is successful. If opening species summary file, world file, or anyspecies program file fails (for example, the file to be opened does not exist), print the followingerror message:: Cannot open file <filename>!where <filename> should be replaced with the name of the file that fails to be opened. If thatfile is not in the same directory as yourprogram, you need to include its path in the<filename>. As you may know, there are multiple ways to specify a path. For us, the path should be specified in the most basic way, i.e., “<dir>/<filename>” (not“./<dir>/<filename>”, “<dir>//filename”, etc.). Once you find a file that cannot beopened, issue the above error message and terminate your program.whether the number of species listed in the species summary file exceeds the maximalnumber of species MAXSPECIES. If so, print the following error message:Error: Toomany species!Maximal number of species is <MAXSPECIES>where <MAXSPECIES> should be replaced with the maximal number of species set by yourprogram.Check whether the number of instructions for a species exceeds the maximal size of a speciesprogram MAXPROGRAM. If so, print the following error message:: Too manyinstructions for species <SPECIES_NAME>!Maximal number of instructions is <MAXPROGRAM>.where <SPECIES_NAME> should be replaced with the name of the species whose program has instructions than the maximal number allowed and <MAXPROGRAM> should be replacewith the maximal size of a species program set by your program.
- Check whether the species program file contains illegal instructions. We only allow nineinstructions as listed in Table 1. Your program needs to check whether the instruction name one of the nine legal instruction names listed in the string array opName (which is defined in
Section III). If an instruction name is not recognized, you should print the following error
message:
Error: Instruction <UNKNOWN_INSTRUCTION> is not recognized!
where <UNKNOWN_INSTRUCTION> should be replaced with the name of the unrecognized
. You can assume that for any recognized instruction, it is given in the correct format.hus, you don’t need to check whether an integer is appended after the instruction name or not.If there are multiple unrecognized instruction names, you only need to print out the first one andhen terminate the program.
- Check whether the number of creatures listed in the world file exceeds the maximal number of
creatures MAXCREATURES. If so, print the following error message:Error: Too many creatures!Maximal number of creatures is <MAXCREATURES>.where <MAXCREATURES> should be replaced with the maximal number of creatures allowedby your program.8. Checkwhether each creature in the world file belongs to one of the species listed in thespecies summary file. If the species for a creature is notrecognized, print the following errormessage:rror: Species <UNKNOWN_SPECIES> not found!where <UNKNOWN_SPECIES> should be replaced with the unrecognized species. If there aremultiple unrecognizedspecies, you only need to print out the first one and then terminate the
- Check whether the direction string for each creature in the world file is one of the strings inhe array directName (which is defined in Section III). If the direction string is not recognized,nt the following error message:Error: Direction <UNKNOWN_DIRECTION> is ot recognized!where <UNKNOWN_DIRECTION> should be replaced with the unrecognized direction name. Ifthere are multiple unrecognized direction names, you only need to print out the first one and thenterminate the program.
- whether the grid height given by the world file is legal. A legal grid height is at leastONE and less than or equal to a maximal value MAXHEIGHT. If the grid height is illegal, printthe following error message:Error: The grid height is illegal!
- Check whether the grid width given by the world file is legal. A legal grid width is at leastONE and less than or equal to a maximal value MAXWIDTH. If the grid width is illegal, print thefollowing error message:Error: The grid width is illegal!Check whether each creature is inside the boundary of the grid. If any creature is outside theboundary, print the following error message:The size is <HEIGHT>-by-<WIDTH>.where <SPECIES> should be replaced with the species the creature belongs to, <DIR> bereplaced with the direction the creature is facing,<R> be replaced with the row location of the, <C> be replaced with the column location of the creature, <HEIGHT> be replaced withthe height of the grid, and<WIDTH> be replaced with the width of the grid. Here, we use thefour-tuple (<SPECIES> <DIR> <R> <C>) to identify the creature. For example, if giventhe followingworld fil32) is outside the boundary. Then, the error message should be:Error: Creature (hop south 3 2) is out of boundThe grid size is 3-by-3.If there are multiple creatures outside the boundary, you only need to print out the first one and
terminate the program.
Check whether each square in the grid is occupied by at most one creature. If any square is
occupied by more than one creature, print the following error message:
rror: Creature (<SP1> <DIR1> <R> <C>) overlaps with creature
<SP2> <DIR2> <R> <C>)!where (<R> <C>) identifies the square which is occupied by more than one creature, the firstfour-tuple (<SP1> <DIR1> <R> <C>) identifies the second creature in order thatoccupies the square, and the second four-tuple (<SP2> <DIR2> <R> <C>) identifies the first creature in order that occupies the square. Once you find two creatures occupying thesame square, you issue the above error message and then terminate the program.Since you may implement the error checking in different order and in the case that there is
more than one error, the first error message printed out may be different. Therefore, we will only test your error checking using test cases containing just one error. You can also assume that except the above errors, there are no other errors. You canassume that the species program file is non-empty and a file without errors 5 and
6 above could be executed for infinite rounds.VII. Simulation Output Once all of the above error checkings on the initial state of the creature world are passed, youcan start simulating the creature world. You should print to the standard output the simulationinformation, either in a verbose mode or in a concise mode, depending on whether an
dditional argument “v” or “verbose” is provided by the user.
In the verbose mode, you first print the initial state of the world. In doing so, you begin withprinting the string “Initial state” followed by a newline. Then you graphically show thlayout of the initial grid using just characters. Each square takes a four-character field in your
There are no blank lines in the output for both the verbose and concise mode.VIII. Source Code Files and Compiling There is a source code file located in the Project3-Related-Files.zip from ourCanvas Resources:world_type.h: The header file that defines a number of types for you to use.You should copy this file into your working directory. DO NOT modify it! You projecttwo. The second file is named as simulation.cpp, which contains all the implementations ofthose functions declared in the in the terminal to compile the program:
g++ -Wall -o p3 p3.cpp simulation.cpp
This will generate a program called p3 in your working directory. In order to ensure that theonline judge compiles your program successfully, you should name you sourcecode files exactlylike how they are specified above.
- Implementation Requirements and Restrictions
- When writing your code, you may use the following standard header files: <iostream>,<fstream>, <sstream>, <iomanip>, <string>, <cstdlib>, and <cassert>. Noother header files can be included.
- You may not define any global variables yourself. You can only use the global constant intsand string arrays defined in world_type.h.
- Pass large structs by reference rather than value. Where appropriate, pass const references pointers-to-const. Do not pass lots of little arguments when you can pass an appropriate, largerstructure instead.
- All required output should be sent to the standard output stream; none to the standard errorstream.5. You should strive not to duplicate identical or nearly‐identical code, and instead collect suchcode into a single function that can be called from various places. Each function should do asingle job, though the definition of "job" is obviously open to interpretation. Most students writetoo few functions that are too large.Hints andTips
- This project will take you longer than project 2 did, so start early!
- Do this project in stages. First, be able to read the species summary file. Second, be able toread the programs for all the species. Third, be able to read the world file. Write some diagnosticcode that can print out the species summary, the program for each species, and the creatures, tomake sure that you are reading them correctly. Implement the errorchecking and test it withdifferent illegal inputs. Once you can read the structures in, implementthesimple moves such asleft and right. Once you have that working, implement moves such as hop and infect. Finally,
implement if*** and go instructions.
- Take advantage of the fact that enumerations are sequentially numbered from 0 to N‐1.
- Use the right methods of input file stream to read file. In some cases, you may first use thegetline() function to read the entire line of a file and then use an input string stream toextract the content from that line.
- The hop instruction will only cause the creature to move forward when the square it is facing
is empty. If moving forward would put the creature outside the boundaries of the grid or wouldcause it to land on top of another creature, the hop instruction does nothing. However, althoughthe hop action is not executed successfully, you should update theprogram counter so that itpoints to the next instruction after this hopinstruction. The similar situationalso applies to theinfect instruction. If there is no enemy to infect, the infect operation does nothing. However, youshould update the program counter to its next instruction.As a hint, you probably need to write the following eight functions or some variations of them.However, these are not the onlyfunctions you have to write. You probably need to write morefunctions for different jobs.bool initWorld(world_t &world, const string &speciesFile,
We provide you with a few test cases in the directory called tests, which can be found insideProject-3-Related-Files.zip from our Canvas Resources.Inside the tests directory, there is an example species summary file called species and twosubdirectories called creatures and world-tests. The creatures directory contains anumber of species program files. The world-tests directory contains five world filesandthefiles recording thecorrect outputs.The first world file is called outside-world,which describes an illegal world with onecreature located outside the boundary of the grid.To run this test case, type the following commands:./p3 species world-tests/outside-world 5 > outside-world.outThen the output of your program is redirected to a file named outside-world.out. Thecorrect output is recorded in the file outside-world.answer in the directory worldests. You can use the diff command to check whether the file outside-world.out isame as the file outside-world.answer.The second world file is called overlap-world, which describes an illegal world with twocreatures located at the same square in the grid. You can run this test case using a similarcommand as shown above and compare your output with the correct output recorded in the fileoverlap-world.answer.The next three world files world1, world2, and world3 are legal world files. You can runthese test cases in the similar way. The number of simulation rounds for world1, world2, andworld3 are 5, 20, and 40, respectively. For these test cases, we provide you with both theverbose and the concise output files. The verbose output files are these files named as*-verbose.answer and the concise output files are these files named as*-concise.answer.These are the minimal amount of tests you should run to check your program. Those programsthat do not pass these tests are not likely to receive much credit. You should also write otherdifferent test cases yourself to test your program extensively. In doing so, you need to write yourown legal/illegal species summary files, legal/illegal world files, and species program files.Indeed, it will be very interesting to create new species yourself and observe what kind ofspecies will finally dominate the SIMPLE WORLD given different initial layout!
- Submitting and Due DateYou should submit your source code files simulation.h, simulation.cpp, and p3.cpp.These files should be submitted via the online judgment system. See announcement from theTAs for details about submission. The due date is 11:59 pm on Nov. 17, 2024.
- GradingYour program will be graded along three criteria:
- Functional Correctness
- Implementation Constraints
- General StyleFunctional Correctness is determined by running a variety of test cases against your program,checking against our reference solution. We will grade Implementation Constraints to see if youhave met all of the implementation requirements and restrictions. General Style refers to the easewith which TAs can read and understand your program, and thecleanliness and elegance of yourcode. For example, significant code duplication will lead to General Style deductions.