Member Avatar for wiliams.kikert

Hi all, I've got a code here, as the title says it is a sudoku puzzle. It can create only one puzzle which is there hard coded. Now, the problem is how to add another puzzle? Or maybe I can turn this into a random generated puzzle which is hard I presume. What should be added or deleted in the code. I'll post it below. Please do consider that I am just learning Java. Thanks

Code1 filename Sudoku

package sudoku3;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Sudoku extends JFrame {
    private static final String INITIAL_BOARD =
            "8156....4/" +
            "6...75.8./" +
            "....9..../" +
            "9...417../" +
            ".4.....2./" +
            "..623...8/" +
            "....5..../" +
            ".5.91...6/" +
            "1....7895";

    private SudokuModel        _sudokuLogic = new SudokuModel(INITIAL_BOARD);
    private SudokuBoardDisplay _sudokuBoard = new SudokuBoardDisplay(_sudokuLogic);

    private JTextField _rowTF = new JTextField(2);
    private JTextField _colTF = new JTextField(2);
    private JTextField _valTF = new JTextField(2);

    public Sudoku() {
        JButton moveBtn = new JButton("Move");

        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new FlowLayout());
        controlPanel.add(new JLabel("Row (1-9):"));
        controlPanel.add(_rowTF);
        controlPanel.add(new JLabel("Col (1-9):"));
        controlPanel.add(_colTF);
        controlPanel.add(new JLabel("Val:"));
        controlPanel.add(_valTF);
        controlPanel.add(moveBtn);

        moveBtn.addActionListener(new MoveListener());

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());

        content.add(controlPanel, BorderLayout.NORTH);
        content.add(_sudokuBoard, BorderLayout.CENTER);

        setContentPane(content);
        setTitle("Sudoku 3");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        pack();
        setLocationRelativeTo(null);
    }


    class MoveListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            try {
                int row = Integer.parseInt(_rowTF.getText().trim()) - 1;
                int col = Integer.parseInt(_colTF.getText().trim()) - 1;
                int val = Integer.parseInt(_valTF.getText().trim());
                if (_sudokuLogic.isLegalMove(row, col, val)) {
                    _sudokuLogic.setVal(row, col, val);
                    _sudokuBoard.repaint();
                } else {
                    JOptionPane.showMessageDialog(null, "Illegal row, col, or value.");
                }

            } catch (NumberFormatException nfe) {
                JOptionPane.showMessageDialog(null, "Please enter numeric values.");
            }
        }
    }

    public static void main(String[] args) {
        new Sudoku().setVisible(true);
    }
}

Code2 filename SudokuBoardDisplay

package sudoku3;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JComponent;

public class SudokuBoardDisplay  extends JComponent {
    private static final int CELL_PIXELS = 50;  // Size of each cell.
    private static final int PUZZLE_SIZE = 9;   // Number of rows/cols
    private static final int SUBSQUARE   = 3;   // Size of subsquare.
    private static final int BOARD_PIXELS = CELL_PIXELS * PUZZLE_SIZE;
    private static final int TEXT_OFFSET = 15;  // Fine tuning placement of text.
    private static final Font TEXT_FONT  = new Font("Sansserif", Font.BOLD, 24);

    private SudokuModel _model;      // Set in constructor.

    public SudokuBoardDisplay(SudokuModel model) {
        setPreferredSize(new Dimension(BOARD_PIXELS + 2, BOARD_PIXELS + 2));
        setBackground(Color.WHITE);
        _model = model;
    }

    @Override public void paintComponent(Graphics g) {
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);

