/ Cave.java
Cave.java
  1  import java.util.Scanner;
  2  
  3  /// Cave - core executable and embeddable class
  4  ///
  5  /// SPDX-License-Identifier: GPL-3.0-or-later
  6  /// SPDX-FileCopyrightText: 2024 Jonas Smedegaard <dr@jones.dk>
  7  ///
  8  /// Collect treasures in a cave, while avoiding traps and obstacles.
  9  ///
 10  /// Core class,
 11  /// containing states in time and space for a cave -
 12  /// i.e. the rules and progress of the game of exploring a cave.
 13  /// Usable self-contained as an executable loading method main(),
 14  /// as well as embedded in a larger system instantiating Cave().
 15  ///
 16  /// * v0.0.3
 17  ///   * major rewrite and separation into multiple files
 18  /// * v0.0.2
 19  ///   * fix distance calculation
 20  /// * v0.0.1
 21  ///   * initial release, as delivery "assignment 6"
 22  ///
 23  /// @version 0.0.3
 24  /// @see <https://app.radicle.xyz/nodes/ash.radicle.garden/rad:z3YzABgyz2D36LiKe3YcdJ6PcDCXM/tree/README.md>
 25  /// @see <https://moodle.ruc.dk/course/section.php?id=201713>
 26  public class Cave {
 27  
 28  	/// Cave constructor
 29  	///
 30  	/// @param bottom         Lowest corner of cave space as integer array
 31  	/// @param top            Highest corner of cave space as integer array
 32  	/// @param treasures      amount of treasures in cave
 33  	/// @param traps          amount of traps in cave
 34  	/// @param obstacles      amount of obstacles in cave
 35  	/// @param playerPos      placement of player
 36  	/// @param playerHeading  orientation of player
 37  	public Cave(
 38  		final int[] bottom,
 39  		final int[] top,
 40  		final int treasures,
 41  		final int traps,
 42  		final int obstacles,
 43  		final int[] playerPos,
 44  		final Bearing playerHeading
 45  	) {
 46  		roster = new Roster(bottom, top);
 47  		player = new Player(playerHeading);
 48  
 49  		// First place entities with a fixed location,
 50  		// then place randomly entities that must be reachable,
 51  		// and finally place randomly blocking entities.
 52  		// This is to avoid supporting and doing backtracking
 53  		// in case a placement violates constraints
 54  		// and require retrying at alternative position
 55  		roster.add(new Player(playerHeading), playerPos);
 56  		for (int i = 0; i < treasures; i++) {
 57  			roster.add(new Treasure());
 58  		}
 59  		for (int i = 0; i < traps; i++) {
 60  			roster.add(new Trap());
 61  		}
 62  		for (int i = 0; i < obstacles; i++) {
 63  			roster.add(new Obstacle());
 64  		}
 65  	}
 66  
 67  	/// JRE entry point
 68  	///
 69  	/// @param args  command-line arguments (ignored)
 70  	public static void main(final String[] args) {
 71  
 72  		// Instantiation as dictated by assignment
 73  		//
 74  		// Assignment dictates northwest corner being at origo,
 75  		// and game engine uses Euclidian space,
 76  		// which leads to the peculiar negative ordinates
 77  		// (i.e. values along the y-axis)
 78  		final int[] bottom = new int[] {-9, 0};
 79  		final int[] top = new int[] {0, 9};
 80  		final int treasures = 5;
 81  		final int traps = 5;
 82  		final int obstacles = 5;
 83  		final int[] playerPos = new int[] {0, 0};
 84  		final Bearing playerHeading = Bearing.NORTH;
 85  
 86  		// Instantiate cave
 87  		Cave cave = new Cave(
 88  			bottom, top, treasures, traps, obstacles,
 89  			playerPos, playerHeading
 90  		);
 91  
 92  		// main read-eval-print-loop (REPL)
 93  		String lastmsg = "Welcome to the cave!";
 94  		while (true) {
 95  			// clear screen and print last collected message
 96  			Utils.clearConsole();
 97  			System.out.println(lastmsg);
 98  			System.out.println();
 99  
100  			System.out.println(cave.roster.map()
101  				.replace("\\n", System.lineSeparator()));
102  
103  			Scanner scanner = new Scanner(System.in);
104  			System.out.println();
105  			System.out.print(
106  				"Legend: forward f, right r, left l, quit q"
107  			);
108  			System.out.println();
109  			System.out.print("Type a letter and press enter: ");
110  			String input = scanner.next();
111  			while (input.isEmpty()) {
112  				input = scanner.next();
113  			}
114  
115  			switch (input.substring(0, 1)) {
116  			  case "f":
117  //FIXME				cave.roster.move(cave.player);
118  				lastmsg = "ERROR: not yet implemented!";
119  				break;
120  			  case "r":
121  				cave.player.turnRight();
122  				break;
123  			  case "l":
124  				cave.player.turnLeft();
125  				break;
126  			  case "q":
127  				System.out.println();
128  				System.out.printf(
129  					"Thanks for playing. Your score was %06d%n",
130  					cave.roster.getScore()
131  				);
132  				System.exit(0);
133  				break;
134  			  default:
135  			}
136  		}
137  	}
138  
139  	/// Roster for the ground truth of the Cave
140  	private Roster roster;
141  
142  	/// Player
143  	private Player player;
144  }