Mastermind part 2: Adding a front end
The previous post was an exercise in building well-tested logic. To turn this in to a workable client-server application, two things need to happen:
- A front-end needs to be built
- The back-end needs to be hosted in a web app
HTML template
I downloaded Bootstrap and used their basic html template.
The board is made up of nested lists, the markup looks roughly like this:
<div id="board">
    <ul id="answer" class="code list-unstyled">
      <li>?</li>
      <li>?</li>
      <li>?</li>
      <li>?</li>
    </ul>
    <ul id="guesses" class="list-unstyled">
      <li>
        <ul class="code list-unstyled">
          <li></li>
          <li></li>
          <li></li>
          <li></li>
        </ul>
        <ul class="score list-unstyled">
          <li class="black"> </li>
          <li class="white"> </li>
          <li class="white"> </li>
        </ul>
      </li>
    </ul>
  </div>
  <div id="addguess">
    <ul class="code list-unstyled">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    <button id="addguessbutton" type="button" class="btn btn-xs btn-primary"><span class="glyphicon glyphicon-ok"></span></button>
  </div>
  <ul id="turns" class="list-unstyled">
    <li>
      <ul class="code list-unstyled">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </li>
     <li>
      <ul class="code list-unstyled">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </li>
  </ul>
  </div>
The following CSS turns those list items into circles:
ul.code li {
        float: left;
        border: 2px solid #999;
        margin-left: 5px;
        width: 30px;
        height: 28px;
        border-radius: 20px;
}
Tying it together: the javascript
To encapsulate the logic for the whole page, I started with this basic pattern:
Mastermind = new function() {
        // private variables
        var selectedPeg;
        var lastGuess;
        var gameId;
        // private functions
   		var addGuess = function () {
   		}
        var reset = function() {
        }
        // first load: attach handlers and reset game.
        $('#newgamebutton').click(reset);
        $('#addguessbutton').click(addGuess);
        reset();
        return {
                // public functions and variables
        };
}();
It is based on Crockford’s private members in Javascript.
Filling in the details is a mix of DOM manipulation using JQuery and lots of trial-and-error. See the complete javascript for some ideas.
The front end implementation is deliberately dumb - it should only allow picking colors and submitting guesses. The game logic will be hooked up in the next step, when we convert our Ruby class into a web app.
The implementation at this point can be seen at this commit in GitHub