| emdiesse |
May 21st, 2007 5:09 PM |
Infinate Loop Issue
Hello. I have a very strange infinate loop issue.
My program is a sudoku generator. It can successfully generate a solution from scratch and solve a puzzle. However, occasionally it goes nuts and it loops infinately around the method Generate() and containsZeros() in the Solution Class.
I was hoping someone here may be able to help me. I am going insane.
Here is my code:
:
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Sudoku extends JFrame
implements ActionListener
{
static Numbers One = new Numbers(1);
static Numbers Two = new Numbers(2);
static Numbers Three = new Numbers(3);
static Numbers Four = new Numbers(4);
static Numbers Five = new Numbers(5);
static Numbers Six = new Numbers(6);
static Numbers Seven = new Numbers(7);
static Numbers Eight = new Numbers(8);
static Numbers Nine = new Numbers(9);
static Strings Possibilities = new Strings(); //Must be below Numbers declarations
static Solution Final = new Solution();
static Solution Initial = new Solution();
JButton btnOption = new JButton("Generate");
JButton[][]btn = new JButton[9][9];
public Sudoku() //Method to set up Sudoku JFrame
{
super("Sudoku");
setSize(250, 290);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
setVisible(true);
FlowLayout flow = new FlowLayout();
pane.setLayout(flow);
flow.setHgap(0); flow.setVgap(0);
for(int r=0;r<9; r++) //Next 2 for loops are used to create and add 81 buttons. 1 button is 1 cell in the sudoku grid
{
for(int c=0;c<9; c++)
{
btn[r][c] = new JButton();
btn[r][c].setMargin(new Insets(0,0,0,0));
btn[r][c].setPreferredSize(new Dimension(25,25));
btn[r][c].setText("0");
btn[r][c].setFocusPainted(false);
btn[r][c].addActionListener(this);
btn[r][c].setActionCommand(Integer.toString(r)+Integer.toString(c));
pane.add(btn[r][c]);
}
}
btnOption.addActionListener(this);
btnOption.setFocusPainted(false);
pane.add(btnOption);
setContentPane(pane);
}
public static void main(String[] args)
{
Sudoku mainFrame = new Sudoku(); //Show Sudoku JFrame
}
public void actionPerformed(ActionEvent e)
{
JButton buttonPressed = (JButton)e.getSource(); //Identify button pressed
int btnRow=-1, btnCol=-1;
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
if(buttonPressed.equals(btn[row][col]))
{
btnRow = row; btnCol=col; //determines the coordinates of the cell button pressed.
}
}
}
if(btnRow!=-1 && btnCol!=-1) //when a cell button is pressed its value is incremented by one in the body of this if
{
String buttonText = btn[btnRow][btnCol].getText();
int buttonInt = Integer.parseInt(buttonText);
if(buttonInt <9) buttonInt += 1;
else buttonInt = 0;
buttonText = Integer.toString(buttonInt);
btn[btnRow][btnCol].setText(buttonText);
}
else if ("Generate".equals(e.getActionCommand())) //else if the option button is pressed in generation mode a solution is generated
{
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
Initial.Table[row][col]=Integer.parseInt(btn[row][col].getText()); //The initial table is set using the values of the cell buttons
}
}
System.out.print("Initial Table Stored\n");
Final.setTable(); //The final solution is set to the same as the initial table
System.out.print("Final set to same as initial\n"); ///Error occurs after here
Final.Generate(); //Then the generation method is called
System.out.print("Solution Generated\n");
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
btn[row][col].setText(Integer.toString(Final.Table[row][col])); //The cell buttons text is changed to the new solution once it has been generated
}
}
System.out.print("Solution Output\n");
btnOption.setText("Reset");
btnOption.setActionCommand("Reset");
btnOption.setToolTipText("Click this button to reset");
System.out.print("Button Changed to Reset\n");
}
else if("Reset".equals(e.getActionCommand())) //else if the option button is pressed in reset mode the whole process is ready to start again.
{
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
btn[row][col].setText("0");
}
}
System.out.print("Cell Buttons Reset\n");
btnOption.setText("Generate");
btnOption.setActionCommand("Generate");
btnOption.setToolTipText("Click this button to generate a solution");
Initial.ZeroTable();
System.out.print("Initial Table Zeroed\n");
restart();
System.out.print("Restart Called\n\n");
}
}
static void Update()
{
One.Update(1);
Two.Update(2);
Three.Update(3);
Four.Update(4);
Five.Update(5);
Six.Update(6);
Seven.Update(7);
Eight.Update(8);
Nine.Update(9);
Possibilities.Update();
}
static void restart()
{
Sudoku.One.Initialise(1);
Sudoku.Two.Initialise(2);
Sudoku.Three.Initialise(3);
Sudoku.Four.Initialise(4);
Sudoku.Five.Initialise(5);
Sudoku.Six.Initialise(6);
Sudoku.Seven.Initialise(7);
Sudoku.Eight.Initialise(8);
Sudoku.Nine.Initialise(9);
Sudoku.Final.setTable();
}
}
class Numbers
{
int[][]Table = new int[9][9];
public Numbers(int value)
{
Initialise(value);
}
void Initialise(int value)
{
for(int row=0; row<9; row++) //Nested for loops used
{ //to address each cell
for(int col=0; col<9; col++) //of the objects table
{
Table[row][col]=value;
}
}
}
void Update(int value) //Update the strings table to show which values are still available for the puzzle
{
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
boolean rowcon;
boolean colcon;
if(Sudoku.Final.Table[row][col]>0)Table[row][col] = 0;
rowcon = Sudoku.Final.getRow(row, value); //Check the current row for the table value
if(rowcon==true) Table[row][col] = 0;
colcon = Sudoku.Final.getCol(col, value); //Check the current col for the table value
if(colcon==true) Table[row][col] = 0;
boolean square = Sudoku.Final.getSquare(row, col, value); //Check the square the cell is in for the table value
if(square==true) Table[row][col] = 0;
}
}
}
void Zero(int row, int col) //Redundant, but can be used to speed up processing
{
Table[row][col] = 0;
}
}
class Strings
{
static String[][]Table = new String[9][9];
String One, Two, Three, Four, Five, Six, Seven, Eight, Nine;
public Strings()
{
Update();
}
void Update()
{
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
if(Sudoku.One.Table[row][col]==1)One="1"; else One="";
if(Sudoku.Two.Table[row][col]==2)Two="2"; else Two="";
if(Sudoku.Three.Table[row][col]==3)Three="3"; else Three="";
if(Sudoku.Four.Table[row][col]==4)Four="4"; else Four="";
if(Sudoku.Five.Table[row][col]==5)Five="5"; else Five="";
if(Sudoku.Six.Table[row][col]==6)Six="6"; else Six="";
if(Sudoku.Seven.Table[row][col]==7)Seven="7"; else Seven="";
if(Sudoku.Eight.Table[row][col]==8)Eight="8"; else Eight="";
if(Sudoku.Nine.Table[row][col]==9)Nine="9"; else Nine="";
Table[row][col] = One+Two+Three+Four+Five+Six+Seven+Eight+Nine;
}
}
}
}
class Solution
{
static Random generator = new Random();
int[][]Table = new int[9][9];
public Solution()
{
ZeroTable();
}
void setTable()
{
Table=Sudoku.Initial.Table;
Sudoku.Update();
}
void ZeroTable()
{
for(int row=0;row<9;row++)
{
for(int col=0; col<9; col++)
{
Table[row][col]=0;
}
}
}
void Generate()
{
while(containsZeros()==true)///infinate loop here, unsure why?
{
genCell();
System.out.print("\tgencell called\n");
Sudoku.Update();
System.out.print("\tUpdate all tables and possibilities\n");
}
}
private void genCell()
{
int row=0, col=0, cellLength=9;
for(int r=0; r<9; r++) //Following for loops used to choose the cell with the minimum possibilities
{
for(int c=0; c<9; c++)
{
if(Sudoku.Possibilities.Table[r][c].length()<cellLength)
{
if(Sudoku.Possibilities.Table[r][c].length()==0){}
else
{
cellLength = Sudoku.Possibilities.Table[r][c].length();
row = r;
col = c;
}
}
}
}
int value=0, index=0, length=Sudoku.Possibilities.Table[row][col].length();
if(length>0)
{
index=generator.nextInt(length);
value = Sudoku.Possibilities.Table[row][col].charAt(index);//This returns the ascii code of the char at point index
}
else
{
Sudoku.restart();
}
//Convert the ascii code to its char equivelent but as an integer using these else if statements
if(value=='1')value=1;
else if(value=='2')value=2;
else if(value=='3')value=3;
else if(value=='4')value=4;
else if(value=='5')value=5;
else if(value=='6')value=6;
else if(value=='7')value=7;
else if(value=='8')value=8;
else if(value=='9')value=9;
Table[row][col]=value;
}
private boolean containsZeros()
{
boolean contains=false;
int attempts=0;
for(int row=0; row<9; row++)
{
for(int col=0; col<9; col++)
{
if(Table[row][col]==0)
{
contains=true;
System.out.print("\t\tIt contains zeros... col=" +col+ "... row="+row+"\n");
}
attempts+=1;
}
}
return(contains);
}
boolean getRow(int row, int value)
{
boolean contains=false, end=false;
int col=0;
while(contains==false && end==false)
{
if(Sudoku.Final.Table[row][col]==value) contains = true;
else contains = false;
col++;
if(col>8) end=true;
}
return(contains);
}
boolean getCol(int col, int value)
{
boolean contains=false, end=false;
int row=0;
while(contains==false && end==false)
{
if(Sudoku.Final.Table[row][col]==value) contains = true;
row++;
if(row>8) end=true;
}
return(contains);
}
boolean getSquare(int row, int col, int value)
{
boolean contains=false;
if(row==0 || row==1 || row==2)
{
if(col==0 || col==1 || col==2)
{
contains=checkSquare(0, 0, value);
}
if(col==3 || col==4 || col==5)
{
contains=checkSquare(0, 3, value);
}
if(col==6 || col==7 || col==8)
{
contains=checkSquare(0, 6, value);
}
}
if(row==3 || row==4 || row==5)
{
if(col==0 || col==1 || col==2)
{
contains=checkSquare(3, 0, value);
}
if(col==3 || col==4 || col==5)
{
contains=checkSquare(3, 3, value);
}
if(col==6 || col==7 || col==8)
{
contains=checkSquare(3, 6, value);
}
}
if(row==6 || row==7 || row==8)
{
if(col==0 || col==1 || col==2)
{
contains=checkSquare(6, 0, value);
}
if(col==3 || col==4 || col==5)
{
contains=checkSquare(6, 3, value);
}
if(col==6 || col==7 || col==8)
{
contains=checkSquare(6, 6, value);
}
}
return(contains);
}
public void Print()
{
System.out.print(" ------- ------- ------- \n");
for(int row=0; row<9; row++)
{
System.out.print("| ");
for(int col=0; col<9; col++)
{
System.out.print(+ Table[row][col] + " ");
if(col==2||col==5||col==8)System.out.print("| ");
}
System.out.print("\n");
if(row==2||row==5||row==8)System.out.print(" ------- ------- ------- \n");
}
System.out.print("\n");
}
boolean checkSquare(int row, int col, int value)
{
boolean contains=false;
int r0w=row, c0l=col;
for(int n=0; n<9; n++)
{
if(Sudoku.Final.Table[r0w][c0l]==value)
{
contains = true;
break;
}
if(++c0l > col+2)
{
c0l=col;
r0w++;
}
}
return(contains);
}
}
|