<div class="xblock xblock-public_view xblock-public_view-vertical" data-request-token="102f5a6ae9a311efb7c90e0e3c45b88f" data-usage-id="block-v1:MITx+6.005.2x+1T2017+type@vertical+block@vertical-ps2-beta" data-graded="True" data-has-score="False" data-runtime-version="1" data-block-type="vertical" data-init="VerticalStudentView" data-course-id="course-v1:MITx+6.005.2x+1T2017" data-runtime-class="LmsRuntime">
<h2 class="hd hd-2 unit-title">Problem Set 2</h2>
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:MITx+6.005.2x+1T2017+type@html+block@html_3c46015bc990">
<div class="xblock xblock-public_view xblock-public_view-html xmodule_display xmodule_HtmlBlock" data-request-token="102f5a6ae9a311efb7c90e0e3c45b88f" data-usage-id="block-v1:MITx+6.005.2x+1T2017+type@html+block@html_3c46015bc990" data-graded="True" data-has-score="False" data-runtime-version="1" data-block-type="html" data-init="XBlockToXModuleShim" data-course-id="course-v1:MITx+6.005.2x+1T2017" data-runtime-class="LmsRuntime">
<script type="json/xblock-args" class="xblock-json-init-args">
{"xmodule-type": "HTMLModule"}
</script>
<link href="/assets/courseware/v1/d93415c23438bb0217f0599a34bdff10/asset-v1:MITx+6.005.2x+1T2017+type@asset+block/prism-edx-v1.css" rel="stylesheet" type="text/css" />
<h1 class="handout-title col-sm-8 col-sm-offset-2" id="problem_set_1_tweet_tweet">Problem Set 2 Starting Code</h1>
<div>
<p>Download the starting code for Problem Set 2 here:</p>
<blockquote>
<a href="/assets/courseware/v1/eba1ec305e98cf86bff3a45e2da3bad4/asset-v1:MITx+6.005.2x+1T2017+type@asset+block/ps2.zip">ps2.zip</a>
</blockquote>
<p>The process for doing this problem set is the same as in <a href="/courses/course-v1:MITx+6.005.2x+1T2017/jump_to_id/vertical-ps1-beta#import">Problem Set 1</a>, but here are quick reminders:</p>
<ul>
<li>
<p>To import the starting code into Eclipse, use File → Import... → General → Existing Projects Into Workspace → Select Archive File, then Browse to find where you downloaded ps2.zip. Make sure <code>ps2-minesweeper</code> is checked and click Finish.</p>
</li>
<li>
<p>To run JUnit tests, right-click on the <code>test</code> folder in Eclipse and choose Run As → JUnit Test.</p>
</li>
<li>
<p>This problem set has no <code>main()</code> method to run, just tests.</p>
</li>
<li>
<p>To run the autograder, right-click on <code>grader.xml</code> in Eclipse and choose Run As → Ant Build.</p>
</li>
<li>
<p>To view the autograder results, make sure your project is Refreshed, then double-click on <code>my-grader-report.xml</code>.</p>
</li>
<li>
<p>To submit your problem set, upload <code>my-submission.zip</code> to the submission page, which is the last section of this handout, at the end of the section bar.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:MITx+6.005.2x+1T2017+type@html+block@html_89e4067421ce">
<div class="xblock xblock-public_view xblock-public_view-html xmodule_display xmodule_HtmlBlock" data-request-token="102f5a6ae9a311efb7c90e0e3c45b88f" data-usage-id="block-v1:MITx+6.005.2x+1T2017+type@html+block@html_89e4067421ce" data-graded="True" data-has-score="False" data-runtime-version="1" data-block-type="html" data-init="XBlockToXModuleShim" data-course-id="course-v1:MITx+6.005.2x+1T2017" data-runtime-class="LmsRuntime">
<script type="json/xblock-args" class="xblock-json-init-args">
{"xmodule-type": "HTMLModule"}
</script>
<link href="/assets/courseware/v1/d93415c23438bb0217f0599a34bdff10/asset-v1:MITx+6.005.2x+1T2017+type@asset+block/prism-edx-v1.css" rel="stylesheet" type="text/css" />
<style>
table.message-table {
width:auto!important;
}
.pull-left {
padding-right: 10px;
}
</style>
<h1 class="handout-title col-sm-8 col-sm-offset-2" id="problem_set_1_tweet_tweet">Problem Set 2: Multiplayer Minesweeper</h1>
<h2 id="overview">Overview</h2>
<div data-outline="overview"><p>You will start with some minimal server code and implement a server and threadsafe data structure for playing a multiplayer variant of the classic computer game “Minesweeper.” </p><ul>
<li><p>You can review the <a href="http://en.wikipedia.org/wiki/Minesweeper_(video_game)"><strong>rules of traditional single-player Minesweeper</strong> on Wikipedia</a>.</p></li>
<li><p>You can also <a href="http://minesweeperonline.com/"><strong>play traditional single-player Minesweeper</strong> online</a>. </p>
<p>(You may notice that the implementation in the latter link above does something subtle.
It ensures that there’s never a bomb where you make your first click of the game.
You should <em>not</em> implement this for the assignment.
It would be in conflict with giving the option to pass in a pre-designed board, for example.) </p></li>
</ul><p>Your final product will consist of a server and no client; it should be fully playable using the <code>telnet</code> utility to send text commands directly over a network connection as described below.</p><h3 id="multiplayer_minesweeper_server">Multiplayer Minesweeper server</h3><div data-outline="multiplayer_minesweeper_server"><p>We will refer to the board as a grid of squares.
Each square is either <em>flagged</em>, <em>dug</em>, or <em>untouched</em>.
Each square also either contains a bomb, or does not contain a bomb.</p><p>Our variant works very similarly to standard Minesweeper, but with multiple players simultaneously playing on a single board.
In both versions, players lose when they try to dig an untouched square that happens to contain a bomb.
Whereas a standard Minesweeper game would end at this point, in our version, the game keeps going for the other players.
In our version, when one player blows up a bomb, they still lose, and the game ends for them (the server ends their connection), but the other players may continue playing.
The square where the bomb was blown up is now a <em>dug</em> square with no bomb.
The player who lost may reconnect to the same game again via <code>telnet</code> to start playing again.</p><p>Note that there are some tricky cases of user-level concurrency.
For example, say user <em>A</em> has just modified the game state (i.e. by digging in one or more squares) such that square <em>i,j</em> obviously has a bomb.
Meanwhile, user <em>B</em> has not observed the board state since this update has taken place, so user <em>B</em> goes ahead and digs in square <em>i,j</em>.
Your program should allow the user to dig in that square — a user of Multiplayer Minesweeper must accept this kind of risk.</p><p>We are not specifically defining, or asking you to implement, any kind of “win condition” for the game.</p></div><h3 id="telnet_client">Telnet client</h3><div data-outline="telnet_client"><p><code>telnet</code> is a utility that allows you to make a direct network connection to a listening server and communicate with it via a terminal interface.
Before starting this problem set, please ensure that you have <code>telnet</code> installed.
*nix operating systems (including Mac OS X) should have <code>telnet</code> installed by default.</p><p>Windows users should first check if telnet is installed by running the command <code>telnet</code> on the command line.</p><ul>
<li><p>If you do not have <code>telnet</code>, you can install it via Control Panel → Programs and Features → Turn Windows features on/off → Telnet client.
However, this version of <code>telnet</code> may be very hard to use.
If it does not show you what you’re typing, you will need to <a href="https://technet.microsoft.com/en-us/library/c.aspx">turn on the <code>localecho</code> option</a>.</p></li>
<li><p>A better alternative is PuTTY: <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">download <code>putty.exe</code></a>.
To connect using PuTTY, enter a hostname and port, select Connection type: Raw, and Close window on exit: Never.
The last option will prevent the window from disappearing as soon as the server closes its end of the connection.</p></li>
</ul><p>You can have <code>telnet</code> connect to a host and port (for example, <code>web.mit.edu:80</code>) from the command line with:</p><pre><code>telnet web.mit.edu 80
</code></pre><p>Since port 80 is usually used for HTTP, we can now make HTTP requests through <code>telnet</code>.
If you now type (where ↵ indicates a newline):</p><pre><code>GET /↵
</code></pre><p><code>telnet</code> should retrieve the HTML for the webpage at <a href="http://web.mit.edu">web.mit.edu</a>.
If you want to connect to your own machine, you can use <code>localhost</code> as the hostname and whatever port your server is listening on.
With the default port of 4444 in this problem set, you can connect to your running Minesweeper server with:</p><pre><code>telnet localhost 4444
</code></pre><p>The server may close the network connection at any time, at which point <code>telnet</code> will exit.
To close a connection from the client, note the first output printed by telnet when it connects:</p><pre><code>Trying 18.9.22.69...
Connected to web.mit.edu.
Escape character is '^]'.
</code></pre><p><code>^]</code> means <code>Ctrl</code>-<code>]</code>, so press that.
Then enter <code>quit</code> to close the connection and exit telnet.</p><hr></div></div>
<h2 id="protocol_and_specification">Protocol and specification</h2>
<div data-outline="protocol_and_specification"><p>You must implement the following protocol for communication between the user and the server.</p><p>The messages in this protocol are described precisely and comprehensively using a pair of grammars.
Your server must accept any incoming message that satisfies the user-to-server grammar, react appropriately, and generate only outgoing messages that satisfy the server-to-user grammar.</p><ul>
<li><p><a href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">Wikipedia description of the <strong>grammar notation: Backus–Naur Form</strong></a></p></li>
<li><p><a href="http://en.wikipedia.org/wiki/Regular_expression">Wikipedia description of <strong>regular expressions</strong>, which are used on the right-hand side of grammar productions</a></p></li>
</ul><h3 id="usertoserver">Messages from the user to the server</h3><div data-outline="usertoserver"><h4>Formal grammar</h4><blockquote class="message-user pull-margin"><pre><code>MESSAGE ::= ( LOOK | DIG | FLAG | DEFLAG | HELP_REQ | BYE ) NEWLINE
LOOK ::= "look"
DIG ::= "dig" SPACE X SPACE Y
FLAG ::= "flag" SPACE X SPACE Y
DEFLAG ::= "deflag" SPACE X SPACE Y
HELP_REQ ::= "help"
BYE ::= "bye"
NEWLINE ::= "\n" | "\r" "\n"?
X ::= INT
Y ::= INT
SPACE ::= " "
INT ::= "-"? [0-9]+
</code></pre></blockquote><p>Each message starts with a message type and arguments to the message are separated by a single SPACE character and the message ends with a NEWLINE.
The NEWLINE can be a single character <code>"\n"</code> or <code>"\r"</code> or the two-character sequence <code>"\r\n"</code>, <a href="#tips">the same definition used by <code>BufferedReader.readLine()</code></a>.</p><p>The user can send the following messages to the server: </p><h4>LOOK message</h4><blockquote class="message-user"><p>The message type is the word “look” and there are no arguments.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>l</td>
<td>o</td>
<td>o</td>
<td>k</td>
<td>\n</td>
</tr>
</tbody></table>
<p>Returns a BOARD message, a string representation of the board’s state.
Does not mutate anything on the server.
See the section below on <a href="#servertouser">messages from the server to the user</a> for the exact required format of the BOARD message.</p></blockquote><h4>DIG message</h4><blockquote class="message-user"><p>The message is the word “dig” followed by two arguments, the X and Y coordinates.
The type and the two arguments are separated by a single SPACE.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>d</td>
<td>i</td>
<td>g</td>
<td> </td>
<td>3</td>
<td> </td>
<td>1</td>
<td>0</td>
<td>\r</td>
<td>\n</td>
</tr>
</tbody></table>
<p>The dig message has the following properties: </p>
<ol>
<li>If either x or y is less than 0, or either x or y is equal to or greater than the board size, or square x,y is not in the <em>untouched</em> state, do nothing and return a BOARD message.</li>
<li>If square x,y’s state is <em>untouched</em>, change square x,y’s state to <em>dug</em>.</li>
<li>If square x,y contains a bomb, change it so that it contains no bomb and send a BOOM message to the user.
Then, if the debug flag is missing (see Question 4), terminate the user’s connection.
See again the section below for the exact required format of the BOOM message.
Note: When modifying a square from containing a bomb to no longer containing a bomb, make sure that subsequent BOARD messages show updated bomb counts in the adjacent squares.
After removing the bomb continue to the next step.</li>
<li>If the square x,y has no neighbor squares with bombs, then for each of x,y’s <em>untouched</em> neighbor squares, change said square to <em>dug</em> and repeat <em>this step</em> (not the entire DIG procedure) recursively for said neighbor square unless said neighbor square was already dug before said change.</li>
<li>For any DIG message where a BOOM message is not returned, return a BOARD message.</li>
</ol></blockquote><h4>FLAG message</h4><blockquote class="message-user"><p>The message type is the word “flag” followed by two arguments the X and Y coordinates.
The type and the two arguments are separated by a single SPACE.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>f</td>
<td>l</td>
<td>a</td>
<td>g</td>
<td> </td>
<td>1</td>
<td>1</td>
<td> </td>
<td>8</td>
<td>\n</td>
</tr>
</tbody></table>
<p>The flag message has the following properties: </p>
<ol>
<li>If x and y are both greater than or equal to 0, and less than the board size, and square x,y is in the <em>untouched</em> state, change it to be in the <em>flagged</em> state.</li>
<li>Otherwise, do not mutate any state on the server.</li>
<li>For any FLAG message, return a BOARD message.</li>
</ol></blockquote><h4>DEFLAG message</h4><blockquote class="message-user"><p>The message type is the word “deflag” followed by two arguments the X and Y coordinates.
The type and the two arguments are separated by a single SPACE.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>d</td>
<td>e</td>
<td>f</td>
<td>l</td>
<td>a</td>
<td>g</td>
<td> </td>
<td>9</td>
<td> </td>
<td>9</td>
<td>\n</td>
</tr>
</tbody></table>
<p>The flag message has the following properties: </p>
<ol>
<li>If x and y are both greater than or equal to 0, and less than the board size, and square x,y is in the <em>flagged</em> state, change it to be in the <em>untouched</em> state.</li>
<li>Otherwise, do not mutate any state on the server.</li>
<li>For any DEFLAG message, return a BOARD message.</li>
</ol></blockquote><h4>HELP_REQ message</h4><blockquote class="message-user"><p>The message type is the word “help” and there are no arguments.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>h</td>
<td>e</td>
<td>l</td>
<td>p</td>
<td>\r</td>
<td>\n</td>
</tr>
</tbody></table>
<p>Returns a HELP message (see below).
Does not mutate anything on the server.</p></blockquote><h4>BYE message</h4><blockquote class="message-user"><p>The message type is the word “bye” and there are no arguments.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>b</td>
<td>y</td>
<td>e</td>
<td>\r</td>
<td>\n</td>
</tr>
</tbody></table>
<p>Terminates the connection with this client.</p></blockquote></div><h3 id="servertouser">Messages from the server to the user</h3><div data-outline="servertouser"><h4>Formal grammar</h4><blockquote class="message-server pull-margin"><pre><code>MESSAGE ::= BOARD | BOOM | HELP | HELLO
BOARD ::= LINE+
LINE ::= (SQUARE SPACE)* SQUARE NEWLINE
SQUARE ::= "-" | "F" | COUNT | SPACE
SPACE ::= " "
NEWLINE ::= "\n" | "\r" "\n"?
COUNT ::= [1-8]
BOOM ::= "BOOM!" NEWLINE
HELP ::= [^\r\n]+ NEWLINE
HELLO ::= "Welcome to Minesweeper. Players: " N " including you. Board: "
X " columns by " Y " rows. Type 'help' for help." NEWLINE
N ::= INT
X ::= INT
Y ::= INT
INT ::= "-"? [0-9]+
</code></pre></blockquote><p>There are no message types in the messages sent by the server to the user.
<strong>The server sends the HELLO message as soon as it establishes a connection to the user.</strong>
After that, for any message it receives that matches the user-to-server message format, other than a BYE message, the server should always return either a BOARD message, a BOOM message, or a HELP message.</p><p><strong>For any message from the user which does not match the user-to-server message format</strong>, discard the incoming message and send a HELP message as the reply to the user.</p><p>The action to take for each different kind of message is as follows: </p><h4>HELLO message</h4><blockquote class="message-server"><p>In this message:</p>
<ul>
<li><em>N</em> is the number of users currently connected to the server, and</li>
<li>the board is <em>X × Y</em>.</li>
</ul>
<p>This message should be sent to the user exactly as defined and only once, immediately after the server connects to the user.
Again the message should end with a NEWLINE.</p>
<p>Example:</p>
<table class="message-table no-markdown">
<tbody><tr>
<td>W</td>
<td>e</td>
<td>l</td>
<td>c</td>
<td>o</td>
<td>m</td>
<td>e</td>
<td> </td>
<td>t</td>
<td>o</td>
<td> </td>
<td>M</td>
<td>i</td>
<td>n</td>
<td>e</td>
<td>s</td>
<td>w</td>
<td>e</td>
<td>e</td>
<td>p</td>
</tr><tr>
<td>e</td>
<td>r</td>
<td>.</td>
<td> </td>
<td>P</td>
<td>l</td>
<td>a</td>
<td>y</td>
<td>e</td>
<td>r</td>
<td>s</td>
<td>:</td>
<td> </td>
<td>1</td>
<td>2</td>
<td> </td>
<td>i</td>
<td>n</td>
<td>c</td>
<td>l</td>
</tr><tr>
<td>u</td>
<td>d</td>
<td>i</td>
<td>n</td>
<td>g</td>
<td> </td>
<td>y</td>
<td>o</td>
<td>u</td>
<td>.</td>
<td> </td>
<td>B</td>
<td>o</td>
<td>a</td>
<td>r</td>
<td>d</td>
<td>:</td>
<td> </td>
<td>8</td>
<td> </td>
</tr><tr>
<td>c</td>
<td>o</td>
<td>l</td>
<td>u</td>
<td>m</td>
<td>n</td>
<td>s</td>
<td> </td>
<td>b</td>
<td>y</td>
<td> </td>
<td>8</td>
<td> </td>
<td>r</td>
<td>o</td>
<td>w</td>
<td>s</td>
<td>.</td>
<td> </td>
<td>T</td>
</tr><tr>
<td>y</td>
<td>p</td>
<td>e</td>
<td> </td>
<td>'</td>
<td>h</td>
<td>e</td>
<td>l</td>
<td>p</td>
<td>'</td>
<td> </td>
<td>f</td>
<td>o</td>
<td>r</td>
<td> </td>
<td>h</td>
<td>e</td>
<td>l</td>
<td>p</td>
<td>.</td>
</tr><tr>
<td>\r</td>
<td>\n</td>
</tr>
</tbody></table></blockquote><h4>BOARD message</h4><blockquote class="message-server"><p>The message has no start type word and consists of a series of newline-separated rows of space-separated characters, thereby giving a grid representation of the board’s state with exactly one char for each square.
The mapping of characters is as follows: </p>
<ul>
<li>“-” for squares with state <em>untouched</em>.</li>
<li>“F” for squares with state <em>flagged</em>.</li>
<li>“ ” (space) for squares with state <em>dug</em> and 0 neighbors that have a bomb.</li>
<li>integer COUNT in range [1-8] for squares with state <em>dug</em> and COUNT neighbors that have a bomb.</li>
</ul>
<div class="pull-left"><p>Here is an example board message with 3 rows and 8 columns:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>2</td>
<td> </td>
<td>-</td>
<td> </td>
<td>-</td>
<td>\r</td>
<td>\n</td>
</tr>
<tr>
<td>1</td>
<td> </td>
<td>1</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>1</td>
<td> </td>
<td>F</td>
<td> </td>
<td>-</td>
<td> </td>
<td>-</td>
<td>\n </td>
</tr>
<tr>
<td>F</td>
<td> </td>
<td>1</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>1</td>
<td> </td>
<td>-</td>
<td> </td>
<td>-</td>
<td> </td>
<td>-</td>
<td>\n</td>
</tr>
</tbody></table>
<p>Notice that in this representation we reveal every square’s state of <em>untouched</em>, <em>flagged</em>, or <em>dug</em>, and we indirectly reveal limited information about whether some squares have bombs or not.</p>
<p>In the printed <strong>BOARD</strong> output, the (x,y) coordinates start at (0,0)
in the top-left corner, extend horizontally to the right in the X
direction, and vertically downwards in the Y direction. (While
different from the standard geometric convention for IV quadrant, this
happens to be the protocol specification.) So the following output
would represent a flagged square at <strong>(x=1,y=2)</strong> and the rest of the
squares being untouched:</p>
<pre class="no-markdown pull-left">- - - - - - -
- - - - - - -
- F - - - - -
- - - - - - -
- - - - - - -
- - - - - - -
- - - - - - -
</pre>
<div class="clearfix"></div>
<p>In order to conform to the protocol specification, you’ll need to preserve this arrangement of cells in board while writing the board messages.
If you change this order in either writing the board message or reading the board from a file (Problem 4) your implementation does not satisfy the spec.</p></blockquote><h4>BOOM message</h4><blockquote class="message-server"><p>The message is the word <em>BOOM!</em> followed by a NEWLINE.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>B</td>
<td>O</td>
<td>O</td>
<td>M</td>
<td>!</td>
<td>\r</td>
<td>\n</td>
</tr>
</tbody></table>
<p>The last message the client will receive from the server before it gets disconnected! </p></blockquote><h4>HELP message</h4><blockquote class="message-server"><p>The message is a sequence of non-NEWLINE characters (your help message) followed by NEWLINE.</p>
<div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>R</td>
<td>T</td>
<td>F</td>
<td>M</td>
<td>!</td>
<td>\n</td>
</tr>
</tbody></table>
<p>Unlike the above example, the HELP message should print out a message which indicates all the commands the user can send to the server.
The exact content of this message is up to you – but it is important that this message not contain multiple NEWLINEs.</p></blockquote><hr></div></div>
<h2 id="problem_1_set_up_the_server_to_deal_with_multiple_clients">Problem 1: set up the server to deal with multiple clients</h2>
<div data-outline="problem_1_set_up_the_server_to_deal_with_multiple_clients"><p>In <code>minesweeper.server.MinesweeperServer</code>, we have provided you with a single-threaded server which can accept connections with one client at a time, and which includes code to parse the input according to the client-server protocol above.</p><p>Modify the server so it can maintain multiple client connections simultaneously.
Each client connection should be maintained by its own thread.
You may wish to add another class to do this.</p><p>As always, all your code should be safe from bugs, easy to understand, and ready for change.
Be sure the code to implement multiple concurrent clients is written clearly and commented if necessary.</p><p>You may continue to do nothing with the parsed user input for now.</p><p>When you write tests in <code>MinesweeperServerTest.java</code>, you may write tests similar to the <a href="/assets/courseware/v1/d04d6df53726e0580cef62eaa5911c42/asset-v1:MITx+6.005.2x+1T2017+type@asset+block/PublishedTest.java"><strong>published test</strong></a> we provide, and you may also write tests using <a href="/courses/course-v1:MITx+6.005.2x+1T2017/jump_to_id/vertical-testing-clientserver#testing_clientserver_code"><code>ByteArrayInput</code>/<code>OutputStream</code> stubs as described in <em>Sockets & Networking</em></a>.</p><hr></div>
<h2 id="problem_2_design_a_data_structure_for_minesweeper">Problem 2: design a data structure for Minesweeper</h2>
<div data-outline="problem_2_design_a_data_structure_for_minesweeper"><p>In <code>minesweeper.Board</code>, we have provided a starting file for this problem.</p><p>Specify, test, and implement a data structure for representing the Minesweeper board (as a Java type, without using sockets or threads).
Define the <code>Board</code> ADT as well as any additional classes you might need to accomplish this.</p><p>You may ignore thread safety for now.</p><p>Your <code>Board</code> class (and other classes) must have specifications for all methods; abstraction function, rep invariant, and safety from rep exposure written as comments; and the rep invariant implemented as a <code>checkRep()</code> method called by your code.</p><hr></div>
<h2 id="problem_3_make_the_entire_system_thread-safe">Problem 3: make the entire system threadsafe</h2>
<div data-outline="problem_3_make_the_entire_system_thread-safe"><div class="list-style-lower-alpha"><ol>
<li><p>Come up with a strategy to make your system thread safe.
As we’ve learned, there are multiple ways to make a system thread safe.
For example, this can be done by:</p>
<ul><li>using immutable or threadsafe data structures</li>
<li>using a queue to send messages that will be processed sequentially by a single thread</li>
<li>using synchronized methods or the synchronized keyword at the right places</li>
<li>or combination of these techniques</li></ul></li>
<li><p>The specification for <code>Board</code> (and any other classes) should state whether that type is thead-safe.</p>
<p>In addition to the other internal documentation, <code>Board</code> (and any other classes) must document their thread safety argument.
Depending on your design, the board (or other classes) may <strong><em>not</em></strong> be threadsafe.
If so, document that.</p>
<p>You will also document your system thread safety argument in <code>MinesweeperServer.java</code> in problem 5.</p>
<p>SFB, ETU, RFC: be sure any code to implement thread safety is written clearly and commented if necessary.</p></li>
</ol></div><hr></div>
<h2 id="problem_4_initialize_the_board_based_on_command-line_options">Problem 4: initialize the board based on command-line options</h2>
<div data-outline="problem_4_initialize_the_board_based_on_command-line_options"><p>We want our server to be able to accept some command-line options.
The exact specification is given in the Javadoc for <code>MinesweeperServer.main()</code>, which is excerpted below: </p><blockquote>
<p>Usage:</p>
<pre><code>MinesweeperServer [--debug | --no-debug] [--port PORT]
[--size SIZE_X,SIZE_Y | --file FILE]
</code></pre>
<p>The <code>--debug</code> argument means the server should run in debug mode.
The server should disconnect a client after a BOOM message if and only if the <code>--debug</code> flag was NOT given.
Using <code>--no-debug</code> is the same as using no flag at all.</p>
<p><em>E.g.</em> <code>MinesweeperServer --debug</code> starts the server in debug mode.</p>
<p><code>PORT</code> is an optional integer in the range 0 to 65535 inclusive, specifying the port the server should be listening on for incoming connections.</p>
<p><em>E.g.</em> <code>MinesweeperServer --port 1234</code> starts the server listening on port 1234.</p>
<p><code>SIZE_X</code> and <code>SIZE_Y</code> are optional positive integer arguments specifying that a random board of size SIZE_X × SIZE_Y should be generated.</p>
<p><em>E.g.</em> <code>MinesweeperServer --size 42,58</code> starts the server initialized with a random board of size 42 × 58.</p>
<p><code>FILE</code> is an optional argument specifying a file pathname where a board has been stored.
If this argument is given, the stored board should be loaded as the starting board.</p>
<p><em>E.g.</em> <code>MinesweeperServer --file boardfile.txt</code> starts the server initialized with the board stored in <code>boardfile.txt</code>.</p>
</blockquote><p>We provide you with the code required to parse these command-line arguments in the <code>main()</code> method already existing in <code>MinesweeperServer</code>. You should not change this method.
Instead, you should change <code>runMinesweeperServer</code> to handle each of the two different ways a board can be initialized: either by random, or through input from a file.
(You’ll deal with the debug flag in Problem 5.) </p><p>For a <strong><code>--size</code></strong> argument: if the passed-in size X,Y > 0, the server’s <code>Board</code> instance should be randomly generated and should have size equal to X by Y.
To randomly generate your board, you should assign each square to contain a bomb with probability .25 and otherwise no bomb.
All squares’ states should be set to <em>untouched</em>.</p><p>For a <strong><code>--file</code></strong> argument: If a file exists at the given path, read the the corresponding file, and if it is properly formatted, deterministically create the <code>Board</code> instance.
The file format for input is: </p><blockquote class="message-file"><pre><code>FILE ::= BOARD LINE+
BOARD := X SPACE Y NEWLINE
LINE ::= (VAL SPACE)* VAL NEWLINE
VAL ::= 0 | 1
X ::= INT
Y ::= INT
SPACE ::= " "
NEWLINE ::= "\n" | "\r" "\n"?
INT ::= [0-9]+
</code></pre></blockquote><p>In a properly formatted file matching the FILE grammar, the first line specifies the board size, and it must be followed by exactly Y lines, where each line must contain exactly X values.
If the file is properly formatted, the <code>Board</code> should be instantiated such that square <em>i,j</em> has a bomb if and only if the <em>i</em>’th VAL in LINE <em>j</em> of the input is 1.
If the file is improperly formatted, your program should throw an unchecked exception (either <code>RuntimeException</code> or define your own).
The following example file describes a board with 4 columns and 3 rows with a single bomb at the location <em>x=2</em>, <em>y=1</em>.</p><blockquote class="message-file"><div class="pull-left"><p>Example:</p></div>
<table class="message-table no-markdown">
<tbody><tr>
<td>4</td>
<td> </td>
<td>3</td>
<td>\n</td>
</tr><tr>
<td>0</td>
<td> </td>
<td>0</td>
<td> </td>
<td>0</td>
<td> </td>
<td>0</td>
<td>\n</td>
</tr><tr>
<td>0</td>
<td> </td>
<td>0</td>
<td> </td>
<td>1</td>
<td> </td>
<td>0</td>
<td>\n</td>
</tr><tr>
<td>0</td>
<td> </td>
<td>0</td>
<td> </td>
<td>0</td>
<td> </td>
<td>0</td>
<td>\n</td>
</tr>
</tbody></table></blockquote><p>If neither <code>--file</code> nor <code>--size</code> is given, generate a random board of size 10 × 10.</p><p>Note that <code>--file</code> and <code>--size</code> may not be specified simultaneously.</p><p><strong>Reading from a file:</strong> see <a href="#tips"><strong>tips for reading and writing</strong></a> below.</p><p>Implement the <code>runMinesweeperServer</code> method so that it handles the two possible ways to initialize a board (randomly or by loading a file).</p><p><strong>Running the server on the command line:</strong> this is easiest to do from the <code>bin</code> directory where your code is compiled.
Open a command prompt, <code>cd</code> to your <code>ps2</code> directory, then <code>cd bin</code>.
Here are some examples:</p><pre><code>cd bin
java minesweeper.server.MinesweeperServer --debug
java minesweeper.server.MinesweeperServer --port 1234
java minesweeper.server.MinesweeperServer --size 123,234
java minesweeper.server.MinesweeperServer --file ../testBoard
java minesweeper.server.MinesweeperServer --debug --port 1234 --size 20,14
</code></pre><p>You can specify command-line arguments in Eclipse by clicking on the drop-down arrow next to “run,” clicking on “Run Configurations…”, and selecting the “Arguments” tab.
Type your arguments into the text box.</p></div>
<h2 id="problem_5_putting_it_all_together">Problem 5: putting it all together</h2>
<div data-outline="problem_5_putting_it_all_together"><div class="list-style-lower-alpha"><ol>
<li><p>Modify your server so that it implements our protocols and specifications, using a single instance of <code>Board</code>.</p>
<p>Note that when we send a BOOM message to the user, we should terminate their connection if and only if the debug flag (see Problem 4) is missing.</p>
<p>The <a href="#tips"><strong>tips for reading and writing</strong></a> below may be useful for reading from and writing to socket streams.</p></li>
<li><p>Near the top of <code>MinesweeperServer</code>, include a substantial comment with an argument for why your system is threadsafe.</p>
<p>SFB, ETU, RFC: be sure the code to implement thread safety is written clearly and commented if necessary.</p></li>
</ol></div><hr></div>
<h2 id="tips">Tips for reading and writing</h2>
<div data-outline="tips"><ul>
<li><p><a href="http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#readLine--"><code>BufferedReader.readLine()</code></a>
reads a line of text from an input stream, where line is considered to be terminated by any one of a line feed (<code>\n</code>), a carriage return (<code>\r</code>), or a carriage return followed immediately by a linefeed.
This behavior matches the NEWLINE productions in our grammars.</p></li>
<li><p>You can wrap a <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/BufferedReader.html"><code>BufferedReader</code></a> around both <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/InputStreamReader.html"><code>InputStreamReader</code></a> and <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/FileReader.html"><code>FileReader</code></a> objects.</p></li>
<li><p><a href="http://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html#println--"><code>PrintWriter.println()</code></a>
prints formatted text to an output stream, and terminates the current line by writing the line separator string.
It always writes a line separator, even if the input string already ends with one.
The line separator is defined by the system property <code>line.separator</code>; you can obtain it using <code>System.lineSeparator()</code>.
It is <code>\n</code> on *nix systems and <code>\r\n</code> on Windows.
Both of these line endings are allowed by the NEWLINE productions in our grammars.</p></li>
<li><p>You can wrap a <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/PrintWriter.html"><code>PrintWriter</code></a> around a <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/Writer.html"><code>Writer</code></a> or <a href="http://docs.oracle.com/javase/8/docs/api/?java/io/OutputStream.html"><code>OutputStream</code></a> objects.</p></li>
</ul></div>
</div>
</div>
</div>
</div>