-
Notifications
You must be signed in to change notification settings - Fork 0
/
progress_log.txt
411 lines (328 loc) · 30.2 KB
/
progress_log.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
5.3.2023
Set up the development environment and added dependencies for ScalaFX and ScalaTest.
Created the initial project structure necessary for developing the game map.
Implemented the TerrainTile trait with a couple of example terrain tile classes
implementing it with different degrade methods based on their nature and
ConfigurationConstants, changing TerrainTiles' "projectile passability" property to
"elevation" to model the terrain itself more realistically and leave projectile
passability to be calculated by the game class based on the tile properties instead.
Dependency for O1Library added to access the grid package, Map class started and
sand terrain tile added along with preliminary sketches of assets to resources.
Development is late due to workload from other courses, resulting in me only reaching
approximately 18h of work, and me being overly careful with every move so that I
would not have to wrestle with IDE configuation issues or git conflicts in the future
as my experience with both thus far consists largely of defeats. Difficulties faced
mostly include bad tutorials for libraries and my cluelessness about best practices,
especially in building the GUI, many of which have not been resolved yet. I hope to
catch up next week and cannot wait to implement the actual game logic.
6.3.2023
Implemented preliminary drawMapTiles and drawPic methods in GUI and updated TerrainTile
subclasses to case classes. GUI now displays the desired tile textures in a single row.
Modified GUI to display tiles in a MapWidth by MapHeight grid layout using GridPane and
added more placeholder assets. Implemented BattleUnit trait to the extent it was defined
in the technical plan with a TankUnit case class to have something to instantiate for
displaying BattleUnits on the map. Also added more class files.
Development has caught up to plan more, considering that many of week 2 goals have been
completed although there are no controllable battle units on the map yet.
20.3.2023
I am extremely late from the intended schedule because of various other course deadlines
and personal reasons. I simply did not have even a chance to open the project in the past
two weeks. I must cut simultaneous turns entirely and not even think about a random
generated map at this point. I must implement my own grid system because that of O1's does
not work and I will most likely have to utilize all the time I have, meaning that I will
not be able to return the project a week before. Plenty of sleepless nights lie ahead!
23.3.2023
Various changes to facilitate displaying BattleUnits on the map including refactoring GUI
methods and many other player- and BattleUnit-related classes. Due to the lack of time,
CompassDir issue was solved by caving in and adding swing as a dependency as a quick
bandaid solution. displayInGrid method was rewritten to draw TerrainTiles and BattleUnits
alike based on their positions in the grid instead of index in a vector, resulting in
BattleUnits finally being displayed on top of the map in the GUI.
24.3.2023
Added a GameMap companion object with tileGenerator and tileUpdater methods for fast and
flexible map building, as well as a getTile method for the GameMap class in anticipation
of future use. Added the symmetricTileUpdater method, which necessitated the ability for
TerrainTiles to copy themselves as well, so that only half of the map must be specified.
This also serves my original idea for the gameplay as identical sides give equal
opportunities to both players. However, I might want to change this symmetry later to be
only about the y-axis to encourage more interesting encounters and conflict. Furthermore,
I refactored drawMapTiles, drawBattleUnits, TerrainTiles and BattleUnits such that the
latter two contain their own images to achieve better encapsulation and built an initial
map for testing. I will have to soon look into some optimization already as building and
launching the GUI takes quite long after the changes. I still have to build the interface
for giving instructions to the BattleUnits but after that I will finally get to work on
the game logic.
25.3.2023
Improved game performance seen as shorter startup times and higher window responsivity by
enabling hardware acceleration and by moving the image generation back to the GUI functions,
leaving only the FileInputStreams to the TerrainTIle and BattleUnit case classes, which
resulted in most performance gains. Added the first element of interactivity through the
drawRectangleAround method, which draws a red rectangle around a selected image. This will
be rewritten pretty much immediately for something more actionable in terms of game logic,
potentially in the game class. Added various GUI methods for selecting and highlighting
BattleUnits and map tiles by rewriting drawRectangleAround. I am not entirely satisfied
with having essentially three versions of a method does very similar things, but it is
necessary to comply with type-specific behavior at this point. highlightTiles currently
places the highlighted tiles on top of the map, which does not allow the original ones
to be selected by the player. It is therefore necessary to modify these methods further.
27.3.2023
Rewrote selectableBattleUnit method's mouse click event listener and removed the
selectTiles method. No new tiles are drawn but instead, colored rectangles are added
between the image and the transparent highlight rectangle of each tile within the field
of view of the selected BattleUnit, which fully enables the necessary communication with
the Game object to finally start building the internal logic.
2.4.2023
Added fovTiles method to Game class that displays the tiles available for direct actions by
a given battleUnit and modified selectableBattleUnit function in drawBattleUnits GUI method
such that only one BattleUnit can be selected at any time. Due to not wanting to fully commit
to this decision just yet and not being a fan of options, I left the selectedBattleUnits in
Game class in vector form still at this point. I was also unsure whether the limitation of
selecting only one BattleUnit at a time should be in the GUI class or in the Game class but
this was significantly easier and therefore justified when the decision is not yet final.
3.4.2023
Rewrote the GUI to be scalable and overhauled the layout by adding more panes for presenting
information and interacting with the game, the first example of which is the updating turnCounter.
Highlighting will most likely have to be updated once again in order to clear out all selections
between turns. Building the UI like this, I really start to miss HTML and CSS...
Made symmetricTileUpdater support more different kinds of symmetries to accommodate any style of
map building.
Interim report:
The user interface starts to finally be implemented but the game is still missing. Because time is
running out and I am starting to get really fed up with ScalaFX and have therefore not implemented
a zoom feature, the map scale will be cut back to around 16 * 9 or slightly larger, which enables
me to cut back quality of life features such as selecting and commanding multiple battle units at
once, saving me development time. As there are now fewer units to control, they do not need to store
default action sets and these can be set separately by the player on each turn. This also enables me
to restrict available move sets based on selected actions and to cut at least the "patrol" action.
None of these majorly affect the spirit of the game but rather simply restrict its scale to perhaps
even a more coherent demo. All this makes simultaneous turns easier to implement but I must still
keep it on hold until the requirements imposed by the Programming Studio A course have been fully met.
I still have hope for being able to pull it off although this project will most certainly not be
completed by 19.4. as I really need all the time I can get up until 26.4. In order to streamline the
development, I will most likely have to rewrite the dreaded GUI draw functions yet again to further
enhance encapsulation of the Game and GUI classes to gain more control for the former so that I do
not have to make every change simultanously in two places.
In terms of the planned timeline, I am pretty much at the start of week 3 although the GUI should soon
be on week 4 level with relatively little work. The GUI will, however, remain less polished than my
initial idea (different from illustration) in favor of more rich gameplay rather than better graphics.
Due to my frustrations with ScalaFX, main menu and pause menu are both dropped already now and as I
envisioned the game to be closer to chess from the beginning anyway, its cut back demo version does
not need a save game feature either. Instead, the game's configurability will be about customizing the
GUI and the initial state of the game in terms of locations and properties of the predefined map tiles
and battle units with maximum freedom and expressivity.
4.4.2023
Changed the GUI so that the "Play Turn" button now visibly resets all selections. It ain't much but it's
honest work (although not too pretty looking) and now that I learned to use the "fireEvent" method, I
believe to finally have gained control over the GUI with the Game class. The only GUI changes necessary
now are to show and restrict the selections of tiles based on the currently selected action and to add
the rest of the ActionSet fields and a visualization for win progress of both players. Modified the GUI
to show action-dependent highlights. Refactored the GUI by writing a few utility functions for getting
the selected battle units and map tiles and to synthesize a mouse click in order to condense and clarify
the GUI code.
5.4.2023
Limited the number and scope of selectable tiles to one and tiles in range of the selected battle unit
and action respectively. Additionally fixed a bug introduced in the latest refactorizations that caused
and index out of bounds error when changing the selected action without a battle unit selected.
11.4.2023
BattleUnits move! ..method is now implemented so that one battleUnit at a time can move 'range' tiles
per turn. This was supposed to be a quick one but ended up taking two whole days to write. The first
was entirely wasted hunting for a bug that, upon re-rendering the StackPanes in the grid, would not
display the images at all. I searched the entire internet, spent hours rubberducking with ChatGPT and
finally, entirely on my own realized that the root cause of the issue was an arbitrary but now very
stupid decision to associate the BattleUnit and TerrainTile images with their respective classes in
the form of FileInputStreams instead of the strings containing the images' file paths, which is how
it is now done. This caused the mysterious behavior of the GUI draw functions working the first time
they are called but not on the second, despite complete removal of grid children, clearing of all
caches and whatever I could come up with. The first half of the second day was still spent on the
same problem, this time from the angle of concurrency but to no avail until the breakthrough. I also
refactored the GUI by separating layout components from display and interaction components.
The move method is currently implemented in the Game class but might be moved to the BattleUnit class
along with the implementation of the ActionSet to facilitate easier management of the multiple actions
for multiple BattleUnits.
12.4.2023
I realized I had overly complicated the action set as well in anticipation of the various convenience
features that would be necessary for a really large map but now that they will not be implemented, I
was able to simplify it much further to only primary and secondary actions and targets. Primary action
will always be attempted and only if it fails, will the secondary action be attempted.
In anticipation for the implementation of ActionSet, I added a "Set Action set" button to the GUI, which
would probably be best renamed, that adds battle units to pending actions and pending targets in place
of the soon-to-be-implemented ActionSet handling and signals the success of this by adding a green
checkmark to the corner of the tile where the battle unit resides. This temporary patchwork solution
enables the moving of multiple battle units per turn.
Next steps include first, finally building tests for the game mechanics, second, implementing ActionSet
handling and third, calculating and displaying the probabilities of different actions.
13.4.2023
Implemented first tests to test the correct initialization of the game and expected behavior of the move
method. These were mostly just for practice and although structuring the tests still needs a bit of
getting used to, it was far less intimidating in the end than what I initially thought. I will not be
testing the GUI however as it is and will remain still easy and quick to test manually. Implemented a
rudimentary ActionSet execution method that only moves units. This might eventually replace playTurn
partially or fully in order to show the tried, failed and successful actions in the GUI after pressing
"Play Turn". Implemented a rudimentary calculateMoveProbability function and displayed its results for
tiles in range of the selected battle unit in the GUI. Next steps include full implemenation of ActionSet,
visualizing its selection in GUI and showing the progressing of the actions in the GUI after playing a turn.
14.4.2023
Added selected tiles to the GUI next to action dropdown, made it impossible for more than one BattleUnits to
move to the same grid tile, such that the latest set ActionSet is always executed. Did some refactorization
and improved documentation and commenting of code.
15.4.2023
Major refactoring of the GUI to change selected units and tiles from vectors to options, which enables the
implementation of the preferred input method for ActionSet. This introduced various bugs, which took a long
time to fix and I am cautious of the number of times I had to use the forbidden get method. It should,
however, be alright because I check that selectedBatleUnit and targetTiles are defined every single time
before using it. Implemented primary and secondary target selection in the GUI. Secondary target does not do
anything yet and secondary action is not even visualized yet but when these are added to the mouse click
event of the "Set Action set" button ActionSet selection will be fully implemented and only its full
execution remains.
18.4.2023
And so became the GUI spaghettified. Implemented ActionSet selection in the GUI fully. This was waaaayyy more
difficult than initially anticipated, taking thrice the time expected and leading to a quite ugly result with
various interdependencies between the methods and the Game and GUI classes. My biggest takeaway from the past
three days is that the GUI should be at least as well planned as the other logic as I have definitely spent
the overwhelming amount of development time in one corner of my original UML. However, I have only gotten the
experience and understanding of ScalaFX now and therefore could not have really planned it much better in the
beginning whereas I can be quite a bit more efficient with my next project. I guess this is the journey of
learning. Now, however, the GUI is essentially done in terms of functionality. I might still add healthbars
and other information related to the BattleUnits or the game state as well as make some slight visual
improvements but all interavticity is now done and I am very happy with it. It is intuitive and comfortable
and after tens of hours of debugging, entirely seamless and perfectly predictable and dare I say, enjoyable.
Now if I manage to add enough variety to the gameplay to facilitate a variety of different types of strategies,
it might become a pretty decent demo of a game that could be really great. Should I continue its development,
however, I would probably immediately switch to some game engine or rebuild the GUI entirely in a different,
more flexible way. Now, as long as it works, I will not touch it. Next I will "animate" the progression of a
turn such that the BattleUnits execute their ActionSets one attempt at a time. Then I will implement the Attack
and Defend actions, after which I will have to make the AI opponent and implement a file reader for the
configuration constants in order to fulfill the requirements of the course. After that, if I still have time,
I will implement the supply chains and potentially simultaneous turns. I will also add more BattleUnit types.
23.4.2023
Implemented probabilistic action execution and improved testing. There is an annoying warning about a
condition being false in the GUI on line 432 but this is not true as it is very important for the proper
functioning of the code. Bug in intelliJ code analyzer?
Got an extension till 3.5. which really saved the project as I should now be able to really finish everything.
In case I will manage to implement simultaneous turns, I will actually forego all animating still until the
very end where, depending on how the project has turned out and whether it seems necessery or not I may or
may not do some animations.
Further to do: conquest gamemode, health bars as rectangles displayed upon changes in health, possibly
simultaneous turns with ram attacks, meaning that there are no conflicting move sets. Tanks ram over foot
soldiers and snipers. Foot soldiers and snipers engage in hand-to-hand combat with foot soldiers usually
beating snipers. Two tanks ram into each other so that one gets destroyed and the other takes damage.
Successfully destroying a rock produces gravel or something traversible and successfully destroying a
forest or grass leaves dirt.
Gave Player 2 some BattleUnits and made their selection turn based.
25.4.2023
Used the entire day to show probabilities of a succesfull attack on an enemy BattleUnit on the GUI and implemented
a very inefficient calculateAttackProbability method. Development is significantly slower than desired due to me
constantly running into dumb issues, some of which are very complex and actually require a ton of work and others
where having sat for hours staring at the screen simply to change one line a bit make me feel exceptionally stupid.
Next, attack method itself, which should, again on paper, be a lot more straightforward. And to show that something
actually happened, I must add healthbars.
Added responsive healthbars for BattleUnits. Move must be modified to accomodate enemies nearby and enable ramming.
26.4.2023
Implemented attack such that attacking other units causes a duel where the loser takes all the damage. The target
tile or that of the loser's gets degraded such that grass and forest turn to dirt, rock turns into gravel and sand
changes form such that the attributes of attacked tiles change such that they are more or less easily traversible.
The displayed probabilities are those of successfully starting a duel, combining the effects of distance and the
enemy BattleUnit's stats. The actual winner is calculated within the method based on attackProbabilityAgainstBattleUnit.
To show the degradations and destroyed BattleUnits on the map, BattleUnit, TerrainTile and the GUI classes were also
edited. Now I must only implement the conquest game mode and thus the minimum viable product has been created.
After that I still must add the configuration file reader and an artificially intelligent opponent so that the
requirements of the course are fulfilled. Additionally, there is some balancing and tweaking still to be done such
as polishing the GUI (by making it prettier and by adding BattleUnit info to the side panel) and giving experience
and possibly ammo some weight in calculating the probabilities for winning a duel as well as adding the implementation
for defend, that temporarily boosts a BattleUnit's health. Finally, I do still want to add supply chains and simultaneous
turns.
27.4.2023
Implemented defend, which decreases the damage received upon potential loss by a factor of DefendStrength.
Finished the GUI fully and fixed a bug causing action set ticks to sometimes disappear and attack probabilities to linger.
The only coming additions to the GUI are a game over / winner window with a reset button after either player wins and lines
representing the supply chains. Annoyingly, the health bar margins cannot easily be bound to the tile dimensions and
therefore they remain in the lower left corners of the tiles when scaling up the GUI. It doesn't look the worst and is
therefore not worthy of spending a lot of time on right now but I might want to revisit it in the end if I have time.
28.4.2023
Added more BattleUnits and TerrainTiles, refactored both classes and made various changes to the Game class to make the
BattleUnits get along better with different attributes. After sketching out how the supply chains would look like in practice,
I decided to leave them out after all as they would make the GUI overly crowded. Instead, I am going to implement Reload and
Rest (formerly Stay) actions that restore ammo and fuel respectively, forcing the unit to stay still (and undefended?) for one
round.
As a result of the changes, Attack probabilities are a bit harder to explain now. Move probabilities simply signify the
probabilities of being able to move to the given square whereas Attack probabilities try to capture both the probability of
initiating a duel and winning it. If a BattleUnit attacks another, the attack method is always called. It first checks for
obstacles and calculates the probability of succeeding in light of these. If this check is passed, the winner of the duel is
calculated next and finally, the probability for that winner to actually reach / hit the loser is calculated. If all these
conditions are passed, only then does the loser take damage. The issue with this is that now the probability number does not
clearly articulate neither hit probability nor win probability but rather something in between. This, I feel is still more
straightforward for gameplay however.
29.4.2023
Implemented the Conquest game mode, making the game finally fully playable. In order for it to be actually playable in practice,
I must fix the move method such that one can move on top of dead/destroyed BattleUnits to prevent blocking of the conquest area.
The conquest area is shown in the color of the player holding it and once either player has held the objective for ConquestTarget
turns, a popup declares the winner. I wanted to add a reset button to this as well but upon quick research, it seems that it would
require major refactorizations for which I do not have time currently. Also made Tanks brighter, which makes them look plastic and
therefore worse in my opinion but at least they can now be seen.
30.4.2023
Refined the move method so that heavier and more armored units can ram (or engage in hand-to-hand combat with) into lighter units,
killing them instantly upon moving. Made appropriate changes to Game class and the GUI so that tiles with dead units are accessible
for alive units so that the conquest area can no longer be blocked.
There is a very rare chance that sometimes both BattleUnits engaging in a duel take damage or one gets a critical hit, dealing more
damage than usual. This is a bug as I do not understand how it is possible for it to happen but due to lack of time and the additional
interesting gameplay twist in harmony with other mechanics it brings, it is now declared a feature. I also will not be implementing
simultaneous turns because the trivial solution would give a slight advantage to either player and a more sophisticated solution
would require a lot more time.
Added an experience system where successfully dealing damage gains the successfull BattleUnit experience points, which increases their
chance of victory against less experienced BattleUnits. As a result of Action refactorizations and the addition of Reload and replacing
of Stay with Rest, Attacks and moves now require and consume ammo and fuel respectively which must be refilled with Reload and Rest
respectively.
1.5.2023
Resolved a bug where some dead units would disappear from the map as a result of the GUI not being able to recognize which units had
already died and been drawn onto their respective tile. This took approximately a day again. Also added highlighting on ammo and fuel
running low and made the "Play Turn" button set the currently selected action set before executing them. Game config file was added as
a play ground for reading game configuration files but is commented out not to interfere with ConfigurationConstants.
When detailing the above tie and critical hit "bugs" I apparently had, in my sleep-deprived state forgotten that this is indeed intended
behavior as losing a duel is not a successful action. Therefore, a tie occurs when first attack is lost and second is won and a "critical
hit" occurs when both are lost. Everything works as it should.
3.5.2023
Implemented loadConfig that loads the game launch configuration from a custom human-readable file. Within certain constraints, it gives a
very flexible way of creating and storing custom maps and BattleUnit configurations. It takes as a parameter a directory (launch-configuration
folder by default) instead of a file so that any file of any name (as long as it is the only file there) will be attempted to read. If the
file meets all criteria and is successfully read, the game is initialized according to the configuration with the GUI responding to the size
of the map. If any kind of exception is encountered, whether resulting from missing or illegal files or anything else, its message is printed
to standard output and the default configuration is loaded from ConfigurationConstants.
I know it is typically not advisable for a single function to do multiple things but as my custom file type is such that the map and the
player objects can and kind of have to be read in a single swipe through, it makes sense for loadConfig to also create all these objects.
This was my first attempt at genuine test-driven development, first writing a general outline of the function and then writing tests for
the desired behavior in each possible scenario based on various more or less functioning or faulty files in test-launch-configurations.
I must say, it makes sense when writing a single, critical method, whose functionality must be known in every scenario and in that it
certainly helped a lot too. However, for the Game class I only wrote the tests more or less for optics because I felt that they just
slowed me down when trying to do a lot very fast. Thus, I am still searching for the optimal balance between rigorous testing and rabid
development, something that does not come naturally yet.
Additionally, I modified the win condition such that the game is over when either player reaches ConquestTarget or runs out of alive units.
Also did some light refactoring and bug fixing as well as made the GUI scale better with map size and added a method to GameMap class for
printing out the current map in a space separated form, just as in the launch-configuration.
Made selected action default to Move everytime "Set Action Set" is clicked and added radiobutton toggles for making Player 1 and/or Player 2 AI
controlled. The current plan for its implementation is to create a new AIPlayer class that has a dependency to the GUI, which it uses to control
that player's units for which the AIPlayer has been selected. It can be Player 1, Player 2 or both, playing against itself. As its general
strategy it simply aims to fill the ConquestTIles and defend them to the best of its abilities by patrolling around the objective.
Changed highlight colors for more contrast and a better look and created another launch configuration with a different map and BattleUnit
formations. I meant to make it such that absolutely every constant in the game is externally configurable and thus this new configuration
would work in combination with ConquestTarget = 1 in a guard and destroy bases manner, but I don't have time for creating more configuration
files and readers and therefore this will have to be adjusted directly in ConfigurationConstants for now.
4.5.2023
Implemented a very poor AI player that was supposed to cleanly interact only with the GUI and actually have some sort of logical algorithm to
its operations but due to major sleep deprivation caused by soon a week of essentially no more than 3h of sleep a night, it ended up being ugly
spaghetti that, yes, does somehow move some BattleUnits around on the map every now and then and usually resolves a winner too when playing against
itself. In compliance to the criteria, it is certainly better than a player playing at random but it often gets unexplainably stuck in trivial
situations and therefore is not adapted to the complexities of the game systems. If not hallucinations, I think I also witnessed some rare, illegal
jumps but at least it does not break the GUI now nor cause any errors. The "AI" Player can be toggled on or off for either player.
Improved the AIPlayer and made other tiny corrections such as privatizing methods and removing non-necessary print commands as well as deleting
redundant variables such as those in class BattleUnit reserved for supply chains. The AI is now a bit better but for some incomrehensible reason it is
way too polite. This probably has something to do with the conditions before each action set selection but I simply cannot figure out why it happens.
Everything works as expected, except that the AI refuses to move BattleUnits to tiles with dead opponent units on them. It has no problem running over
its own dead companions but it simply refuses to ram to opponents or stand on top of them even if they are dead. This is highly peculiar as this can
easily be done by a human player in every and all situations, even when just temporarily pausing the AI control to do so and there is no such condition
int the AIPlayer class that would dictate this kind of behavior. Therefore the way to win the AI opponent currently is simply to just block it off from
the conquest objective using your BattleUnits' corpses.
5.5.20223
Added the ability to set an action set by pressing enter after selecting targets for both actions. Fixed a bug causing a heap memory error when quitting
the game while the aiPlayerThread is running. Also increased the thread sleep time to make sure only one turn is played at a time. This is very crude and
should be addressed by synchronizing threads and waiting but I unfortunately ran out of time to play around with that.
Edited two comments, refactored checkmark image and deleted the empty SupplyChain class. Added final report pdf. (Course) project done.