"""Robot Strategy === CSC148 Winter 2021 === Department of Mathematical and Computational Sciences, University of Toronto Mississauga === Module Description === This code is an example of object-oriented design that utilizes both inheritance and composition. """ import random class Strategy: """ A Strategy class === Attributes === name: the name of the strategy attack_probability: the probability (%) of attacking, int between 0 and 100 defense_probability: the probability (%) of attacking, int between 0 and 100 (the probability of hold is calculated as (100 - attack - defense)) === Representation Invariants === - 0 <= self.attack_probability + self.defense_probability <= 100 """ # Attribute types name: str attack_probability: int defense_probability: int def __init__(self, name: str) -> None: self.name = name self.attack_probability = 0 self.defense_probability = 0 # TODO: complete the Strategy class. Think about the following: # - What methods should this class have? Look carefully at how this class is # used by the Robot class # - If this class will be a base class, which methods' implementation should # be in the base class and which ones should be the subclasses? # TODO: add all the necessary subclasses of Strategy. Think about # - What class are needed? Read carefull how these classes are used in the Robot # class. # - To make your design optimal, any implementation that's shared by the # subclasses should be written only once in the base class and inherited. Each # subclass should only do what's special about itself. class Robot: """ A Robot class === Attributes === name: the name of the robot strategy: the current strategy that is adopted by the robot """ # Attribute types name: str # TODO: what other attributes does a robot have? def __init__(self, name: str) -> None: """ Create a robot with a name and a default strategy of NormalStrategy """ self.name = name # TODO: initialize any other attributes def set_strategy(self, strategy: Strategy) -> None: """ Set the current strategy to """ print("Setting strategy to {} ...".format(strategy.get_name())) # TODO: complete this def move(self) -> None: """ Make a move by printing a string """ next_move = "wrong move" # TODO: fix this line print("{} made a move to {}!".format(self.name, next_move)) if __name__ == "__main__": robot = Robot("Cocomelon") # The following 10 moves should be performed with the normal strategy # A normal strategy means 33% attack, 33% defense, and 34% hold for _ in range(10): robot.move() robot.set_strategy(AggressiveStrategy()) # The following 10 moves should be performed with the aggressive strategy # An aggressive strategy means 100% attack for _ in range(10): robot.move() robot.set_strategy(DefensiveStrategy()) # The following 10 moves should be performed with the aggressive strategy # A defensive strategy means 100% defense for _ in range(10): robot.move() # Below is an example printout """ Cocomelon made a move to DEFENSE! Cocomelon made a move to HOLD! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to HOLD! Cocomelon made a move to HOLD! Cocomelon made a move to ATTACK! Cocomelon made a move to DEFENSE! Setting strategy to aggressive ... Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Cocomelon made a move to ATTACK! Setting strategy to defensive ... Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! Cocomelon made a move to DEFENSE! """