Imports System.IO Imports System.Runtime.Serialization.Formatters.Binary Module MonsterOOP Sub Main() Dim MyGame As Game Dim GameExited As Boolean = False Console.WriteLine("================OBJECT ORIENTED VERSION==========") Dim Choice As Integer = 0 While Choice <> 9 DisplayMenu(GameExited) Choice = GetMainMenuChoice() Select Case Choice Case 1 MyGame = New Game(False) MyGame.SetUpGame() GameExited = MyGame.Play() Case 2 MyGame = New Game(True) MyGame.SetUpGame() GameExited = MyGame.Play() Case 3 If Not GameExited Then Console.WriteLine("There is no game to save") Else MyGame.Save() End If Case 4 MyGame = New Game(False) MyGame.Load() GameExited = MyGame.Play() Case 5 If Not GameExited Then Console.WriteLine("There is no game to continue") Else GameExited = MyGame.Play() End If End Select End While End Sub Public Sub DisplayMenu(GameExited As Boolean) Console.WriteLine("MAIN MENU") Console.WriteLine() Console.WriteLine("1. Start new game") Console.WriteLine("2. Play training game") If GameExited Then Console.WriteLine("3. Save game") End If Console.WriteLine("4. Load game") If GameExited Then Console.WriteLine("5. Continue game") End If Console.WriteLine("9. Quit") Console.WriteLine() Console.Write("Please enter your choice: ") End Sub Public Function GetMainMenuChoice() As Integer Dim Choice As Integer Choice = CInt(Console.ReadLine()) Console.WriteLine() Return Choice End Function Structure CellReference Dim NoOfCellsEast As Integer Dim NoOfCellsSouth As Integer End Structure Class Game 'Original NS=4, WE=6 Const NS As Integer = 6 Const WE As Integer = 8 Const TRAPCOUNT As Integer = 4 'Only used for new games Const TELEPORTINGTRAPCOUNT As Integer = 4 'Only used for new games Const MONSTERMOVECOUNT As Integer = 2 Structure GameData Dim TrapPositions() As CellReference Dim TeleportingTrapPositions() As CellReference Dim MonsterPosition As CellReference Dim PlayerPosition As CellReference Dim FlaskPosition As CellReference Dim PitPosition As CellReference Dim MonsterAwake As Boolean End Structure Private Player As New Character Private Cavern As New Grid(NS, WE) Private Monster As New Enemy(MONSTERMOVECOUNT) Private Flask As New Item Private Traps() As Trap Private TeleportingTraps() As Trap Private Pit As New Item Private TrainingGame As Boolean Public Sub New(ByVal IsATrainingGame As Boolean) TrainingGame = IsATrainingGame Randomize() End Sub Public Function Play() As Boolean Dim Count As Integer Dim Eaten As Boolean Dim FlaskFound As Boolean Dim MoveDirection As Char Dim ValidMove As Boolean Dim Position As CellReference Dim TrapTriggered As Boolean Dim PlayerHitPit As Boolean Dim MonsterHitPit As Boolean Dim ShotDirection As Char Dim ValidShot As Boolean Eaten = False FlaskFound = False Cavern.Display(Monster.GetAwake) Do Do DisplayMoveOptions() MoveDirection = GetMove() ValidMove = CheckValidMove(MoveDirection) Loop Until ValidMove If MoveDirection <> "M" Then Cavern.PlaceItem(Player.GetPosition, " ") If MoveDirection = "T" Then Player.SetPosition(SetPositionOfItem("*")) Else Player.MakeMove(MoveDirection) End If Cavern.PlaceItem(Player.GetPosition, "*") Cavern.Display(Monster.GetAwake) FlaskFound = Player.CheckIfSameCell(Flask.GetPosition) If FlaskFound Then DisplayWonGameMessage() End If Eaten = Monster.CheckIfSameCell(Player.GetPosition) PlayerHitPit = Player.CheckIfSameCell(Pit.GetPosition) MonsterHitPit = Monster.CheckIfSameCell(Pit.GetPosition) 'This selection structure checks to see if the player has triggered one of the traps in the cavern If Not Monster.GetAwake And Not FlaskFound And Not Eaten And Not PlayerHitPit And Not MonsterHitPit Then TrapTriggered = False For i = 0 To Traps.Count - 1 If Player.CheckIfSameCell(Traps(i).GetPosition) And Not Traps(i).GetTriggered Then TrapTriggered = True End If Next If TrapTriggered Then Monster.ChangeSleepStatus() DisplayTrapMessage() Cavern.Display(Monster.GetAwake) Else For i = 0 To TeleportingTraps.Count - 1 If Player.CheckIfSameCell(TeleportingTraps(i).GetPosition) And Not TeleportingTraps(i).GetTriggered Then TrapTriggered = True End If Next If TrapTriggered Then Monster.ChangeSleepStatus() DisplayTeleportingTrapMessage() Cavern.PlaceItem(Player.GetPosition, " ") Player.SetPosition(SetPositionOfItem("*")) Cavern.PlaceItem(Player.GetPosition, "*") Cavern.Display(Monster.GetAwake) End If End If End If If Monster.GetAwake And Not Eaten And Not FlaskFound And Not PlayerHitPit And Not MonsterHitPit Then 'before the monster gets its go, offer the player a chance to shoot it Do DisplayShotOptions() ShotDirection = GetShotDirection() ValidShot = CheckValidShot(ShotDirection) Loop Until ValidShot If ShotDirection <> "I" And Monster.CheckIfIsShot(Player.GetPosition, ShotDirection) Then DisplayShotMonsterMessage() Else If ShotDirection <> "I" Then DisplayMissedMonsterMessage() End If Count = 0 Do Cavern.PlaceItem(Monster.GetPosition, " ") Position = Monster.GetPosition Monster.MakeMove(Player.GetPosition) Cavern.PlaceItem(Monster.GetPosition, "M") If Monster.CheckIfSameCell(Flask.GetPosition) Then Flask.SetPosition(Position) Cavern.PlaceItem(Position, "F") End If Eaten = Monster.CheckIfSameCell(Player.GetPosition) MonsterHitPit = Monster.CheckIfSameCell(Pit.GetPosition) Console.WriteLine() Console.WriteLine("Press Enter key to continue") Console.ReadLine() Cavern.Display(Monster.GetAwake) Count = Count + 1 Loop Until Count = Monster.GetMoveCount() Or Eaten Or MonsterHitPit End If End If If Eaten Then DisplayEatenMessage() ElseIf PlayerHitPit Then DisplayPlayerHitPitMessage() ElseIf MonsterHitPit Then DisplayMonsterHitPitMessage() End If End If Loop Until Eaten Or FlaskFound Or PlayerHitPit Or MonsterHitPit Or MoveDirection = "M" If MoveDirection = "M" Then Return True Else Return False End If End Function Public Sub DisplayMoveOptions() Console.WriteLine() Console.WriteLine("Enter N to move NORTH") Console.WriteLine("Enter S to move SOUTH") Console.WriteLine("Enter E to move EAST") Console.WriteLine("Enter W to move WEST") Console.WriteLine("Enter T to teleport") Console.WriteLine("Enter M to return to the Main Menu") Console.WriteLine() End Sub Public Function GetMove() As Char Dim Move As Char Move = Console.ReadLine Console.WriteLine() Return Move End Function Public Sub DisplayWonGameMessage() Console.WriteLine("Well done! You have found the flask containing the Styxian potion.") Console.WriteLine("You have won the game of MONSTER!") Console.WriteLine() End Sub Public Sub DisplayTrapMessage() Console.WriteLine("On no! You have set off a trap. Watch out, the monster is now awake!") Console.WriteLine() End Sub Public Sub DisplayTeleportingTrapMessage() Console.WriteLine("On no! You have set off a teleporting trap. You have been teleported but watch out, the monster is now awake!") Console.WriteLine() End Sub Public Sub DisplayEatenMessage() DisplayLostGameMessage("The monster has eaten you") End Sub Public Sub DisplayPlayerHitPitMessage() DisplayLostGameMessage("The monster hit the Pit of Doom") End Sub Public Sub DisplayMonsterHitPitMessage() DisplayLostGameMessage("You hit the Pit of Doom") End Sub Public Sub DisplayLostGameMessage(PartMessage As String) Console.WriteLine($"ARGHHHHHH! {PartMessage}. GAMEOVER.") Console.WriteLine("Maybe you will have better luck next time you play MONSTER! ") Console.WriteLine() End Sub Public Sub DisplayShotMonsterMessage() Console.WriteLine("You hit the monster! Have another turn while it recovers.") Console.WriteLine() End Sub Public Sub DisplayMissedMonsterMessage() Console.WriteLine("You missed the monster! Better luck next time.") Console.WriteLine() End Sub Public Function CheckValidMove(ByVal Direction As Char) As Boolean Dim ValidMove As Boolean ValidMove = True If Not (Direction = "N" Or Direction = "S" Or Direction = "W" Or Direction = "E" Or Direction = "M" Or Direction = "T") Then Console.WriteLine("Please enter a valid command") ValidMove = False End If If (Direction = "N" And Player.GetPosition().NoOfCellsSouth = 0) Or (Direction = "S" And Player.GetPosition().NoOfCellsSouth = NS) Or (Direction = "W" And Player.GetPosition().NoOfCellsEast = 0) Or (Direction = "E" And Player.GetPosition().NoOfCellsEast = WE) Then Console.WriteLine("You have moved off the grid. Please enter a valid direction") ValidMove = False End If Return ValidMove End Function Public Function SetPositionOfItem(ByVal Item As Char) As CellReference Dim Position As CellReference Do Position = GetNewRandomPosition() Loop Until Cavern.IsCellEmpty(Position) Cavern.PlaceItem(Position, Item) Return Position End Function Public Sub SetUpGame() Dim Position As CellReference Cavern.Reset() If Not TrainingGame Then ReDim Traps(TRAPCOUNT - 1) ReDim TeleportingTraps(TELEPORTINGTRAPCOUNT - 1) Position.NoOfCellsEast = 0 Position.NoOfCellsSouth = 0 Player.SetPosition(Position) Cavern.PlaceItem(Position, "*") For i = 0 To TRAPCOUNT - 1 Traps(i) = New Trap Traps(i).SetPosition(SetPositionOfItem("T")) Next For i = 0 To TELEPORTINGTRAPCOUNT - 1 TeleportingTraps(i) = New Trap TeleportingTraps(i).SetPosition(SetPositionOfItem("B")) Next Monster.SetPosition(SetPositionOfItem("M")) Flask.SetPosition(SetPositionOfItem("F")) Pit.SetPosition(SetPositionOfItem("P")) Else 'Create 2 traps for the training game ReDim Traps(1) Traps(0) = New Trap Traps(1) = New Trap ReDim TeleportingTraps(1) TeleportingTraps(0) = New Trap TeleportingTraps(1) = New Trap Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 2 Player.SetPosition(Position) Cavern.PlaceItem(Position, "*") Position.NoOfCellsEast = 6 Position.NoOfCellsSouth = 2 Traps(0).SetPosition(Position) Cavern.PlaceItem(Position, "T") Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 3 Traps(1).SetPosition(Position) Cavern.PlaceItem(Position, "T") Position.NoOfCellsEast = 5 Position.NoOfCellsSouth = 4 TeleportingTraps(0).SetPosition(Position) Cavern.PlaceItem(Position, "B") Position.NoOfCellsEast = 1 Position.NoOfCellsSouth = 2 TeleportingTraps(1).SetPosition(Position) Cavern.PlaceItem(Position, "B") Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 0 Monster.SetPosition(Position) Cavern.PlaceItem(Position, "M") Position.NoOfCellsEast = 3 Position.NoOfCellsSouth = 1 Flask.SetPosition(Position) Cavern.PlaceItem(Position, "F") Position.NoOfCellsEast = 4 Position.NoOfCellsSouth = 4 Pit.SetPosition(Position) Cavern.PlaceItem(Position, "P") End If End Sub Public Function GetNewRandomPosition() As CellReference Dim Position As CellReference Do Position.NoOfCellsSouth = Int(Rnd() * (NS + 1)) Position.NoOfCellsEast = Int(Rnd() * (WE + 1)) Loop Until Position.NoOfCellsSouth > 0 Or Position.NoOfCellsEast > 0 Return Position End Function Public Sub Load() Dim Filename As String Dim LoadedGameData As GameData Console.Write("Enter the name of the file to load: ") Filename = Console.ReadLine Console.WriteLine() FileOpen(1, Filename, OpenMode.Binary, OpenAccess.Read) FileGet(1, LoadedGameData) FileClose(1) Cavern.Reset() 'manage traps ReDim Traps(LoadedGameData.TrapPositions.Count - 1) For i = 0 To LoadedGameData.TrapPositions.Count - 1 Traps(i) = New Trap Traps(i).SetPosition(LoadedGameData.TrapPositions(i)) Cavern.PlaceItem(Traps(i).GetPosition(), "T") Next ReDim TeleportingTraps(LoadedGameData.TeleportingTrapPositions.Count - 1) For i = 0 To LoadedGameData.TeleportingTrapPositions.Count - 1 TeleportingTraps(i) = New Trap TeleportingTraps(i).SetPosition(LoadedGameData.TeleportingTrapPositions(i)) Cavern.PlaceItem(TeleportingTraps(i).GetPosition(), "B") Next Monster.SetPosition(LoadedGameData.MonsterPosition) Player.SetPosition(LoadedGameData.PlayerPosition) Flask.SetPosition(LoadedGameData.FlaskPosition) Pit.SetPosition(LoadedGameData.PitPosition) Monster.SetAwake(LoadedGameData.MonsterAwake) Cavern.PlaceItem(Monster.GetPosition(), "M") Cavern.PlaceItem(Flask.GetPosition(), "F") Cavern.PlaceItem(Pit.GetPosition(), "P") Cavern.PlaceItem(Player.GetPosition(), "*") End Sub Public Sub Save() Dim Filename As String Dim CurrentGameData As GameData ReDim CurrentGameData.TrapPositions(Traps.Count - 1) For i = 0 To Traps.Count - 1 CurrentGameData.TrapPositions(i) = Traps(i).GetPosition() Next ReDim CurrentGameData.TeleportingTrapPositions(TeleportingTraps.Count - 1) For i = 0 To TeleportingTraps.Count - 1 CurrentGameData.TeleportingTrapPositions(i) = TeleportingTraps(i).GetPosition() Next CurrentGameData.MonsterPosition = Monster.GetPosition() CurrentGameData.PlayerPosition = Player.GetPosition() CurrentGameData.FlaskPosition = Flask.GetPosition() CurrentGameData.PitPosition = Pit.GetPosition() CurrentGameData.MonsterAwake = Monster.GetAwake() Console.Write("Enter new file name: ") Filename = Console.ReadLine Console.WriteLine() FileOpen(1, Filename, OpenMode.Binary, OpenAccess.Write) FilePut(1, CurrentGameData) FileClose(1) End Sub Public Sub DisplayShotOptions() Console.WriteLine() Console.WriteLine("You may take a shot at the monster") Console.WriteLine("Enter N to shoot NORTH") Console.WriteLine("Enter S to shoot SOUTH") Console.WriteLine("Enter E to shoot EAST") Console.WriteLine("Enter W to shoot WEST") Console.WriteLine("Enter I to Ignore") Console.WriteLine() End Sub Public Function GetShotDirection() As Char Dim Shot As Char Shot = Console.ReadLine Console.WriteLine() Return Shot End Function Public Function CheckValidShot(ByVal Shot As Char) As Boolean Dim ValidShot As Boolean = True If Not (Shot = "N" Or Shot = "S" Or Shot = "W" Or Shot = "E" Or Shot = "I") Then Console.WriteLine("Please enter a valid direction or I to Ignore") ValidShot = False End If Return ValidShot End Function End Class Class Grid Private NS As Integer Private WE As Integer Private CavernState(,) As Char Public Sub New(ByVal S As Integer, ByVal E As Integer) NS = S WE = E ReDim CavernState(NS, WE) End Sub Public Sub Reset() Dim Count1 As Integer Dim Count2 As Integer For Count1 = 0 To NS For Count2 = 0 To WE CavernState(Count1, Count2) = " " Next Next End Sub Public Sub Display(ByVal MonsterAwake As Boolean) Dim Count1 As Integer Dim Count2 As Integer For Count1 = 0 To NS Console.Write(" ") For Count2 = 1 To WE * 2 + 1 Console.Write("-") Next Console.WriteLine(" ") For Count2 = 0 To WE If CavernState(Count1, Count2) = " " Or CavernState(Count1, Count2) = "*" Or (CavernState(Count1, Count2) = "M" And MonsterAwake) Then Console.Write("|" & CavernState(Count1, Count2)) Else Console.Write("| ") End If Next Console.WriteLine("|") Next Console.Write(" ") For Count2 = 1 To WE * 2 + 1 Console.Write("-") Next Console.WriteLine(" ") Console.WriteLine() End Sub Public Sub PlaceItem(ByVal Position As CellReference, ByVal Item As Char) CavernState(Position.NoOfCellsSouth, Position.NoOfCellsEast) = Item End Sub Public Function IsCellEmpty(ByVal Position As CellReference) As Boolean If CavernState(Position.NoOfCellsSouth, Position.NoOfCellsEast) = " " Then Return True Else Return False End If End Function End Class Class Enemy Inherits Item Private Awake As Boolean Private MoveCount As Integer Public Overridable Sub MakeMove(ByVal PlayerPosition As CellReference) If NoOfCellsSouth < PlayerPosition.NoOfCellsSouth Then NoOfCellsSouth = NoOfCellsSouth + 1 ElseIf NoOfCellsSouth > PlayerPosition.NoOfCellsSouth Then NoOfCellsSouth = NoOfCellsSouth - 1 ElseIf NoOfCellsEast < PlayerPosition.NoOfCellsEast Then NoOfCellsEast = NoOfCellsEast + 1 Else NoOfCellsEast = NoOfCellsEast - 1 End If End Sub Public Function GetAwake() As Boolean Return Awake End Function Public Sub SetAwake(IsAwake As Boolean) Awake = IsAwake End Sub Public Overridable Sub ChangeSleepStatus() If Awake Then Awake = False Else Awake = True End If End Sub Public Function GetMoveCount() As Integer GetMoveCount = MoveCount End Function Public Sub SetMoveCount(Moves As Integer) MoveCount = Moves End Sub Public Sub New(Moves As Integer) Awake = False MoveCount = Moves End Sub Public Function CheckIfIsShot(ByVal Position As CellReference, ByVal ToDirection As Char) If ((ToDirection = "S" And NoOfCellsEast = Position.NoOfCellsEast And NoOfCellsSouth > Position.NoOfCellsSouth) Or (ToDirection = "N" And NoOfCellsEast = Position.NoOfCellsEast And NoOfCellsSouth < Position.NoOfCellsSouth) Or (ToDirection = "E" And NoOfCellsSouth = Position.NoOfCellsSouth And NoOfCellsEast > Position.NoOfCellsEast) Or (ToDirection = "W" And NoOfCellsSouth = Position.NoOfCellsSouth And NoOfCellsEast < Position.NoOfCellsEast)) Then Return True Else Return False End If End Function End Class Class Character Inherits Item Public Sub MakeMove(ByVal Direction As Char) Select Case Direction Case "N" NoOfCellsSouth = NoOfCellsSouth - 1 Case "S" NoOfCellsSouth = NoOfCellsSouth + 1 Case "W" NoOfCellsEast = NoOfCellsEast - 1 Case "E" NoOfCellsEast = NoOfCellsEast + 1 End Select End Sub End Class Class Trap Inherits Item Private Triggered As Boolean Public Function GetTriggered() As Boolean Return Triggered End Function Public Sub New() Triggered = False End Sub Public Sub ToggleTrap() Triggered = Not Triggered End Sub End Class Class Item Protected NoOfCellsEast As Integer Protected NoOfCellsSouth As Integer Public Function GetPosition() As CellReference Dim Position As CellReference Position.NoOfCellsEast = NoOfCellsEast Position.NoOfCellsSouth = NoOfCellsSouth Return Position End Function Public Sub SetPosition(ByVal Position As CellReference) NoOfCellsEast = Position.NoOfCellsEast NoOfCellsSouth = Position.NoOfCellsSouth End Sub Public Function CheckIfSameCell(ByVal Position As CellReference) As Boolean If NoOfCellsEast = Position.NoOfCellsEast And NoOfCellsSouth = Position.NoOfCellsSouth Then Return True Else Return False End If End Function End Class End Module