CSE142

Project #7

Board Games


November 21, 2003

Due Date: Electronic deadline:  Sunday Dec. 7, 9:00pm.  Receipts due in class the following Monday, the 8th.
Intermediate (step by step--just to avoid procrastination) deadlines: 
    Tuesday Nov. 25, 9:00pm -- Hook up with partners, decide on which game, and submit a stub implementation of the interfaces.
    Tuesday Dec. 2,  9:00pm -- Submit something that at least displays your game board, with no game play required.

The Project

In this project we will implement a board game.  What game you implement is up to you.  It could even be one of your own invention (something perhaps with some very simple rules).   The only requirement is that your game program needs to implement the given interfaces.  This requirement implies that your game should be played on a gridded board, like a checker board.  Possible games that fit this requirement range from very simple, such as Tic Tac Toe (a good choice if you want to keep it simple!) to more challenging options such as Othello (also a good and recommended choice for people wanting a challenge), Checkers, Go, some variant of the Game Of Life, or even Chess. The game you chose to implement being up to you is intended to let you choose something at a level of challenge to which you feel prepared to rise.  To learn more about games you may not be familiar with, follow the links above. Needless to say, the more complex games will call for more work on the AI end of things.  But since the minimum bar for successful completion of the project is really to create concrete implementations of the given interfaces, and work a little with two dimensional arrays, then even a trivial game in which I plunk down a piece on the board and the computer answers by plunking down another one on a random square could be considered minimally acceptable, though not a very interesting game.  If you do choose to make up your own game or find some obscure thing we don't know about, please document in comments the rules of play that you are implementing.

What is the point of this exercise?

The purpose of this project is to work with Java interfaces and to get a sense of their power, and to work with two dimensional arrays.  Also, to see how to implement mouse event driven input using a library interface.

The interfaces

The interfaces that your game needs to implement are four:
Cell             // representing, for example, a square on a checkerboard, or a space,
Board          // representing a game board, consisting of a 2-D array of Cells, such as a checker-board,
Game           // being the wrapper object holding it all together, and embodying the game-play, the players' moves, and
Opponent     // representing the "AI" player, against whom the human plays.

The code for these four interface definitions can be found by following the links on them above.  Note and beware!  Do not change theses interface declarations!  The reason why is that when you turn in your code, your code will be compiled against these declarations and only these declarations as they appear on the turn in server.  In other words, if you modified them and included them in your turn in, that will not work. 

The interfaces should all be loaded into your Java environment. Your job is then to implement four concrete classes that implement these  interfaces.  For example if your game is Tic Tac Toe ("TTT" for short) you  would create the classes TTTCell, TTTBoard, TTTGame, and TTTOpponent.     Each class definition would begin like:        
     public class TTTCell implements Cell { ... }, etc.

So how is this supposed to work?  You can tell a lot just by reading the interfaces. If you look at the Board interface you can see that the intent is to hold and give access to a two dimensional array of Cell objects (see the parameters and return types to setCell and getCell).  Each Cell is has a mark indicating how it has been marked or what kind of piece is on it.  A simple marking scheme might be zero for empty squares, -1 for spaces with pieces belonging to the AI player, and +1 for the human's pieces.  Of course if you are doing chess or Stratego or something with more and different pieces you could expand this scheme.  The Board knows how to display itself on a GWindow, (in the manner to which you have become accustomed, even though it was admittedly unnecessary before) by iterating through its array of Cells (hint: nested for-loops are good for 2-D arrays) and telling each of these to display itself on the GWindow, which gets passed along.  A Cell can do the trivial thing of adding its rectangle to the GWindow, or any other fancy thing like O' and X's or drawings of chess pieces, or just coloring the cells depending on what its mark is.

But there is stuff to implement that may not be clear from the interface specs.  Cheifly this would be in the constructors, which need to set things up.  (Also of course the reasoning that needs to be implemented to embody the game-play.)
In particular:

User Mouse Input

You could play your game by successively typing game.userMove(x, y); into the Interactions Pane, and while this a fine way to test things, it just isn't much fun to play.  What you want surely is to be able to click on the board to indicate your move.  This is surprisingly easy to do using a very little bit of magic that is available to you in the uwcse graphics package.  This package defines an interface called GWindowEventHandler, which if you have your Game class implement that too, you're almost set up to capture user events.  Thus, your game class will implement two interfaces, thus for example:
   public class OthelloGame implements Game, GWindowEventHandler {...}
So you look at the API docs on GWindowEventHandler and you say, gee, there are 6 methods there, do I have to implement all of them?  The answer is "yes", but do not despair, since all but one can be empty no op methods like:
   public void mouseDragged(GWindowEvent e) {}  //note: literally nothing between the square brackets.
the only one you really need to implement is mousePressed().  In fact, why don't you just go ahead and use this code:
           
  public void mousePressed(GWindowEvent e) {
    ArrayList Set freeCells = this.board.getFreeCells(); //my bad.  Should have been Set, not ArrayList
    Iterator cellsIter = freeCells.iterator();
   
    while (cellsIter.hasNext()) {
      Cell aCell = (Cell)cellsIter.next();
      Rectangle r = aCell.getRectangle();
      if (  (r.getX() <= e.getX())  //determine whether click was in this cell
          &&(r.getY() <= e.getY())  //since events know where they occured in the window
          &&(r.getX() + r.getWidth()  >= e.getX())
          &&(r.getY() + r.getHeight() >= e.getY())   ) {
        this.userMove(aCell.getColumn(), aCell.getRow());  //if so, this is the user's move
      }
    }
  }

The final bit of magic to get this to work is that you have to tell the GWindow to send events within it to your game object which will handle the events, which it is prepared to do since it implements the GWindowEventHandler interface.  So in your Game class constructor just invoke something rather like the following magical incantation (among others):
  public OthelloGame() {
    gameWindow = new GWindow(500, 500);
    gameWindow.addEventHandler(this); //so the window will send events to your game.
                                     // Yes!  The 'this' reference is valid, even though the object
                                     // is only in the process of being created at this point!
...
  }

That should do it.  It makes things much more fun.  Can you get a sense of how powerful using interfaces is from this?  The GWindow class knows nothing at all about my Game class.  But since I've entered into a contract stating that I'm implementing the GWindowEventHandler interface, then when I pass my Game object in to the window (with .addEventHandler(this)) then the Window can refer to my game thing with a reference of type GWindowEventHandler and work its magic.

What you are asked to do:

  1. Implement and turn-in four files named something like YourGame.java, YourCell.java, YourBoard.java, and YourOpponent.java, where "Your" stands in for something like "Othello", or "Checkers", etc.
  2. This is a pairs programming project again, if that works for you.
  3. The first turn-in form is here. The first turn in should consist of the four implementation files, which should make it clear what game you and your partner (if you have one) have agreed on implementing.  But there is no expectation that anything should actually work, though your code must compile.  This means at the very least that all the methods declared in the interfaces that your classes implement must at least be stubbed in, i.e. be defined with the correct signatures, but empty curly braces {}.  But you are certainly free to turn in as much as you've got by this time, if you get a start on your constructors of display routines for example.
  4. The second turn-in form is here. The second turn in should at least display the board when you start a game.  Again it consists of the four main java files for your classes and any other helper classes you may have defined.
  5.  The final turn-in form is here.
  6.  If you would like to face your game off in an AI vs. AI tournament let us know.
Good luck and have fun!