I need some help with this programming assignment. it’s just 2 questions.
I use blueJ for this.
training/Main.ctxt
#BlueJ class context
comment0.target=Main
comment0.text=\r\n\r\n
comment1.params=
comment1.target=Main()
comment1.text=Default\ constructor.
comment2.params=e
comment2.target=void\ componentResized(java.awt.event.ComponentEvent)
comment3.params=event
comment3.target=void\ actionPerformed(java.awt.event.ActionEvent)
comment3.text=\r\n\ Default\ action\ listener.\r\n\ \r\n\ @param\ event\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ action\ event.\r\n
comment4.params=args
comment4.target=void\ main(java.lang.String[])
comment4.text=\r\n\ The\ main\ method\ for\ the\ program.\r\n\ \r\n\ @param\ args\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ command\ line\ arguments.\r\n
numComments=5
training/Game.ctxt
#BlueJ class context
comment0.target=Game
comment0.text=\r\n\r\n
comment1.params=
comment1.target=Game()
comment1.text=\r\n\ Create\ the\ game\ and\ initialize\ its\ internal\ map.\r\n
comment2.params=
comment2.target=void\ play()
comment2.text=\r\n\ Main\ play\ routine.\ Loops\ until\ end\ of\ play.\r\n
comment3.params=
comment3.target=void\ printLocationInformation()
comment3.text=\r\nPrintsoutthecurrentlocationandexits.\r\n
comment4.params=command
comment4.target=boolean\ processCommand(Command)
comment4.text=\r\n\ Given\ a\ command,\ process\ (that\ is\:\ execute)\ the\ command.\r\n\ \r\n\ @param\ command\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ command\ to\ be\ processed.\r\n\ @return\ true\ If\ the\ command\ ends\ the\ game,\ false\ otherwise.\r\n
comment5.params=command
comment5.target=void\ goRoom(Command)
comment5.text=\r\n\ Try\ to\ go\ to\ one\ direction.\ If\ there\ is\ an\ exit,\ enter\ the\ new\ room,\r\n\ otherwise\ print\ an\ error\ message.\r\n\ \r\n\ @param\ command\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ command\ to\ be\ processed.\r\n
comment6.params=
comment6.target=void\ printGoodbye()
comment6.text=\r\n\ Print\ out\ the\ closing\ message\ for\ the\ player.\r\n
comment7.params=
comment7.target=void\ printHelp()
comment7.text=\r\n\ Print\ out\ some\ help\ information.\ Here\ we\ print\ some\ stupid,\ cryptic\r\n\ message\ and\ a\ list\ of\ the\ command\ words.\r\n
comment8.params=
comment8.target=void\ printWelcome()
comment8.text=\r\n\ Print\ out\ the\ opening\ message\ for\ the\ player.\r\n
comment9.params=command
comment9.target=boolean\ quit(Command)
comment9.text=\r\n\ “Quit”\ wasI\ entered.\ Check\ the\ rest\ of\ the\ command\ to\ see\ whether\ we\r\n\ really\ quit\ the\ game.\r\n\r\n\ @param\ command\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ command\ to\ be\ processed.\r\n\ @return\ true,\ if\ this\ command\ quits\ the\ game,\ false\ otherwise.\r\n
numComments=10
training/Player.ctxt
#BlueJ class context
comment0.target=Player
comment0.text=\r\n
comment1.params=currentRoom
comment1.target=Player(Room)
comment1.text=\ A\ constructor\ for\ the\ player\ class.\r\n\ @param\ currentRoom\ for\ the\ room\ field.\r\n
comment2.params=
comment2.target=Room\ getRoom()
comment2.text=\ Accossor\ for\ getting\ the\ room.\r\n\ @return\ for\ getting\ the\ current\ room\ that\ the\ player\ is\ in.\r\n
comment3.params=newRoom
comment3.target=void\ setRoom(Room)
comment3.text=\ Mutator\ for\ setting\ the\ current\ room.\r\n@param\ newRoom\ for\ setting\ the\ current\ room.\r\n
numComments=4
training/Room.java
training/Room.java
/**
*/
public
class
Room
{
/** Counter for the total number of rooms created in the world. */
private
static
int
counter
;
/** The name of this room. Room names should be unique. */
private
String
name
;
/** The description of this room. */
private
String
description
;
/** This room’s north exit, null if none exits. */
private
Door
northExit
;
/** This room’s south exit, null if none exits. */
private
Door
southExit
;
/** This room’s east exit, null if none exits. */
private
Door
eastExit
;
/** This room’s west exit, null if none exits. */
private
Door
westExit
;
/** Static initializer. */
static
{
counter
=
0
;
}
/**
* Create a room described “description”. Initially, it has no exits.
* “description” is something like “a kitchen” or “an open court yard”.
*
*
@param
name The room’s name.
*
@param
description
* The room’s description.
*/
public
Room
(
String
name
,
String
description
)
{
this
.
name
=
name
;
this
.
description
=
description
;
counter
++
;
}
/**
* Returns the name of this room.
*
*
@return
The name of this room.
*/
public
String
getName
()
{
return
name
;
}
/**
* Returns the description of this room.
*
*
@return
The description of this room.
*/
public
String
getDescription
()
{
return
description
;
}
/** Accessor for geting the northExit.
*
@return
getNorthExit for getting that direction.
*/
public
Door
getNorthExit
(){
return
northExit
;
}
/** Accessor for geting the southExit.
*
@return
getSouthExit for getting that direction.
*/
public
Door
getSouthExit
(){
return
southExit
;
}
/** Accessor for geting the eastExit.
*
@return
getEastExit for getting that direction.
*/
public
Door
getEastExit
(){
return
eastExit
;
}
/** Accessor for geting the westExit.
*
@return
getWestExit for getting that direction.
*/
public
Door
getWestExit
(){
return
westExit
;
}
/** Mutator for setting the northExit.
*
@param
newNorthExit for setting that direction.
*/
public
void
setNorthExit
(
Door
newNorthExit
){
northExit
=
newNorthExit
;
}
/** Mutator for setting the southExit.
*
@param
newSouthExit for setting that direction.
*/
public
void
setSouthExit
(
Door
newSouthExit
){
southExit
=
newSouthExit
;
}
/** Mutator for setting the eastExit.
*
@param
newEastExit for setting that direction.
*/
public
void
setEastExit
(
Door
newEastExit
){
eastExit
=
newEastExit
;
}
/** Mutator for setting the westExit.
*
@param
newWestExit for setting that direction.
*/
public
void
setWestExit
(
Door
newWestExit
){
westExit
=
newWestExit
;
}
/**
* Returns the number of rooms that have been created in the world.
*
@return
The number of rooms that have been created in the world.
*/
public
static
int
getCounter
()
{
return
counter
;
}
/**
* Returns a string description including all the details of a Room .
* For example ,
*Outside :
*You are outside in the center of the King’s College campus .
*Exits : north east south west
*
*
@return
A string representing all the details of a Room .
*/
public
String
toString
(){
String
roomInformation
=
“”
;
roomInformation
=
getName
()
+
” ”
+
getDescription
();
boolean
memo
=
false
;
if
((
getNorthExit
()
!=
null
)
&&
(
getSouthExit
()
!=
null
)
&&
(
getEastExit
()
!=
null
)
&&
(
getWestExit
()
!=
null
)){
memo
=
true
;
// roomInformation = getNorthExit();
//roomInformation = getName() + ” ” + getDescription() + getNorthExit() + getSouthExit() + getEastExit() + getWestExit() ;
}
return
roomInformation
;
}
}
training/Door.java
training/Door.java
/**
*/
public
class
Door
{
/** The room that this door leads to. */
private
Room
destination
;
/** Whether this door is locked. */
private
boolean
locked
;
/**
* Constructor for the Door class.
*
@param
destination The room this door leads to
*/
public
Door
(
Room
destination
)
{
this
.
destination
=
destination
;
this
.
locked
=
false
;
}
/**
* A getter for the room this door leads to.
*
@return
The room this door leads to
*/
public
Room
getDestination
()
{
return
destination
;
}
/**
* A getter for whether this door is locked.
*
@return
Whether this door is locked
*/
public
boolean
isLocked
()
{
return
locked
;
}
/**
* A setter for whether this door is locked.
*
@param
locked Whether this door is locked.
*/
public
void
setLocked
(
boolean
locked
)
{
this
.
locked
=
locked
;
}
}
training/CommandWords.ctxt
#BlueJ class context
comment0.target=CommandWords
comment0.text=\r\n\r\n
comment1.params=aString
comment1.target=boolean\ isCommand(java.lang.String)
comment1.text=\r\n\ Check\ whether\ a\ given\ String\ is\ a\ valid\ command\ word.\r\n\ \r\n\ @param\ aString\ The\ string\ to\ determine\ whether\ it\ is\ a\ valid\ command.\r\n\ @return\ true\ if\ a\ given\ string\ is\ a\ valid\ command,\ false\ if\ it\ isn’t.\r\n
numComments=2
training/Reader.class
public synchronized class Reader {
private static java.util.Scanner reader;
public void Reader();
public static Command getCommand();
public static String getResponse();
public static String getResponseKeepCase();
static void
}
training/World.java
training/World.java
import
java
.
util
.
HashMap
;
/**
*/
public
class
World
{
/** The rooms in the world. */
private
HashMap
<
String
,
Room
>
rooms
;
/**
* Constructor for the world.
*/
public
World
()
{
rooms
=
new
HashMap
<
String
,
Room
>
();
createRooms
();
}
/**
* This method takes care of creating all of the aspects of the world for
* the “Campus of Kings” application.
*
*
@param
name
* The provided name of the room.
*
@return
The room associated with the provided name
*/
public
Room
getRoom
(
String
name
)
{
return
rooms
.
get
(
name
.
toLowerCase
());
}
/////////////////////////////////////////////////////////////////////////////////////
// Start of private helper methods
/**
* Helper method for recreating a Room. Ensure that the room is created and
* installed in to the collection of Rooms
*
*
@param
theRoom
* The room to add to the world.
*/
private
void
addRoom
(
Room
theRoom
)
{
rooms
.
put
(
theRoom
.
getName
().
toLowerCase
(),
theRoom
);
}
/**
* Helper method for creating doors between rooms.
*
*
@param
from
* The room where the door originates.
*
@param
north
* The room to the north of the originating room.
*/
private
void
createNorthDoor
(
Room
from
,
Room
north
)
{
Door
northDoor
=
new
Door
(
north
);
from
.
setNorthExit
(
northDoor
);
}
/**
* Helper method for creating doors between rooms.
*
*
@param
from
* The room where the door originates.
*
@param
east
* The room to the east of the originating room.
*/
private
void
createEastDoor
(
Room
from
,
Room
east
)
{
Door
eastDoor
=
new
Door
(
east
);
from
.
setSouthExit
(
eastDoor
);
}
/**
* Helper method for creating doors between rooms.
*
*
@param
from
* The room where the door originates.
*
@param
south
* The room to the south of the originating room.
*/
private
void
createSouthDoor
(
Room
from
,
Room
south
)
{
Door
southDoor
=
new
Door
(
south
);
from
.
setSouthExit
(
southDoor
);
}
/**
* Helper method for creating doors between rooms.
*
*
@param
from
* The room where the door originates.
*
@param
west
* The room to the west of the originating room.
*/
private
void
createWestDoor
(
Room
from
,
Room
west
)
{
Door
westDoor
=
new
Door
(
west
);
from
.
setWestExit
(
westDoor
);
}
/**
* This method creates all of the individual places in this world and all
* the doors connecting them.
*/
private
void
createRooms
()
{
// Creating all the rooms.
Room
outside
=
new
Room
(
“Outside”
,
“outside in the center of the King’s College campus.”
);
Room
holyCross
=
new
Room
(
“Holy Cross”
,
“at one of two main dormitories on campus.”
);
Room
essef
=
new
Room
(
“Essef”
,
“at the other main dormitory on campus.”
);
Room
campusCenter
=
new
Room
(
“Campus Center”
,
“in the center of student activities on campus.”
);
Room
admin
=
new
Room
(
“Admin”
,
“in the oldest building on campus and home to the computer science department.”
);
Room
jumpOffice
=
new
Room
(
“Jump’s Office”
,
“in Dr Jump’s office.”
);
Room
hoggOffice
=
new
Room
(
“Hogg’s Office”
,
“in Dr Hogg’s office.”
);
Room
lab
=
new
Room
(
“Computer Lab”
,
“in the Computer Science and Math computing lab.”
);
Room
classroom
=
new
Room
(
“Classroom”
,
“in the classroom where the computer science classes are taught.”
);
// Adding all the rooms to the world.
this
.
addRoom
(
outside
);
this
.
addRoom
(
holyCross
);
this
.
addRoom
(
essef
);
this
.
addRoom
(
campusCenter
);
this
.
addRoom
(
admin
);
this
.
addRoom
(
jumpOffice
);
this
.
addRoom
(
hoggOffice
);
this
.
addRoom
(
lab
);
this
.
addRoom
(
classroom
);
// Creating all the doors between the rooms.
this
.
createSouthDoor
(
essef
,
outside
);
this
.
createNorthDoor
(
outside
,
essef
);
this
.
createEastDoor
(
campusCenter
,
outside
);
this
.
createWestDoor
(
outside
,
campusCenter
);
this
.
createEastDoor
(
outside
,
holyCross
);
this
.
createWestDoor
(
holyCross
,
outside
);
this
.
createSouthDoor
(
outside
,
admin
);
this
.
createNorthDoor
(
admin
,
outside
);
this
.
createEastDoor
(
admin
,
lab
);
this
.
createWestDoor
(
lab
,
admin
);
this
.
createSouthDoor
(
admin
,
hoggOffice
);
this
.
createNorthDoor
(
hoggOffice
,
admin
);
this
.
createWestDoor
(
admin
,
jumpOffice
);
this
.
createEastDoor
(
jumpOffice
,
admin
);
this
.
createSouthDoor
(
lab
,
classroom
);
this
.
createNorthDoor
(
classroom
,
lab
);
}
}
training/Game.class
public synchronized class Game {
private World world;
private int turns;
private int score;
private Character character;
private Player playerClass;
public void Game();
public void play();
private void printLocationInformation();
private boolean processCommand(Command);
private void goRoom(Command);
private void printGoodbye();
private void printHelp();
private void printWelcome();
private boolean quit(Command);
}
training/Writer.java
training/Writer.java
import
java
.
awt
.
Color
;
import
java
.
io
.
BufferedWriter
;
import
java
.
io
.
File
;
import
java
.
io
.
FileNotFoundException
;
import
java
.
io
.
FileWriter
;
import
java
.
io
.
IOException
;
import
java
.
util
.
Scanner
;
import
javax
.
swing
.
JFileChooser
;
import
javax
.
swing
.
JTextPane
;
import
javax
.
swing
.
text
.
BadLocationException
;
import
javax
.
swing
.
text
.
Document
;
import
javax
.
swing
.
text
.
SimpleAttributeSet
;
import
javax
.
swing
.
text
.
StyleConstants
;
/**
*/
public
class
Writer
{
/** System new line character. */
private
static
final
String
NEW_LINE
;
/** Name of the default log. */
private
static
final
String
DEFAULT_LOG
;
/** The text area that we will be writing to. */
private
static
JTextPane
textArea
;
/** Static block. */
static
{
NEW_LINE
=
System
.
getProperty
(
“line.separator”
);
DEFAULT_LOG
=
“defaultlog.txt”
;
textArea
=
null
;
restartLog
();
}
/**
* Mutator for the text component.
*
*
@param
text
* The text component.
*/
public
static
void
setTextArea
(
JTextPane
text
)
{
textArea
=
text
;
textArea
.
setEditable
(
false
);
}
/**
* Print the user input in blue.
*
*
@param
input
* The text entered by the user.
*/
public
static
void
printInput
(
String
input
)
{
SimpleAttributeSet
attributes
=
new
SimpleAttributeSet
();
StyleConstants
.
setForeground
(
attributes
,
Color
.
BLUE
);
printWithAttributes
(
attributes
,
input
+
NEW_LINE
);
}
/**
* Prints an empty line.
*/
public
static
void
println
()
{
standardPrint
(
NEW_LINE
);
}
/**
* Prints out a single integer to a line.
*
*
@param
toPrint
* The integer to print.
*/
public
static
void
println
(
int
toPrint
)
{
String
text
=
“”
+
toPrint
+
NEW_LINE
;
standardPrint
(
text
);
}
/**
* Prints out a single integer.
*
*
@param
toPrint
* The integer to print.
*/
public
static
void
print
(
int
toPrint
)
{
String
text
=
“”
+
toPrint
;
standardPrint
(
text
);
}
/**
* Prints out a double to a line.
*
*
@param
toPrint
* The double to print.
*/
public
static
void
println
(
double
toPrint
)
{
String
text
=
“”
+
toPrint
+
NEW_LINE
;
standardPrint
(
text
);
}
/**
* Prints out a double.
*
*
@param
toPrint
* The double to print.
*/
public
static
void
print
(
double
toPrint
)
{
String
text
=
“”
+
toPrint
;
standardPrint
(
text
);
}
/**
* Prints out an object to a line.
*
*
@param
toPrint
* The object to print.
*/
public
static
void
println
(
Object
toPrint
)
{
String
text
=
“”
+
toPrint
+
NEW_LINE
;
standardPrint
(
text
);
}
/**
* Prints out a object.
*
*
@param
toPrint
* The object to print.
*/
public
static
void
print
(
Object
toPrint
)
{
String
text
=
“”
+
toPrint
;
standardPrint
(
text
);
}
/**
* Prints a string after word-wrapping it to 80 characters if possible. Note
* that this fails to calculate correct widths if the string contains tabs.
* Ends with a line return.
*
*
@param
toPrint
* The String to print.
*/
public
static
void
println
(
String
toPrint
)
{
String
text
=
toPrint
+
NEW_LINE
;
standardPrint
(
text
);
}
/**
* Prints a string after word-wrapping it to 80 characters if possible. Note
* that this fails to calculate correct widths if the string contains tabs.
*
*
@param
toPrint
* The String to print.
*/
public
static
void
print
(
String
toPrint
)
{
standardPrint
(
toPrint
);
}
/**
* Helper method for standard printing.
*
*
@param
toPrint
* The String to print.
*/
private
static
void
standardPrint
(
String
toPrint
)
{
SimpleAttributeSet
attributes
=
new
SimpleAttributeSet
();
printWithAttributes
(
attributes
,
toPrint
);
}
/**
* Helper method printing with attributes.
*
*
@param
attributes
* A set of attributes to use when printing.
*
@param
toPrint
* The String to print.
*
@throws
IllegalStateException
* If the text area has not been set and we are trying to print
* to it.
*/
private
static
void
printWithAttributes
(
SimpleAttributeSet
attributes
,
String
toPrint
)
throws
IllegalStateException
{
if
(
textArea
==
null
)
{
throw
new
IllegalStateException
(
“Need to set the text area before printing to it.”
);
}
try
{
Document
document
=
textArea
.
getDocument
();
document
.
insertString
(
document
.
getLength
(),
toPrint
,
attributes
);
textArea
.
setCaretPosition
(
document
.
getLength
());
BufferedWriter
log
=
new
BufferedWriter
(
new
FileWriter
(
DEFAULT_LOG
,
true
));
log
.
write
(
toPrint
);
log
.
close
();
}
catch
(
BadLocationException
ex
)
{
System
.
err
.
println
(
“ERROR: Should never get this [”
+
toPrint
+
“]”
);
System
.
exit
(
2
);
}
catch
(
IOException
ex
)
{
System
.
err
.
println
(
“ERROR printing to default log (see instructor for help)”
);
System
.
exit
(
1
);
}
}
/**
* Restart the default log.
*/
public
static
void
restartLog
()
{
try
{
BufferedWriter
log
=
new
BufferedWriter
(
new
FileWriter
(
DEFAULT_LOG
,
false
));
log
.
close
();
}
catch
(
IOException
ex
)
{
System
.
err
.
println
(
“ERROR resetting the default log (see instructor for help)”
);
System
.
exit
(
1
);
}
}
/**
* Copy the default log.
*/
public
static
void
copyDefaultLog
()
{
Scanner
input
=
null
;
BufferedWriter
output
=
null
;
try
{
JFileChooser
chooser
=
new
JFileChooser
();
chooser
.
setCurrentDirectory
(
new
File
(
“.”
));
int
result
=
chooser
.
showOpenDialog
(
null
);
if
(
result
==
JFileChooser
.
APPROVE_OPTION
)
{
input
=
new
Scanner
(
new
File
(
DEFAULT_LOG
));
output
=
new
BufferedWriter
(
new
FileWriter
(
chooser
.
getSelectedFile
(),
false
));
while
(
input
.
hasNextLine
())
{
String
line
=
input
.
nextLine
();
output
.
write
(
line
+
NEW_LINE
);
}
output
.
close
();
input
.
close
();
}
}
catch
(
FileNotFoundException
exception
)
{
System
.
err
.
println
(
“ERROR: default log file cannot be found”
);
System
.
exit
(
3
);
}
catch
(
IOException
exception
)
{
System
.
err
.
println
(
“ERROR: file for copy cannot be written to”
);
System
.
exit
(
4
);
}
}
}
training/Main$1.class
synchronized class Main$1 extends java.awt.event.ComponentAdapter {
void Main$1(Main);
public void componentResized(java.awt.event.ComponentEvent);
}
training/CommandWords.class
public synchronized class CommandWords {
private static String[] validCommands;
public void CommandWords();
public static boolean isCommand(String);
static void
}
training/Command.java
training/Command.java
import
java
.
util
.
ArrayList
;
/**
*/
public
class
Command
{
/** The command word for this command. */
private
String
commandWord
;
/** The rest of the line with all the spaces removed. */
private
ArrayList
<
String
>
restOfLine
;
/**
* Create a command object. First is supplied. The second word is assumed
* to be null.
*
*
@param
firstWord
* The first word of the command. Null if the command was not
* recognized.
*/
public
Command
(
String
firstWord
)
{
commandWord
=
firstWord
;
restOfLine
=
new
ArrayList
<
String
>
();
}
/**
* Create a command object. First and second word must be supplied, but
* either one (or both) can be null.
*
*
@param
firstWord
* The first word of the command. Null if the command was not
* recognized.
*
@param
rest
* The rest of the command.
*/
public
Command
(
String
firstWord
,
ArrayList
<
String
>
rest
)
{
commandWord
=
firstWord
;
restOfLine
=
rest
;
}
/**
* Return the command word (the first word) of this command. If the command
* was not understood, the result is null.
*
*
@return
The command word.
*/
public
String
getCommandWord
()
{
return
commandWord
;
}
/**
* Returns if this command was not understood.
*
*
@return
true if this command was not understood.
*/
public
boolean
isUnknown
()
{
return
(
commandWord
==
null
);
}
/**
* Returns if this command has a second word.
*
*
@return
true if the command has a second word.
*/
public
boolean
hasSecondWord
()
{
return
restOfLine
!=
null
;
}
/**
* Returns if this command has more words.
*
*
@param
index The index of the word needed.
*
@return
true if the command has a word at given index.
*/
public
boolean
hasWord
(
int
index
)
{
return
index
>=
0
&&
index
<
restOfLine
.
size
();
}
/**
* Returns the word at the requested index in the command.
*
*
@param
index
* The index of word in the command that is being requested.
*
*
@return
A particular word in the command. Returns null if there is no
* word corresponding to that requested index.
*
*/
public
String
getWord
(
int
index
)
{
String
result
=
null
;
if
(
index
>=
0
&&
index
<
restOfLine
.
size
())
{
result
=
restOfLine
.
get
(
index
);
}
return
result
;
}
/**
* Returns the second word of this command, if it exists.
*
*
@return
The second word of this command. Returns null if there was no
* second word.
*/
public
String
getRestOfLine
()
{
StringBuffer
buffer
=
null
;
if
(
restOfLine
.
size
()
!=
0
)
{
for
(
String
word
:
restOfLine
)
{
if
(
buffer
==
null
)
{
buffer
=
new
StringBuffer
();
buffer
.
append
(
word
);
}
else
{
buffer
.
append
(
" "
);
buffer
.
append
(
word
);
}
}
}
String
result
=
""
;
if
(
buffer
!=
null
)
{
result
+=
buffer
.
toString
();
}
return
result
;
}
}
training/Command.class
public synchronized class Command {
private String commandWord;
private java.util.ArrayList restOfLine;
public void Command(String);
public void Command(String, java.util.ArrayList);
public String getCommandWord();
public boolean isUnknown();
public boolean hasSecondWord();
public boolean hasWord(int);
public String getWord(int);
public String getRestOfLine();
}
training/Room.class
public synchronized class Room {
private static int counter;
private String name;
private String description;
private Door northExit;
private Door southExit;
private Door eastExit;
private Door westExit;
public void Room(String, String);
public String getName();
public String getDescription();
public Door getNorthExit();
public Door getSouthExit();
public Door getEastExit();
public Door getWestExit();
public void setNorthExit(Door);
public void setSouthExit(Door);
public void setEastExit(Door);
public void setWestExit(Door);
public static int getCounter();
public String toString();
static void
}
training/defaultlog.txt
Welcome to the Campus of Kings!
Campus of Kings is a new, incredibly boring adventure game.
Type ‘help’ if you need help.
Outside:
You are outside in the center of the King’s College campus.
Exits: north east south west
> go west
Campus Center:
You are in the center of student activities on campus.
Exits: north east south west
>
training/Reader.java
training/Reader.java
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Scanner
;
/**
*/
public
class
Reader
{
/** The source of command input. */
private
static
Scanner
reader
;
/**
* Create a parser to read from the terminal window.
*/
static
{
reader
=
new
Scanner
(
System
.
in
);
}
/**
* Returns the next command from the user.
*
@return
The next command from the user.
*/
public
static
Command
getCommand
()
{
String
inputLine
;
// will hold the full input line
String
word1
=
null
;
ArrayList
<
String
>
restOfLine
=
null
;
Writer
.
print
(
“> ”
);
// print prompt
inputLine
=
reader
.
nextLine
().
toLowerCase
();
Writer
.
printInput
(
inputLine
);
// Find up to two words on the line.
Scanner
tokenizer
=
new
Scanner
(
inputLine
);
if
(
tokenizer
.
hasNext
())
{
word1
=
tokenizer
.
next
();
// get first word
if
(
tokenizer
.
hasNext
())
{
restOfLine
=
new
ArrayList
<
String
>
();
while
(
tokenizer
.
hasNext
())
{
restOfLine
.
add
(
tokenizer
.
next
());
}
}
}
tokenizer
.
close
();
// Now check whether this word is known. If so, create a command
// with it. If not, create a “null” command (for unknown command).
Command
result
=
null
;
if
(
CommandWords
.
isCommand
(
word1
))
{
result
=
new
Command
(
word1
,
restOfLine
);
}
else
{
result
=
new
Command
(
null
,
restOfLine
);
}
return
result
;
}
/**
* Return the response to a question in all lower case.
*
*
@return
The response typed in by the user.
*/
public
static
String
getResponse
()
{
return
getResponseKeepCase
().
toLowerCase
();
}
/**
* Return the response to a question in the case used by the player.
*
*
@return
The response typed in by the user.
*/
public
static
String
getResponseKeepCase
()
{
String
response
=
reader
.
nextLine
().
trim
();
Writer
.
printInput
(
response
);
return
response
;
}
}
training/team.defs
#Sat Feb 03 11:17:26 EST 2018
bluej.teamsettings.groupname=
bluej.teamsettings.git.repositoryPrefix=/kings-cs/CS117-S18-AlyousifMustafa.git
bluej.teamsettings.git.protocol=https
bluej.teamsettings.user=mustafa77a
bluej.teamsettings.git.server=github.com
bluej.teamsettings.yourEmail=mustafaalyousif@kings.edu
bluej.teamsettings.ignore8=\\.DS_Store
bluej.teamsettings.vcs=git
bluej.teamsettings.ignore7=.*\\\#backup
bluej.teamsettings.yourName=Mustafa
bluej.teamsettings.ignore6=.*\\\#
bluej.teamsettings.ignore5=.*\\~
bluej.teamsettings.ignore4=.*\\.ctxt
bluej.teamsettings.ignore3=team\\.defs
bluej.teamsettings.ignore2=bluej\\.pkh
bluej.teamsettings.ignore1=.*\\.class
training/README.md
Project: CampusOfKings-bad
Authors: Maria Jump
This project is a simple framework for an text adventure game. In this version,
it has a few rooms and the ability for a player to walk between these rooms.
That’s all.
This version of the game contains some very bad class design. It should NOT
be used as a basis for extending the project without fixing these design
problems. It serves as an example to discuss good and bad design.
We will fix the problems with this project through the next couple of labs which
walk students through fixing bad design decisions and give them an opportunity
to become familiar with the existing code.
training/World.ctxt
#BlueJ class context
comment0.target=World
comment0.text=\r\n\r\n
comment1.params=
comment1.target=World()
comment1.text=\r\n\ Constructor\ for\ the\ world.\r\n
comment2.params=name
comment2.target=Room\ getRoom(java.lang.String)
comment2.text=\r\n\ This\ method\ takes\ care\ of\ creating\ all\ of\ the\ aspects\ of\ the\ world\ for\r\n\ the\ “Campus\ of\ Kings”\ application.\r\n\ \r\n\ @param\ name\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ provided\ name\ of\ the\ room.\r\n\ @return\ The\ room\ associated\ with\ the\ provided\ name\r\n
comment3.params=theRoom
comment3.target=void\ addRoom(Room)
comment3.text=\r\n\ Helper\ method\ for\ recreating\ a\ Room.\ Ensure\ that\ the\ room\ is\ created\ and\r\n\ installed\ in\ to\ the\ collection\ of\ Rooms\r\n\ \r\n\ @param\ theRoom\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ to\ add\ to\ the\ world.\r\n
comment4.params=from\ north
comment4.target=void\ createNorthDoor(Room,\ Room)
comment4.text=\r\n\ Helper\ method\ for\ creating\ doors\ between\ rooms.\r\n\ \r\n\ @param\ from\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ where\ the\ door\ originates.\r\n\ @param\ north\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ to\ the\ north\ of\ the\ originating\ room.\r\n
comment5.params=from\ east
comment5.target=void\ createEastDoor(Room,\ Room)
comment5.text=\r\n\ Helper\ method\ for\ creating\ doors\ between\ rooms.\r\n\ \r\n\ @param\ from\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ where\ the\ door\ originates.\r\n\ @param\ east\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ to\ the\ east\ of\ the\ originating\ room.\r\n
comment6.params=from\ south
comment6.target=void\ createSouthDoor(Room,\ Room)
comment6.text=\r\n\ Helper\ method\ for\ creating\ doors\ between\ rooms.\r\n\ \r\n\ @param\ from\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ where\ the\ door\ originates.\r\n\ @param\ south\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ to\ the\ south\ of\ the\ originating\ room.\r\n
comment7.params=from\ west
comment7.target=void\ createWestDoor(Room,\ Room)
comment7.text=\r\n\ Helper\ method\ for\ creating\ doors\ between\ rooms.\r\n\ \r\n\ @param\ from\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ where\ the\ door\ originates.\r\n\ @param\ west\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room\ to\ the\ west\ of\ the\ originating\ room.\r\n
comment8.params=
comment8.target=void\ createRooms()
comment8.text=\r\n\ This\ method\ creates\ all\ of\ the\ individual\ places\ in\ this\ world\ and\ all\r\n\ the\ doors\ connecting\ them.\r\n
numComments=9
training/.gitignore
*.class
*.ctxt
*.*~
doc
/.project
default.log
training/Player.java
training/Player.java
/**
*/
public
class
Player
{
/** This stores the room that the player is currnetly in. */
private
Room
room
;
/** A constructor for the player class.
*
@param
currentRoom for the room field.
*/
public
Player
(
Room
currentRoom
){
room
=
currentRoom
;
}
/** Accossor for getting the room.
*
@return
for getting the current room that the player is in.
*/
public
Room
getRoom
(){
return
room
;
}
/** Mutator for setting the current room.
*
@param
newRoom for setting the current room.
*/
public
void
setRoom
(
Room
newRoom
){
room
=
newRoom
;
}
}
training/Room.ctxt
#BlueJ class context
comment0.target=Room
comment0.text=\r\n\r\n
comment1.params=name\ description
comment1.target=Room(java.lang.String,\ java.lang.String)
comment1.text=\r\n\ Create\ a\ room\ described\ “description”.\ Initially,\ it\ has\ no\ exits.\r\n\ “description”\ is\ something\ like\ “a\ kitchen”\ or\ “an\ open\ court\ yard”.\r\n\ \r\n\ @param\ name\ \ The\ room’s\ name.\r\n\ @param\ description\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ room’s\ description.\r\n
comment10.params=newEastExit
comment10.target=void\ setEastExit(Door)
comment10.text=\ Mutator\ for\ setting\ the\ eastExit.\r\n\ @param\ newEastExit\ for\ setting\ that\ direction.\r\n
comment11.params=newWestExit
comment11.target=void\ setWestExit(Door)
comment11.text=\ Mutator\ for\ setting\ the\ westExit.\r\n\ @param\ newWestExit\ for\ setting\ that\ direction.\r\n
comment12.params=
comment12.target=int\ getCounter()
comment12.text=\r\n\ Returns\ the\ number\ of\ rooms\ that\ have\ been\ created\ in\ the\ world.\r\n\ @return\ The\ number\ of\ rooms\ that\ have\ been\ created\ in\ the\ world.\r\n
comment13.params=
comment13.target=java.lang.String\ toString()
comment13.text=\r\n\ Returns\ a\ string\ description\ including\ all\ the\ details\ of\ a\ Room\ .\r\n\ For\ example\ ,\r\nOutside\ \:\r\nYou\ are\ outside\ in\ the\ center\ of\ the\ King’s\ College\ campus\ .\r\nExits\ \:\ north\ east\ south\ west\r\n\r\n\ @return\ A\ string\ representing\ all\ the\ details\ of\ a\ Room\ .\r\n
comment2.params=
comment2.target=java.lang.String\ getName()
comment2.text=\r\n\ Returns\ the\ name\ of\ this\ room.\r\n\ \r\n\ @return\ The\ name\ of\ this\ room.\r\n
comment3.params=
comment3.target=java.lang.String\ getDescription()
comment3.text=\r\n\ Returns\ the\ description\ of\ this\ room.\r\n\ \r\n\ @return\ The\ description\ of\ this\ room.\r\n
comment4.params=
comment4.target=Door\ getNorthExit()
comment4.text=\ Accessor\ for\ geting\ the\ northExit.\r\n\ @return\ getNorthExit\ for\ getting\ that\ direction.\r\n
comment5.params=
comment5.target=Door\ getSouthExit()
comment5.text=\ Accessor\ for\ geting\ the\ southExit.\r\n\ @return\ getSouthExit\ for\ getting\ that\ direction.\r\n
comment6.params=
comment6.target=Door\ getEastExit()
comment6.text=\ Accessor\ for\ geting\ the\ eastExit.\r\n\ @return\ getEastExit\ for\ getting\ that\ direction.\r\n
comment7.params=
comment7.target=Door\ getWestExit()
comment7.text=\ Accessor\ for\ geting\ the\ westExit.\r\n\ @return\ getWestExit\ for\ getting\ that\ direction.\r\n
comment8.params=newNorthExit
comment8.target=void\ setNorthExit(Door)
comment8.text=\ Mutator\ for\ setting\ the\ northExit.\r\n\ @param\ newNorthExit\ for\ setting\ that\ direction.\r\n
comment9.params=newSouthExit
comment9.target=void\ setSouthExit(Door)
comment9.text=\ Mutator\ for\ setting\ the\ southExit.\r\n\ @param\ newSouthExit\ for\ setting\ that\ direction.\r\n
numComments=14
training/2018sp-cs117-assignment03-Refactoring (2)
Name CS117 Lab 03 – Page 1
Lab 03: Refactoring Room
Assigned: Tuesday, January 30, 2018
Due: Sunday, February 4, 2018 at 6:00am
1 Overview
In this lab we are going to continue refactoring the code that was provided for your game to improve its
design and implementation. “Refactoring is the process of changing a software system in such a way that
it does not alter the external behavior of the code yet improves its internal structure.”1 It is the process
of reorganizing code to provide a better design while maintaining equivalence. When we refactor code, we
want the quality of the code to improve while keeping the functionality of the code exactly the same.
1.1 Cohesion
A well-designed class has all of the code that it needs, and no more code. It should represent one clearly-
defined kind of thing. Every method should have one specific purpose, and it should be obvious what that
purpose is. The same code should not be repeated multiple places. Classes with these properties are cohesive.
We already improved the cohesiveness of the Game class in the first lab when we moved duplicate code into
the new printLocationInformation method.
1.2 Coupling
A well-designed class can be used correctly without knowledge of the details of how it works, so that when
those details change it will not be necessary to change the code that uses it. When this is true, classes
are loosely coupled. When a class depends highly on the messy details of another, they are highly coupled.
Currently, the Room class is tightly coupled with several other classes. We are going to fix the design of the
Room class today to fix this.
2 Assignment
2.1 Resolving Issues
If you have any outstanding issues from prior labs, you should fix those before doing anything else. Remember
to use one commit per issue, and to include “Fixes #4” (or whatever number it is) in your commit message.
2.2 Fixing Some Bad Style
We have learned that unless there is a very good reason to do otherwise, fields should always be private.
Keeping fields private decreases the coupling between classes because it allows things to change behind the
scenes without having to change multiple classes. If you look at the Room class, you will find that it contains
public fields. We are going to fix this now. Start by changing each of them to private.
But now, when you try to compile the code, you will find that there are lots of compiler errors because of
places outside the Room class that had been using those public fields. We still need to have ways for other
code to get information about Room objects, so we need to write some accessor and mutator methods in it.
1Martin Fowler in Refactoring: Improving the Design of Existing Code, 1999.
Name CS117 Lab 03 – Page 2
You will then need to update every class that uses those fields directly to use your newly written accessor
and mutator methods instead. (Hint: The easiest way to do this is to let the compiler tell you about those
places.) Look for opportunities to simplify the code as you do this. Again, make sure that you test
your code to make sure that it still works, then commit and push your changes.
2.3 Improving Cohesion
Writing cohesive code means that the Game class really shouldn’t know all of the possible exits that a Room
can have or really know the details of what it means to write out the details of a room. It would be better
for the Room class to handle this. The perfect way to do this is to create a toString method in the Room
class:
1 /∗ ∗
2 ∗ R e t u r n s a s t r i n g d e s c r i p t i o n i n c l u d i n g a l l t h e d e t a i l s o f a Room .
3 ∗ F o r e x a m p l e ,
4 ∗ O u t s i d e :
5 ∗ You a r e o u t s i d e i n t h e c e n t e r o f t h e King ’ s C o l l e g e campus .
6 ∗ E x i t s : n o r t h e a s t s o u t h w e s t
7 ∗
8 ∗ @ r e t u r n A s t r i n g r e p r e s e n t i n g a l l t h e d e t a i l s o f a Room .
9 ∗/
10 public String toString ()
As you can see, this method should print first the room’s name, then its description, then a list of all the
directions out of the room (those that are not null).
Remember that we want to keep the output isolated in a single class so we don’t really want this method
to print the exit string directly – only to return it. Modify the Game class to use the toString method
instead of relying on knowledge of all the possible exits a Room can have. Be sure that you test to make
sure that your modifications didn’t change the behavior of the application. Then commit and push your
changes.
2.4 Adding Support for Multiple Directions
Currently, a player can only move in four directions. What if we wanted to add a new direction of movement
to our game? How many places in the code would need to be modified in order to add a new direction (e.g.,
up) or down)? Fortunately, the work we have done to clean up the interface to the Room class means that it
is now easier to change the way exits are stored in the Room class without any need to worry about breaking
anything in the Game class.
We would like to add support in our game for movement in any arbitrary direction, rather then try to
anticipate all of the directions our game may need. We will refactor the Room class to use a HashMap to
store exits. The HashMap will map a named direction (like “north” or “east”) to the Door that lies in that
direction. We will do this now.
1. Replace the individual exit fields of the Room class with a HashMap. The HashMap should map a
direction string to the Door that is located in the specified direction. Be sure to completely delete
the individual fields for each of the directions.
2. Since we no longer have individual fields for each exit, replace the mutator methods for old fields we
just added with a new setExit method that can handle an exit in any direction. This method only
needs to put the exit information into the HashMap. It should have the following signature:
Name CS117 Lab 03 – Page 3
1 /∗ ∗
2 ∗ D e f i n e s an e x i t f r o m t h i s room .
3 ∗
4 ∗ @param d i r e c t i o n The d i r e c t i o n o f t h e e x i t .
5 ∗ @param n e i g h b o r The d o o r i n t h e g i v e n d i r e c t i o n .
6 ∗/
7 public void setExit(String direction , Door neighbor)
3. Similarly, we can replace the accessor methods for the old fields we added earlier with a new getExit
method that can return the exit that exists in any direction. This method need only get the exit
information from the HashMap. It should have the following signature:
1 /∗ ∗
2 ∗ G e t s a d o o r i n a s p e c i f i e d d i r e c t i o n i f i t e x i s t s .
3 ∗
4 ∗ @ r e t u r n The d o o r i n t h e s p e c i f i e d d i r e c t i o n o r n u l l i f i t d o e s n o t
e x i s t .
5 ∗/
6 public Door getExit(String direction)
4. Modify the rest of the Room class so that it properly uses the HashMap. HINT: The toString() method
can iterate over the keys of the HashMap.
5. Modify the goRoom method in the Game class to use your newly written getExit() method. HINT:
Look for an opportunity to greatly simplify this code.
6. Finally, we need to modify the World class. Notice that the World class has methods for each of the
directions. We should be able to simplify this by replacing all of the direction specific methods for
creating doors with a single method similar what we did in the Room class:
1 /∗ ∗
2 ∗ H e l p e r method f o r c r e a t i n g d o o r s b e t w e e n r o o m s .
3 ∗
4 ∗ @param f r o m The room w h e r e t h e d o o r o r i g i n a t e s .
5 ∗ @param d i r e c t i o n The d i r e c t i o n o f t h e d o o r i n t h e f r o m room .
6 ∗ @param t o The room w h e r e t h e d o o r g o e s .
7 ∗/
8 private void createDoor(Room from , String direction , Room to)
Congratulations, you have modified your game in such a way that we can create a multi-dimensional
world in which our player can move in any direction. Be sure to test to make sure that your modifications
didn’t change the behavior of the application and then commit and push your changes.
2.5 Introducing Checkstyle
We have talked a lot about why it is beneficial to use good style when programming. Sometimes, however,
we are so focused at the task that we are trying to accomplish that we forget to following some of our coding
Name CS117 Lab 03 – Page 4
standards. The result of this is that we have code that is harder to understand. In order to help us develop
good habits, we will use a tool called Checkstyle.
Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard.
It automates a lot of the process of checking Java code to spare humans of this boring (but important) task.
This makes it ideal for projects that want to enforce a coding standard like this project. You can run
Checkstyle on your project to make sure that it follows the standards we have been teaching you this year.
The first thing we want to do is check that we are using the correct style file. You can double check the
style file that BlueJ is using by going to the “Tools” … “Preferences” menu and selecting the “Extensions”
tab. At the top of this tab are two text fields for where Checkstyle will look for its configuration. Be sure
that both of them point to http://www.kings-cs.com/kings-cs/java/kings-cs-lower.xml.
Now run Checkstyle from the “Tools” menu. This should open a window that lists any problems that
were detected in your program. If there are any problems, you should fix them. You should do this at
minimum before everytime that you complete an assignment in this course (and all future programming
courses).
If you needed to make any changes to fix Checkstyle problems, run your program again to make sure
that it still works, and then commit and push your changes.
If you downloaded BlueJ to your own computer, it probably does not have Checkstyle installed, because
it is an extension. You should follow the instructions at http://bluejcheckstyle.sourceforge.net/ to
install activate Checkstyle for your copy of BlueJ, because you should be running it before every commit
and push that you do for this project (and homework assignments too)! If you need help with this, ask!
2.6 Design Document
That is all of the code that you need to write for today. If you have extra time, work on / talk to me about
your design document.
3 Finishing
When you are finished, you will need to send me information about which commit is the final one for this
assignment. To do so, refresh the github.com page for your repository one more time. Then find the section
labeled “Latest commit” followed by a strange sequence of seven numbers and letters, then the date. If
you click on the numbers and letters, you will go to a page showing the changes made in your most recent
commit.
Copy the URL of that webpage and paste it into the Moodle submission box. (I can show you how to
do all of this if you are unsure.) Make sure that you click the “Submit Assignment” button in Moodle.
To avoid any confusion, I strongly recommend that you delete the repository from your local computer
and re-clone it next time you are ready to work on it.
__MACOSX/training/._2018sp-cs117-assignment03-Refactoring (2)
training/Game.java
training/Game.java
/**
*/
public
class
Game
{
/** The world where the game takes place. */
private
World
world
;
///** The room the player character is currently in. */
//private Room currentRoom;
/** The number of movments that the player has made. */
private
int
turns
;
/** The score that the player earns. */
private
int
score
;
/** This is the character that is controlled by the player. */
private
Character
character
;
/** This is an object for getting the room from the Player class. */
private
Player
playerClass
;
/**
* Create the game and initialize its internal map.
*/
public
Game
()
{
world
=
new
World
();
playerClass
=
new
Player
(
world
.
getRoom
(
“outside”
));
score
=
0
;
turns
=
0
;
character
=
character
;
// set the starting room
//playerClass = world.getRoom(“outside”);
}
/**
* Main play routine. Loops until end of play.
*/
public
void
play
()
{
printWelcome
();
// Enter the main game loop. Here we repeatedly read commands and
// execute them until the game is over.
boolean
wantToQuit
=
false
;
while
(
!
wantToQuit
)
{
Command
command
=
Reader
.
getCommand
();
wantToQuit
=
processCommand
(
command
);
// other stuff that needs to happen every turn can be added here.
turns
++
;
}
printGoodbye
();
}
/**
*Printsoutthecurrentlocationandexits.
*/
private
void
printLocationInformation
(){
boolean
wantToQuit
=
false
;
Writer
.
println
(
playerClass
.
getRoom
().
getName
()
+
“:”
);
//printWelcome();
Writer
.
println
(
“You are ”
+
playerClass
.
getRoom
().
getDescription
());
Writer
.
print
(
“Exits: ”
);
if
(
playerClass
.
getRoom
()
!=
null
)
{
Writer
.
print
(
“north ”
);
}
if
(
playerClass
.
getRoom
()
!=
null
)
{
Writer
.
print
(
“east ”
);
}
if
(
playerClass
.
getRoom
()
!=
null
)
{
Writer
.
print
(
“south ”
);
}
if
(
playerClass
.
getRoom
()
!=
null
)
{
Writer
.
print
(
“west ”
);
}
Writer
.
println
();
// other stuff that needs to happen every turn can be added here.
}
///////////////////////////////////////////////////////////////////////////
// Helper methods for processing the commands
/**
* Given a command, process (that is: execute) the command.
*
*
@param
command
* The command to be processed.
*
@return
true If the command ends the game, false otherwise.
*/
private
boolean
processCommand
(
Command
command
)
{
boolean
wantToQuit
=
false
;
if
(
command
.
isUnknown
())
{
Writer
.
println
(
“I don’t know what you mean…”
);
}
else
{
String
commandWord
=
command
.
getCommandWord
();
if
(
commandWord
.
equals
(
“help”
))
{
printHelp
();
}
else
if
(
commandWord
.
equals
(
“go”
))
{
goRoom
(
command
);
}
else
if
(
commandWord
.
equals
(
“quit”
))
{
wantToQuit
=
quit
(
command
);
}
else
{
Writer
.
println
(
commandWord
+
” is not implemented yet!”
);
}
}
return
wantToQuit
;
}
///////////////////////////////////////////////////////////////////////////
// Helper methods for implementing all of the commands.
// It helps if you organize these in alphabetical order.
/**
* Try to go to one direction. If there is an exit, enter the new room,
* otherwise print an error message.
*
*
@param
command
* The command to be processed.
*/
private
void
goRoom
(
Command
command
)
{
Room
currentRoom
=
playerClass
.
getRoom
();
if
(
!
command
.
hasSecondWord
())
{
// if there is no second word, we don’t know where to go…
Writer
.
println
(
“Go where?”
);
}
else
{
String
direction
=
command
.
getRestOfLine
();
// Try to leave current.
Door
doorway
=
null
;
if
(
direction
.
equals
(
“north”
))
{
doorway
=
currentRoom
.
getNorthExit
();
}
if
(
direction
.
equals
(
“east”
))
{
doorway
=
currentRoom
.
getEastExit
();
}
if
(
direction
.
equals
(
“south”
))
{
doorway
=
currentRoom
.
getSouthExit
();
}
if
(
direction
.
equals
(
“west”
))
{
doorway
=
currentRoom
.
getWestExit
();
}
if
(
doorway
==
null
)
{
Writer
.
println
(
“There is no door!”
);
}
else
{
Room
newRoom
=
doorway
.
getDestination
();
playerClass
.
setRoom
(
newRoom
);
printLocationInformation
();
Writer
.
println
();
}
}
}
/**
* Print out the closing message for the player.
*/
private
void
printGoodbye
()
{
Writer
.
println
(
“I hope you weren’t too bored here on the Campus of Kings!”
);
Writer
.
println
(
“Thank you for playing. Good bye.”
);
Writer
.
println
(
“You have earned”
+
score
+
“points in”
+
turns
+
“turns.”
);
}
/**
* Print out some help information. Here we print some stupid, cryptic
* message and a list of the command words.
*/
private
void
printHelp
()
{
Writer
.
println
(
“You are lost. You are alone. You wander”
);
Writer
.
println
(
“around at the university.”
);
Writer
.
println
();
Writer
.
println
(
“Your command words are:”
);
Writer
.
println
(
” go quit help”
);
}
/**
* Print out the opening message for the player.
*/
private
void
printWelcome
()
{
Room
currentRoom
=
playerClass
.
getRoom
();
Writer
.
println
();
Writer
.
println
(
“Welcome to the Campus of Kings!”
);
Writer
.
println
(
“Campus of Kings is a new, incredibly boring adventure game.”
);
Writer
.
println
(
“Type ‘help’ if you need help.”
);
Writer
.
println
();
//Writer.println(currentRoom.getName() + “:”);
Writer
.
println
();
printLocationInformation
();
}
/**
* “Quit” wasI entered. Check the rest of the command to see whether we
* really quit the game.
*
*
@param
command
* The command to be processed.
*
@return
true, if this command quits the game, false otherwise.
*/
private
boolean
quit
(
Command
command
)
{
boolean
wantToQuit
=
true
;
if
(
command
.
hasSecondWord
())
{
Writer
.
println
(
“Quit what?”
);
wantToQuit
=
false
;
}
return
wantToQuit
;
}
}
training/Main.java
training/Main.java
import
java
.
awt
.
BorderLayout
;
import
java
.
awt
.
Dimension
;
import
java
.
awt
.
event
.
ActionEvent
;
import
java
.
awt
.
event
.
ActionListener
;
import
java
.
awt
.
event
.
ComponentAdapter
;
import
java
.
awt
.
event
.
ComponentEvent
;
import
java
.
io
.
InputStream
;
import
java
.
io
.
IOException
;
import
javax
.
swing
.
JButton
;
import
javax
.
swing
.
JFrame
;
import
javax
.
swing
.
JMenu
;
import
javax
.
swing
.
JMenuBar
;
import
javax
.
swing
.
JMenuItem
;
import
javax
.
swing
.
JPanel
;
import
javax
.
swing
.
JScrollPane
;
import
javax
.
swing
.
JTextField
;
import
javax
.
swing
.
JTextPane
;
/**
*/
public
class
Main
extends
JFrame
implements
ActionListener
{
/** Generated unique serial unique id. */
private
static
final
long
serialVersionUID
=
–
4610552759287004513L
;
/** Starting dimension of the window. */
private
static
final
Dimension
WINDOW_DIMENSION
;
/** The scroll pane so we can resize it when the window is resized. */
private
JScrollPane
outputScrollPane
;
/** The save log menu item. */
private
JMenuItem
saveItem
;
/** The exit menu item. */
private
JMenuItem
exitItem
;
/** The game instance. */
private
Game
game
;
/** Static block for initializing static fields. */
static
{
WINDOW_DIMENSION
=
new
Dimension
(
500
,
500
);
}
/** Default constructor. */
public
Main
()
{
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
setLayout
(
new
BorderLayout
());
// Setting up the menu bar
JMenuBar
menuBar
=
new
JMenuBar
();
setJMenuBar
(
menuBar
);
JMenu
fileMenu
=
new
JMenu
(
“File”
);
menuBar
.
add
(
fileMenu
);
saveItem
=
new
JMenuItem
(
“Save Log …”
);
saveItem
.
addActionListener
(
this
);
fileMenu
.
add
(
saveItem
);
exitItem
=
new
JMenuItem
(
“Exit”
);
exitItem
.
addActionListener
(
this
);
fileMenu
.
add
(
exitItem
);
// Setting out the output area
JTextPane
output
=
new
JTextPane
();
outputScrollPane
=
new
JScrollPane
(
output
);
Dimension
outputSize
=
new
Dimension
();
outputSize
.
setSize
(
WINDOW_DIMENSION
.
getWidth
(),
WINDOW_DIMENSION
.
getHeight
()
–
100
);
outputScrollPane
.
setPreferredSize
(
outputSize
);
// So that the scroll pane will resize when the window is resized
addComponentListener
(
new
ComponentAdapter
()
{
public
void
componentResized
(
ComponentEvent
e
)
{
Dimension
outputSize
=
new
Dimension
();
outputSize
.
setSize
(
getContentPane
().
getWidth
(),
getContentPane
().
getHeight
()
–
100
);
outputScrollPane
.
setPreferredSize
(
outputSize
);
}
});
add
(
BorderLayout
.
NORTH
,
outputScrollPane
);
// Set up the Writer so that it can be used throughout the game.
Writer
.
setTextArea
(
output
);
// Setting up the bottom panel for input
JPanel
bottomPane
=
new
JPanel
();
bottomPane
.
setLayout
(
new
BorderLayout
());
JButton
enterButton
=
new
JButton
(
“Enter”
);
JTextField
commandField
=
new
JTextField
();
TextFieldStreamer
streamer
=
new
TextFieldStreamer
(
commandField
);
// maybe this next line should be done in the TextFieldStreamer ctor
// but that would cause a “leak a this from the ctor” warning
commandField
.
addActionListener
(
streamer
);
enterButton
.
addActionListener
(
streamer
);
System
.
setIn
(
streamer
);
bottomPane
.
add
(
BorderLayout
.
CENTER
,
commandField
);
bottomPane
.
add
(
BorderLayout
.
EAST
,
enterButton
);
add
(
BorderLayout
.
SOUTH
,
bottomPane
);
setSize
(
WINDOW_DIMENSION
);
setVisible
(
true
);
commandField
.
requestFocus
();
game
=
new
Game
();
game
.
play
();
}
/**
* Default action listener.
*
*
@param
event
* The action event.
*/
@
Override
public
void
actionPerformed
(
ActionEvent
event
)
{
if
(
event
.
getSource
()
==
saveItem
)
{
Writer
.
copyDefaultLog
();
}
else
if
(
event
.
getSource
()
==
exitItem
)
{
System
.
exit
(
0
);
}
}
/**
* The main method for the program.
*
*
@param
args
* The command line arguments.
*/
public
static
void
main
(
String
[]
args
)
{
new
Main
();
}
/**
* Implementation of InputStream that uses the text from a JTextField as the
* input buffer.
*
*
@author
Maria Jump
*/
private
class
TextFieldStreamer
extends
InputStream
implements
ActionListener
{
/** The JTextField to use for input. */
private
JTextField
textField
;
/** The string of text that being passed as input. */
private
String
text
;
/** Used for checking if the available input has reached its end. */
private
int
position
;
/**
* Default constructor for TextFieldStreamer.
*
*
@param
field
* JTextField component being used as input buffer.
*/
public
TextFieldStreamer
(
JTextField
field
)
{
position
=
0
;
text
=
null
;
textField
=
field
;
}
// gets
/**
* Invoked when an action occurs. In this case, prints the text of the
* JTextField to StdOut as an error message to differentiate between
* user input and game output. Triggered every time that “Enter” is
* pressed on the JTextField.
*
* Triggered every time that “Enter” is pressed on the textfield
*
*
@param
event
* ActionEvent passed by the component.
*/
@
Override
public
void
actionPerformed
(
ActionEvent
event
)
{
text
=
textField
.
getText
()
+
System
.
getProperty
(
“line.separator”
);
position
=
0
;
textField
.
setText
(
“”
);
synchronized
(
this
)
{
// maybe this should only notify() as multiple threads may
// be waiting for input and they would now race for input
this
.
notifyAll
();
}
}
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an int
in the range 0
to
* 255
. If no byte is available because the end of the
* stream has been reached, the value -1
is returned. This
* method blocks until input data is available, the end of the stream is
* detected, or an exception is thrown.
*
*
* A subclass must provide an implementation of this method.
*
*
@return
the next byte of data, or -1
if the end of the
* stream is reached.
*
@exception
IOException
* if an I/O error occurs.
*/
@
Override
public
int
read
()
throws
IOException
{
int
result
=
0xDEADBEEF
;
// test if the available input has reached its end
// and the EOS should be returned
if
(
text
!=
null
&&
position
==
text
.
length
())
{
text
=
null
;
// this is supposed to return -1 on “end of stream”
// but I’m having a hard time locating the constant
result
=
java
.
io
.
StreamTokenizer
.
TT_EOF
;
}
if
(
result
==
0xDEADBEEF
)
{
// no input available, block until more is available because
// that’s
// the behavior specified in the Javadocs.
while
(
text
==
null
||
position
>=
text
.
length
())
{
try
{
// read() should block until new input is available.
synchronized
(
this
)
{
this
.
wait
();
}
}
catch
(
InterruptedException
ex
)
{
ex
.
printStackTrace
();
}
}
// read an additional character, return it and increment the
// index.
result
=
text
.
charAt
(
position
++
);
}
return
result
;
}
}
}
training/CommandWords.java
training/CommandWords.java
/**
*/
public
class
CommandWords
{
/** A constant array that holds all valid command words. */
private
static
String
[]
validCommands
;
/**
* Static block to initialize the fields of CommandWords.
*/
static
{
String
[]
tempCommands
=
{
“go”
,
“quit”
,
“help”
};
validCommands
=
tempCommands
;
}
/**
* Check whether a given String is a valid command word.
*
*
@param
aString The string to determine whether it is a valid command.
*
@return
true if a given string is a valid command, false if it isn’t.
*/
public
static
boolean
isCommand
(
String
aString
)
{
boolean
valid
=
false
;
int
index
=
0
;
while
(
!
valid
&&
index
<
validCommands
.
length
)
{
if
(
validCommands
[
index
].
equals
(
aString
))
{
valid
=
true
;
}
index
++
;
}
// if we get here, the string was not found in the commands
return
valid
;
}
}
training/Main$TextFieldStreamer.class
synchronized class Main$TextFieldStreamer extends java.io.InputStream implements java.awt.event.ActionListener {
private javax.swing.JTextField textField;
private String text;
private int position;
public void Main$TextFieldStreamer(Main, javax.swing.JTextField);
public void actionPerformed(java.awt.event.ActionEvent);
public int read() throws java.io.IOException;
}
training/Door.ctxt
#BlueJ class context
comment0.target=Door
comment0.text=\r\n\r\n
comment1.params=destination
comment1.target=Door(Room)
comment1.text=\r\n\ Constructor\ for\ the\ Door\ class.\r\n\ @param\ destination\ The\ room\ this\ door\ leads\ to\r\n
comment2.params=
comment2.target=Room\ getDestination()
comment2.text=\r\n\ A\ getter\ for\ the\ room\ this\ door\ leads\ to.\r\n\ @return\ The\ room\ this\ door\ leads\ to\r\n
comment3.params=
comment3.target=boolean\ isLocked()
comment3.text=\r\n\ A\ getter\ for\ whether\ this\ door\ is\ locked.\r\n\ @return\ Whether\ this\ door\ is\ locked\r\n
comment4.params=locked
comment4.target=void\ setLocked(boolean)
comment4.text=\r\n\ A\ setter\ for\ whether\ this\ door\ is\ locked.\r\n\ @param\ locked\ Whether\ this\ door\ is\ locked.\r\n
numComments=5
training/Player.class
public synchronized class Player {
private Room room;
public void Player(Room);
public Room getRoom();
public void setRoom(Room);
}
training/World.class
public synchronized class World {
private java.util.HashMap rooms;
public void World();
public Room getRoom(String);
private void addRoom(Room);
private void createNorthDoor(Room, Room);
private void createEastDoor(Room, Room);
private void createSouthDoor(Room, Room);
private void createWestDoor(Room, Room);
private void createRooms();
}
training/documents/Untitled Document
The Stolen Treasure
The player is a guy named Kevin. He can enter some restaurant and get some water and some food. He can get keys from the ground when he finds one and these keys open some specific cars. He can get two weapons, a small one like a rock and a big one like a baseball bat.
He needs to get some water if he made 100 turns during midday and 170 turns during night time.
Some achievement:
He gets 10 points when he finds the silver key and 15 point when he finds the golden key.
If he earns 40 point, he will get a map with the next item he finds which makes his mission easier like hunts such as a picture of building that he might find something valuable in or the a picture of a car that he might find something that leads him to figure something out.
When he earns 80 points he will get a partner named Sarah who will help him.
training/package.bluej
#BlueJ package file
dependency1.from=Player
dependency1.to=Room
dependency1.type=UsesDependency
dependency10.from=Game
dependency10.to=Door
dependency10.type=UsesDependency
dependency11.from=Game
dependency11.to=Reader
dependency11.type=UsesDependency
dependency12.from=Game
dependency12.to=Writer
dependency12.type=UsesDependency
dependency13.from=Main
dependency13.to=Game
dependency13.type=UsesDependency
dependency14.from=Main
dependency14.to=Writer
dependency14.type=UsesDependency
dependency15.from=Reader
dependency15.to=Command
dependency15.type=UsesDependency
dependency16.from=Reader
dependency16.to=Writer
dependency16.type=UsesDependency
dependency17.from=Reader
dependency17.to=CommandWords
dependency17.type=UsesDependency
dependency2.from=Door
dependency2.to=Room
dependency2.type=UsesDependency
dependency3.from=World
dependency3.to=Room
dependency3.type=UsesDependency
dependency4.from=World
dependency4.to=Door
dependency4.type=UsesDependency
dependency5.from=Room
dependency5.to=Door
dependency5.type=UsesDependency
dependency6.from=Game
dependency6.to=World
dependency6.type=UsesDependency
dependency7.from=Game
dependency7.to=Player
dependency7.type=UsesDependency
dependency8.from=Game
dependency8.to=Command
dependency8.type=UsesDependency
dependency9.from=Game
dependency9.to=Room
dependency9.type=UsesDependency
editor.fx.0.height=680
editor.fx.0.width=800
editor.fx.0.x=316
editor.fx.0.y=23
objectbench.height=101
objectbench.width=776
package.divider.horizontal=0.599476439790576
package.divider.vertical=0.8007380073800738
package.editor.height=427
package.editor.width=651
package.editor.x=236
package.editor.y=85
package.frame.height=600
package.frame.width=800
package.numDependencies=17
package.numTargets=10
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=Player
target1.showInterface=false
target1.type=ClassTarget
target1.width=80
target1.x=460
target1.y=10
target10.height=50
target10.name=Writer
target10.showInterface=false
target10.type=ClassTarget
target10.width=80
target10.x=30
target10.y=170
target2.height=50
target2.name=Game
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.width=80
target2.x=240
target2.y=20
target3.height=50
target3.name=Command
target3.showInterface=false
target3.type=ClassTarget
target3.width=90
target3.x=40
target3.y=340
target4.height=50
target4.name=Reader
target4.showInterface=false
target4.type=ClassTarget
target4.width=80
target4.x=120
target4.y=110
target5.height=50
target5.name=World
target5.showInterface=false
target5.type=ClassTarget
target5.width=80
target5.x=370
target5.y=20
target6.height=50
target6.name=CommandWords
target6.showInterface=false
target6.type=ClassTarget
target6.width=130
target6.x=10
target6.y=260
target7.height=50
target7.name=Room
target7.showInterface=false
target7.type=ClassTarget
target7.width=80
target7.x=430
target7.y=220
target8.height=50
target8.name=Main
target8.showInterface=false
target8.type=ClassTarget
target8.width=80
target8.x=70
target8.y=20
target9.height=50
target9.name=Door
target9.showInterface=false
target9.type=ClassTarget
target9.width=80
target9.x=510
target9.y=80
training/Door.class
public synchronized class Door {
private Room destination;
private boolean locked;
public void Door(Room);
public Room getDestination();
public boolean isLocked();
public void setLocked(boolean);
}
training/Command.ctxt
#BlueJ class context
comment0.target=Command
comment0.text=\r\n\r\n
comment1.params=firstWord
comment1.target=Command(java.lang.String)
comment1.text=\r\n\ Create\ a\ command\ object.\ First\ is\ supplied.\ The\ second\ word\ is\ assumed\r\n\ to\ be\ null.\r\n\ \r\n\ @param\ firstWord\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ first\ word\ of\ the\ command.\ Null\ if\ the\ command\ was\ not\r\n\ \ \ \ \ \ \ \ \ \ \ \ recognized.\r\n
comment2.params=firstWord\ rest
comment2.target=Command(java.lang.String,\ java.util.ArrayList)
comment2.text=\r\n\ Create\ a\ command\ object.\ First\ and\ second\ word\ must\ be\ supplied,\ but\r\n\ either\ one\ (or\ both)\ can\ be\ null.\r\n\ \r\n\ @param\ firstWord\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ first\ word\ of\ the\ command.\ Null\ if\ the\ command\ was\ not\r\n\ \ \ \ \ \ \ \ \ \ \ \ recognized.\r\n\ @param\ rest\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ rest\ of\ the\ command.\r\n
comment3.params=
comment3.target=java.lang.String\ getCommandWord()
comment3.text=\r\n\ Return\ the\ command\ word\ (the\ first\ word)\ of\ this\ command.\ If\ the\ command\r\n\ was\ not\ understood,\ the\ result\ is\ null.\r\n\ \r\n\ @return\ The\ command\ word.\r\n
comment4.params=
comment4.target=boolean\ isUnknown()
comment4.text=\r\n\ Returns\ if\ this\ command\ was\ not\ understood.\r\n\ \r\n\ @return\ true\ if\ this\ command\ was\ not\ understood.\r\n
comment5.params=
comment5.target=boolean\ hasSecondWord()
comment5.text=\r\n\ Returns\ if\ this\ command\ has\ a\ second\ word.\r\n\ \r\n\ @return\ true\ if\ the\ command\ has\ a\ second\ word.\r\n
comment6.params=index
comment6.target=boolean\ hasWord(int)
comment6.text=\r\n\ Returns\ if\ this\ command\ has\ more\ words.\r\n\r\n\ @param\ index\ The\ index\ of\ the\ word\ needed.\r\n\ @return\ true\ if\ the\ command\ has\ a\ word\ at\ given\ index.\r\n
comment7.params=index
comment7.target=java.lang.String\ getWord(int)
comment7.text=\r\n\ Returns\ the\ word\ at\ the\ requested\ index\ in\ the\ command.\r\n\ \r\n\ @param\ index\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ index\ of\ word\ in\ the\ command\ that\ is\ being\ requested.\r\n\ \r\n\ @return\ A\ particular\ word\ in\ the\ command.\ Returns\ null\ if\ there\ is\ no\r\n\ \ \ \ \ \ \ \ \ word\ corresponding\ to\ that\ requested\ index.\r\n\ \r\n
comment8.params=
comment8.target=java.lang.String\ getRestOfLine()
comment8.text=\r\n\ Returns\ the\ second\ word\ of\ this\ command,\ if\ it\ exists.\r\n\ \r\n\ @return\ The\ second\ word\ of\ this\ command.\ Returns\ null\ if\ there\ was\ no\r\n\ \ \ \ \ \ \ \ \ second\ word.\r\n
numComments=9
training/Main.class
public synchronized class Main extends javax.swing.JFrame implements java.awt.event.ActionListener {
private static final long serialVersionUID = -4610552759287004513;
private static final java.awt.Dimension WINDOW_DIMENSION;
private javax.swing.JScrollPane outputScrollPane;
private javax.swing.JMenuItem saveItem;
private javax.swing.JMenuItem exitItem;
private Game game;
public void Main();
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
static void
}
training/Reader.ctxt
#BlueJ class context
comment0.target=Reader
comment0.text=\r\n\r\n
comment1.params=
comment1.target=Command\ getCommand()
comment1.text=\r\n\ Returns\ the\ next\ command\ from\ the\ user.\r\n\ @return\ The\ next\ command\ from\ the\ user.\r\n
comment2.params=
comment2.target=java.lang.String\ getResponse()
comment2.text=\r\n\ Return\ the\ response\ to\ a\ question\ in\ all\ lower\ case.\r\n\r\n\ @return\ The\ response\ typed\ in\ by\ the\ user.\r\n
comment3.params=
comment3.target=java.lang.String\ getResponseKeepCase()
comment3.text=\r\n\ Return\ the\ response\ to\ a\ question\ in\ the\ case\ used\ by\ the\ player.\r\n\r\n\ @return\ The\ response\ typed\ in\ by\ the\ user.\r\n
numComments=4
training/Writer.ctxt
#BlueJ class context
comment0.target=Writer
comment0.text=\r\n\r\n
comment1.params=text
comment1.target=void\ setTextArea(javax.swing.JTextPane)
comment1.text=\r\n\ Mutator\ for\ the\ text\ component.\r\n\ \r\n\ @param\ text\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ text\ component.\r\n
comment10.params=toPrint
comment10.target=void\ println(java.lang.String)
comment10.text=\r\n\ Prints\ a\ string\ after\ word-wrapping\ it\ to\ 80\ characters\ if\ possible.\ Note\r\n\ that\ this\ fails\ to\ calculate\ correct\ widths\ if\ the\ string\ contains\ tabs.\r\n\ Ends\ with\ a\ line\ return.\r\n\r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ String\ to\ print.\r\n
comment11.params=toPrint
comment11.target=void\ print(java.lang.String)
comment11.text=\r\n\ Prints\ a\ string\ after\ word-wrapping\ it\ to\ 80\ characters\ if\ possible.\ Note\r\n\ that\ this\ fails\ to\ calculate\ correct\ widths\ if\ the\ string\ contains\ tabs.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ String\ to\ print.\r\n
comment12.params=toPrint
comment12.target=void\ standardPrint(java.lang.String)
comment12.text=\r\n\ Helper\ method\ for\ standard\ printing.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ String\ to\ print.\r\n
comment13.params=attributes\ toPrint
comment13.target=void\ printWithAttributes(javax.swing.text.SimpleAttributeSet,\ java.lang.String)
comment13.text=\r\n\ Helper\ method\ printing\ with\ attributes.\r\n\r\n\ @param\ attributes\r\n\ \ \ \ \ \ \ \ \ \ \ \ A\ set\ of\ attributes\ to\ use\ when\ printing.\r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ String\ to\ print.\r\n\ @throws\ IllegalStateException\r\n\ \ \ \ \ \ \ \ \ \ \ \ \ If\ the\ text\ area\ has\ not\ been\ set\ and\ we\ are\ trying\ to\ print\r\n\ \ \ \ \ \ \ \ \ \ \ \ \ to\ it.\r\n
comment14.params=
comment14.target=void\ restartLog()
comment14.text=\r\n\ Restart\ the\ default\ log.\r\n
comment15.params=
comment15.target=void\ copyDefaultLog()
comment15.text=\r\n\ Copy\ the\ default\ log.\r\n
comment2.params=input
comment2.target=void\ printInput(java.lang.String)
comment2.text=\r\n\ Print\ the\ user\ input\ in\ blue.\r\n\ \r\n\ @param\ input\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ text\ entered\ by\ the\ user.\r\n
comment3.params=
comment3.target=void\ println()
comment3.text=\r\n\ Prints\ an\ empty\ line.\r\n
comment4.params=toPrint
comment4.target=void\ println(int)
comment4.text=\r\n\ Prints\ out\ a\ single\ integer\ to\ a\ line.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ integer\ to\ print.\r\n
comment5.params=toPrint
comment5.target=void\ print(int)
comment5.text=\r\n\ Prints\ out\ a\ single\ integer.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ integer\ to\ print.\r\n
comment6.params=toPrint
comment6.target=void\ println(double)
comment6.text=\r\n\ Prints\ out\ a\ double\ to\ a\ line.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ double\ to\ print.\r\n
comment7.params=toPrint
comment7.target=void\ print(double)
comment7.text=\r\n\ Prints\ out\ a\ double.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ double\ to\ print.\r\n
comment8.params=toPrint
comment8.target=void\ println(java.lang.Object)
comment8.text=\r\n\ Prints\ out\ an\ object\ to\ a\ line.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ object\ to\ print.\r\n
comment9.params=toPrint
comment9.target=void\ print(java.lang.Object)
comment9.text=\r\n\ Prints\ out\ a\ object.\r\n\ \r\n\ @param\ toPrint\r\n\ \ \ \ \ \ \ \ \ \ \ \ The\ object\ to\ print.\r\n
numComments=16
training/Writer.class
public synchronized class Writer {
private static final String NEW_LINE;
private static final String DEFAULT_LOG;
private static javax.swing.JTextPane textArea;
public void Writer();
public static void setTextArea(javax.swing.JTextPane);
public static void printInput(String);
public static void println();
public static void println(int);
public static void print(int);
public static void println(double);
public static void print(double);
public static void println(Object);
public static void print(Object);
public static void println(String);
public static void print(String);
private static void standardPrint(String);
private static void printWithAttributes(javax.swing.text.SimpleAttributeSet, String) throws IllegalStateException;
public static void restartLog();
public static void copyDefaultLog();
static void
}
Name CS117 Lab 03 – Page 1
Lab 03: Refactoring Room
Assigned: Tuesday, January 30, 2018
Due: Sunday, February 4, 2018 at 6:00am
1 Overview
In this lab we are going to continue refactoring the code that was provided for your game to improve its
design and implementation. “Refactoring is the process of changing a software system in such a way that
it does not alter the external behavior of the code yet improves its internal structure.”1 It is the process
of reorganizing code to provide a better design while maintaining equivalence. When we refactor code, we
want the quality of the code to improve while keeping the functionality of the code exactly the same.
1.1 Cohesion
A well-designed class has all of the code that it needs, and no more code. It should represent one clearly-
defined kind of thing. Every method should have one specific purpose, and it should be obvious what that
purpose is. The same code should not be repeated multiple places. Classes with these properties are cohesive.
We already improved the cohesiveness of the Game class in the first lab when we moved duplicate code into
the new printLocationInformation method.
1.2 Coupling
A well-designed class can be used correctly without knowledge of the details of how it works, so that when
those details change it will not be necessary to change the code that uses it. When this is true, classes
are loosely coupled. When a class depends highly on the messy details of another, they are highly coupled.
Currently, the Room class is tightly coupled with several other classes. We are going to fix the design of the
Room class today to fix this.
2 Assignment
2.1 Resolving Issues
If you have any outstanding issues from prior labs, you should fix those before doing anything else. Remember
to use one commit per issue, and to include “Fixes #4” (or whatever number it is) in your commit message.
2.2 Fixing Some Bad Style
We have learned that unless there is a very good reason to do otherwise, fields should always be private.
Keeping fields private decreases the coupling between classes because it allows things to change behind the
scenes without having to change multiple classes. If you look at the Room class, you will find that it contains
public fields. We are going to fix this now. Start by changing each of them to private.
But now, when you try to compile the code, you will find that there are lots of compiler errors because of
places outside the Room class that had been using those public fields. We still need to have ways for other
code to get information about Room objects, so we need to write some accessor and mutator methods in it.
1Martin Fowler in Refactoring: Improving the Design of Existing Code, 1999.
Name CS117 Lab 03 – Page 2
You will then need to update every class that uses those fields directly to use your newly written accessor
and mutator methods instead. (Hint: The easiest way to do this is to let the compiler tell you about those
places.) Look for opportunities to simplify the code as you do this. Again, make sure that you test
your code to make sure that it still works, then commit and push your changes.
2.3 Improving Cohesion
Writing cohesive code means that the Game class really shouldn’t know all of the possible exits that a Room
can have or really know the details of what it means to write out the details of a room. It would be better
for the Room class to handle this. The perfect way to do this is to create a toString method in the Room
class:
1 /∗ ∗
2 ∗ R e t u r n s a s t r i n g d e s c r i p t i o n i n c l u d i n g a l l t h e d e t a i l s o f a Room .
3 ∗ F o r e x a m p l e ,
4 ∗ O u t s i d e :
5 ∗ You a r e o u t s i d e i n t h e c e n t e r o f t h e King ’ s C o l l e g e campus .
6 ∗ E x i t s : n o r t h e a s t s o u t h w e s t
7 ∗
8 ∗ @ r e t u r n A s t r i n g r e p r e s e n t i n g a l l t h e d e t a i l s o f a Room .
9 ∗/
10 public String toString ()
As you can see, this method should print first the room’s name, then its description, then a list of all the
directions out of the room (those that are not null).
Remember that we want to keep the output isolated in a single class so we don’t really want this method
to print the exit string directly – only to return it. Modify the Game class to use the toString method
instead of relying on knowledge of all the possible exits a Room can have. Be sure that you test to make
sure that your modifications didn’t change the behavior of the application. Then commit and push your
changes.
2.4 Adding Support for Multiple Directions
Currently, a player can only move in four directions. What if we wanted to add a new direction of movement
to our game? How many places in the code would need to be modified in order to add a new direction (e.g.,
up) or down)? Fortunately, the work we have done to clean up the interface to the Room class means that it
is now easier to change the way exits are stored in the Room class without any need to worry about breaking
anything in the Game class.
We would like to add support in our game for movement in any arbitrary direction, rather then try to
anticipate all of the directions our game may need. We will refactor the Room class to use a HashMap to
store exits. The HashMap will map a named direction (like “north” or “east”) to the Door that lies in that
direction. We will do this now.
1. Replace the individual exit fields of the Room class with a HashMap. The HashMap should map a
direction string to the Door that is located in the specified direction. Be sure to completely delete
the individual fields for each of the directions.
2. Since we no longer have individual fields for each exit, replace the mutator methods for old fields we
just added with a new setExit method that can handle an exit in any direction. This method only
needs to put the exit information into the HashMap. It should have the following signature:
Name CS117 Lab 03 – Page 3
1 /∗ ∗
2 ∗ D e f i n e s an e x i t f r o m t h i s room .
3 ∗
4 ∗ @param d i r e c t i o n The d i r e c t i o n o f t h e e x i t .
5 ∗ @param n e i g h b o r The d o o r i n t h e g i v e n d i r e c t i o n .
6 ∗/
7 public void setExit(String direction , Door neighbor)
3. Similarly, we can replace the accessor methods for the old fields we added earlier with a new getExit
method that can return the exit that exists in any direction. This method need only get the exit
information from the HashMap. It should have the following signature:
1 /∗ ∗
2 ∗ G e t s a d o o r i n a s p e c i f i e d d i r e c t i o n i f i t e x i s t s .
3 ∗
4 ∗ @ r e t u r n The d o o r i n t h e s p e c i f i e d d i r e c t i o n o r n u l l i f i t d o e s n o t
e x i s t .
5 ∗/
6 public Door getExit(String direction)
4. Modify the rest of the Room class so that it properly uses the HashMap. HINT: The toString() method
can iterate over the keys of the HashMap.
5. Modify the goRoom method in the Game class to use your newly written getExit() method. HINT:
Look for an opportunity to greatly simplify this code.
6. Finally, we need to modify the World class. Notice that the World class has methods for each of the
directions. We should be able to simplify this by replacing all of the direction specific methods for
creating doors with a single method similar what we did in the Room class:
1 /∗ ∗
2 ∗ H e l p e r method f o r c r e a t i n g d o o r s b e t w e e n r o o m s .
3 ∗
4 ∗ @param f r o m The room w h e r e t h e d o o r o r i g i n a t e s .
5 ∗ @param d i r e c t i o n The d i r e c t i o n o f t h e d o o r i n t h e f r o m room .
6 ∗ @param t o The room w h e r e t h e d o o r g o e s .
7 ∗/
8 private void createDoor(Room from , String direction , Room to)
Congratulations, you have modified your game in such a way that we can create a multi-dimensional
world in which our player can move in any direction. Be sure to test to make sure that your modifications
didn’t change the behavior of the application and then commit and push your changes.
2.5 Introducing Checkstyle
We have talked a lot about why it is beneficial to use good style when programming. Sometimes, however,
we are so focused at the task that we are trying to accomplish that we forget to following some of our coding
Name CS117 Lab 03 – Page 4
standards. The result of this is that we have code that is harder to understand. In order to help us develop
good habits, we will use a tool called Checkstyle.
Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard.
It automates a lot of the process of checking Java code to spare humans of this boring (but important) task.
This makes it ideal for projects that want to enforce a coding standard like this project. You can run
Checkstyle on your project to make sure that it follows the standards we have been teaching you this year.
The first thing we want to do is check that we are using the correct style file. You can double check the
style file that BlueJ is using by going to the “Tools” … “Preferences” menu and selecting the “Extensions”
tab. At the top of this tab are two text fields for where Checkstyle will look for its configuration. Be sure
that both of them point to http://www.kings-cs.com/kings-cs/java/kings-cs-lower.xml.
Now run Checkstyle from the “Tools” menu. This should open a window that lists any problems that
were detected in your program. If there are any problems, you should fix them. You should do this at
minimum before everytime that you complete an assignment in this course (and all future programming
courses).
If you needed to make any changes to fix Checkstyle problems, run your program again to make sure
that it still works, and then commit and push your changes.
If you downloaded BlueJ to your own computer, it probably does not have Checkstyle installed, because
it is an extension. You should follow the instructions at http://bluejcheckstyle.sourceforge.net/ to
install activate Checkstyle for your copy of BlueJ, because you should be running it before every commit
and push that you do for this project (and homework assignments too)! If you need help with this, ask!
2.6 Design Document
That is all of the code that you need to write for today. If you have extra time, work on / talk to me about
your design document.
3 Finishing
When you are finished, you will need to send me information about which commit is the final one for this
assignment. To do so, refresh the github.com page for your repository one more time. Then find the section
labeled “Latest commit” followed by a strange sequence of seven numbers and letters, then the date. If
you click on the numbers and letters, you will go to a page showing the changes made in your most recent
commit.
Copy the URL of that webpage and paste it into the Moodle submission box. (I can show you how to
do all of this if you are unsure.) Make sure that you click the “Submit Assignment” button in Moodle.
To avoid any confusion, I strongly recommend that you delete the repository from your local computer
and re-clone it next time you are ready to work on it.