1. Finish Knight Tour
  - check for out of bounds conditions
  - draw the knight and the board

Out of bounds condition

The final piece of completing the Knight Tour was to make sure that we check
whether each potential move is actually within the confines of the board. Since
this check comes up frequently when working with 2D arrays we wrote a separate 
method that we can later use in other programs (it also makes the rest of the
code more readable.

Write a method isValidIndex(table, row, col) which takes a 2D array and
a pair of indices r and c and returns true if the given indices are valid,
i.e. if they reference a cell within the table; otherwise false is returned.

Assumptions:
* given matrix is rectangular --- all rows have same number of columns
* given matrix is non-empty --- has at least one row

For example:

int[][] board = new int[3][4];    // 3 rows X 4 columns
isValidIndex(board, 1, 1);        // returns true
isValidIndex(board, 3, 1);        // returns false -- no row 3
isValidIndex(board, 2, 4);        // returns false -- no column 4
isValidIndex(board, -1, 3);       // returns false -- no row -1
isValidIndex(board, 2, -2);       // returns false -- no column -2
The idea is straightforward:

1. Let numRows and numCols be the number of rows and columns in the table
2. Check to see if the given indices are within the legal range, i.e.:

   0 <= row < numRows
                       and
   0 <= col < numCols
Here is the Java code:
// returns true if the given coordinates (row, col) are valid
// for indexing in the given table; otherwise false is returned
// assumes: rectangular, non-empty table given
//
boolean isValidIndex(int[][] table, int row, int col)
{
    int numRows = table.length;      
    int numCols = table[0].length;    // first row exists -- table non empty

    if ( (row >= 0) && (row < numRows) && (col >= 0) && (col < numCols) )
    {
         return true;
    }
    else
    {
         return false;
    }
}
Drawing the board The final method helps show the board and a moving knight on the screen. This is similar to an earlier example on drawing a grid of circles. Given the (startX, startY) coordinates of the upper-left corner of the board, we need to be able to find the (curX, curY coordinates for a given cell at position (r, c) in the table for a given size of the board squares. From earlier examples we know the given (r, c) we can compute (curX, curY) for a board whose squares have dimensions (imageSize, imageSize) as follows:
curX = startX + c*imageSize;
curY = startY + r*imageSize;
Here is the final code -- for any non-empty cell on the board (i.e. not 0), draw the knight; otherwise, draw a black or white square:
void drawChessBoard( int[][] board )
{
    canvas.clear();
    
    int imageSize = 30;  // assuming the board squares are 30x30
    
    int numRows = board.length;
    int numCols = board[0].length;
    
    double startX = 50;  // need to fix this, so that (startX, startY) are
    double startY = 50;  // computed to center the board on the screen
    
    for ( int r = 0 ; r < numRows ; r = r + 1 )
    {
        for ( int c = 0 ; c < numCols ; c = c + 1 )
        {
            double curX = startX + c*imageSize;
            double curY = startY + r*imageSize;
            
            String color = pickColor( r, c );
            canvas.drawSquare( curX, curY, imageSize, color );

            if ( board[r][c] != 0 )
            {
                canvas.drawImage( curX, curY, "knight.png" );
                canvas.drawText( curX, curY, board[r][c], "white|14" );
            }
        }
    }

    canvas.sleep( 0.5 );
}
Picking a color -- integer division and remainder The squares on the chess board alternate in color and in the method drawChessBoard we needed to pick a color for the squares. We observed that squares at position (r, c) for which (r+c) is an even number are "black"; otherwise, the squares are "white". To test if a number is even we can test if it is divisible by 2, i.e. if the remainder of the division is 0. In Java the % operator gives the remainder from integer division.
The % operator gives the remainder from integer division.

If we try to divide equally 5 slices of pizza among 3 people, each person gets
1 slice and 2 remain unclaimed:

5 / 3 = 1     // 1 slice per person, so everyone gets same number
5 % 3 = 2     // 2 slices remain -- cannot be divided among the 3 people

With 16 slices and 3 people we get:

16 / 3 = 5     // 5 slices per person, so everyone gets same number
16 % 3 = 1     // 1 slice remains -- cannot be divided among the 3 people

With 24 slices and 3 people we get:

24 / 3 = 8     // 8 slices per person, so everyone gets same number
24 % 3 = 0     // 0 slices remains -- all slices distributed evenly

24 / 7 = 3     17 / 5 = 3     17 / 2 = 8      18 / 2 = 9
24 % 7 = 3     17 % 5 = 3     17 % 2 = 1      18 % 2 = 0

 6 / 7 = 0      2 / 5 = 0      1 / 2 = 0
 6 % 7 = 6      2 % 5 = 2      1 % 2 = 1
Here is the method that computes the color for a square at position (r, c) by checking if the sum of the coordinates is evenly divisible by 2, i.e if the remainder is 0:
String pickColor( int row, int col )
{
    int sum = row + col;

    if ( sum % 2 == 0 )
    {
        return "sienna";
    }
    else
    {
        return "tan";
    }
}
Putting it all together Below is the complete code that puts all the components together. The board is redrawn every time we mark the board -- i.e. place the knight. The knight image is available here
public class KnightTourApp
{    
    void playKnightTour( int numRows, int numCols, int startRow, int startCol )
    {
        int[][] board = new int[numRows][numCols];

        int curRow = startRow;
        int curCol = startCol;
        
        int steps = 1;
        board[ curRow ][ curCol ] = steps;
        drawChessBoard( board );
        
        int[] move = findNextMove( board, curRow, curCol );
        while ( move != null )
        {
            curRow = move[0];
            curCol = move[1];
            
            steps = steps + 1;
            board[ curRow ][ curCol ] = steps;
            drawChessBoard( board );
        
            move = findNextMove( board, curRow, curCol );
        }
    }

    int[] findNextMove( int[][] board, int curRow, int curCol )
    {
        int[] rowJumps = { -2, -1, +1, +2, +2, +1, -1, -2};
        int[] colJumps = { +1, +2, +2, +1, -1, -2, -2, -1};
        
        for ( int i = 0 ; i < rowJumps.length ; i = i + 1 )
        {
            int nextRow = curRow + rowJumps[i];
            int nextCol = curCol + colJumps[i];
            
            if ( isValid( board, nextRow, nextCol ) && board[ nextRow][ nextCol ] == 0 )
            {
                int[] move = { nextRow, nextCol };
                return move;
            }
        }
       
        return null;
    }

    boolean isValid( int[][] board, int row, int col )
    {
        if ( row >= 0 && row < board.length && col >= 0 && col < board[0].length )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    void drawChessBoard( int[][] board )
    {
        canvas.clear();
        
        int imageSize = 30;  // assuming the board squares are 30x30
    
        int numRows = board.length;
        int numCols = board[0].length;
    
        double startX = 50;  // need to fix this, so that (startX, startY) are
        double startY = 50;  // computed to center the board on the screen
        
        for (int r = 0 ; r < numRows ; r = r + 1)
        {
            for (int c = 0 ; c < numCols ; c = c + 1)
            {
                double curX = startX + c*imageSize;
                double curY = startY + r*imageSize;
                
                String color = pickColor( r, c );
                canvas.drawSquare( curX, curY, imageSize, color );
 
                if ( board[r][c] != 0 )
                {
                    // canvas.drawImage( curX, curY, "knight.png" );
                    canvas.drawCircle( curX, curY, imageSize / 3, "black" );
                    canvas.drawText( curX, curY, board[r][c], "white|14" );
                }
            }
        }
        
        canvas.sleep( 0.5 );
    }
    
    String pickColor( int row, int col )
    {
        int sum = row + col;

        if ( sum % 2 == 0 )
        {
            return "sienna";
        }
        else
        {
            return "tan";
        }
    }
    
    public void run()
    {
        // 8x8 board, start at (4,4)
        playKnightTour( 8, 8, 4, 4 );
    }
}