Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ANALYSIS.md #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 91 additions & 16 deletions analyses/01_game/ANALYSIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,116 @@ Project Journal

###Time Review

I spent approximately 30 hours on the project, starting from the afternoon of September 1st and ending on the early morning of September 4th. Additionally, I spent an additional 5 hours on the readings for the class before starting the project, including all the reading content for the first two weeks. I spent about 40% of my time coding, and about 30% of my time reading the example_javafx code and about the different components available in javafx that I could use in my implementation. The latter involved reading additional sources online that supplemented the example_javafx code. I did not spend much time designing my code, as I wanted to test components individually first; but I did not realize that since some classes were dependent or built upon existing classes, that some of the “test” classes I created branched into the production code for my final implementation. I spent maybe 10% of my time refactoring my code; since there was not too much code in the first place, it did not take too much time. However, since I did not plan the refactoring in advance (as it came up due to not being able to figure out the classes I built up and cleaning up my code in order to make it more readable), it did delay the implementation of the rest of the classes I had planned, and I lost my train of thought due to not writing down what I had thought of implementing beforehand.

I started quite late on the project and if I had started two or three more days in advance, I probably would have been able to finish the complete project. In essence, since I did not plan the project ahead in writing, and since I underestimated the complexity of javafx and spent more time than I thought I would need on understanding the classes available to me, I had to finish the project under a tighter deadline that I thought I had, and I needed to finish large components at the same time, which made my schedule less flexible and sapped my productivity. If I had written down my design and set good stopping points for developing my code, my schedule would have been more flexible and I would have been able to think about and incorporate any design changes I needed mid-way.

I did not believe I timed myself well in implementing my code; what I did was develop, test, and incorporate my code with existing code, sequentially for each class, without the proper planning for each class beforehand. Hence, when I had finished developing my class, I realized that sometimes I could not make full use of other classes to cooperate with the class I had developed, and it made building on other classes more difficult. If I had planned better before I started writing code, I may have found a better way in order to order my classes and integrate them together.

Some of the tasks that I missed included documenting my code and adding comments to it; if I had added comments regularly, I would have been more comfortable taking a break between coding days and going back to my code and reviewing it. I may also consider doing a parallel write-up or log along with my code, to update along with the development of my code so that I can better keep the lessons I learned along the way.

I should also consider better scheduling of the tasks that I assigned to myself. For example, instead of reading all the texts beforehand, I should read or review the design texts before I start and complete the design of the project, and read or review the refactoring texts right before I planned to refactor my code. That way the assigned texts appear less as busywork and more relevant to the current material or task at hand.

The easiest tasks for me to do were the coding and the refactoring portions of the project. The coding appeared to be relatively straightforward as I started off with small and simple functions, and read a lot about how to use and extend the classes given to me beforehand. The hardest part of the project was the design aspect of the project, since I didn’t have a clear idea of how to build everything before I got started. Incorporating more time into the design aspect is definitely an area of improvement.


###Commits

