Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   Java (http://www.programmingforums.org/forum17.html)
-   -   Infinate Loop Issue (http://www.programmingforums.org/showthread.php?t=13187)

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);
        }
}


crawforddavid2006 May 22nd, 2007 3:54 AM

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.


All times are GMT -5. The time now is 2:04 AM.

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