        drawGridLines(g);
        drawCellValues(g);
    }

    private void drawGridLines(Graphics g) {

        for (int i = 0; i <= PUZZLE_SIZE; i++) {
            int acrossOrDown = i * CELL_PIXELS;
            g.drawLine(acrossOrDown, 0, acrossOrDown, BOARD_PIXELS);
            g.drawLine(0, acrossOrDown, BOARD_PIXELS, acrossOrDown);

            if (i % SUBSQUARE == 0) {
                acrossOrDown++;  // Move one pixel and redraw as above
                g.drawLine(acrossOrDown, 0, acrossOrDown, BOARD_PIXELS);
                g.drawLine(0, acrossOrDown, BOARD_PIXELS, acrossOrDown);
            }
        }
    }

    private void drawCellValues(Graphics g) {
        g.setFont(TEXT_FONT);
        for (int i = 0; i < PUZZLE_SIZE; i++) {
            int yDisplacement = (i+1) * CELL_PIXELS - TEXT_OFFSET;
            for (int j = 0; j < PUZZLE_SIZE; j++) {
                if (_model.getVal(i, j) != 0) {
                    int xDisplacement = j * CELL_PIXELS + TEXT_OFFSET;
                    g.drawString("" + _model.getVal(i, j), xDisplacement, yDisplacement);
                }
            }
        }
    }

}

Code3 filename SudokuModel

package sudoku3;

public class SudokuModel {
    private static final int BOARD_SIZE = 9;

    private int[][] _board;

    public SudokuModel() {
        _board = new int[BOARD_SIZE][BOARD_SIZE];
    }

    public SudokuModel(String initialBoard) {
        this();       // Call no parameter constructor first.
        initializeFromString(initialBoard);
    }

    public void initializeFromString(final String boardStr) {
        clear();  // Clear all values from the board.
        int row = 0;
        int col = 0;
        for (int i = 0; i < boardStr.length(); i++) {
            char c = boardStr.charAt(i);
            if (c >= '1' && c <='9') {
                if (row > BOARD_SIZE || col > BOARD_SIZE) {
                    throw new IllegalArgumentException("SudokuModel: "
                            + " Attempt to initialize outside 1-9 "
                            + " at row " + (row+1) + " and col " + (col+1));
                }
                _board[row][col] = c - '0';
                col++;
            } else if (c == '.') {
                col++;
            } else if (c == '/') {
                row++;
                col = 0;
            } else {
                throw new IllegalArgumentException("SudokuModel: Character '" + c
                        + "' not allowed in board specification");
            }
        }
    }

    public boolean isLegalMove(int row, int col, int val) {
        return row>=0 && row<BOARD_SIZE && col>=0 && col<BOARD_SIZE
                && val>0 && val<=9 && _board[row][col]==0;
    }

    public void setVal(int r, int c, int v) {
        _board[r][c] = v;
    }

    public int getVal(int row, int col) {
        return _board[row][col];
    }

    public void clear() {
        for (int row = 0; row < BOARD_SIZE; row++) {
            for (int col = 0; col < BOARD_SIZE; col++) {
                setVal(row, col, 0);
            }
        }
    }
}

well ... creating a generator for puzzles is a possibility, but make no mistake, it'll be pretty hard.
not only will you have to generate a correct sudoku puzzle, but you'll have to be able to figure out how to select some random values that will be used as pre-defined values and will be enough to help the player complete the puzzle, yet not so much as to make it to easy.

Member Avatar for wiliams.kikert

thanks, random generated puzzle will be out of the choices then.. so have you looked into the code? im lost on how to add a second puzzle.

Your puzzle is defined in the String INITIAL_BOARD, which is hard-coded, but it would be easy to read those 9 lines of text from a text file instead. Then you can have any number of puzzles by just creating new files in a text editor.

Member Avatar for wiliams.kikert

Your puzzle is defined in the String INITIAL_BOARD, which is hard-coded, but it would be easy to read those 9 lines of text from a text file instead. Then you can have any number of puzzles by just creating new files in a text editor.

thanks.. but as you can see, our professor havent introduced us to opening a file. given that, what other alterations needed to add the second puzzle?

In that case you could define another String INITIAL_BOARD_2 and store a different puzzle in that, then ask the user which one they want. Even better have an array of Strings so you can have a many puzzles as you want

To generate a random fully filled sudoku table is easy, but the challenge is to eliminate certain numbers until it becomes a puzzle. In other words, you need to have an algorithm to solve a sudoku puzzle before you can randomly generate a new one. If you have no good algorithm yet, stick to the hard-coded for now. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.