import random import pickle import sys class Logical(): # The Logical class is used to allow the value of a Boolean variable to be returned from a subroutine. def __init__(self): self.Is = False class GameData(): # Creates object with accessible TrapPositions, MonsterPosition, PlayerPosition, FlaskPosition and MonsterAwake properties def __init__(self): self.Trap1Position = CellReference() self.Trap2Position = CellReference() self.MonsterPosition = CellReference() self.PlayerPosition = CellReference() self.FlaskPosition = CellReference() self.MonsterAwake = Logical() class CellReference: def __init__(self): self.NoOfCellsEast = 0 self.NoOfCellsSouth = 0 class Item: def __init__(self): self._NoOfCellsEast = 0 self._NoOfCellsSouth = 0 def CheckIfSameCell(self, Position): if (self._NoOfCellsEast == Position.NoOfCellsEast) and (self._NoOfCellsSouth == Position.NoOfCellsSouth): return True else: return False def GetPosition(self): Position = CellReference() Position.NoOfCellsEast = self._NoOfCellsEast Position.NoOfCellsSouth = self._NoOfCellsSouth return Position def SetPosition(self, Position): self._NoOfCellsEast = Position.NoOfCellsEast self._NoOfCellsSouth = Position.NoOfCellsSouth class Character(Item): def __init__(self): Item.__init__(self) def MakeMove(self, Direction): if Direction == 'N': self._NoOfCellsSouth = self._NoOfCellsSouth - 1 elif Direction == 'S': self._NoOfCellsSouth = self._NoOfCellsSouth + 1 elif Direction == 'W': self._NoOfCellsEast = self._NoOfCellsEast - 1 elif Direction == 'E': self._NoOfCellsEast = self._NoOfCellsEast + 1 class Enemy(Item): def __init__(self): Item.__init__(self) self.__Awake = False def ChangeSleepStatus(self): self.__Awake = not self.__Awake def GetAwake(self): return self.__Awake def SetAwake(self, Awake): self.__Awake = Awake def MakeMove(self, PlayerPosition): if self._NoOfCellsSouth < PlayerPosition.NoOfCellsSouth: self._NoOfCellsSouth = self._NoOfCellsSouth + 1 elif self._NoOfCellsSouth > PlayerPosition.NoOfCellsSouth: self._NoOfCellsSouth = self._NoOfCellsSouth - 1 elif self._NoOfCellsEast < PlayerPosition.NoOfCellsEast: self._NoOfCellsEast = self._NoOfCellsEast + 1 else: self._NoOfCellsEast = self._NoOfCellsEast - 1 class Trap(Item): def __init__(self): Item.__init__(self) self.__Triggered = False def GetTriggered(self): return self.__Triggered def ToggleTrap(self): self.__Triggered = not self.__Triggered class Grid: def __init__(self, NS, WE): self.__NSDistance = NS self.__WEDistance = WE self.__CavernState = [] for Count1 in range(self.__NSDistance + 1): __BlankRow = [] for Count2 in range(self.__WEDistance + 1): __BlankRow.append(' ') self.__CavernState.append(__BlankRow) def Display(self, MonsterAwake): print(" ------------- ") for Count1 in range(self.__NSDistance + 1): for Count2 in range(self.__WEDistance + 1): if (self.__CavernState[Count1][Count2] == ' ') or (self.__CavernState[Count1][Count2] == '*') or ((self.__CavernState[Count1][Count2] == 'M') and MonsterAwake): print('|' + self.__CavernState[Count1][Count2], end='') else: print('| ', end='') print('|') print(" ------------- ") print() def PlaceItem(self, Position, Item): self.__CavernState[Position.NoOfCellsSouth][Position.NoOfCellsEast] = Item def IsCellEmpty(self, Position): if Position.NoOfCellsEast < 0 or Position.NoOfCellsEast > Game.WE: print("Error") if Position.NoOfCellsSouth < 0 or Position.NoOfCellsSouth > Game.NS: print("Error") if self.__CavernState[Position.NoOfCellsSouth][Position.NoOfCellsEast] == ' ': return True else: return False def Reset(self): for Count1 in range(self.__NSDistance + 1): for Count2 in range(self.__WEDistance + 1): self.__CavernState[Count1][Count2] = ' ' class Game: NS = 4 WE = 6 def __init__(self, IsATrainingGame, LoadGame): self.__Player = Character() self.__Cavern = Grid(Game.NS, Game.WE) self.__Monster = Enemy() self.__Flask = Item() self.__Trap1 = Trap() self.__Trap2 = Trap() self.__TrainingGame = IsATrainingGame self.__LoadGame = LoadGame random.seed() self.SetUpGame() self.Play() def Play(self): Eaten = False FlaskFound = False MoveDirection = ' ' Position = CellReference() self.__Cavern.Display(self.__Monster.GetAwake()) while not Eaten and not FlaskFound and (MoveDirection != 'M'): ValidMove = False while not ValidMove: self.DisplayMoveOptions() MoveDirection = self.GetMove() ValidMove = self.CheckValidMove(MoveDirection) if MoveDirection != 'M': self.__Cavern.PlaceItem(self.__Player.GetPosition(), ' ') self.__Player.MakeMove(MoveDirection) self.__Cavern.PlaceItem(self.__Player.GetPosition(), '*') self.__Cavern.Display(self.__Monster.GetAwake()) FlaskFound = self.__Player.CheckIfSameCell(self.__Flask.GetPosition()) if FlaskFound: self.DisplayWonGameMessage() Eaten = self.__Monster.CheckIfSameCell(self.__Player.GetPosition()) # This selection structure checks to see if the player has triggered one of the traps in the cavern if not self.__Monster.GetAwake() and not FlaskFound and not Eaten and (self.__Player.CheckIfSameCell(self.__Trap1.GetPosition()) and not self.__Trap1.GetTriggered() or self.__Player.CheckIfSameCell(self.__Trap2.GetPosition()) and not self.__Trap2.GetTriggered()): self.__Monster.ChangeSleepStatus() self.DisplayTrapMessage() self.__Cavern.Display(self.__Monster.GetAwake()) if (self.__Monster.GetAwake()) and not Eaten and not FlaskFound: Count = 0 while Count != 2 and not Eaten: self.__Cavern.PlaceItem(self.__Monster.GetPosition(), ' ') Position = self.__Monster.GetPosition() self.__Monster.MakeMove(self.__Player.GetPosition()) self.__Cavern.PlaceItem(self.__Monster.GetPosition(), 'M') if self.__Monster.CheckIfSameCell(self.__Flask.GetPosition()): self.__Flask.SetPosition(Position) self.__Cavern.PlaceItem(Position, 'F') Eaten = self.__Monster.CheckIfSameCell(self.__Player.GetPosition()) print() print('Press Enter key to continue') input() self.__Cavern.Display(self.__Monster.GetAwake()) Count = Count + 1 if Eaten: self.DisplayLostGameMessage() def Save(self): CurrentGameData = GameData() CurrentGameData.Trap1Position = self.__Trap1.GetPosition() CurrentGameData.Trap2Position = self.__Trap2.GetPosition() CurrentGameData.MonsterPosition = self.__Monster.GetPosition() CurrentGameData.PlayerPosition = self.__Player.GetPosition() CurrentGameData.FlaskPosition = self.__Flask.GetPosition() CurrentGameData.MonsterAwake = self.__Monster.GetAwake() Filename = input('Enter new file name: ') print('') CurrentFile = open(Filename,'wb') pickle.dump(CurrentGameData, CurrentFile) CurrentFile.close() def Load(self): Filename = input('Enter the name of the file to load: ') print('') LoadedGameFile = open(Filename,'rb') LoadedGameData = pickle.load(LoadedGameFile) LoadedGameFile.close() self.__Trap1.SetPosition(LoadedGameData.Trap1Position) self.__Trap2.SetPosition(LoadedGameData.Trap2Position) self.__Monster.SetPosition(LoadedGameData.MonsterPosition) self.__Flask.SetPosition(LoadedGameData.FlaskPosition) self.__Player.SetPosition(LoadedGameData.PlayerPosition) self.__Monster.SetAwake(LoadedGameData.MonsterAwake) def DisplayMoveOptions(self): print() print("Enter N to move NORTH") print("Enter S to move SOUTH") print("Enter E to move EAST") print("Enter W to move WEST") print("Enter M to return to the Main Menu") print() def GetMove(self): Move = input() print() if Move != "": return Move[0] else: return "" def DisplayWonGameMessage(self): print("Well done! You have found the flask containing the Styxian potion.") print("You have won the game of MONSTER!") print() def DisplayTrapMessage(self): print("Oh no! You have set off a trap. Watch out, the monster is now awake!") print() def DisplayLostGameMessage(self): print("ARGHHHHHHH! The monster has eaten you. GAME OVER.") print("Maybe you will have better luck next time you play MONSTER!") print() def CheckValidMove(self, Direction): ValidMove = True Position = self.__Player.GetPosition() if not(Direction in ['N', 'S', 'W', 'E', 'M']): print("Please enter a valid character") ValidMove = False if ((Direction == 'N' and Position.NoOfCellsSouth == 0) or (Direction == 'S' and Position.NoOfCellsSouth == self.NS) or (Direction == 'W' and Position.NoOfCellsEast == 0) or (Direction == 'E' and Position.NoOfCellsEast == self.WE)): print("You have moved off the grid. Please enter a valid direction.") ValidMove = False return ValidMove def SetPositionOfItem(self, Item): Position = self.GetNewRandomPosition() while not self.__Cavern.IsCellEmpty(Position): Position = self.GetNewRandomPosition() self.__Cavern.PlaceItem(Position, Item) return Position def SetUpGame(self): Position = CellReference() self.__Cavern.Reset() if not self.__TrainingGame: if self.__LoadGame: self.Load() self.__Cavern.PlaceItem(self.__Trap1.GetPosition(), 'T') self.__Cavern.PlaceItem(self.__Trap2.GetPosition(), 'T') self.__Cavern.PlaceItem(self.__Monster.GetPosition(), 'M') self.__Cavern.PlaceItem(self.__Flask.GetPosition(), 'F') self.__Cavern.PlaceItem(self.__Player.GetPosition(), '*') else: Position.NoOfCellsEast = 0 Position.NoOfCellsSouth = 0 self.__Player.SetPosition(Position) self.__Cavern.PlaceItem(Position, '*') self.__Trap1.SetPosition(self.SetPositionOfItem('T')) self.__Trap2.SetPosition(self.SetPositionOfItem('T')) self.__Monster.SetPosition(self.SetPositionOfItem('M')) self.__Flask.SetPosition(self.SetPositionOfItem('F')) else: Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 2 self.__Player.SetPosition(Position) self.__Cavern.PlaceItem(Position, '*') Position.NoOfCellsEast = 6 Position.NoOfCellsSouth = 2 self.__Trap1.SetPosition(Position) self.__Cavern.PlaceItem(Position, 'T') Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 3 self.__Trap2.SetPosition(Position) self.__Cavern.PlaceItem(Position, 'T') Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 0 self.__Monster.SetPosition(Position) self.__Cavern.PlaceItem(Position, 'M') Position.NoOfCellsEast = 3 Position.NoOfCellsSouth = 1 self.__Flask.SetPosition(Position) self.__Cavern.PlaceItem(Position, 'F') def GetNewRandomPosition(self): Position = CellReference() while (Position.NoOfCellsSouth == 0) and (Position.NoOfCellsEast == 0): Position.NoOfCellsSouth = random.randint(0, Game.NS) Position.NoOfCellsEast = random.randint(0, Game.WE) return Position def DisplayMenu(): print("MAIN MENU") print() print("1. Start new game") print("2. Load game") print("3. Save game") print("4. Play training game") print("9. Quit") print() print("Please enter your choice: ", end='') def GetMainMenuChoice(): Choice = int(input()) print() return Choice if __name__ == "__main__": Choice = 0 while Choice != 9: DisplayMenu() Choice = GetMainMenuChoice() if Choice == 1: MyGame = Game(False, False) elif Choice == 2: MyGame = Game(False, True) elif Choice == 3: MyGame.Save() elif Choice == 4: MyGame = Game(True, False)