These are room and thing class: ROOM Constructor Summary Method Summary Add a ne
ID: 3719601 • Letter: T
Question
These are room and thing class:
ROOM
Constructor Summary
Method Summary
Add a new exit to this Room.
Add Thing to this Room.
What Things are in this Room?
A description of the room.
What exits are there from this Room?
Remove item from Room.
Connects two rooms both ways.
Remove an exit from this Room Note: silently fails if exit does not exist.
Change Room description Note: each or in the new description will be replaced with a `*`.
THING
Note: each, , and semi-colon in the parameter will be replaced by *
Method Summary
Get long description of the Thing (possibly with extra info at subclass' discretion)..
Allows subclasses to read the raw longDescription value.
Allows subclasses to read the raw longDescription value.
Get short description of the Thing.
Get a representation of the object suitable for saving.
Change the long description for the Thing.
Change the short description for the Thing.
Need help with this class and methods please:
Constructor Summary (MapIO Class)
MapIO()
Methods:
Write Rooms to a new file (using encoded String form)
Parameters:
root - Start room
filename - Filename to write to
Returns:
true if successful
Detail.:
The structure of a file is:
The number of rooms in the file
Room descriptions
Room exits
Room contents
Rooms are always listed in the same order with the start room first.
Note that this format does not preserver player inventory.
The file format is as follows:
number_of_rooms
description_of_room_0
description_of_room_1
description_of_room_2
... (more descriptions)
number_of_exits_from_room_0
number_0_0 name_0_0
number_0_1 name_0_1
... (more room_0)
number_of_exits_from_room_1
number_1_0 name_1_0
number_1_1 name_1_1
... (more room_1)
number_of_exits_from_room_2
number_2_0 name_2_0
... (more room_2)
... (more rooms)
number_items_in_room_0
repr_for_item_0_0
repr_for_item_0_1
... (more items in room 0)
number_items_in_room_0
repr_for_item_0_0
repr_for_item_0_1
... (more items in room 0)
... (more rooms)
Note: even if a entry would have zero items, it still needs to be there.
As an example:
Room r1=new Room("#1");
Room r2=new Room("#2");
r2.enter(new Critter("frog", "a frog", 1, 5));
r1.enter(new Explorer("doris", "a doris"));
try {
r1.addExit("North", r2);
r2.addExit("South", r1);
} catch (ExitExistsException ee) {
} catch (NullRoomException nr) {
}
MapIO.saveMap(r1, "mymap");
Would produce a file containing:
2
#1
#2
1
1 North
1
0 South
1
E;10;doris;a doris
1
C;1.0;5;frog;a frog
Require:
There is exactly one player object anywhere in the map(appearing exactly once).
Decode a String into a Thing. (Need to be able to decode, Treasure, Critter, Builder and Explorer) <-- create Thing object from String (encoded)
Parameters:
encoded - String to decode
root - start room for the map
Returns:
Decoded Thing or null on failure. (null arguments or incorrectly encoded input)
Read information from a file created with saveMap
Parameters:
filename - Filename to read from
Returns:
null if unsucessful. If successful, an array of two Objects. [0] being the Player object (if found) and [1] being the start room.
Detail.:
Do not add the player to the room they appear in, the caller will be responsible for placing the player in the start room.
Constructor and Description Room(java.lang.String description)Explanation / Answer
Room.java
import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Room implements Serializable {
// Description for this Room
private String description;
// Exits from this Room. Strings are names of the exits
private Map<String, Room> exits;
// Things in this Room
private List<Thing> contents;
private void replaceDescription(String description) {
this.description = description.replace(' ', '*')
.replace(' ', '*');
}
/**
* @param description Description for the room Note: each
* in description will be replaced with a `*`.
*/
public Room(String description) {
replaceDescription(description);
exits = new TreeMap<String, Room>();
contents = new LinkedList<Thing>();
}
/**
* A description of the room.
*
* @return Description
*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
replaceDescription(description);
}
/**
* What exits are there from this Room?
*
* @return Non-modifiable map of names to Rooms
*/
public Map<String, Room> getExits() {
return Collections.unmodifiableMap(this.exits);
}
/**
* What Things are in this Room?
*
* @return Non-modifiable List of Things in the Room
*/
public List<Thing> getContents() {
return Collections.unmodifiableList(this.contents);
}
public void addExit(String name, Room target) throws ExitExistsException,
NullRoomException {
if (exits.containsKey(name)) {
throw new ExitExistsException();
}
if (target == null) {
throw new NullRoomException();
}
exits.put(name, target);
}
/**
* Remove an exit from this Room Note: silently fails if exit does not
* exist.
*
* @param name Name of exit to remove
*/
public void removeExit(String name) {
exits.remove(name);
}
/**
* Add Thing to this Room.
*
* @param item Thing to add
*/
public void enter(Thing item) {
if (!contents.contains(item)) {
contents.add(item);
}
}
public boolean leave(Thing item) {
if (!contents.contains(item)) {
return false;
}
boolean trap = false;
if (item instanceof Mob) {
for (Thing i : contents) {
if ((i instanceof Mob) && (i != item)) {
if (((Mob) i).wantsToFight((Mob) item)) {
trap = true;
break;
}
}
}
}
if (trap) {
return false;
}
contents.remove(item);
return true;
}
public static void makeExitPair(Room room1, Room room2, String label1,
String label2) throws ExitExistsException, NullRoomException {
//if either room1 or room2 is null
if (null == room1 || null == room2)
throw new NullRoomException();
//if either label is null
if (null == label1 || null == label2)
throw new NullPointerException();
//if one or more of the exits are in use
if (room1.getExits().get(label1) != null || room2.getExits().get(label2) != null)
throw new ExitExistsException();
room1.addExit(label1, room2);
room2.addExit(label2, room1);
}
}
Thing.java
import java.io.Serializable;
public abstract class Thing implements Serializable {
/*
* Short name of the Thing. Note: Will be used to identify the Thing in
* commands. Note: This will be saved, so varying information should not
* be stored here.
*/
private String shortDescription;
/*
* More detailed description of the Thing. Note: This will be saved, so
* varying information should not be stored here.
*/
private String longDescription;
public Thing(String shortDescription, String longDescription) {
this.shortDescription=replaceDescription(shortDescription);
this.longDescription=replaceDescription(longDescription);
}
/**
* Allows subclasses to read the raw longDescription value.
*
* @return the raw shortDesc value
*/
protected String getShort() {
return shortDescription;
}
/**
* Allows subclasses to read the raw longDescription value.
*
* @return the raw longDesc value
*/
protected String getLong() {
return longDescription;
}
/*
* Replace characters in description strings
* It is very important that this is private so it will be resolved
* correctly during construction
*/
private String replaceDescription(String description) {
return description.replace(' ', '*')
.replace(';', '*')
.replace(' ', '*');
}
/** Change the short description for the Thing.
* Note: each, , and semi-colon in the parameter
* will be replaced by *
* @param shortDescription A short name or description for the Thing
*/
protected void setShort(String shortDescription) {
this.shortDescription = replaceDescription(shortDescription);
}
/** Change the long description for the Thing.
* Note: each, , and semi-colon in the parameter
* will be replaced by *
* @param longDescription A detailed description for the Thing
*/
protected void setLong(String longDescription) {
this.longDescription = replaceDescription(longDescription);
}
/**
* Get long description of the Thing (possibly with extra info at subclass'
* discretion)..
* <br />Note: not to be used for saving or encoding due
* possible extra info being included.
*
* @return Long description
*/
public String getDescription() {
return longDescription;
}
/**
* Get short description of the Thing.
*
* @return short description Note: This name is used to represent the Thing
* in text and to choose it in dialogs.
*/
public String getShortDescription() {
return shortDescription;
}
/**
* Get a representation of the object suitable for saving.
* @return A single line encoding enough information to identify the type and recreate it.
*/
public abstract String repr();
}
MapIo.java
import java.io.*;
import java.util.*;
public class MapIO {
public static boolean serializeMap(Room root, String filename) {
if (null == root || null == filename || "".equals(filename.trim()))
return false;
ObjectOutputStream os = null;
try {
os = new ObjectOutputStream(new FileOutputStream(filename));
os.writeObject(root);
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != os)
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
public static Room deserializeMap(String filename) {
if (null == filename || "".equals(filename.trim()))
return null;
ObjectInputStream is = null;
Object o = null;
try {
is = new ObjectInputStream(new FileInputStream(filename));
o = is.readObject();
if (null == o || !(o instanceof Room))
return null;
return (Room) o;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is)
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static boolean saveMap(Room root, String filename) {
if (null == root || null == filename || "".equals(filename.trim()))
return false;
Set<Room> visitedRooms = new LinkedHashSet<>();
searh(root, visitedRooms);
Map<Room, Integer> roomIndexes = new HashMap<>();
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
//The number of rooms in the file
bw.write(String.valueOf(visitedRooms.size()));
bw.newLine();
//Room descriptions
int i = 0;
for (Room room: visitedRooms) {
roomIndexes.put(room, i++);
bw.write(room.getDescription());
bw.newLine();
}
//Room exits
for (Room room: visitedRooms) {
Map<String, Room> exits = room.getExits();
bw.write(String.valueOf(exits.size()));
bw.newLine();
for (Map.Entry<String, Room> entry: exits.entrySet()) {
String d = entry.getKey();
Room r = entry.getValue();
bw.write(roomIndexes.get(r) + " " + d);
bw.newLine();
}
}
Player player = null;
//Room contents
int curRoomIndex = 0;
int lastRoomIndex = visitedRooms.size();
for (Room room: visitedRooms) {
curRoomIndex++;
List<Thing> contents = room.getContents();
List<Thing> validContents = new ArrayList<>();
for (Thing item: contents) {
//There is exactly one player object anywhere in the map(appearing exactly once).
if (!(item instanceof Player) || null == player) {
if (item instanceof Player)
player = (Player) item;
validContents.add(item);
}
}
bw.write(String.valueOf(validContents.size()));
bw.newLine();
int curContentIndex = 0;
int lastContentIndex = validContents.size();
for (Thing item: validContents) {
curContentIndex++;
bw.write(item.repr());
if (!(curRoomIndex == lastRoomIndex && curContentIndex == lastContentIndex))
bw.newLine();
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != bw)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
private static void searh(Room room, Set<Room> visitedRooms) {
// return if reach the bound of map or room has visited
if (null == room || visitedRooms.contains(room))
return;
visitedRooms.add(room);
searh(room.getExits().get("North"), visitedRooms);
searh(room.getExits().get("South"), visitedRooms);
searh(room.getExits().get("East"), visitedRooms);
searh(room.getExits().get("West"), visitedRooms);
}
public static Thing decodeThing(String encoded, Room root) {
if (null == root || null == encoded || "".equals(encoded.trim()))
return null;
try {
String type = encoded.split(";")[0];
switch (type) {
case "T":
return Treasure.decode(encoded);
case "C":
return Critter.decode(encoded);
case "B":
return Builder.decode(encoded, root);
case "E":
return Explorer.decode(encoded);
default:
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object[] loadMap(String filename) {
if (null == filename || "".endsWith(filename.trim()))
return null;
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
//The number of rooms in the file
int numberOfRooms = Integer.valueOf(br.readLine());
Room[] rooms = new Room[numberOfRooms];
//Room descriptions
for (int i=0; i<numberOfRooms; i++) {
rooms[i] = new Room(br.readLine());
}
//Room exits
for (int i=0; i<numberOfRooms; i++) {
int numberOfExits = Integer.valueOf(br.readLine());
for (int j = 0; j < numberOfExits; j++) {
String[] exit = br.readLine().split(" ");
int roomIndex = Integer.valueOf(exit[0]);
String direction = exit[1];
rooms[i].addExit(direction, rooms[roomIndex]);
}
}
Player player = null;
//Room contents
for (int i=0; i<numberOfRooms; i++) {
int numberOfItems = Integer.valueOf(br.readLine());
for (int k=0; k<numberOfItems; k++) {
String item = br.readLine();
Thing thing = decodeThing(item, rooms[i]);
/* Do not add the player to the room they appear in,
the caller will be responsible for placing the player in the start room.
*/
if (thing instanceof Player) {
if (null == player)
player = (Player) thing;
} else {
rooms[i].enter(thing);
}
}
}
return new Object[] {player, rooms[0]};
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != br)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.