You can put links to commits like this: [My favorite commit](https://github.com/duke-compsci308-fall2015/example_bins/commit/7be1fe10327f20a14293ef39fddd9f75b7359e43)
I committed code five times over the course of September 3rd, and I mostly altered the three classes I was working with: ButtonGrid.java, Main.java, and MineButton.java. The amount of code I altered for each of the classes depended on the task I wanted to finish; for example, the refactoring component replaced a lot of the redundant code with smaller for loops instead, while the minefield generation involved adding four smaller functions.

I based the size and the purpose of the commits as following a logical path of how my project was progressing. I made sure that each commit added some meaningful understanding to the progression and thought process of my code development, and that each commit would be able to compile and play either a slightly different and improved version of my code, or play it with (hopefully) better performance.

I believe that in general, the commits I released were reasonable for someone to review and give critical feedback in a timely manner.

###Conclusions

I believe I drastically underestimated the size of the project at hand, especially since I did not have any previous javafx experience and since I did not have a strong coding background. I can overestimate the amount of time it takes to complete the project, and start much earlier in order to make the estimate matter less.

I would say the MineButton.java file required the most editing, because of the constantly changing requirements I needed from the tiles. I added and deleted functions according to what I needed to implement in ButtonGrid.java. I believe barring the poor design planning aspect of this project, it was to my advantage that I change MineButton.java, because it meant that the functions I needed to implement in ButtonGrid.java would be simpler and the distribution of work would be more even than otherwise.

If I want to become a better designer, I need to start thinking at minimum all the classes I need to implement from the very start, instead of adding classes halfway through the code development. Methods are relatively easy to add to a class; classes are hard to add to a project. I need to think about user interaction with the program and how interrupts will interact with classes and methods I build. I should continue to think about how best to refactor my code so that I can continue to use it after building more functionality of the program, and make it more readable and understandable. I should also continue to think about how my classes should distribute the work between them so that they are cooperating together. I should stop writing code without a design and start understanding that badly written code takes more time to fix than using that time to create a good design. I should also stop any reading or work that does not immediately apply to my project, and start thinking about how to distribute my reading within my project in order to maximize the amount of application I can benefit from the readings.

Design Review
=======

###Status

* Bullets are made with asterisks
In my view, the coding is generally consistent in its layout, descriptiveness, and style, but could improve upon naming conventions. In the beginning, the code used a standard “my + variableName”as the standard naming convention, but as the usage of local variables grew the naming convention suffered in consistency, as I did not expect to use them later on in production. Eventually the naming became just the variable name without some sort of identifier; while it was generally clear what the variables and functions were doing, it would be difficult in the future to search for a function name if standard naming conventions are not kept.

1. You can order things with numbers.
Comments are generally spread out and infrequent, as the refactored code is generally quite easy to understand. Functions are broken down into at most 20 lines of code, and use commonly encountered local variable names. Comments are reserved for functions that are typically hard to understand, such as the ones incorporating classes like VBox and HBox. Function names are generally accurate and precise. There were a serious number of global variables incorporated into the ButtonGrid.java class, however most of the global variables were only used within one or two functions, and the purpose of them being that they needed to keep track of state over the course of the stepping animation. Ordering of the methods is generally done by the importance of the method to the class; lesser methods such as those generating the minefield and checking for certain conditions tended to be at the bottom, and more important methods, such as initializing and returning the scene and creating the step function tended to be at the top. This is primarily a result of the refactoring; before the functions were arranged based on when they were created.

###Design
I am particularly proud of how I organized my step function for the animation:




public void step(double elapsedTime) {

// keep the selected buttons down so they can't be clicked anymore
if (!clickedButtons.isEmpty()) {
for (MineButton button : clickedButtons) {
button.setSelected(true);
}
}

// find out which new buttons have been selected;
MineButton button = checkForClickedButtons();
if (button != null)
exploreMinefield(button);
checkGameState(button);
if(gameWon || gameLost){ // if the game has a conclusion
return;
}
}


This function maintains the previous state of the game while polling for any changes in the minefield. First, it looks at the set of buttons in the minefield that have already been clicked and logged into the set clickedButtons. If there are any buttons in that set, it takes each button and presses it down for the duration of the step. This has the effect of making the button depressed once clicked, and not being able to click it until the game resets. The next part of the program searches for a button that has been clicked during that step, and returns it to the variable “button”. If there is a button that has been pressed during that time, the step function expand the minefield as appropriate. Regardless, it will check the gameState to update the Booleans gameWon and gameLost, which when asserted tell the program whether the game has been won or lost. If the game has been won or lost, the step function returns and exits the animation loop.

You can put blocks of code in here like this:
```java
/**
* Returns sum of all values in given list.
*/
public int getTotal (Collection<Integer> data) {
int total = 0;
for (int d : data) {
total += d;
}
return total;
}
I am also proud about how I refactored my getLegitimateAdjacentTiles function:

```
private Set<MineButton> getLegitimateAdjacentTiles(int row, int col) {
Set<MineButton> set = new HashSet<MineButton>();
for (int i = row - 1; i < row + 2; i++) {
for (int j = col - 1; j < col + 2; j++) {
MineButton tempButton = getMineButton(i, j);
if (tempButton != null) {
if (!tempButton.equals(getMineButton(row, col)))
set.add(tempButton);
}
}
}
return set;
}
```

Initially I had set to get each tile adjacent to the square by itself; I realized that instead, I could just get all nine squares, including the adjacent tiles and the tile at (row, col) itself, and just leave out the tile at (row, col). I made sure to check the object using the object.equals method. Using nested for loops stylistically makes the function closer to other functions in the class, and gets rid of unnecessary local variables.

###Design

There are three classes in this minesweeper game: Main.java, ButtonGrid.java, and MineButton.java. MineButton.java, which extends ToggleButton, is one tile of the minesweeper grid. All attributes of the button-level playing of the game belong to this class. ButtonGrid.java instantiates the minesweeper grid, and describes how to generate the minefield and play the minesweeper game by itself. All grid-level attributes of the game belong in this class. Main.java begins the game, and handles the staging of the game (which stages belong in which part of the process, and how to manage the stages).

First, Main.java is invoked. It launches into the start function that is part of the default javafx call. It instantiates the new minesweeper grid, sets the title of the stage, and creates a new scene. It then displays the scene on the stage. Then the animation loop runs with a fixed delay. ButtonGrid.java creates a new minesweeper grid, using MineButton.java. During the animation, ButtonGrid.java looks at any key presses and depressed buttons, and expands and explores the minefield accordingly until there is an end game state (either the game is lost or the game is won).

A new level can be easily added by setting a timer to start on the first button depression (i.e. when the set of clicked buttons equals one and setting a lose condition when either the player steps on a mine or when the timer runs out. Varying difficulties can be added by setting the difficulty factor available in ButtonGrid.java.

This code is designed the way it is because I had thought the highest level component I would need is ButtonGrid.java, and that Main.java would only consist of invoking ButtonGrid.java and animating it. This was a flawed perception, as I was unable to make ButtonGrid.java handle a splash page and display output back to the user without detrimentally altering the grid, and thus needed some method in order to manage different stages at Main.java level. Additionally, since event handling came in at the Main.java level, when it came time to integrate Mario into the game, I was unable to do so since I had only prepared for ButtonGrid.java to run.

Several dependencies limited the development of my program; they occur primarily during the display of the graphic elements in the scene. Javafx had some deficiencies when it came to grid-based games; for example, I needed to create my own grid of buttons, as well as use global variables and class extension when retrieving buttons from the grid in order to alter. In addition, traversal of Mario on top of ButtonGrid.java was especially hard; Mario needed to interact with the program at both a Main.java level (due to the need for event handling) and a MineButton.java level (due to the retrieval and traversal of his position, and the restoration of settings on previously traversed tiles).

One feature of the design specification that was difficult to implement on my end was the requirement of two levels or “modes” that differ algorithmically. This difficulty manifested itself not only in the design of the game, but also the staging. Since the minesweeper grid was less flexible in graphics than layered images, it required different staging for an acceptable experience (i.e. I could not overlay images over the minesweeper grid without disrupting the grid), requiring a StageManager class of some sort. This feature would not have impacted the complexity of the interaction between the Mario class and the MineButton.java class though; if Mario would be able to traverse the minefield, dynamic changes to the minefield could be added relatively quickly.

Another feature of the design specification that was difficult to implement was the necessity of a splash page. Again, since the display of such images would need to be handled separately from the minesweeper grid, a StageManager class would need to be invoked. Additionally, since an entirely new scene needs to be generated, a SplashPageGenerator class would also need to instantiate and animate the splash page.

###Alternate Designs

One of the most important choices I made was regarding the graphic display of the minesweeper grid. I considered either extending GridPane (which is an existing class in JavaFX) or creating my own grid class using VBox and HBox (storage boxes for elements that added either vertically or horizontally). Using or extending GridPane would save me the hassle of developing my own class, and perhaps increase performance if the functions written were optimized. However, I would have a lack of understanding behind one of the key functions in my classes, and as GridPane’s intended use cases are not aimed towards uniform arrays of identical items, I would still need to build out traversal and other functions relevant to the minesweeper grid. The added functionality in GridPane may prove to be a hindrance if the usage of the functions available prove to have unintended consequences (for example, if there is a default padding around each tile). The other solution is to create my own grid implementation, out of an array of HBoxes in a VBox, with minesweeper tiles within the HBoxes. This implementation would be simpler to debug and would have as much functionality as I deemed necessary to fit; however, the time needed to develop and test the functions I needed would be substantial. In the end, I decided to build out my own class, since the HBox and VBox functions already provide a good deal of the work needed in order to create a grid, and because the brief experience I had with GridPane convinced me that a better solution could be made by developing my own class.

Another decision I decided to go with was extending the ToggleButton class instead of extending the Button class or just creating a new Tile class with self-defined functions. If I extended the ToggleButton class, I would be able to use the methods in the ToggleButton class, which specifically target toggled button use cases like the buttons available in minesweeper. At the same time, extending the Button class or creating a wholly new Tile class would add flexibility. In the end, I decided to extend the ToggleButton class as it appeared to be the most straightforward (at MineButton.java level, the functions are not very complicated), and because the buttons provided a more professional look to the game than a Tile class would.

I mistakenly focused on writing and refactoring code rather than developing the full functionality needed of the game; therefore my program had less in terms of bugs and more in terms of missing functions; missing level, missing splash page, and missing cheat keys.


Code Masterpiece
================