Computer Science 15-100 (Sections S-V), Fall 2008
Homework 7
Due:  Thu 16-Oct-2008 at 11:59pm (email copy) and at Friday's class/recitation (identical physical copy)
(no late submissions accepted).


Read these instructions first!


  1. More Array Practice
    1. isAlmostMagicSquare
    2. isSudokuRectangle
    3. isSudokoBoard
  2. Snake
  3. Bonus/Optional:  Better Snake

  1. More Array Practice
    In a file named Hw7MoreArrayPractice.java, write each of the following methods along with their corresponding well-designed and aptly-named test methods.
     
    1. isAlmostMagicSquare
      We will say that a square of numbers is "almost" a magic square if it can be made into a magic square by exactly one swap of two numbers.  For example:

      This square is not magic because (among other reasons) the first row sums to 15, but the first column sums to 8.  However, if we swap the 1 and the 8 we obtain this magic square:

      So the first square above, while not a magic square, is an "almost" magic square.

      Write the following method:
         public static boolean isAlmostMagicSquare(int[][] a)
      This method takes a 2d-array of int's and returns true if it represents an almost-magic square, and false otherwise.  Note that non-square matrices and null matrices are not magic squares, so your method should return false in these cases.

      Note:  In solving this problem, you will almost surely want to make use of your isMagicSquare method from the previous assignment.

      Also note:  magic squares do not have to be 3x3.  They can be as small as 1x1 or arbitrarily larger.
       
    2. isSudokuRectangle
      In the very popular game of Sudoku, players are presented with an N2-by-N2 square board in which they must fill all the cells with the numbers from 1 to N2 such that each row, each column, and each N-by-N  "box" contains all the numbers from 1 to N2.  For example, if N=3, players get a 9-by-9 board like so:

      For this board (again, where N=3), players must fill each 1-by-9 row, each 9-by-1 column, and each 3-by-3 highlighted "box" with the numbers from 1 to 9.  Here is a solution for this particular Sudoku:

      For more information, read the Wikipedia page on Sudoku:
          http://en.wikipedia.org/wiki/Sudoku

      Write the following method:
         public static boolean isSudokuRectangle(int[][] board,
                                                 int row0, int col0,
                                                 int row1, int col1)

      This method takes a 2d-array of int's (the "board"), and a rectangle on the board defined by its top-left row and column (row0, col0), and its bottom right row and column (row1, col1), and returns true if this rectangular region of the board can be part of a legal Sudoku solution and false otherwise.

      Note that this method is only expected to work over rectangular regions defining a single row (so col0 equals col1), a single column (so row0 equals row1), or a single "box" -- so the method returns false if any other rectangle is specified.  The method also returns false if the board is null, is not square, or is not N2-by-N2 for some positive integer N.

      Also note:  if the board is not full, as in the first example above, then the empty spaces will be signified by a 0 in that cell of the board.  Thus, this method amounts to checking that all the values in the given rectangle are in the range [0,N2], inclusive, and that none of the values besides 0 occurs more than once.

      For your benefit, here are the two Sudoku boards from the examples above:

         private static int[][] board1 = {
           { 5, 3, 0, 0, 7, 0, 0, 0, 0 },
           { 6, 0, 0, 1, 9, 5, 0, 0, 0 },
           { 0, 9, 8, 0, 0, 0, 0, 6, 0 },
           { 8, 0, 0, 0, 6, 0, 0, 0, 3 },
           { 4, 0, 0, 8, 0, 3, 0, 0, 1 },
           { 7, 0, 0, 0, 2, 0, 0, 0, 6 },
           { 0, 6, 0, 0, 0, 0, 2, 8, 0 },
           { 0, 0, 0, 4, 1, 9, 0, 0, 5 },
           { 0, 0, 0, 0, 8, 0, 0, 7, 9 }
         };

         private static int[][] board2 = {
           { 5, 3, 4, 6, 7, 8, 9, 1, 2 },
           { 6, 7, 2, 1, 9, 5, 3, 4, 8 },
           { 1, 9, 8, 3, 4, 2, 5, 6, 7 },
           { 8, 5, 9, 7, 6, 1, 4, 2, 3 },
           { 4, 2, 6, 8, 5, 3, 7, 9, 1 },
           { 7, 1, 3, 9, 2, 4, 8, 5, 6 },
           { 9, 6, 1, 5, 3, 7, 2, 8, 4 },
           { 2, 8, 7, 4, 1, 9, 6, 3, 5 },
           { 3, 4, 5, 2, 8, 6, 1, 7, 9 }
        };


      Hint:  Remember that Sudoku boards can be 1-by-1, 4-by-4, 9-by-9, 25-by-25, and so on.
       
    3. isSudokoBoard
      Write the following method:
         public static boolean isSudokuBoard(int[][] board)
      This method takes a 2d-array of int's (the "board"), as defined in the previous problem, and returns true if the board is a partial or complete solution to a Sudoku, and false otherwise.  Note that the previous method does all the "heavy lifting".  This method simply calls the previous helper method once for each row, each column, and each "box".  As with the previous method, this method returns false if the board is null, is not square, or is not N2-by-N2 for some positive integer N.
       
  2. Snake
    In a file named Hw7Snake.java, write a simple version of the game of Snake:
       snake.html (applet)   or   snake.jar (app)

    To play the game:  The player controls the snake using the up, down, left, and right arrows.  The snake also moves one space ahead on each timer click (where "ahead" is whatever direction it last moved).  When the snake eats (randomly-placed) food, it grows by one cell.  If the snake goes off the board or crawls into itself, it dies.  In this simple game, there is no score, no timer, no advanced effects, and when the snake dies the game simply starts over.  For more details, here is the Wikipedia page on Snake:
       http://en.wikipedia.org/wiki/Snake_(video_game)

    Note:
      Of the many ways to represent a snake, we will use one that is not very efficient but which greatly simplifies our coding effort.  Despite its inefficiency, it will run perfectly fine for any Snake game any human player is realistically going to play.  In any case, you are required to use this approach:

    Note:  To get a clearer picture of how we are representing the board, you can run this version of Snake, where the board values are displayed:
       snakeWithBoardValues.html (applet)   or   snakeWithBoardValues.jar (app)
    This version is only to help you understand how this design works.  Your submitted version should not display the board values, and should work like the first version from above.
     

  3. Bonus/Optional:  Better Snake
    The Snake game you just wrote is fairly simple.  In a file named Hw7BonusBetterSnake.java, make a better Snake game.  Here are some features you might consider:

    To be sure that you get credit for all your great efforts, be sure to provide a detailed comment at the head of your Java file listing ALL the extra features you added, along with a timesheet of all the time spent on your bonus Snake project (not including, of course, the time spent on the assigned Snake project).


Carpe diem!