Tue, 28 Jul 2020 13:48:59 +0200
adds more tests
/* * Copyright 2013 Mike Becker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package de.uapcore.sudoku; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; /** * A panel rendering the Sudoku field. * <p> * Cells are identified by zero-based indices from top-left to bottom-right. */ public final class Field extends JPanel { private final SudokuTextField[][] cells; /** * Constructs a new 9x9 Sudoku grid. */ public Field() { setBackground(Color.WHITE); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(5, 5, 5, 5); cells = new SudokuTextField[9][9]; for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { cells[x][y] = new SudokuTextField(); c.gridx = x; c.gridy = y; add(cells[x][y], c); } } } /** * Paints the grid and all contained cells. * * @param graphics the graphics context */ @Override public void paint(Graphics graphics) { final int w = getWidth(); final int h = getHeight(); final int cw = w / 9; final int ch = h / 9; BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = img.createGraphics(); g.setBackground(Color.WHITE); g.clearRect(0, 0, w, h); g.setColor(Color.BLACK); g.drawRect(1, 1, w - 2, h - 2); g.drawRect(2, 2, w - 4, h - 4); for (int x = cw; x < w; x += cw) { for (int y = ch; y < h; y += ch) { g.drawLine(x, 2, x, h - 2); g.drawLine(2, y, w - 2, y); if ((x / cw) % 3 == 0) { g.drawLine(x + 1, 2, x + 1, h - 2); } if ((y / ch) % 3 == 0) { g.drawLine(2, y + 1, w - 2, y + 1); } } } graphics.drawImage(img, 0, 0, this); super.paintChildren(graphics); } /** * Checks whether a cell is empty * * @param x horizontal position * @param y vertical position * @return true if the cell is empty, false otherwise */ public boolean isCellEmpty(int x, int y) { return getCellValue(x, y) == 0; } /** * Returns value of a specific cell. * * @param x horizontal position * @param y vertical position * @return the cell's value */ public int getCellValue(int x, int y) { return cells[x][y].getValue(); } /** * Sets the value of a specific cell. * * @param x horizontal position * @param y vertical position * @param v the cells value * @throws IllegalArgumentException if v is not between 0 and 9 */ public void setCellValue(int x, int y, int v) { cells[x][y].setValue(v); } /** * Clears the value of a specific cell. * * @param x horizontal position * @param y vertical position */ public void clearCellValue(int x, int y) { setCellValue(x, y, 0); } /** * Sets the modified state of a specific cell. * * @param x horizontal position * @param y vertical position * @param modified the modified state */ public void setCellModified(int x, int y, boolean modified) { cells[x][y].setModified(modified); } /** * Sets the modified state of all cells. * * @param modified the modified state */ public void setAllCellsModified(boolean modified) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { cells[x][y].setModified(modified); } } } /** * Checks whether any cell is modified. * * @return true if any cell is modified, false otherwise */ public boolean isAnyCellModified() { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (cells[x][y].isModified()) { return true; } } } return false; } /** * Clears all cells. */ public void clear() { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { cells[x][y].setValue(0); } } } /** * Returns a square identified by square coordinates. * <p> * Cells within the square are identified by the same coordinate system. * * @param x horizontal position from 0 to 2 * @param y vertical position from 0 to 2 * @return a two-dimensional array containing the square cell values * @throws IllegalArgumentException if the coordinates are out of bounds */ public int[][] getSquare(int x, int y) { if (x < 0 || x > 2 || y < 0 || y > 2) { throw new IllegalArgumentException("Invalid square coordinates"); } int[][] square = new int[3][3]; for (int u = 0; u < 3; u++) { for (int v = 0; v < 3; v++) { square[u][v] = getCellValue(3 * x + u, 3 * y + v); } } return square; } /** * Returns an entire row. * * @param y the row position * @return an array containing the row values * @throws IllegalArgumentException if y is not between 0 and 8 */ public int[] getRow(int y) { if (y < 0 || y > 8) { throw new IllegalArgumentException("Invalid row number"); } int[] row = new int[9]; for (int x = 0; x < 9; x++) { row[x] = getCellValue(x, y); } return row; } /** * Returns an entire column * * @param x the column position * @return an array containing the column values * @throws IllegalArgumentException if x is not between 0 and 8 */ public int[] getColumn(int x) { if (x < 0 || x > 8) { throw new IllegalArgumentException("Invalid column number"); } int[] column = new int[9]; for (int y = 0; y < 9; y++) { column[y] = getCellValue(x, y); } return column; } }