Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 21st, 2007, 4:09 PM   #1
emdiesse
Programmer
 
Join Date: Jul 2004
Location: Hampshire
Posts: 56
Rep Power: 5 emdiesse is on a distinguished road
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);
	}
}
emdiesse is offline   Reply With Quote
Old May 22nd, 2007, 2:54 AM   #2
crawforddavid2006
Expert Programmer
 
crawforddavid2006's Avatar
 
Join Date: Apr 2005
Location: Not sure yet
Posts: 579
Rep Power: 0 crawforddavid2006 is an unknown quantity at this point
Send a message via AIM to crawforddavid2006 Send a message via MSN to crawforddavid2006
i think its because contains is set to true and never changes back

if(Table[row][col]==0)
{
	contains=true;
	System.out.print("\t\tIt contains zeros... col=" +col+ "... row="+row+"\n");
}

there fore, after that point, contains will ALWAYS equal true, and your loop becomes infinite. I'm pretty sure you need an else to go with that if. Please correct me if i'm wrong, and I hope that helps.
__________________
Quote:
Originally Posted by DaWei View Post
Well, it's better than Pen Islands url....;)

crawforddavid2006 is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Value of index incorrect after loop aznluvsmc C 13 Nov 6th, 2005 9:47 PM
Help in QBASIC (I think it's similar to VB) phoenix987 Visual Basic 3 May 9th, 2005 12:33 PM
Help with a QBASIC program phoenix987 Other Programming Languages 4 May 5th, 2005 12:27 PM
WinSock accept() hangs program in Do loop... layer C++ 5 Apr 29th, 2005 11:28 AM
Timing loop problems badbasser98 C++ 11 Mar 10th, 2005 8:30 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 6:21 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC