Marine Biology Case Study For AP Computer Science Class By Norma N. Mackenzie
For this presentation, I am going to start at the very beginning of the MBCS. I am going through the entire case study, starting with fishsim.cpp and going from there. Everywhere that the program steps, we will go with it with explanations. Follow along with your MBCS so that you do not get confused. Make notes as you feel necessary
In fishsim,page C13, the input file is identified as fish.dat env is declared as an object of type environment. The input file is being sent to the environment so that there it can be used as a constructor to make the new environment object. Go now to environment.cpp and the constructor page C2. There is only one environment constructor and you can see that it receives an input file. At the same time this environment object has its private data members initialized. My World is initialized, as is myFishCreated and my FishCount. After numRows, numCols, row, and col are initialized, we start reading from the input file (fish.dat) you can see here that we read the numRows and the numCols and then take that information to resize the matrix myWorld to whatever the number of rows and columns are as read from the input file. Initially myWorld was 0 rows and 0 columns
Now you are entering a while loop that will continue so long as it reads a row and a column from the input file After each input of a row and a column we now take off to AddFish but we must always send the Position which is the row and the column of the fish you are adding. AddFish is an Environment function found on page C4 The first thing that AddFish does is to check and see if the position you are sending IsEmpty. Pos is a parameter. If you go to IsEmpty on page C3 you see that the first thing that IsEmpty does it to take you to InRange on C4. InRange checks to see if the row and the column of position are in our boundary. Return true sends it back to IsEmpty on pageC3.
The next thing that IsEmpty does is to check and see if the fish that is positioned in the row and column of myWorld, is not defined. The Function IsUndefined is on page C5. All that happens here is it checks the private variable amIDefined. On page C5, observe where the private variable, AmIDefined is defaulted to false. If the fish is not defined then ! amIDefined is true. This takes us back to IsEmpty on C3 and from there we go back to AddFish on page C4. Then AddFish increases the number of fish in the environment by one and then the fish at that row and column of myWorld is equal to the Fish object with two parameters. One parameter is myFishCreated (later to be the ID #) and the other is pos). To understand this assignment go to the fish constructor on page C5
You can see looking at the proper constructor that myFishCreated becomes the ID and the position remains pos. In addition you can see that the ID of the fish is now equal to myFishCreated, and myPos is =the position that was sent and that amIDefined is true. When you assigned Fish(myFishCreated,pos) to the position in myWorld..go to the last slide..last comment…you created that fish with those private variables now assigned. This takes us back to AddFish, page C4, where myFishCount is increased by 1. Now we go back to where AddFish was originally called which was on page C2. We are in a loop and will remain there until all fish have been added from the file
Now we go back to fishsim.cpp on page C13. We are now ready to look at Display display Obviously display is an object of the Display class. We go to the Display class on page C1 We can see the constructor which has no private members to set. Now we go to the Show function taking the env with us as a parameter. WIDTH is a constant set at 1 We find out how many rows we need by calling the env function NumRows which simple returns the number of columns in myWorld and the same thing for the int cols. Go to page C2 to see the Numrows() and C3 to see NumCols()
Now fishIndex is initialized to 0; numFish and r,c and pos are also initialized. Next you will see that an apvector of type fish (page C5) is initialized. The apvector of fishlList is now =to env.AllFish(). Lets go to C3 to see the environment class to the function AllFish()
The first thing that happens in AllFish is that the apvector fishList which is made up of Fish is sized to myFishCount which is a private member of the Environment class and is increased each time you added a fish in AddFish.. FishIndex is set to myFishCount which tells you how many fish are in the environment, r,c and k are declared and apstring s is set to a space Next a matrix is set up with r as rows and c as columns they go to a max of NumRows() on page C2 and NumCols on page C3. The next statement tells you that if the fish in myWorld[r][c] is not undefined the fish in myWorld[r][c] is placed in fishList[count] and count is increased by 1.
Remember that even though you just placed a fish in fishlist it retains its position in the original matrix myWorld, because it keeps its position myPos as its Private Variable. (Page C5 constructor We now go back to C1 to the place where AllFish was called. We see that numFish will equal the number of fish in fishList. The reason that it was necessary to put the myWorld matrix into a vector called fishList is because this is where we get the left to right, top to bottom means of moving the fish. The fish are always picked up in the order that they are in fishList which is the same order, right to left top to bottom of myWorld but it is minus all of the empty spaces that you find in myWorld.
Next you can see that the variable numFish is initialized to the length of the new vector fishList. Then looking at the next loop you can see that you take fishindex which was earlier indexed to zero and you loop through setting the location, which is the position = to pos for every member of the fish in fishList. Remember that fishlist is a vector of fish and from the fish constructor (C5) you see the private variable pos. Then on page C5 note the function Location(). It returns pos. After this it sets up a matrix with r being the column and c being the columns. Then it says if the row(r) and column(c) for the matrix = the row and the column of the location of the fish in fishList, then we have found a spot that has a fish. Then we go to ShowMe on C6.
ShowMe takes the ID number and equates it to a letter of the alphabet. Thus ID() ends at 26 and the number representing A is 0. See if it does not work. If there is no ID number. It will display a star. Now go back to where ShowMe was called which is page C1 fishIndex is then increased so that the next time through we will get another position in the fishList. If fishIndex < numFish If the position is > or < numFish then the position is not in the grid and will not be displayed. By going to Position() constructor on page C8. You will see that the pos that was not within numFish is assigned -1,-1. The position is then set such that there is nothing displayed but a blank space indicating no fish there. It then loops back to for (r=0;r<rows; r++) until all spots in fishList are processed. Go back to fishSim page C13
Now back at fishsim.cpp on page C13 we start under display.Show(env) because that was the last place we came from. You can see that initialized will be displayed. You will then be asked how many steps. You can see in fishsim that s was declared as an apstring. It is nothing other than a slow down. The program will not continue until you hit enter. You are entering a blank character..or any other string you want it is only letting you be in control as to when the program will execute. It will now loop through until it is just shy of the number of steps. You can see that the first step is to use the simulation object to go to simulate and access the function Step. It is necessary for env (the environment object) to be sent as a parameter. Go now to page C10 to sim.Step(env)
Again looking at the beginning of simulate you can see in Step that we are going to use fishList again and that it is a vector of fish. Next you can see that it gets AllFish again. AllFish in on page C3 but you have been there before. Remember it puts all the fish from the matrix myWorld into a vector called AllFish reading from right to left, to to bottom. It may be necessary for you to go back and look at it. Anyway fishList is a vector that takes all the fish out of the myWorld matrix. Next you can see a loop in which you go from 0 to one less than the length of fishList. At this point every fish is going to go systematically, one by one to the Move function. Go to the Fish Move function on page C6
In move you can see that one of the first things that is done is that a random number object of class RandGen is declared. Then the neighborhood object nbrs is going to get whatever EmptyNeighbors returns. Before we go to EmptyNeighbors lets go to look at the Neighborhood Constructor on page C7. You can see that the object of this class is going to be a list with a maximum of 4 entries and initially there is nothing in the list. Keep this in mind. Now on to EmptyNeighbors on page C6. It is a private function of the fish class. The first thing that happens is that nbrs is to be the object of the fish class. That means that nbrs is to be a list with a max of 4 items.Next we move to AddIfEmpty and send the parameters env,nbrs, and pospos. These functions are located on page C7
There what will happen is we will check and see if the position north of the current position we sent the function is empty, south, is it empty? etc. Then if the positions are empty, then we will add the position to the object nbrs. Go to AddIfEmpty on page C7. The first thing that is to be done is we take the env object and send it to the function IsEmpty.(C3) The parameter is the fishs current position. Next at IsEmpty page C3, It will return false if the position is not in range (go to C4 to see how InRange does this. ) The first statement should not be a problem. The second statement simply says is that if the fish in that position is undefined…nothing is in there return true) Now go back to C7 AddIfEmpty Now since that position is empty, we will go to the neighborhood function
Add and send the parameter of the empty spot to add. Go to page C8 the Add function. The first thing it done is we check to see if the private member myList is no greater then the length which if you recall was set at 4. If it is not myList, which is a list of the Position data type, receives the position that was sent to it, which is the empty function. At this time, myCount is increases. We now go back to Empty Neighbors (C6) because that is the function that called AddIfEmpty. You can see that it now goes to AddIfEmpty Postion South, East and West. functions work We want to go see how these position functions work so go to page C9. It should be pretty obvious how these position are programmed
Now we return to the Move Function which is on page C6. We have followed through with the EmptyNeighbors function which is statement #1. The next statement we will do only if the size of the nbrs object, which is a list of positions of max 4, is greater then 1 in other words we will do this only if there was an empty neighbor to move into. You see where oldpos is equal to the my pos. Obviously at this point the two positions are the same. My pos is about to change in the next statement. MyPos is going to equal the neighbors function Select which will have as its parameter a random number from 0 to the size of the nbrs list -1). Go check out Select which is on page C7. You see that it takes one parameter which is an int. That is a random number. Go back to Move on C6.
After the last slide myPos has been assigned a pos from the nbrs array. The index of the array, that was later to be assigned to myPos, was assigned by a random number.The next statement takes us to the environment function called Update. As parameters we send it the oldPosition, and the fish. Update is on page C4. A fish variable of type emptyFish is declared. This is a fish with nothing..no constructors at all. The Update Function, does exactly what it said that it would do… it takes the old position and checks to see if it is in range. You have done this function before, review it by turning to page C4 bottom of the page. It should not be a problem. Then it says if the fish in the oldLoc has an Id that does not equal to the fishs ID being moved then no go.
If they are the same fish then the new location is equal to the current location of the fish, and the old position is equal to an emptyFish. We now go back to Move on C6 and see that we are now through with Fish Move, so this takes us back to StepFunction from where Move was called. If you notice here, it will loop through sending all of the fish in fishList to the move function and when all of the fish have been moved, we go back to fishsim.cpp, page C13, from where Step was called. The Final place we go from fishsim is the Show function on page C1. We have been through display.Show before. Go through it again and see that you are now just displaying the fish with their new positions.