...
Your assignment is to fill in the stubbed out members of the DoCommandVisitor
(members with degenerate bodies (return "";
). In the process you may choose to define some new classes to support your DoCommandVisitor
class implementation. The Student
class which repeatedly invokes DoCommandVisitor
models the laundry habits of Acker. In our test simulations, we will typically only create a single instance of Student
representing Acker, but your code should support multiple students (e.g., Acker and his brothers) at a time. Since these students do not interact with each other, supporting this form of multiplicity is a trivial consequence of OO coding style used in the framework.
The String
return value of the cases of the DoCommandVisitor
is the output of processing that Command
. For example, if the expected output of processing a Change
command is "doffed blue shirt, donned red shirt
" " then that is the String
object that you should return from the appropriate case when processing that Change
command object, i.e. it accepts
your DoCommandVisitor
visitor object.
Testing
Complete testing of your DoCommandVisitor
cases is required.
Test each case by creating a test cases that call each case explicitly with known host and Command
parameters. Then proceed to test the visitor as a whole.
Running the Simulation
GUI Mode
The supplied DrJava project is set up to run the GUI version of the simulation. Thus, clicking on the Run Project
button in DrJava will run the GUI version of the simulation (See sample laundry test class edu.rice.comp211.laundry.tests.LaundryTest
for examples of how to test an entire command both manually and by using an input test file and comparison output file.
The Test Project
button in DrJava runs all of the JUnit test files in the project.
Use the test files in the data} folder as guides for inputs and expected outputs. For example, given the text input in {{sampleIn.txt
, your program should generate the text in sampleOut.txt
. testIn.txt
is a fairly extensive test. You'll probably want to start with something smaller such as sampleIn.txt} or {{tinyIn.txt
though.
Initially, the provided framework should compile but LaundryTest
will fail because most of the members in the key class DoCommandVisitor
have been stubbed out.
The Student
class includes:
- the name of the student,
- the closet shelf with its piles of clean clothes,
- the dirty laundry pile, and
- the laundry room with its piles of laundered garmets sitting on tables.
- and methods to manipulate those data representations to perform the specified simulation
Wiki Markup |
---|
When the simulation begins, Acker is wearing _white_ pants, _white_ socks, and a _white_ shirt. The closet shelf, dirty laundry pile, and laundry facilities are all initially empty. The program starts execution using the special method {{public static void main(String\[\] args)}} in class {{Main}}. The {{main}} method interface is the only vehicle for executing Java programs directly from the command line. (DrJava has a {{main}} method for this reason.) |
Your solution will be graded using the textual interface. Graphical interfaces are notoriously difficult to test and all of the graphical interface code is part of our support code anyway. Your correctness and testing scores (which each count 25% of your grade) will be based on how well your implementation of each command complies with the given specifications and on how well you demonstrate this compliance with test cases. You can test your DoCommandVisitor using the same approach given in our LaundryTest.java
class. These tests use the simulate
method in Student
to drive the execution of DoCommandVisitor
. If you write some utility methods fopr BiLists
you should separately test these methods. You are NOT responsible for testing any of our support code in laundry.zip
including the BiList
class.
A major portion of your grade (35%) will be based on your program style. If you write your code in the OO style practiced in this course, you should do very well on this aspect of the assignment. The remaining 15% of your grade is based on your documentation, particularly your javadoc
comments for classes and methods.
Form of Event Commands
Your program executes a loop that repeatedly reads input from an input "process" that returns Command
objects. The input process (provided by our supporting framework) reads a series of event description commands, one to a line, either from the console or from a file. The input process converts a stream of characters to Command
objects which are passed to your program.
In addition to performing the specified command, your program should output a brief description of for each command that it performs in the exact format described below. In the following list of commands, the output line specifies what your program should print.
ui.SimLaundry2010Application
), which enables you to load test files and either step through them one command at a time or run all the commands automatically. The output will appear in the Interactions pane.
The GUI version also allows you to run individual commands. Select the "GUI
" mode from the drop list in the lower left corner of the window.
Text Mode
You may find it easier to run the simulation as a textual input application. Simply right-click the {edu.rice.comp211.laundry.Main.java}} file and select "Run File
" or change the the DrJava project properties to change the Main Class
to this classand then use the Run Project
button.
In the text mode, you simply type in each command, such as "receive blue socks
" into the input box that will appear in the Interactions pane. See below for more information on the command format. The output will show immediately below in the Interactions pane and new input box will appear.
Testing
Complete testing of your DoCommandVisitor
cases is required.
Test each case by creating a test cases that call each case explicitly with known host and Command
parameters. Then proceed to test the visitor as a whole.
See sample laundry test class edu.rice.comp211.laundry.tests.LaundryTest
for examples of how to test an entire command both manually and by using an input test file and comparison output file.
The Test Project
button in DrJava runs all of the JUnit test files in the project.
Use the test files in the data} folder as guides for inputs and expected outputs. For example, given the text input in {{sampleIn.txt
, your program should generate the text in sampleOut.txt
. testIn.txt
is a fairly extensive test. You'll probably want to start with something smaller such as sampleIn.txt} or {{tinyIn.txt
though.
Initially, the provided framework should compile but LaundryTest
will fail because most of the members in the key class DoCommandVisitor
have been stubbed out.
Important Note: When the simulation begins, Acker is wearing white pants, white socks, and a white shirt. The closet shelf, dirty laundry pile, and laundry facilities are all initially empty.
Assume that the supplied test files are NOT exhaustive!! You are responsible for the complete testing of your code!
Grading
Your solution will be graded using the textual interface. Graphical interfaces are notoriously difficult to test and all of the graphical interface code is part of our support code anyway. Your correctness and testing scores (which each count 25% of your grade) will be based on how well your implementation of each command complies with the given specifications and on how well you demonstrate this compliance with test cases. You can test your DoCommandVisitor using the same approach given in our LaundryTest.java
class. These tests use the simulate
method in Student
to drive the execution of DoCommandVisitor
. If you write some utility methods fopr BiLists
you should separately test these methods. You are NOT responsible for testing any of our support code in HW10.zip
including the BiList
class.
A major portion of your grade (35%) will be based on your program style. If you write your code in the OO style practiced in this course, you should do very well on this aspect of the assignment. The remaining 15% of your grade is based on your documentation, particularly your javadoc
comments for classes and methods.
The Student
class includes:
- the name of the student,
- the closet shelf with its piles of clean clothes,
- the dirty laundry pile, and
- the laundry room with its piles of laundered garmets sitting on tables.
- and methods to manipulate those data representations to perform the specified simulation
Form of Event Commands
Your program executes a loop that repeatedly reads input from an input "process" that returns Command
objects. The input process (provided by our supporting framework) reads a series of event description commands, one to a line, either from the console or from a file. The input process converts a stream of characters to Command
objects which are passed to your program.
In addition to performing the specified command, your program should output a brief description of for each command that it performs in the exact format described below. In the following list of commands, the output line specifies what your program should print.
- The command
means Acker received a gift of the specified article (<adjective> <article>) of clothing. In response, the simulation outputsCode Block receive <adjective> <article>
The commandCode Block received
means Acker received a gift of the specified article (<adjective> <article>) of clothing. In response, the simulation outputsCode Block receive <adjective> <article>
and updates the state of theCode Block received <adjective> <article>
StudentEnvironment
. For example,
generatesCode Block receive argyle socks
and adds theCode Block received argyle socks
argyle socks
to the top of thesocks
pile on the shelf.
The command
means Acker misplaced the specified article of clothing. If the item exists and Acker is not wearing it, the simulation outputsCode Block lose <adjective> <article>
and updates the state of theCode Block lost <adjective> <article>
StudentEnvironment
accordingly. If Acker is wearing it, the simulation outputs . For example,
and leaves theCode Block Ackerreceive is wearing <adjective> <article>
StudentEnvironment
unchanged. If the item does not exist, the simulation outputs
generatesargyle socks
and leaves theCode Block <adjective>received <article> does not existargyle socks
StudentEnvironment
unchangedadds theargyle socks
to the top of thesocks
pile on the shelf. - The command
means Acker doffed misplaced the specified article of clothing, discarding it in the dirty laundry pile, and donned a replacement article using the protocol described above. In response. If the item exists and Acker is not wearing it, the simulation outputsCode Block changelose <adjective> <article>
and updates the state of theCode Block doffedlost <adjective> <article>
StudentEnvironment
accordingly. If Acker is wearing it, the simulation outputs
describing the article doffed and the article donned.Code Block Acker is wearing donned <adjective> <article>
The command
means Acker washed and dried a load of laundry. If the dirty clothes pile is not emptyleaves theCode Block {{launder}}
StudentEnvironment
unchanged. If the item does not exist, the simulation outputs
listing the clothes in the order they were removed from the dirty clothes pile. If the dirty clothes pile is empty, the simulation outputsCode Block washed <adjective> <article>, ..., <adjective> <article>
Code Block nothing to wash
and leaves thedoes not exist
StudentEnvironment
unchanged. - The command
means Acker retrieved a load of laundry, folded it, and put it on the closet shelf. If a load of laundry is availabledoffed the specified article of clothing, discarding it in the dirty laundry pile, and donned a replacement article using the protocol described above. In response, the simulation outputsCode Block foldchange <article>
for the oldest unfolded load. List the clothes in the order they are placed on the shelf. Hence the top garment on the shelf should be the last one listed. If no load of laundry has been washed and dried, then the simulation outputs describing the article doffed and the article donned.Code Block foldeddoffed <adjective> <article>, ...,donned <adjective> <article>
- The command
means Acker washed and dried a load of laundry. If the dirty clothes pile is not emptyCode Block {{launder}}
If the oldest load is empty (because all items in it were lost), the simulation outputsCode Block nothing to fold
The commandCode Block folded empty load
asks "what is Acker wearing?" The simulation outputsCode Block outfit
Code Block wearing <adjective> <shirt>, <adjective> pantswashed <adjective> <article>, ..., <adjective> socks
Supporting Code and Programming Details
Our supporting framework is provided in the zip file laundry.zip\. The test input in the file sampleIn
(with corresponding output) sampleOut
is far from comprehensive.
All of our supporting code is included in the unzipped project. Each file resides in a package that is identified by a package
statement at the beginning of the file. Most support classes are public
so that they can be accessed anywhere. Classes without a visibility modifier have "default" visibility, which means that they can only be accessed from classes within the same package.
Our supporting framework includes an input processor that reads event commands from the input stream and returns high level data representations for these commands. The input processor can also print debugging output describing the state of your simulation before each command is performed. To communicate with your code, the input processor uses four interfaces:
IOProcess
which describes the visible methods supported by the input processor;
StudentEnvironment
which describes methods for inspecting the state of Acker's environment;
EnumI
which describes methods for inspecting (but not mutating!) lists within Acker's environment; and
ReadIteratorI
which includes methods for moving a cursor through lists implementing the EnumI
interface.
The interfaces are already defined in the framework provided by the course staff.
The input processor class TerminalIO
implements the IOProcess
interface. You are welcome to inspect the code of TerminalIO
but it relies heavily on the Java I/O library, particularly the class StreamTokenizer
. To understand this code, you will need to read Chapter 11 of JLS (or similar reference). The framework also includes implementations of EnumI
and ReadIteratorI
as part of a BiList
(mutable circular doubly linked list) class implementation.
The Student
class implements the StudentEnvironment
interface, which includes the simulate
method supporting the laundry simulation. The simulate method contains a loop that reads commands from its IOProcess
and invokes DoCommandVisitor
on each command. Within the DoCommandVistor
class you must implement methods that process the various possible commands.
The program includes two class definitions defining unions (composites without recursion): Garment
, specifying the representation of garments that appear in the input stream, and Command
, specifying the representation of event description commands. Both classes include the hooks required to support the visitor pattern. The data definition for Garment
is important because the graphical version of the user interface included in the framework animates the state of your implementation before each command. This graphical user interface (GUI) expects the garments that appear as elements in lists (as revealed by the EnumI
and ReadIteratorI
interfaces) to be instances of the Garment
class. Hence, you must use the representation of garments that our class Garment
provides.
The file DoCommandVisitor.java
contains comments describing all of the members that you need to write. This class could have been defined as an inner class of Student
but we made it a top level class to simplify debugging.
The IOProcess
interface includes a method PrintStream open(StudentEnvironmenta, boolean debug)
which initializes an IOProcess
object for a laundry simulation of the specified environment and returns the PrintStream
object to be used for terminal output. (Up to now you have implicitly used the PrintStream
object System.out
.) The PrintStream
method println(String s)
prints the string s
followed by a newline character to the PrintStream
. The boolean debug
argument indicates whether or not debugging output should be produced. The IOProcess
interface also includes a method nextCommand
which reads the next command from the input channel supported by the IOProcess
object.
Each call on nextCommand
returns the next command in the stream provided by the IOProcess
object, until it reaches an end-of-file (<control>-d
from the keyboard). End-of-file is reported as a null reference of type Command
.
The nextCommand
method in TerminalIO
processes character strings consisting of words separated by ``space'' characters such as ' '
and '\n'
. A word
is any sequence of printable characters other than space, '\n'
(newline), and '\r'
. (return). An adjective
must be a single word. An article
must be one the words shirt
, pants
, or socks
. The same adjective, say argyle
may be applied to garments of different types, but there are no duplicate items of clothing.
The program passes a boolean debug flag
to (TerminalIO
). The value of the flag is true iff the command line argument -d
or -debug
is passed to main
.
The Graphical User Interface (GUI)
The initialization of the GUI creates an Acker Student object and associated DoCommandVisitor. Each GUI event triggers the execution of DoCommandVisitor; in some cases, such as reading input from a file, it triggers the execution of DoCommandVisitor on a stream of Commands. In essence, the event-handling loop built-in to the Java Swing framework is used to drive the computation rather than a separate loop in the main thread such as the one in the simulate method in Student.
The GUI could also have been written as an implementation of the IOProcess interface. This approach, which conforms to the classic "model-view-controller" (MVC) pattern, is more flexible because it decouples the GUI (the view in MVC terminology) from the model, but it is also more complex because it involves the cooperative execution of
two loops in separate threads--a main program loop in the simulate method of Student and the loop driving the event-handling thread supporting the processing of GUI inputs. The SimLaundryApplication dispenses with the main program loop by absorbing the application (the model) into the GUI (the view).
Efficiency
For this assignment, you should be concerned about relevant asymptotic efficiency. Choose the simplest representation that yields good performance on inputs of plausible size.
Changing an article of clothing should take constant time (i.e., no searching should be done) provided there's an appropriate garment on the shelf. If the shelf contains no clothing of that type, then in the common case we expect to find one of those near the bottom of the pile, no matter how big the pile is: make that case fast. Infrequent operations need not be particularly fast, because they have little impact on the running time of the entire system. (Suppose one operation accounts for 5% of the running time, and we can make it run 10 times as fast. How does that compare to making an operation that accounts for 25% of the running time twice as fast?)
Example
With Acker initially wearing white shirt, socks, and pants, given the input:
Code Block |
---|
receive blue socks
receive green pants
receive red shirt
change socks
receive yellow shirt
change shirt
outfit
change socks
launder
change pants
fold
change socks
|
your program should produce:
Code Block |
---|
received blue socks
received green pants
received red shirt
doffed white socks, donned blue socks
received yellow shirt
doffed white shirt, donned yellow shirt
wearing yellow shirt, white pants, blue socks
doffed blue socks, donned white socks
washed blue socks, white shirt
doffed white pants, donned green pants
folded blue socks, white shirt
doffed white socks, donned blue socks
|
The sample input and output files tinyin
and tinyout
are a good starting point for testing your program but they are far from exhaustive.
listing the clothes in the order they were removed from the dirty clothes pile. If the dirty clothes pile is empty, the simulation outputs<article>
Code Block nothing to wash
- The command
means Acker retrieved a load of laundry, folded it, and put it on the closet shelf. If a load of laundry is available, the simulation outputsCode Block fold
for the oldest unfolded load. List the clothes in the order they are placed on the shelf. Hence the top garment on the shelf should be the last one listed. If no load of laundry has been washed and dried, then the simulation outputsCode Block folded <adjective> <article>, ..., <adjective> <article>
If the oldest load is empty (because all items in it were lost), the simulation outputsCode Block nothing to fold
Code Block folded empty load
- The command
asks "what is Acker wearing?" The simulation outputsCode Block outfit
Code Block wearing <adjective> <shirt>, <adjective> pants, <adjective> socks
Supporting Code and Programming Details
Code Details
Our supporting framework is provided in the zip file laundry.zip\. The test input in the file sampleIn
(with corresponding output) sampleOut
is far from comprehensive.
All of our supporting code is included in the unzipped project. Each file resides in a package that is identified by a package
statement at the beginning of the file. Most support classes are public
so that they can be accessed anywhere. Classes without a visibility modifier have "default" visibility, which means that they can only be accessed from classes within the same package.
Our supporting framework includes an input processor that reads event commands from the input stream and returns high level data representations for these commands. The input processor can also print debugging output describing the state of your simulation before each command is performed. To communicate with your code, the input processor uses four interfaces:
IOProcess
which describes the visible methods supported by the input processor;
StudentEnvironment
which describes methods for inspecting the state of Acker's environment;
EnumI
which describes methods for inspecting (but not mutating!) lists within Acker's environment; and
ReadIteratorI
which includes methods for moving a cursor through lists implementing the EnumI
interface.
The interfaces are already defined in the framework provided by the course staff.
The input processor class TerminalIO
implements the IOProcess
interface. You are welcome to inspect the code of TerminalIO
but it relies heavily on the Java I/O library, particularly the class StreamTokenizer
. To understand this code, you will need to read Chapter 11 of JLS (or similar reference). The framework also includes implementations of EnumI
and ReadIteratorI
as part of a BiList
(mutable circular doubly linked list) class implementation.
The Student
class implements the StudentEnvironment
interface, which includes the simulate
method supporting the laundry simulation. The simulate method contains a loop that reads commands from its IOProcess
and invokes DoCommandVisitor
on each command. Within the DoCommandVistor
class you must implement methods that process the various possible commands.
The program includes two class definitions defining unions (composites without recursion): Garment
, specifying the representation of garments that appear in the input stream, and Command
, specifying the representation of event description commands. Both classes include the hooks required to support the visitor pattern. The data definition for Garment
is important because the graphical version of the user interface included in the framework animates the state of your implementation before each command. This graphical user interface (GUI) expects the garments that appear as elements in lists (as revealed by the EnumI
and ReadIteratorI
interfaces) to be instances of the Garment
class. Hence, you must use the representation of garments that our class Garment
provides.
The file DoCommandVisitor.java
contains comments describing all of the members that you need to write. This class could have been defined as an inner class of Student
but we made it a top level class to simplify debugging.
The IOProcess
interface includes a method PrintStream open(StudentEnvironmenta, boolean debug)
which initializes an IOProcess
object for a laundry simulation of the specified environment and returns the PrintStream
object to be used for terminal output. (Up to now you have implicitly used the PrintStream
object System.out
.) The PrintStream
method println(String s)
prints the string s
followed by a newline character to the PrintStream
. The boolean debug
argument indicates whether or not debugging output should be produced. The IOProcess
interface also includes a method nextCommand
which reads the next command from the input channel supported by the IOProcess
object.
Each call on nextCommand
returns the next command in the stream provided by the IOProcess
object, until it reaches an end-of-file (<control>-d
from the keyboard). End-of-file is reported as a null reference of type Command
.
The nextCommand
method in TerminalIO
processes character strings consisting of words separated by ``space'' characters such as ' '
and '\n'
. A word
is any sequence of printable characters other than space, '\n'
(newline), and '\r'
. (return). An adjective
must be a single word. An article
must be one the words shirt
, pants
, or socks
. The same adjective, say argyle
may be applied to garments of different types, but there are no duplicate items of clothing.
The program passes a boolean debug flag
to (TerminalIO
). The value of the flag is true iff the command line argument -d
or -debug
is passed to main
.
The Graphical User Interface (GUI)
The initialization of the GUI creates an Acker Student object and associated DoCommandVisitor. Each GUI event triggers the execution of DoCommandVisitor; in some cases, such as reading input from a file, it triggers the execution of DoCommandVisitor on a stream of Commands. In essence, the event-handling loop built-in to the Java Swing framework is used to drive the computation rather than a separate loop in the main thread such as the one in the simulate method in Student.
The GUI could also have been written as an implementation of the IOProcess interface. This approach, which conforms to the classic "model-view-controller" (MVC) pattern, is more flexible because it decouples the GUI (the view in MVC terminology) from the model, but it is also more complex because it involves the cooperative execution of
two loops in separate threads--a main program loop in the simulate method of Student and the loop driving the event-handling thread supporting the processing of GUI inputs. The SimLaundryApplication dispenses with the main program loop by absorbing the application (the model) into the GUI (the view).
Efficiency
For this assignment, you should be concerned about relevant asymptotic efficiency. Choose the simplest representation that yields good performance on inputs of plausible size.
Changing an article of clothing should take constant time (i.e., no searching should be done) provided there's an appropriate garment on the shelf. If the shelf contains no clothing of that type, then in the common case we expect to find one of those near the bottom of the pile, no matter how big the pile is: make that case fast. Infrequent operations need not be particularly fast, because they have little impact on the running time of the entire system. (Suppose one operation accounts for 5% of the running time, and we can make it run 10 times as fast. How does that compare to making an operation that accounts for 25% of the running time twice as fast?)
Example
With Acker initially wearing white shirt, socks, and pants, given the input:
Code Block |
---|
receive blue socks
receive green pants
receive red shirt
change socks
receive yellow shirt
change shirt
outfit
change socks
launder
change pants
fold
change socks
|
your program should produce:
Code Block |
---|
received blue socks
received green pants
received red shirt
doffed white socks, donned blue socks
received yellow shirt
doffed white shirt, donned yellow shirt
wearing yellow shirt, white pants, blue socks
doffed blue socks, donned white socks
washed blue socks, white shirt
doffed white pants, donned green pants
folded blue socks, white shirt
doffed white socks, donned blue socks
|
The sample input and output files tinyIn.txt
and tinyOut.txt
are a good starting point for testing your program but they are far from exhaustive.
You are responsible for testing your own program.
Supplemental Program Running Information
Wiki Markup |
---|
The program starts execution using the special method {{public static void main(String\[\] args)}} in class {{Main}}. The {{main}} method interface is the only vehicle for executing Java programs directly from the command line. (DrJava has a {{main}} method for this reason.) |
You are responsible for testing your own program. Since your class containing main
is called edu.rice.comp211.laundry.Main
, you can enter the line
...