6.813/6.831 User Interface Design & Implementation

Due at 11:59pm, Wednesday, March 30, 2016, by uploading submission to Stellar.
You must complete the self-assessment form before you hand in the assignment.
You should make sure that your problem set works correctly in Chrome (which we'll be using for evaluating it) and in either Firefox or Safari.

This assignment explores the following topics related to GUI input:

  • event handling
  • hit detection
  • dragging
  • undo and redo
  • enabling/disabling commands based on view state

In this problem set, you will implement input handling for the checkerboard you created in PS2, so that the user can pick up checkers with the mouse and drag them around. We provide a class which implements the rules of checkers that gives you feedback about the legality of the user's moves. You will use this object to implement turn order, undo, and redo. After this problem set, you should have a basic but functional checkers game.

Provided Resources

This assignment builds on top of the code you wrote for PS2.

In addition to the Board object provided in board.js, you will be using the Rules object found in rules.js. The Rules object wraps the Board object and provides an interface to the board that constrains your manipulations to those which fall into the rules of checkers.

The Rules class has two methods you'll need: one which attempts a pre-selected move for a player and one which attempts to randomly move for a player. Both of these methods return null if the move was invalid (or no moves were possible for that player, in the latter case). On success, they return an object containing the results of the move if successful (any jumped pieces, etc). See the rules.js file for detailed documentation.

You will need to know about mouse input and event handling in Javascript, and these references may be helpful:

If you want to review HTML5 canvas, here are useful video tutorials picked by the course staff:

If you want to review HTML/CSS/Javascript/jQuery/jQueryUI, here are useful video tutorials picked by the course staff:

Problem 1: Dragging Checkers (40%)

Add input handling to your Checkerboard, so that the user can drag checkers around.

Pressing and dragging in a square containing a checker should pick up the checker from the board. The checker should not make any abrupt jumps when it is picked up — not when the user presses the mouse button, and not when the user starts moving the mouse. The checker should move smoothly with the mouse pointer, hovering over the other checkers on the board.

You must implement dragging by listening for mousedown, mouseup, mousemove events. Solutions that use HTML5 drag and drop or jQuery UI draggable or other drag-and-drop libraries will not receive credit. This requirement is in place for two reasons: these packages do not implement the behavior we're looking for, so you will have more headaches if you try to use them; and because you should learn how to handle low-level mouse events, just as you're learning how to use strokes as well as objects for output.

  • If the user releases the mouse button when the mouse pointer is over an empty square, the checker should be moved to that square using Board.moveTo(). The board model should not be changed until then. If the mouse pointer is over a filled square, then the dropped checker should be put back where it was taken from. (note: we'll change this to use the Rules object on the next step)
  • If the mouse pointer leaves the checkerboard during the drag operation, the dragged checker may either follow it or stop wherever it is on checkerboard — the behavior is up to you. But if the mouse pointer moves back into the checkerboard, the checker should resume following the mouse. If the mouse button is released when the mouse pointer is off the checkerboard, the checker should be put back where it was taken from. If the mouse button is released when the mouse pointer is outside the browser window entirely, the behavior is unspecified.
  • The feedback arrow you drew in PS2 should still appear for the user's specified move.

Hints:

  • Be aware of z-order, since you want the dragged component to hover on top. (note: HTML5-compatible browsers may not require adjusting z-order) Here is a useful video tutorial on z-order picked by the course staff.
  • You will need to do mouse capture correctly to handle cases where the mouse pointer leaves the whole browser window. You can either attach mouse listeners to the root of the view tree (document or window object), or (on HTML5-compatible browsers), simply listening to drag and drop events on the game objects may be sufficient.
  • Problem 2: Turn-based Play and Following the Rules (20%)

    To make the checkers game actually playable, you'll need to constrain the user's inputs those that respect turn order and the rules of the game. You've already implemented turn order tracking in PS2, so this should be an easy step.

    • Only the checkers belonging to the player who has the active turn should be draggable. On red's turn, the user should only be able to drag red pieces. On black's turn, the user should only be able to drag black pieces. An undraggable piece should not move when the mouse is pressed and dragged over it.
    • Any checker that has the current turn can be picked up, but it can only be dropped in a square if that square is a legal move for that checker. To do this, modify your code from Problem 1 so that checker movements are performed through the Rules object instead of the Board object.
      • If the Rules object returns a null value, you should return the piece to its original position and not advance to the next turn.
      • If the Rules object returns a non-null value, you should drop the checker in the new square and advance to the next turn.
    • Keep the "Auto Move" button from PS2 -- that way you can play against the (randomly moving) computer.

    Hints:

    • You'll need to keep track of both whose turn it is (red or black) and what direction that player is moving. When you attempt to make a move, you'll need to call the appropriate method on the Rules object, along with the correct parameters.
    • Take particular note of the two arguments, turnDirection and playerDirection. They each can be either the value +1 or -1. Turn direction represents whose turn it is. Player direction represents which color piece is trying to move. For example, if red is +1 and black is -1, and on red's turn, the user moves a black piece, then turn direction would be +1 and player direction would be -1. See the documentation in rules.js for details.

    Problem 3: Undo (20%)

    What's a game without the ability to take a move back?

    • Add an "Undo" button that, each time it is pressed, goes one step backwards in history.
    • The feedback arrow should be displayed and be drawn from the location of the checker before the "Undo" button press to the location of the checker after the "Undo" button press.
    • The "Undo" buttons should only be enabled when that action is possible. For example, "Undo" should be disabled upon game start.

    Hints:

    • When you make a move, either randomly or specific, the Rules object returns a data structure with sufficient information to implement the undo and redo functionality.
    • Undo is outside the rules of checkers. That means you'll have to implement it using direct operations on the Board object. Don't worry about Rules -- it takes whatever the current state of the board is, even if you've manipulated the board behind its back.

    Problem 4: Redo (20%)

    What's an "Undo" button without the ability to take an "Undo" back?

    • Add a "Redo" button that plays the undo stack foward.
    • The feedback arrow should be displayed and be drawn from the location of the checker before the "Redo" button press to the location of the checker after the "Redo" button press.
    • The "Redo" button should only be enabled when that action is possible

    Hints:

    • Think about what should happen to the redo stack when the user makes a move (either manually or by pressing automove)

    Going Further

    If you found this assignment easy and you're inclined to go further, here are some ideas for optional improvements:

    • Do hit testing for the true area of a checker, so that clicking in the corner of a square doesn't pick up the checker.

    What to Hand In

    You must complete the self-assessment form before you hand in the assignment.

    Package your completed assignment as a zip file that contains all of your files. Failure to include all necessary files for running your program will result in a loss of points from your final grade. (Please test by unzipping your zip file into, say, your /tmp directory, turning off your Internet connection, and then opening your page to see if it still works.)

    List your collaborators in the comment at the top of index.html, or explicitly say that you discussed the assignment with nobody. Collaborators are any people you discussed this assignment with. This is an individual assignment, so be aware of the course's collaboration policy.

    Here's a checklist of things you should confirm before you hand in:

    1. Complete the self assessment.
    2. Make sure your collaborators are named in index.html.
    3. Make sure that the page renders correctly on Chrome (which we'll be using for evaluating your projects) and in either Firefox or Safari.
    4. Make a fresh folder and unpack your zip file into it.
    5. Make sure all assets (images, jQuery source, JS files, CSS files, etc.) used by your code are found in the fresh folder and load successfully.

    Submit your zip file on Stellar.