I am creating a random maze generator in Java using the recursive backtracker algorithm. I need to set the edges of my maze cell data array to have been already visited by the algorithm so that it won't step out of bounds. The problem is probably staring me right in the face, I just cannot see where my error is.
Here is the whole error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 30
at mazeMaker.Maze.initBoundries(Maze.java:55)
at mazeMaker.Maze.<init>(Maze.java:46)
at mazeMaker.Main.main(Main.java:8)
I have tried tracing the error as best I could and experimented with changing my variables. The program relies on multiple class files, so I think it would be best just to show the whole thing.
Main.java
package mazeMaker;
public class Main
{
public static void main(String[] args)
{
Maze mainMaze = new Maze(20, 30);
}
}
Maze.java
package mazeMaker;
import java.util.Random;
import java.util.Stack;
public class Maze
{
public int xSize = 0;
public int ySize = 0;
public int totalDimensions = 0;
Random randomGenerator = new Random();
public Cell[][] cellData;
public Stack<Cell> cellStack = new Stack<Cell>();
Cell tempCell; // Temporary variable used for maze generation
public Maze(int xSize, int ySize)
{
cellData = new Cell[xSize][ySize];
this.xSize = xSize;
this.ySize = ySize;
this.totalDimensions = this.xSize * this.ySize;
// Initialize array objects
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j] = new Cell();
}
}
// Assign x and y positions
for (int i = 0; i < this.xSize; i++)
{
for (int j = 0; j < this.ySize; j++)
{
cellData[i][j].xPos = i;
cellData[i][j].yPos = j;
}
}
initBoundries();
}
private void initBoundries()
{
// Initialize the border cells as visited so we don't go out of bounds
for (int col = 0; col < this.xSize; col++)
{
cellData[0][col].hasBeenVisited = true;
cellData[this.ySize][col].hasBeenVisited = true;
}
for (int row = 0; row < this.ySize; row++)
{
cellData[row][0].hasBeenVisited = true;
cellData[row][this.xSize].hasBeenVisited = true;
}
}
private void generateMaze(int x, int y)
{
// Set current cell as visited
cellData[x][y].hasBeenVisited = true;
// While there are unvisited neighbors
while (!cellData[x][y+1].hasBeenVisited || !cellData[x+1][y].hasBeenVisited || !cellData[x][y-1].hasBeenVisited || !cellData[x-1][y].hasBeenVisited)
{
// Select a random neighbor
while (true)
{
int r = randomGenerator.nextInt(4);
if (r == 0 && !cellData[x][y+1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasNorthWall = false;
cellData[x][y+1].hasSouthWall = false;
generateMaze(x, y + 1);
break;
}
else if (r == 1 && !cellData[x+1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasEastWall = false;
cellData[x+1][y].hasWestWall = false;
generateMaze(x+1, y);
break;
}
else if (r == 2 && !cellData[x][y-1].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasSouthWall = false;
cellData[x][y-1].hasNorthWall = false;
generateMaze(x, y-1);
break;
}
else if (r == 3 && !cellData[x-1][y].hasBeenVisited)
{
cellStack.push(cellData[x][y]);
cellData[x][y].hasWestWall = false;
cellData[x-1][y].hasEastWall = false;
generateMaze(x-1, y);
break;
}
}
}
// There are no unvisited neighbors
tempCell = cellStack.pop();
generateMaze(tempCell.xPos, tempCell.yPos);
}
// Begin generating maze at top left corner
private void generateMaze()
{
generateMaze(1,1);
}
}
Cell.java
package mazeMaker;
public class Cell
{
public boolean isCurrentCell;
public boolean hasBeenVisited;
public boolean hasNorthWall;
public boolean hasSouthWall;
public boolean hasEastWall;
public boolean hasWestWall;
public int xPos;
public int yPos;
}
cellData[this.ySize][col].hasBeenVisited = true;
You have initialized your cellData as cellData[20][30], but in the above-mentioned line you are calling cellData[30][col]. Instead of 30, the first bracket should have a value from 0 to 19, because the row size is 20.
My guess is from this code in initBoundries()
// Initialize the border cells as visited so we don't go out of bounds
for (int col = 0; col < this.xSize; col++)
{
cellData[0][col].hasBeenVisited = true;
cellData[this.ySize][col].hasBeenVisited = true;
}
this.ySize after initialize (from constructor) has value 30.
Related
I'm making a program to play Misere Nim, and I'm running into some problems with memory. I use ArrayLists to hold the possible moves that could be done, and this is causing an OutOfMemory exception. How can I lessen the memory I use when using ArrayLists? Should I be clearing something after every run?
EDIT: added copy method
EDIT: full project can be found at https://github.com/DatOneRam/ScienceFair
do
{
int tempWin = board.playRound();
if (tempWin == 0)
stratWins++;
else
randWins++;
}
while (rounds <= 10000);
public int playRound()
{
Board board = new Board();
NimBot strat = new NimBot(board);
NimBot rand = new NimBot(board);
do
{
strat.makeStrategicMove();
if (board.hasEnded())
break;
rand.makeRandomMove();
}
while (!board.hasEnded());
return board.getPlayer();
}
public void makeStrategicMove()
{
ArrayList<int[]> goodMoves = board.getGoodMoves();
Random rand = new Random();
int[] move;
if (goodMoves.size() != 0)
{
move = goodMoves.get(rand.nextInt(goodMoves.size()));
}
else
{
ArrayList<int[]> simpleMoves = board.getSimpleMoves();
move = simpleMoves.get(rand.nextInt(simpleMoves.size()));
}
board.setPosition(move);
}
public void makeRandomMove()
{
ArrayList<int[]> moves = board.getMoves();
Random rand = new Random();
int[] move = moves.get(rand.nextInt(moves.size()));
board.setPosition(move);
}
public ArrayList<int[]> getMoves()
{
ArrayList<int[]> x = new ArrayList<int[]>();
int j = 0, i = 1;
x.add(0, copy(position));
do
{
x.add(i, copy(position));
if (x.get(i-1)[j] == 0)
j++;
x.get(i)[j] = x.get(i-1)[j] - 1;
i++;
if (x.get(i-1)[j] == 0)
{
j++;
if (j == 5)
{
break;
}
}
}
while(x.get(i - 1)[j] != 0);
for (int r = 0; r < x.size(); r++)
{
x.get(r)[4] = toggle(x.get(r)[4]);
}
x.remove(0);
//resize(x);
return x;
}
public ArrayList<int[]> getSimpleMoves()
{
ArrayList<int[]> x = new ArrayList<int[]>(4);
for (int i = 0; i < 4; i++)
{
x.add(copy(position));
x.get(i)[i] = position[i] - 1;
x.get(i)[4] = toggle(x.get(i)[4]);
if (x.get(i)[i] < 0)
x.get(i)[i] = 0;
}
//resize(x);
return x;
}
public int[] copy(int[] y)
{
int[] z = new int[y.length];
for (int i = 0; i < y.length; i++)
z[i] = y[i];
return z;
}
I apologize if I put too much code here, I wasn't sure how to shorten it.
I have a two dimensional integer array and a two dimensional double array. If a value in the double array is less than the integer value at the same position of the two dimensional array, then in that part of the boolean array the value would is true. If it is greater, then the boolean would be false.
How would I go about on this?
This is what I tried so far:
public static boolean[][] CompareIntDouble(int[][] pizza, double[][] pasta) {
boolean x = true;
for (int hotdog=0; hotdog < pizza.length; hotdog++) {
for (int toast=0; toast < pizza[hotdog].length; toast++) {
pizza[hotdog][toast] = hotdog * 10 + toast;
if (pasta[1][1] > pizza[1][1]) {
x = true;
} else {
x = false;
}
if (pasta[1][2] > pizza[1][2]) {
x = true;
} else {
x = false
}
}
}
}
Picture of the code
public static void main(String... args) throws IOException {
int[][] t1 = new int[2][2];
t1[0][0] = 0;
t1[0][1] = 1;
t1[1][0] = 2;
t1[1][1] = 3;
double[][] t2 = new double[2][2];
t2[0][0] = 3;
t2[0][1] = 2;
t2[1][0] = 1;
t2[1][1] = 0;
boolean[][] f = new boolean[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
if (t1[i][j] > t2[i][j]) {
f[i][j] = true;
} else {
f[i][j] = false;
}
System.out.println(i+" "+j+" :"+f[i][j]);
}
}
}
even tho you should try it by yourself first here you have a working example
Assuming that 2d input arrays have the same size
public static boolean[][] foo( int[][] a,double[][]b) {
boolean[][] c = new boolean[a.length][a.length];
for (int i=0;i<a[0].length ;i++ ) {
for (int j=0;j<a.length ;j++ ) {
c[i][j]= (a[i][j]>(int)b[i][j]);
}
}
return c;
}
I am doing a game called 1010! Probably some of you have heard of it. Bascially I encouter some trouble when writing the Algorithm for clearance.
The rule is such that if any row or any column is occupied, then clear row and column respectively.
The scoring is such that each move gains a+10*b points. a is the number of square in the input piece p and b is the total number of row&column cleared.
To start, I create a two dimensional Array board[10][10], poulate each elements in the board[][] with an empty square.
In the class of Square, it has public void method of unset()-> "empty the square" & boolean status() -> "judge if square is empty"In the class of piece, it has int numofSquare -> "return the number of square in each piece for score calculation"
In particular, I don't know how to write it if both row and column are occupied as they are inter-cross each other in an two dimensional array.
It fail the test under some condition, in which some of the squares are not cleared but they should have been cleared and I am pretty sure is the logic problem.
My thinking is that:
Loop through squares in first row and first column, record the number of square that are occupied (using c and r); if both are 10, clear row&column, otherwise clear row or column or do nothing.
reset the c &r to 0, loop through square in the second row, second column…
update score.
Basically the hard part is that if I seperate clear column and clear row algorithm ,I will either judge row or column first then clear them . However, as every column contains at least one square belong to the row, and every row contains at least one square belong to the column, there will be mistake when both row and column are full.
Thanks for help.
import java.util.ArrayList;
public class GameState{
public static final int noOfSquares = 10;
// the extent of the board in both directions
public static final int noOfBoxes = 3;
// the number of boxes in the game
private Square[][] board; // the current state of the board
private Box[] boxes; // the current state of the boxes
private int score; // the current score
// initialise the instance variables for board
// all squares and all boxes are initially empty
public GameState()
{
getboard();
score = 0;
board = new Square[10][10];
for(int i =0;i<board.length;i++){
for(int j =0;j<board[i].length;j++){
board[i][j] = new Square();
}
}
boxes = new Box[3];
for(int k =0;k<boxes.length;k++){
boxes[k] = new Box();
}
}
// return the current state of the board
public Square[][] getBoard()
{
return board;
}
// return the current score
public int getScore()
{
return score;
}
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
for (int row=0;row<10;row++){
for (int column=0;column<10;column++) {
if (board[row][column].status() == true){
c = c + 1;
if( c == 10 ) {
rowandcolumn = rowandcolumn + 1;
for(int z=0;z<10;z++){
board[row][z].unset(); //Clear column
}
}
}
if (board[column][row].status() == true){
r = r + 1;
if( r == 10) {
rowandcolumn = rowandcolumn + 1;
for(int q=0;q<10;q++){
board[q][row].unset(); //Clear row
}
}
}
}
r=0; //reset
c=0;
}
score = score + p.numberofBox()+10*rowandcolumn;
}
how about this
void Background::liquidate(int &score){
int arr_flag[2][10]; //0 is row,1 is column。
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 10; j++)
{
arr_flag[i][j] = 1;
}
}
//column
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[i][j].type == 0)
{
arr_flag[0][i] = 0;
break;
}
}
}
//row
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (arr[j][i].type == 0)
{
arr_flag[1][i] = 0;
break;
}
}
}
//clear column
for (int i = 0; i < 10; i++)
{
if (arr_flag[0][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[i][j].Clear();
}
}
}
//clear row
for (int i = 0; i < 10; i++)
{
if (arr_flag[1][i] == 1)
{
for (int j = 0; j < 10; j++)
{
arr[j][i].Clear();
}
}
}
}
I tried to write somme code for the idea I posted
// place p on the board with its (notional) top-left corner at Square x,y
// clear columns and rows as appropriate
int r =0;
int c = 0;
int rowandcolumn = 0;
int row=FindFirstRow();
int column=FindFirstColumn();
if(row!=-1 && column!=-1)
{
rowandcolumn++;
//actions here: row found and column found
//clear row and column
clearRow(row);
clearColumn(column);
}
else if(row!=-1)
{
//only row is found
//clear row
clearRow(row);
}
else if(column!=-1)
{
//only column is found
//clear column
clearColumn(column);
}
else
{
//nothing is found
}
public void clearRow(int row)
{
for(int i=0; i<10;i++)
{
board[row][i].unset();
}
}
public void clearColumn(int column)
{
for(int i=0; i<10;i++)
{
board[i][column].unset();
}
}
//this method returns the first matching row index. If nothing is found it returns -1;
public int FindFirstRow()
{
for (int row=0;row<10;row++)
{
int r=0;
for (int column=0;column<10;column++)
{
if (board[row][column].status() == true)
{
r = r + 1;
if( r == 10)
{
//row found
return row;
}
}
}
r=0; //reset
}
//nothing found
return -1;
}
//this method returns the first matching column index. If nothing is found it returns -1;
public int FindFirstColumn()
{
for (int column=0;column<10;column++)
{
int c=0;
for (int row=0;row<10;row++)
{
if (board[row][column].status() == true)
{
c = c + 1;
if( c == 10 )
{
//matching column found
return column;
}
}
}
c=0; //reset
}
//nothing found
return -1;
}
This is the main class:
public class Sudoku extends JFrame {
MenuBar Bar;
MenuItem itemFile[];
MenuItem itemHelp[];
Menu file;
Menu help;
public Sudoku() {
super("Sudoku");
setLayout(new FlowLayout());
setResizable(false);
itemFile =new MenuItem[2];
itemHelp =new MenuItem[2];
itemFile[0]=new MenuItem("New");
itemFile[1]=new MenuItem("Exit");
itemHelp[0]= new MenuItem("Rules");
itemHelp[1]= new MenuItem("Creators");
file=new Menu("File");
help=new Menu("Help");
file.add(itemFile[0]);
help.add(itemHelp[0]);
file.add(itemFile[1]);
help.add(itemHelp[1]);
Bar =new MenuBar();
Bar.add(file);
Bar.add(help);
setMenuBar(Bar);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
Game game = new Game();
ButtonController buttonController = new ButtonController(game);
ButtonPanel buttonPanel = new ButtonPanel();
buttonPanel.setController(buttonController);
add(buttonPanel, BorderLayout.EAST);
SudokuPanel sudokuPanel = new SudokuPanel();
SudokuController sudokuController = new SudokuController(sudokuPanel, game);
sudokuPanel.setGame(game);
sudokuPanel.setController(sudokuController);
add(sudokuPanel, BorderLayout.CENTER);
game.addObserver(buttonPanel);
game.addObserver(sudokuPanel);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public boolean action(Event evt, Object arg){
if(evt.target instanceof MenuItem){
String text=(String)arg;
System.out.println("Selected="+arg);
if(text.equals("Exit"))
System.exit(0);
else if(text.equals("New"))
// Get newGame() of Game class to run here.
}
return true;
}
This is the Game class:
package sudoku.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
public class Game extends Observable {
private int[][] solution;
private int[][] game;
private boolean[][] check;
private int selectedNumber;
private boolean help;
public Game() {
newGame();
check = new boolean[9][9];
help = true;
}
public void newGame() {
solution = generateSolution(new int[9][9], 0);
game = generateGame(copy(solution));
setChanged();
notifyObservers(UpdateAction.NEW_GAME);
}
public void checkGame() {
selectedNumber = 0;
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++)
check[y][x] = game[y][x] == solution[y][x];
}
setChanged();
notifyObservers(UpdateAction.CHECK);
}
public void setHelp(boolean help) {
this.help = help;
setChanged();
notifyObservers(UpdateAction.HELP);
}
public void setSelectedNumber(int selectedNumber) {
this.selectedNumber = selectedNumber;
setChanged();
notifyObservers(UpdateAction.SELECTED_NUMBER);
}
public int getSelectedNumber() {
return selectedNumber;
}
public boolean isHelp() {
return help;
}
public boolean isSelectedNumberCandidate(int x, int y) {
return game[y][x] == 0 && isPossibleX(game, y, selectedNumber)
&& isPossibleY(game, x, selectedNumber) && isPossibleBlock(game, x, y, selectedNumber);
}
public void setNumber(int x, int y, int number) {
game[y][x] = number;
}
public int getNumber(int x, int y) {
return game[y][x];
}
public boolean isCheckValid(int x, int y) {
return check[y][x];
}
private boolean isPossibleX(int[][] game, int y, int number) {
for (int x = 0; x < 9; x++) {
if (game[y][x] == number)
return false;
}
return true;
}
private boolean isPossibleY(int[][] game, int x, int number) {
for (int y = 0; y < 9; y++) {
if (game[y][x] == number)
return false;
}
return true;
}
private boolean isPossibleBlock(int[][] game, int x, int y, int number) {
int x1 = x < 3 ? 0 : x < 6 ? 3 : 6;
int y1 = y < 3 ? 0 : y < 6 ? 3 : 6;
for (int yy = y1; yy < y1 + 3; yy++) {
for (int xx = x1; xx < x1 + 3; xx++) {
if (game[yy][xx] == number)
return false;
}
}
return true;
}
private int getNextPossibleNumber(int[][] game, int x, int y, List<Integer> numbers) {
while (numbers.size() > 0) {
int number = numbers.remove(0);
if (isPossibleX(game, y, number) && isPossibleY(game, x, number) && isPossibleBlock(game, x, y, number))
return number;
}
return -1;
}
private int[][] generateSolution(int[][] game, int index) {
if (index > 80)
return game;
int x = index % 9;
int y = index / 9;
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++) numbers.add(i);
Collections.shuffle(numbers);
while (numbers.size() > 0) {
int number = getNextPossibleNumber(game, x, y, numbers);
if (number == -1)
return null;
game[y][x] = number;
int[][] tmpGame = generateSolution(game, index + 1);
if (tmpGame != null)
return tmpGame;
game[y][x] = 0;
}
return null;
}
private int[][] generateGame(int[][] game) {
List<Integer> positions = new ArrayList<Integer>();
for (int i = 0; i < 81; i++)
positions.add(i);
Collections.shuffle(positions);
return generateGame(game, positions);
}
private int[][] generateGame(int[][] game, List<Integer> positions) {
while (positions.size() > 0) {
int position = positions.remove(0);
int x = position % 9;
int y = position / 9;
int temp = game[y][x];
game[y][x] = 0;
if (!isValid(game))
game[y][x] = temp;
}
return game;
}
private boolean isValid(int[][] game) {
return isValid(game, 0, new int[] { 0 });
}
private boolean isValid(int[][] game, int index, int[] numberOfSolutions) {
if (index > 80)
return ++numberOfSolutions[0] == 1;
int x = index % 9;
int y = index / 9;
if (game[y][x] == 0) {
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++)
numbers.add(i);
while (numbers.size() > 0) {
int number = getNextPossibleNumber(game, x, y, numbers);
if (number == -1)
break;
game[y][x] = number;
if (!isValid(game, index + 1, numberOfSolutions)) {
game[y][x] = 0;
return false;
}
game[y][x] = 0;
}
} else if (!isValid(game, index + 1, numberOfSolutions))
return false;
return true;
}
private int[][] copy(int[][] game) {
int[][] copy = new int[9][9];
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++)
copy[y][x] = game[y][x];
}
return copy;
}
}
I want when I click "New" from my menubar (its action is in the main class), the newGame(); method of the Game class to be executed. I've tried many ways but all failed .. it's such a headache...
Any ideas ?
In the constructor you create an instance of the Game object - but it goes out of scope at the end of the method. You should keep a reference in the Sudoku class:
public class Sudoku extends JFrame {
...
private Game game;
public Sudoku() {
...
game = new Game();
Then:
public boolean action(Event evt, Object arg) {
if(evt.target instanceof MenuItem) {
String text=(String)arg;
System.out.println("Selected="+arg);
if(text.equals("Exit")) {
System.exit(0);
} else if(text.equals("New")) {
game.newGame();
}
}
return true;
}
Add a "Game" object as a member class of your main class, then you can access its methods anywhere in your class:
public class Sudoku extends JFrame {
private Game game;
// rest of your Sudoku class code as it currently is, but change:
Game game = new Game();
// to:
this.game = new Game();
// In your 'action' method, you can now call like this:
this.game.newGame();
In my last question seen here: Sudoku - Region testing I asked how to check the 3x3 regions and someone was able to give me a satisfactory answer (although it involved a LOT of tinkering to get it working how I wanted to, since they didn't mention what the class table_t was.)
I finished the project and was able to create a sudoku generator, but it feels like it's contrived. And I feel like I've somehow overcomplicated things by taking a very brute-force approach to generating the puzzles.
Essentially my goal is to create a 9x9 grid with 9- 3x3 regions. Each row / col / region must use the numbers 1-9 only once.
The way that I went about solving this was by using a 2-dimensional array to place numbers at random, 3 rows at a time. Once the 3 rows were done it would check the 3 rows, and 3 regions and each vertical col up to the 3rd position. As it iterated through it would do the same until the array was filled, but due to the fact that I was filling with rand, and checking each row / column / region multiple times it felt very inefficient.
Is there an "easier" way to go about doing this with any type of data construct aside from a 2d array? Is there an easier way to check each 3x3 region that might coincide with checking either vert or horizontal better? From a standpoint of computation I can't see too many ways to do it more efficiently without swelling the size of the code dramatically.
I built a sudoku game a while ago and used the dancing links algorithm by Donald Knuth to generate the puzzles. I found these sites very helpful in learning and implementing the algorithm
http://en.wikipedia.org/wiki/Dancing_Links
http://cgi.cse.unsw.edu.au/~xche635/dlx_sodoku/
http://garethrees.org/2007/06/10/zendoku-generation/
import java.util.Random;
import java.util.Scanner;
public class sudoku {
/**
* #antony
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int p = 1;
Random r = new Random();
int i1=r.nextInt(8);
int firstval = i1;
while (p == 1) {
int x = firstval, v = 1;
int a[][] = new int[9][9];
int b[][] = new int[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if ((x + j + v) <= 9)
a[i][j] = j + x + v;
else
a[i][j] = j + x + v - 9;
if (a[i][j] == 10)
a[i][j] = 1;
// System.out.print(a[i][j]+" ");
}
x += 3;
if (x >= 9)
x = x - 9;
// System.out.println();
if (i == 2) {
v = 2;
x = firstval;
}
if (i == 5) {
v = 3;
x = firstval;
}
}
int eorh;
Scanner in = new Scanner(System.in);
System.out
.println("hey lets play a game of sudoku:take down the question and replace the 0's with your digits and complete the game by re entering your answer");
System.out.println("enter your option 1.hard 2.easy");
eorh = in.nextInt();
switch (eorh) {
case 1:
b[0][0] = a[0][0];
b[8][8] = a[8][8];
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][8] = a[3][8];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][8] = a[6][8];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
b[0][0] = a[0][0];
b[8][8] = a[8][8];
break;
case 2:
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[1][8] = a[1][8];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][5] = a[3][5];
b[3][8] = a[3][8];
b[4][0] = a[4][0];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][4] = a[4][4];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][1] = a[5][1];
b[5][4] = a[5][4];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][6] = a[6][6];
b[6][8] = a[6][8];
b[7][0] = a[7][0];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][2] = a[8][2];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
break;
default:
System.out.println("entered option is incorrect");
break;
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
System.out.print(b[y][z] + " ");
}
System.out.println("");
}
System.out.println("enter your answer");
int c[][] = new int[9][9];
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
c[y][z] = in.nextInt();
}
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
System.out.print(c[y][z] + " ");
System.out.println();
}
int q = 0;
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
if (a[y][z] == c[y][z])
continue;
else {
q++;
break;
}
}
if (q == 0)
System.out
.println("the answer you have entered is correct well done");
else
System.out.println("oh wrong answer better luck next time");
System.out
.println("do you want to play a different game of sudoku(1/0)");
p = in.nextInt();
firstval=r.nextInt(8);
/*if (firstval > 8)
firstval -= 9;*/
}
}
}
I think you can use a 1D array, in much the same way a 1D array can model a binary tree. For example, to look at the value below a number, add 9 to the index.
I just made this up, but could something like this work?
private boolean makePuzzle(int [] puzzle, int i)
{
for (int x = 0; x< 10 ; x++)
{
if (//x satisfies all three conditions for the current square i)
{
puzzle[i]=x;
if (i==80) return true //terminal condition, x fits in the last square
else
if makePuzzle(puzzle, i++);//find the next x
return true;
}// even though x fit in this square, an x couldn't be
// found for some future square, try again with a new x
}
return false; //no value for x fit in the current square
}
public static void main(String[] args )
{
int[] puzzle = new int[80];
makePuzzle(puzzle,0);
// print out puzzle here
}
Edit: its been a while since I've used arrays in Java, sorry if I screwed up any syntax. Please consider it pseudo code :)
Here is the code as described below in my comment.
public class Sudoku
{
public int[] puzzle = new int[81];
private void makePuzzle(int[] puzzle, int i)
{
for (int x = 1; x< 10 ; x++)
{
puzzle[i]=x;
if(checkConstraints(puzzle))
{
if (i==80)//terminal condition
{
System.out.println(this);//print out the completed puzzle
puzzle[i]=0;
return;
}
else
makePuzzle(puzzle,i+1);//find a number for the next square
}
puzzle[i]=0;//this try didn't work, delete the evidence
}
}
private boolean checkConstraints(int[] puzzle)
{
int test;
//test that rows have unique values
for (int column=0; column<9; column++)
{
for (int row=0; row<9; row++)
{
test=puzzle[row+column*9];
for (int j=0;j<9;j++)
{
if(test!=0&& row!=j&&test==puzzle[j+column*9])
return false;
}
}
}
//test that columns have unique values
for (int column=0; column<9; column++)
{
for(int row=0; row<9; row++)
{
test=puzzle[column+row*9];
for (int j=0;j<9;j++)
{
if(test!=0&&row!=j&&test==puzzle[column+j*9])
return false;
}
}
}
//implement region test here
int[][] regions = new int[9][9];
int[] regionIndex ={0,3,6,27,30,33,54,57,60};
for (int region=0; region<9;region++) //for each region
{
int j =0;
for (int k=regionIndex[region];k<regionIndex[region]+27; k=(k%3==2?k+7:k+1))
{
regions[region][j]=puzzle[k];
j++;
}
}
for (int i=0;i<9;i++)//region counter
{
for (int j=0;j<9;j++)
{
for (int k=0;k<9;k++)
{
if (regions[i][j]!=0&&j!=k&®ions[i][j]==regions[i][k])
return false;
}
}
}
return true;
}
public String toString()
{
String string= "";
for (int i=0; i <9;i++)
{
for (int j = 0; j<9;j++)
{
string = string+puzzle[i*9+j];
}
string =string +"\n";
}
return string;
}
public static void main(String[] args)
{
Sudoku sudoku=new Sudoku();
sudoku.makePuzzle(sudoku.puzzle, 0);
}
}
Try this code:
package com;
public class Suduku{
public static void main(String[] args ){
int k=0;
int fillCount =1;
int subGrid=1;
int N=3;
int[][] a=new int[N*N][N*N];
for (int i=0;i<N*N;i++){
if(k==N){
k=1;
subGrid++;
fillCount=subGrid;
}else{
k++;
if(i!=0)
fillCount=fillCount+N;
}
for(int j=0;j<N*N;j++){
if(fillCount==N*N){
a[i][j]=fillCount;
fillCount=1;
System.out.print(" "+a[i][j]);
}else{
a[i][j]=fillCount++;
System.out.print(" "+a[i][j]);
}
}
System.out.println();
}
}
}