|Version 1 (modified by rthomas, 2 years ago)|
One of our major design choices was the decision to have a state object that stores the main game stats, money, material, pollution, power, and food. The state also stores a record of what has been built. Both the game class and the turn class have a state object. This is so the costs can be broken up into one-time and recurring while not charging the recurring costs until one turn after the player has decided to build the technology. Thus after using the game’s state to calculated the recurring costs at the end of the turn we copy the turn’s state over the game’s state object. While this seems undesirable because we are storing the same data in two places we have chosen to use this setup as it lends itself well to allowing the user to undo a turn if the build something they do not want because we can simply copy the game’s state over the turn’s state.
The building struct has two sets of specifications, the image filename, and the thresholds required to build it. Thus both the map class and the state class need access to this information. To not repeat the information about the different types of technology in multiple places we store all the building specific stats in one place that multiple classes can access. This results in higher coupling than we would like however since this is a structure that does not change we do not have to worry about classes modifying it when debugging. Additionally, we have a specs struct that stores ints for pollution, space, money, power, and material. By creating a struct we can allow each building to have one-time and recurring stats without having to repeat code and instead having a one-time spec object and recurring spec object.
While our game class interacts with many of the other classes, state, turn, map, scene and user interface, it still obeys the single responsibility principle. The purpose of the game class is simply to interface between these classes and the UI class which deals with user input and the rendering of screen images. Game passes the windows that are created up to the UI class, which has an array containing the active windows and sends responses down so that new windows can be created.
To signal when to display different windows based on user clicks and what is already displayed we are using a system of responses and flags. The flags are simply boolean values that tell us whether the menu is currently displayed or not. If the build menu, for example, is displayed then we do not want to reopen the menu when the build button is clicked. Each window entry that we have has a specific response associated with it so if you were to click the build solar panel button it would send the response BUILDSOLAR. The responses are simply constants with an integer value assigned to them. We realize that this is poor style but we are working in python and python enums are simply keys with integer values assigned to them. So in the absence of a better data structure this is how we are representing our responses.