In this project, we created a path which an object traveled along, decreasing "mushroom" size as it went along. The mushrooms grew over time, and they grew faster near fertile patches. The gatherer seeks places with the biggest mushrooms.
Task 1 was to make the Agent class. We initialized it with a row and a column value. There was also a get and set method for both column and row, and in addition, an update state method that was left blank. I tested it by having it print out the row and column (henceforth called "col") I assigned it.
Task 2 was to make a mushroom class. This has a row and col, as well, and also a size that was initialized to 0. Shrink and grow methods decremented and incremented size, respectively, and die set the size to 0. In the draw method, I used the provided code to draw a mushroom light brown in appearance.
Task 3 was to make a landscape class. It held the amount of rows, cols, fertile patches, and vertices, and had a method to return the number of rows/cols, as well as one to return a mushroom at a given row and col. I looped through every item in the rows and cols, and used them as coordinates to draw mushrooms on the grid positions, which was a 2D array field in the landscape class.
Task 4 was to make a display class for the landscape, which was similar to past ones. The main difference was that in the main function, I tested the mushrooms' grow method. For a random number of times from 0 to 9, we grew any given mushroom as we looped through all of them. After this worked, I went to task 5.
In task 5, we just had to create a FertileGround class. All it needed was row and column fields, and a way to be drawn. They were to be drawn as green hollow squares.
Task 6 was a longer one. I used the provided code to add a line of patches across the landscape grid in the constructor. Then I tested it until it worked, and started to write the method that determines what the closest growth patch is. It took two arguments, row and col, and used the distance formula to see how far away from each growth patch it was. I stored all results in an arraylist, then used Collections.min to return the smallest, which was the int that the method needed to return. Next, I made a growMushrooms method, which tells the mushrooms to grow, which is more likely the closer to a growth patch they are. The mushrooms were told to "try" to grow a passed-in number or times.
Task 7 was to create a simulation class, in which we only tested growing the mushrooms and displaying for them.
Task 8 was simply to create a PathVertex class, which was just like the fertile ground class in that it only needed a position and a draw method, in this case being drawn as a blue hollow square.
Task 9 was to add vertices to landscape and test drawing them. Also, we added in methods to return both a forward and a backward iterator, which took the iterators from the linked list class, of which type the vertex path was; this would be needed to traverse the path later.
In task 10, we made a gatherer class, and initialized and drew it, leaving its updateState method empty for the time being. In landscape, we added a way to access the gatherer, and we tested out the display. My gatherer is a black square.
For task 11, I made the run method in the simulation, following the outline. First, I grew the mushrooms, then I traversed the path back and forth. Every time one lap was finished, the iterator had to be made fresh within the loop, and it had to use the opposite kind of iterator because the direction would be different. First, the path was traversed forward, then backward, and this was done 10 times; while the iterator had a next node, it was done within each iteration. Then, I changed the position of the gatherer to be where the next node it should go to is. After that, i repainted and slept. Gatherer's update state just told it to go to the desired location for now.
In task 12,I added the function to "eat" the mushrooms in a 7x7 grid around each vertex. I had a for loop within a for loop, each having an int going from -3 to 3 so that I could use those as offsets for the current column in order to reach around the location and check each mushroom's size. If it was the biggest so far, it would update the vertex to land on it, and at the end of each loop, I used mushroom.shrink() to make the given mushroom smaller. At the end, I set the vertex col and row to be equal to one of the biggest mushroom.My code was as follows:
In the last task, we had to play around with the parameters to make the vertices closer to the growth patches. I changed the simulation so it would make more vertices. Since there were more, it was more likely that their 7x7 grids would overlap and they would end up roughly in the same spaces, and would also eat more, making it more likely that a bigger mushroom nearby would be found soon. Meanwhile, making more fertile ground patches would make also make it likely for the gatherer to land on one just because there were many. Also, making the mushrooms grow bigger would keep the vertices from moving up too much, which they did because they started searching for a mushroom from the top left, and it would go toward the next "biggest" mushroom in that direction, forgetting about the bottom. Gifs of more vertices and bigger mushrooms are below.
I did the first extension, in which I made the vertices move more, by which I mean I told it to move even when no mushrooms were nearby. Before, the gatherer waited until mushrooms had grown nearby, but this way, I kept it moving to search for a spot where more mushrooms were growing instead of waiting for them to grow where it was. I added this into the gatherer updateState method as shown below.
I also did extension 5, in which I drew connecting lines between vertices. To do this, I thought that I would check if any given vertex had another after it, and if it did, I passed it into the vertex draw method and drew a line between the coordinates of the two vertices. The code below shows that I initialize my index to 0, then as I go through each vertex in the path, I increment it at the end, and before that, I pass into vertex.draw the vertex at the index+1.
If it is the last vertex, its next will be null, so I check if it is not, and if that is the case, I draw a black line between the two vertices, with nextVertex being the parameter I am now passing in. You can see the lines present in my previous gifs.
In this project, I had to be careful to remember that col represented a x coordinate and row represented a y coordinate. Also, I learned that we had to import the iterator type to be able to use the iterators of the linked list class. Overall, I became more comfortable working with a linked list structure and at following the tendencies of objects and trying to manipulate them.
Thank you to: