CS 107 (Spring '09)
[Schedule] [Programs] [Notes & Reference] [Examples][Syllabus] [Lab & TA] [Tests] [Grades]

Program #3: Yote, part 1

Prof. Reed, CS 107, Fall '08
Due Friday 10/31 at 6:00 PM

Description

Write a program in Java to allow two human players to play the game of Yote. Rules of the game are:

This variant on the ancient African game of Yote (YOH-tay) is played on an empty 4x5 square board, where each player has 8 stones initially off the board in their "reserve."

TURN - On each turn, each player may either deploy a stone from their reserve to any empty space on the board, or move a stone already on the board. Moves must be made vertically or horizontally, but not diagonally. Stones move either by sliding to an adjacent empty cell or by jumping over and capturing an adjacent opponent's stone, landing in an empty square immediately beyond. When a Stone captures another stone, the player may then select any other opponent stone on the board (but not in their opponent's reserve) and capture it as well. Captures are not mandatory.

GOAL - The player who captures all of her opponent's stones wins. If either player is unable to move, then the game ends and the player with the most stones remaining wins. If both players are reduced to three or less stones, then the game is a draw.

(The above copy of rules slightly modified from here. See also the Zillions of Games site link.)

For this first part we will only be displaying the board and allowing the human players to place pieces on the board. No moves need to be made, and no error checking is needed in this first part. You must create a graphical representation of this game, that will look something like what is shown at left below, allowing two human players to play against each other. As play progresses, user input is given from the keyboard in the terminal window. Black goes first:

Empty board

Then after entering 7 to place the piece in square 7, the board looks like:

Board with one piece
Then entering 9 for white, would give:

Board with two pieces

And so on. Note that the 8 white pieces are labelled sequentially, staring with 'A'. The 8 black pieces (actually "darkGray") are labelled sequentially starting with 'J'. As play progresses, each time pieces are placed on the board the respective counters at the top and bottom of the board are updated. Eventually the game might look like:

Midgame board

On each move, the user will enter either the square number where the piece is to be placed, or 'x' to exit the program.

You need to know the following concepts in order to write this program:

Everything from the first two assignments; reading the textbook through chapter 5; how to use objects and classes, including class (e.g. board) that themselves use other classes (e.g. MyRectangle and Circle); using an array of objects to create a graphical representation of a board.

Notes:

  1. To do this you will need to use the following classes: Canvas.java, MyRectangle.java, Square.java, Circle.java, PlayGame.java (see all these together in a zip file). You will need to create at least one more class, called Board.java, and will probably also want to create the Piece class. In BlueJ this would like something like:
    BlueJClasses
  2. Create these classes one at time, in the order shown below:
    1. Piece
    2. Board
    3. PlayGame
  3. Below I have provided for you details for each of the above 3 classes, giving the fields, constructors, and methods that are needed for each one. It is essentially a roadmap for what you need to do, and in what order. Details for each of the above 3 classes can be found in this javadoc link. The javadoc link has many details that are not included in the narrative description below.
    1. First see the Piece class using the above javadoc link. Instead of having a separate Piece class, you could get away with a modified version of the Circle class, though in my description for this assignment I will assume you have a separate Piece class.
            A Piece has two fields: a circle (that has the color, position, size, text, etc.) and an index, which tracks its position on the board. Most of the methods in the Piece class serve as intermediaries of sorts, passing on the constructor, get, and set method information on to the Circle class.
           Once you have written the Piece class (or your modified version of Circle), test it to make sure it works. You should be able to create an array of Pieces and then manipulate individual Pieces, moving them and changing their values. If you implemented it correctly, then you should be able to place the following code inside of the PlayGame main() method and have it run correctly.
          	System.out.println("Starting the code to test the Piece class...");

      /** Generate an array that can keep track of 4 pieces */
      Piece[] thePieces = new Piece[ 4];

      // Now allocate memory and initialize values for each Piece
      for( int i=0; i<thePieces.length; i++) {
      // for this particular piece, call the constructor
      // Note that even though created, they are not visible!
      thePieces[ i] = new Piece(0,0,60,"blue",false,"A",-1);
      }

      // now one at a time change values for the Pieces

      // change position to 75,75 and change color to red, make it visible
      // and set label to "B"
      thePieces[ 0].setCircleValues(75,75,60,"red",true,"B");
      // store a value into the index field, just to show we can
      thePieces[ 0].setBoardPosition( 3);
      int theIndexValue = thePieces[ 0].getBoardPosition();
      System.out.println("index value for this piece is: " + theIndexValue);

      // for this one, move it first, then make it visible
      thePieces[ 1].moveTheCircle('r'); // move it to the right
      thePieces[ 1].setLabel("C");
      thePieces[ 1].setVisibility( true);

      // for this one just change location and visibility
      // note that label is still default of "A"
      thePieces[ 2].setCircleValues(25,75,true);
      thePieces[ 2].setColor("green");

      // for this last one make it visible and move it down two "squares" worth
      thePieces[ 3].setVisibility( true);
      thePieces[ 3].setLabel("D");
      thePieces[ 3].moveTheCircle('d', 2);

      System.out.println("Done testing the Piece class. Exiting...");
      The above code should create the output shown below.
      PieceTestCodeResult
    2. Next you should write the Board class, again refering to the javadoc link that gives you the details on the fields, constructors, and methods that you should have.
                 The first step is to write the code that "paints" the screen background, which is the playing surface. There is a good amount of detail on this given in the javadoc link. Scroll down to see the constructor detail, which gives steps to take. Remember that the x,y position of each of the light grey background squares in the playing window is from the point of view of the upper-left hand corner. So, as we create each light grey background square we should also create the small square containing the reference numbers. These small squares should be about 1/4 the size of the large ones, but notice that they are at the same x,y position.

                  To test this code now create the PlayGame class. As done in previous assignments, have main chain off to a non-static method (e.g. doIt()) and put your code inside method doIt(). Your code inside doIt() at this point might look something like the following:
          	// Create the playing board
          	theBoard = new Board(); 	// calls the Board constructor which "paints" the screen
          	
      Running the code should now give you:
      BlankBoard

                 Next create a loop (still inside the PlayGame class) that prompts the user for location into which to move. You should have a variable that keeps track of the move number, starting at 1. On each move, check this moveNumber variable to see if it is even or odd.
                  if ((moveNumber %2) == 10) 
      If moveNumber is odd, then it is the turn of "black", else it is the turn of "white". Your code inside the PlayGame class doIt() method at this point might look something like the following:
          	// Create the playing board
          	theBoard = new Board(); 	// calls the Board constructor which "paints" the screen
          	moveNumber = 1;   		    // odd moves mean "black", evens mean "white"
              
          	while( true) {
      	        // prompt for and get user input
      	        System.out.print("At what position would you like to place your piece? ");
      	        int destination = keyboard.nextInt();
                  // See if the current move is for "black" or "white", depending on the move number
      	        if( moveNumber%2 == 1) {
      	        	// it is odd since the remainder is 1, so it is black's move
      	        	// theBoard.placePiece("black", destinationPosition);     // make a black piece to the destinationPosition
      	        }
      	        else {
      	        	// it is even since the remainder is 0, so it is white's move
      	        	// theBoard.placePiece("white", destinationPosition);     // make a white piece to the destinationPosition
      	        }
      	        
      	        // update the move
      	        moveNumber++;
              }
              
      Remember that the arrays of pieces are handled inside the Board class. We interact with them by calling methods in the Board class, such as theBoard.placePiece(...) method that is commented out above. Let's look at the details of what this method should do.

                Go back to the Board class, to write the placePiece method referred to in the previous paragraph. Again, see the javadoc link for a fair amount of detail on this method. Use parameter theColor to store the color ("white" or "black"). The code below shows making a move for "black". First the if statement verifies it is the turn of "black", and "black" still has pieces to be placed on the board. Next the code figures out which is the index of the next available piece in the blackPieces array. That piece has its x,y values changed, and it is made visible, which has the effect of making it appear at the correct position on the board. Lastly the counter of remaining black pieces is updated, and the playing window label is updated to reflect this new number.
      if( theColor.equals("black") && (blackPiecesNumber > 0)) {
          // place the appropriate next piece into the requested position and make it visible
          int nextPieceIndex = 8 - blackPiecesNumber;
          blackPieces[ nextPieceIndex].setCircleValues(x, y, true);
      	 // decrement the count of black pieces and update that display on the playing board
      	 blackPiecesNumber--;
      	 updatePiecesDisplay( "black", blackPiecesNumber); 
      } 
      There should be similar code for "white". At this point you should be able to place pieces on the board, both black and white, giving (at some point in some game) a board that might look like:
      Midgame1
      At this point it is not yet possible to move a piece on the board, or to jump a piece, or check for the end of the game. Also no error checking is done yet on the input. These are left for the next assignment.

  4. Turnin your program electronically using the "turnin" command from your CS account. The turnin command should be used as follows:
  5. turnin -c cs107 -p program3 Yote

    where the directory containing your solution is called Yote.  Within this directory the java class containing the main( ) method used to start the program must be defined in a file called PlayGame.java

    If you wrote *both* program 3 and 4 together, and want to turn them in together, then turn them in to a project called prog3and4 rather than the project name (program3) specified above.

[CS Dept] [UIC] [Prof. Reed]