import objectdraw.*; import java.awt.*; import java.util.Random; /** * A grid of numbers that may or may not be a magic square. */ public class NumberGrid { // size of cell inside square private static final int CELLSIZE = 60; // text offset inside a cell private static final int TEXT_OFFSET = 25; // the canvas to draw the grid private DrawingCanvas canvas; // size of the grid private int size; // the entries of the grid private int[][] entries; // draw a new magic square wherever the mouse is clicked public NumberGrid(int size, DrawingCanvas canvas) { this.size = size; this.canvas = canvas; entries = new int[size][size]; // fillRandomSquare(); fillMagicSquare(); } private static final int MAX_RAND_VAL = 10; public void fillRandomSquare() { Random rand = new Random(); for (int row = 0; row < entries.length; row++) { for (int col = 0; col < entries[row].length; col++) { entries[row][col] = rand.nextInt(MAX_RAND_VAL); } } } // Place values to make a magic square // For an n-by-n matrix, if n is odd: // First, place a 1 in the center of the bottom row. // Then, repeat the following until finished: // Try to place the next integer (one greater than the last one) one below and to the right. // If you fall off the bottom of the grid, go to the top row of the same column. // If you fall off the right edge of the grid, go to the leftmost column. // If that cell is empty, write the next integer there and continue. // Otherwise, go back to where you wrote the last integer and use the cell directly above it. public void fillMagicSquare() { // Initially all entries default to 0 // Set the indices for the middle of the bottom row int curRow = size - 1; int curCol = size / 2; // Fill each cell int numSquares = size * size; for (int nextInt = 1; nextInt <= numSquares; nextInt++) { entries[curRow][curCol] = nextInt; // Find the next cell, wrapping around if necessary int nextRow = (curRow + 1) % size; int nextCol = (curCol + 1) % size; // If the cell is empty, remember those indices for the // next assignment if (entries[nextRow][nextCol] == 0) { curRow = nextRow; curCol = nextCol; } else { // The cell was full - Use the cell above the previous one curRow = (curRow - 1 + size) % size; } } } // draws the square on the canvas public void print(Location point) { int width = CELLSIZE * size; int height = CELLSIZE * size; double cornerX = point.getX(); double cornerY = point.getY(); // draw the vertical lines for (double x = cornerX; x <= cornerX + width; x = x + CELLSIZE) { new Line(x, cornerY, x, cornerY+height, canvas); } // draw the horizontal lines for (double y = cornerY; y <= cornerY + height; y = y + CELLSIZE) { new Line(cornerX, y, cornerX+width, y, canvas); } // fill in the grid for (int row = 0; row < entries.length; row++) { for (int col = 0; col < entries[row].length; col++) { if (entries[row][col] < 10) { new Text(" " + entries[row][col], cornerX+col * CELLSIZE + TEXT_OFFSET, cornerY + row * CELLSIZE + TEXT_OFFSET, canvas); } else { new Text(" " + entries[row][col], cornerX + col * CELLSIZE + TEXT_OFFSET, cornerY + row * CELLSIZE + TEXT_OFFSET, canvas); } } } } public boolean isMagicSquare() { int checkSum = 0; // get sum of numbers in first row, i.e. index 0 for (int col = 0; col < size; col++) { checkSum = checkSum + entries[0][col]; } // check the rows for (int row = 1; row < size; row++) { int sum = 0; for (int col = 0; col < size; col++) { sum = sum + entries[row][col]; } if (sum != checkSum) { return false; } } // check the columns for (int col = 0; col < size; col++) { int sum = 0; for (int row = 0; row < size; row++) { sum = sum + entries[row][col]; } if (sum != checkSum) { return false; } } // check the diagonals int sum = 0; for (int i = 0; i < size; i++) { sum = sum + entries[i][i]; } if (sum != checkSum) { return false; } sum = 0; int maxIndex = size - 1; for (int i = 0; i < size; i++) { sum = sum + entries[i][maxIndex - i]; } if (sum != checkSum) { return false; } return true; } }