Computer Science I for majors by James Tam |
(Note: new design principles, e.g., Object-Orientation, as well design/style requirements from previous assignments such as good naming conventions from the semester must be applied in your work).
For this assignment you can make use of the len() function, if so desired, as well as: the methods of the random module, the function to open a file, open(), and the method to close a file, close().
Write a simple a text-based fight simulator (in case you have never seen a "2-man" kombat sequence here is a video). There are two opponents: an attacker (that only launches attacks) and a defender (that can only defend against the attacks). There's four types of attacks categorized by height: extra-low, low, medium and high (JT: to fulfill style requirements you need to use the global constants: EXTRA_LOW = 1, LOW = 2, MED = 3, HIGH = 4 to represent each type of attack [see the 'Globals.py' file]). To use these constants from another file/module you can use the following import: "from Globals import *" (or you can import the constants individually).
Similar to the attacks there are four types of defenses: extra-low, low, medium and high. If the heights of the attack-defense match then the attack is blocked. Otherwise the attack is counted as a 'hit'. When the program is first run the proportion of each type of attacks and defenses will come from file (e.g., high = 50%, medium = 30%, low = 20%, extra low = 0%). Also the number of turns that the simulation will run is read from the first line of the file: [Here is a sample input file: input.txt].
This file contains only one example set of inputs.
100
attacker,50,20,20,10
defender,50,20,30,0
General format:
<number of turns>
attacker,<p(x) extra low>,<p(x) low>,<p(x) medium>,<p(x) high>
defender,<p(x) extra low>,<p(x) low>,<p(x) medium>,<p(x) high>
You can assume that any other version of the input file used by your TA will have the same format and the four probabilities for each of the attacker and defender will sum to 100%. The text in front of the first comma on the second and third line is only a label and need not be used by your program, the program only needs to read in the 4 probabilities. If you cannot get the file input portion working then the values can be read from user input at the console. You won't get the file input marks but you can potentially get marks for the rest of the assignment.
The name of the input file (containing the above information) is typed in by the user at run time. The program will re-prompt the user for the file name (using recursion - no credit using a loop) if the file name is empty. Your program should also use the Python exception handling mechanism to repeatedly prompt the user (a loop is acceptable) for an input file if there are file related problems (e.g. input file name wrong, input file could not be opened, problems occur when reading from the file etc.)
After reading in the probabilities the program will then randomly generate attacks and defense using the appropriate proportions read in from file for the specified number of turns (1-100). If you are unclear of how to write a program that generates some random events based on probabilities of those events then see the lecture and tutorial examples such as the following: [forest fire simulator]. Since the number of turns will be read in file so you can assume that the value will always be an integer value in the range from 1 - 100.
The program will produce a number of statistics and display them during each round and at the end of the simulation. To make marking reasonable (and for you to be awarded credit) here is the information that MUST be generated by your program
Each round: the round number, the type of attack and defense chosen, the result of the attack-defense combination (showing the probabilities for the four types of defenses would be useful if you implement an intelligent defender).
At the end of Kombat: the total number of successful attacks and blocks and the probabilities of each type of attack-defense at the end (the values for the attacker won't change but an intelligent defender's proportions should go from the values read in from file to more closely reflect the proportions of the attacker).
The per turn and end of simulation report should be written to an output file called 'results.txt'. If you cannot get the file output working then you can write the information to the console (onscreen) so you can demonstrate how other features work. You won't, of course, be awarded any credit for file output but may be awarded credit for other features. Here is a sample output file.
The program must be split into multiple modules/files: Attacker, Defender, Manager, FileIO and the Driver. You will also refer to the constants defined in the Globals module. Make sure you not only submit each module individually (don't combine them or you won't get grades for your work). To make things simple for your marker please submit the Globals module (even if you don't modify it) along with the modules that you write yourself.
Driver module:
The starting execution point for the program, contains the start() function. It will instantiate an instance of the Manager class and call the appropriate method or methods to run the simulation. There will likely be very little code in the start function e.g.
def start():
aManager = Manager()
aManager.runSimulation()
Manager class:
It manages or runs the simulation. Tasks include but are not limited to:
getting a FileIO object to read the information from the input file,
running the simulation for the specified number of turns (main program loop),
during each turn getting the attacker to attack and the defender to generate a defense,
determine the result of the attack-defense and generate the appropriate per-turn report,
at the end of the simulation the manager will generate the appropriate end-of-simulation report and write the per- turn and end-of-simulation report to file.
Each task will be implemented as one or more methods. This class will likely be one of the larger ones for this simulation. However, the code for this module (like the other modules) must still conform to good style conventions you have been taught during the term e.g. the principles of good design for functions applies to methods: implement one well defined task and not exceed one screen length, do not use global variables (constants are okay) except for debugging flags etc. To fulfill style requirements this class should consist of at least 3 methods (including the constructor).
The minimum attributes for this class should include:
a FileIO object,
an Attacker object,
a Defender object
FileIO class:
This class is responsible for all file input and output (getting the input file name from the user - multiple times if necessary, reading the number of turns and probabilities from file and writing the turn-by-turn and end of simulation report to 'results.txt'. To fulfill style requirements this class should consist of at least 4 methods (including the constructor).
Attacker class:
This class is responsible for generating an attack based on the probabilities read in from file. The minimum attributes for this class should include (you will likely have many more):
the probability of extra-low attacks occurring,
the probability of low attacks occurring,
the probability of medium attacks occurring,
the probability of high attacks occurring,
a tally of the number of extra-low attacks that occurred during the simulation,
a tally of the number of low attacks that occurred during the simulation,
a tally of the number of medium attacks that occurred during the simulation,
a tally of the number of high attacks that occurred during the simulation.
To fulfill style requirements this class should consist of at least 2 methods (including the constructor).
Defender class:
This class is responsible for generating a defense based on the probabilities read in from file. The minimum attributes for this class should include (you will likely have many more):
the probability of extra-low defenses occurring,
the probability of low defenses occurring,
the probability of medium defenses occurring,
the probability of high defenses occurring,
a tally of the number of extra-low defenses that occurred during the simulation,
a tally of the number of low defenses that occurred during the simulation,
a tally of the number of medium defenses that occurred during the simulation,
a tally of the number of high defenses that occurred during the simulation.
To fulfill style requirements the basic Defender should consist of at least 2 methods (including the constructor). The intelligent Defender should consist of at least 3 methods.
Intelligent defender (Bonus feature: may allow students a grade point higher than 4.0 up to a maximum of 4.3. Conversely implementing all features except for this one but with no style & documentation issues may allow for a maximum grade point of 4.0)
The default non-intelligent defender will only generate defense purely based on the probabilities read from file. A program that implements an 'intelligent' defender will analyze the pattern of attacks for ten turns and adjust the probability of each type of defense being employed from turn eleven onward. (For example if the attacker always throws high attacks then the defender will eventually extrapolate the pattern and use high defenses more frequently).
In order to 'prime' the simulation the defender will generate defenses based on the probabilities read in from file for the first ten turns of the simulation. From turn eleven onwards, defender adjusts to the pattern of attacks. Because an intelligent defender will run as a regular defender for the first 10 turns there is no need to explicitly implement the non-intelligent defender if you choose to implement an intelligent one.
Exactly what constitutes 'intelligent' for this assignment? Because this isn't a formal class in Artificial Intelligence the definition is fairly broad: as long the program demonstrates the ability to somehow adapt to the pattern of attackers and the marker can clearly see the pattern as the program executes (the display of statistics each round will be very useful for communicating this). If for instance the attacker throws only medium attacks, after the learning period is over the defender should eventually employ only medium height defenses (or at least have an extremely high probability of employing this type of defense).
You can either come up with your own algorithm for the defender or you can freely research algorithms online. In the latter case make sure you clearly cite all your sources. (Failing to list a source may be regarded as academic misconduct).
As in the case with the rest of your program it is imperative that you have an output for an intelligent defender that matches the results show in my files. This will allow your marker to quickly see the defender adapt after turn 10.
D2L configuration:
Points to keep in mind: