Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / December 2005

Tip: Looking for answers? Try searching our database.

Calling a Subroutine

Thread view: 
Mike - 11 Dec 2005 00:51 GMT
I'm fumbling again. I'm trying to write this Sudoku solver to work up
my java skills. What I thought to do was to create a fairly static
subroutine to set up the board with values until I have time to master
the gui interface. So I thought I should write a separate class
SudokuSetUp to contains this code, then later I can write the GUI code
in there. I didn't want to write this in my main class the SudokuGame.

But now I can't figure out how to pass the entire array that is the
board over to the other class to insert values into some of the cells.

I tried

  sudokuBoard = SudokuSetup(sudokuBoard);

but that complained that it could not find the method SudokuSetup in my
SudokuGame class.

Then I tried

  sudokuBoard = SudokuSetup.setvalues(sudokuboard)

but that complained that non-static method setValues(SudokuCell[][])
cannot be referenced from a static context

I''m posting my code here, apologies if it is too much code.

Class SudokuGame:

import java.text.*;
import java.util.*;

public class SudokuGame
{
    public static void main (String[] args)
    {

        SudokuCell[] [] arrSudokuBoard = new SudokuCell[9] [9];

//        set up a board with all cells initialized.
        for (int i=0; i<9; i++)
        {
            for (int j=0; j<9; j++)
            {
                arrSudokuBoard[i] [j] = new SudokuCell( i, j);
            }
        }

//      set certain cells to specific values
        arrSudokuBoard = SudokuSetUp.setValues(arrSudokuBoard);

//      print current board
        for (int i=0; i<9; i++)
        {
            System.out.println("x-value " + i);
            for (int j=0; j<9; j++)
            {
                System.out.print(arrSudokuBoard[i] [j].toString());
            }

            System.out.println();
        }

    }
}

Class SudokuCell:
import java.util.*;
import java.text.*;

public class SudokuCell
{
    // Declare instance variables
    private int xCoord;
    private int yCoord;
    private int xRegionCoord;
    private int yRegionCoord;
    List<Integer> cell = new ArrayList<Integer>();

    // Constructor with x,y reference
    public SudokuCell(int x, int y)
    {
        xCoord = x;
        yCoord = y;
        xRegionCoord = xCoord/3;
        yRegionCoord = yCoord/3;
       for (int i=1; i<10; i++)
          {
              cell.add(i);
        }

    }

    public void setValue(int value)
    {
        cell.retainAll(Collections.singleton(value));
    }

    public void removeValue(int value)
    {
        cell.remove(value);
    }

    public int[] getRegion()
    {
        int[] regionCoord = new int[2];
        regionCoord[0] = xRegionCoord;
        regionCoord[1] = yRegionCoord;
        return regionCoord;
    }

    public int [] [] getXAdj()
    {
        int [] [] xAdj = new int [2] [2];
        int pos = xCoord % 3;
        switch (pos)
        {
            case 0:
                xAdj[1] [1] = xCoord + 1;
                xAdj[1] [2] = yCoord;
                xAdj[2] [1] = xCoord + 2;
                xAdj[2] [2] = yCoord;
                break;
            case 1:
                xAdj[1] [1] = xCoord - 1;
                xAdj[1] [2] = yCoord;
                xAdj[2] [1] = xCoord + 1;
                xAdj[2] [2] = yCoord;

                break;
            case 2:
                xAdj[1] [1] = xCoord - 2;
                xAdj[1] [2] = yCoord;
                xAdj[2] [1] = xCoord - 1;
                xAdj[2] [2] = yCoord;
                break;
        }
        return xAdj;
    }

    public int [] [] getYAdj()
    {
        int [] [] yAdj = new int [2] [2];
        int pos = yCoord % 3;
        switch (pos)
        {
            case 0:
                yAdj[1] [1] = xCoord;
                yAdj[1] [2] = yCoord + 1;
                yAdj[2] [1] = xCoord;
                yAdj[2] [2] = yCoord + 2;
                break;
            case 1:
                yAdj[1] [1] = xCoord;
                yAdj[1] [2] = yCoord - 1;
                yAdj[2] [1] = xCoord;
                yAdj[2] [2] = yCoord + 1;

                break;
            case 2:
                yAdj[1] [1] = xCoord;
                yAdj[1] [2] = yCoord - 2;
                yAdj[2] [1] = xCoord;
                yAdj[2] [2] = yCoord - 1;
                break;
        }
        return yAdj;
    }

    public String toString()
    {
        String outString = new String("Cell at
X("+xCoord+"),Y("+yCoord+"):("+cell+")");
        return outString;
    }
}

Class SudokuSetup:

import java.text.*;
import java.util.*;

public class SudokuSetUp
{
    public class SudokuSetup
    {
    }

    public SudokuCell[] [] setValues(SudokuCell board [] [])
    {
        board[0] [0].setValue(1);
        board[2] [0].setValue(9);
        board[3] [0].setValue(3);
        board[7] [0].setValue(2);
        board[0] [1].setValue(7);
        board[2] [1].setValue(3);
        board[3] [1].setValue(6);
        board[4] [1].setValue(2);
        board[5] [1].setValue(5);
        board[6] [1].setValue(1);
        board[1] [2].setValue(2);
        board[3] [2].setValue(1);
        board[8] [2].setValue(7);
        board[1] [3].setValue(6);
        board[3] [3].setValue(8);
        board[5] [3].setValue(1);
        board[1] [4].setValue(5);
        board[2] [4].setValue(2);
        board[6] [4].setValue(8);
        board[7] [4].setValue(7);
        board[3] [5].setValue(2);
        board[5] [5].setValue(3);
        board[7] [5].setValue(5);
        board[0] [6].setValue(4);
        board[5] [6].setValue(2);
        board[7] [6].setValue(3);
        board[2] [7].setValue(6);
        board[3] [7].setValue(7);
        board[4] [7].setValue(3);
        board[5] [7].setValue(8);
        board[6] [7].setValue(4);
        board[8] [7].setValue(2);
        board[1] [8].setValue(3);
        board[5] [8].setValue(9);
        board[6] [8].setValue(7);
        board[8] [8].setValue(5);

        return board;
    }
}

Thanks
Mike
IchBin - 11 Dec 2005 01:48 GMT
[snip code]

> public class SudokuGame
> {
>     public static void main (String[] args)
>     {

          SudokuSetup sudokuSetUp = new SudokuSetup();

[snip code]>
> //      set certain cells to specific values
>         arrSudokuBoard = SudokuSetUp.setValues(arrSudokuBoard);

          arrSudokuBoard = sudokuSetUp.setValues(arrSudokuBoard);

[snip code]

I just added the one line above and changed one line to new reference.
Signature


Thanks in Advance...
IchBin, Pocono Lake, Pa, USA
http://weconsultants.servebeer.com/JHackerAppManager
__________________________________________________________________________

'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor,  Regular Guy (1952-)

Mike - 11 Dec 2005 02:08 GMT
Thanks so much!

Mike
Mike - 11 Dec 2005 16:55 GMT
> [snip code]
> >
[quoted text clipped - 14 lines]
>
> I just added the one line above and changed one line to new reference.

Based on what you showed me, I went back to my textbook and re-read the
bits about static methods and variables. Basically, what I understand
is that a non-static method must be instantiated (as you did) before it
can be used. Alternatively, I can make the method static and then I
don't have to instantiate it.

My textbook doesn't dwell much on this and suggests that it will become
clearer when I use it. But I'm confused. On the surface it _seems_
easier to simply make the method static and then I dont have to
instantiate it. What is the downside? In my main class I'm creating
several methods, and I found the same issue that I have to either
instantiate the methods or make them static. What is the best way to
proceed?

Thanks
Mike
IchBin - 11 Dec 2005 17:56 GMT
>> [snip code]
>>> public class SudokuGame
[quoted text clipped - 29 lines]
> Thanks
> Mike

It is better to use static methods only when really needed. This so that
you can really take advantage of Java and build OOP\OOD applications.

This has been answered in other emails. Look at this thread..
http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/7a
25ef704fd23c12/ba18da7e9a1e73f0?lnk=st&q=%22Styles+of+programming%22&rnum=2#ba18
da7e9a1e73f0

or do a google against groups with "Styles of programming"

At your leisure look at 'The Java Language Specification, Third Edition'
http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html

'Thinking in Java, 3rd ed. Revision 4.0'
http://jamesthornton.com/eckel/TIJ-3rd-edition4.0/TIJ3.htm

Signature

Thanks in Advance...
IchBin, Pocono Lake, Pa, USA
http://weconsultants.servebeer.com/JHackerAppManager
__________________________________________________________________________

'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor,  Regular Guy (1952-)

Rhino - 11 Dec 2005 17:57 GMT
>> [snip code]
>> >
[quoted text clipped - 28 lines]
> instantiate the methods or make them static. What is the best way to
> proceed?

Have a look at the "Styles of Programming" thread on
comp.lang.java.programmer which was created today, particularly the remarks
by Francesco Devittori: I think he states the basic principle very well.

My remarks in the "non-static context" thread on comp.lang.java.help
(started on Dec 9) _may_ also be useful to you.

Rhino
Mark Haase - 11 Dec 2005 18:14 GMT
> Based on what you showed me, I went back to my textbook and re-read the
> bits about static methods and variables. Basically, what I understand
[quoted text clipped - 9 lines]
> instantiate the methods or make them static. What is the best way to
> proceed?

Not quite...you can't "instantiate a method". But a non-static method
can only be called on a particular instance of that class, and you do
have to instantiate an object before you call a non-static method on it.
In memory, though, there's only one copy of the method.

A static method, as you've noted, can be called without having any
objects lying around.

What's the practical difference? Use non-static methods for most things.
In a non-static context, you have a reference to "this" (whatever object
the method was called on). In general, good OO design is going to
involve calling non-static methods on objects rather than calling static
methods on classes. This is true because notice what happens when you
use static methods to do everything: you're basically writing procedural
code.

Static methods do have uses (obviously). The main method is always
static, for instance. If it wasn't, what object would it be called on?
It gets called before you've instantiated any objects, so it must be
static. (In other languages, they get around this problem by
instantiating a root object for you and then calling the "main" method
on it.)

Static methods also make sense for algorithms which don't work on
objects or may not often be used in an OO context. A lot of the
java.lang.Math classes use static methods, because you wouldn't want to
call, say sqrt() or sin() or cos() on most objects. You'd rather just
call them statically and pass a few primitives as arguments. There are
lots of static methods in java.lang.String as well for the same reason:
convenience.

Finally, static methods are useful whenever you're trying to control
access to a class. If you didn't want a class to be instantiable, for
instance, you could mark all of its constructors as private and then
provide static methods to instantiate and return new objects. Such a
method is called a "factory method" because it does the work of building
a new object for you. Why would you want to do this? I can name one
reason: if you're writing a class that represents a constrained
computing or i/o resource. So if you write a class that represents
serial ports, for instance, most computers only have one or two. So you
could write your class, mark the contructors as private (so nobody else
can instantiate a serial port except the serial port class itself), and
then provide static methods which instantiate serial port objects and
make sure that no more than one piece of code ever has a reference to
the same serial port.

Hope this helps, search on google for "java math" and "java string" and
read through the APIs that pop up. It should give you a better feel what
static is for.

|\/|  /|  |2  |<
mehaase(at)gmail(dot)com
Mike - 11 Dec 2005 19:56 GMT
That was great. Thanks to IchBin, Rhino and Mark Haase. I now have a
clearer understanding of the static issue.

Now however, I'm in doubt as to my design for my Sudoku solver. I'll
try to outline my thinking, hopefully it is not too unclear and someone
can tell me if I'm on the right track or if a better design is possible
in Java.

I have a main class SudokuGame

In this class, the main method creates a sudokuBoard, a 9X9 array of
SudokuCells
The main method then calls (invokes?) SudokuSetUp to get the
configuration of the current game board. For now I've got only one game
configuration, I'll make SudokuSetUp the piece (module?) that interacts
with the user to get the configuration once I've got the rest of this
in place.

The main method then iterates over a number of other methods for
solving various possible configurations. It does this for as long as
each iteration results in more solved cells than in the previous
iteration.

The methods in SudokuGame that main can invoke are routines such as
a) count the number of solved cells (a solved cell has only one value).
b) remove a value from a region, a row or a column.
c) identify a region with only two cells with the same value in both
and where the cells are in line either horizontally or vertically.
d) identify a row, column or region where there is only one cell that
has a particular value.

The class SudokuCell creates an instance (one of 81) of the cells in
the array. Each cell has a List with, initially, 9 values. Each cell
has methods to return the region the cell belongs to, the (x,y)
co-ordinates of the other 8 cells in the same region, the (x,y)
coordinates of the other cells in the same region in the same
row/column, as well as methods to set the value of the cell to a single
value or to remove a specific value from the cell list.

I considered making this a class that extends ArrayList, but I was not
sure about that. I think I may rewrite it to extend ArrayList so that I
don't have to create a method in my class for every method I want to
use on the ArrayList in SudokuCell. Advice on this will be greatly
appreciated.

So currently I have 3 classes. SudokuGame (main + manipulation for the
sudokuBoard), SudokuSetUp (create initial board configuration) and
SudokuCell(manipulate the cell contents and provide navigation info on
the cell position on the board/column, row and region).

I don't see a problem with making SudokuSetUp static, it can only be
invoked once from SudokuGame and it serves no purpose to have this
class instantiated.

Clearly the SudokuCell class is instantiated for each cell in the
sudokuBoard, each cell an instance of the class.

I think I can make the methods in SudokuGame also static, they don't
need to be instantiated at this time, perhaps if I invent a solution
method that is recursive?

I'm also toying with making the entire sudokuBoard a static variable so
that I don't have to keep passing and returning it to the various
methods in the SudokuGame class that I want to operate on the board.

Again, I hope this is clear and I appreciate any feedback on the design
I've got (I don't mind changing it, after all I'm only doing it to
learn).

Thanks
Mike
Mark Haase - 11 Dec 2005 23:38 GMT
> In this class, the main method creates a sudokuBoard, a 9X9 array of
> SudokuCells
[quoted text clipped - 3 lines]
> with the user to get the configuration once I've got the rest of this
> in place.

Why not make SudukoBoard its own class? It isn't strictly necessary, but
if you're going to be providing a graphical interface, then it makes
more sense to have a SudukoBoard class which can draw itself.

Is SudokuSetUp a method or a class? Are you referring to setting up
which squares initially have numbers in them? setUp should probably be a
static method -- unless you want to have different ways of setting up
the board (download from internet, manual input, random puzzle, etc).

> The class SudokuCell creates an instance (one of 81) of the cells in
> the array. Each cell has a List with, initially, 9 values. Each cell
[quoted text clipped - 9 lines]
> use on the ArrayList in SudokuCell. Advice on this will be greatly
> appreciated.

The SudokuCell class sounds good as it is. Why does it return the x,y
coords of other cells in its region? It shouldn't have to. In fact, it
doesn't even necessarily have to know its region -- although that is a
convenient (and acceptable) shortcut if you're not going to write a
SudokuRegion class.

Don't extend ArrayList. If you did, that would imply that the essense of
a SudokuCell is a List. But a SudokuCell,  at its core, is really just a
holder of a single value. The ArrayList is auxiliary to that central
purpose, so just give each SudokuCell its own ArrayList.

> I think I can make the methods in SudokuGame also static, they don't
> need to be instantiated at this time, perhaps if I invent a solution
> method that is recursive?

Keep in mind, methods can not be instantiated. I don't think a recursive
solution would depend on whether the methods were static or not. You can
definitely write recursive solutions of both forms:

class Test { // not tested!
  public static int factorialOne(int n) {
     if (n>1)
        return n * Test.factorialOne(n-1);
     else
        return 1;
  }
  public int factorialTwo(int n) {
     if (n>1)
        return n * this.factorialTwo(n-1);
     else
        return 1;
  }
}

Notice that in this particular case, static makes more sense because the
method doesn't use any data from the "this" object.

> I'm also toying with making the entire sudokuBoard a static variable so
> that I don't have to keep passing and returning it to the various
> methods in the SudokuGame class that I want to operate on the board.

This isn't ideal. If you do that, then you're designing the code so that
only one SudokuBoard exists. Despite not comporting with reality, it
also limits you if you ever try to add the functionality for a 2nd board
down the road. In general you want to avoid getting yourself into these
corners; instead, code for the most general case when feasible.
Especially if you ever write code professionally, you'll find that
bosses are rarely sympathetic with the "But the code isn't written to do
that! I'd have to start from scratch!" excuse.

> Again, I hope this is clear and I appreciate any feedback on the design
> I've got (I don't mind changing it, after all I'm only doing it to
> learn).

This sounds like a very good exercise to me. Keep in mind that there's
generally not a "right way" -- only subjective judgments on the various
approaches available...you could write this entire program procedurally,
but the idea behind good OO design is to make code more readable, more
maintainable and more reusable.

|\/|  /|  |2  |<
mehaase(at)gmail(dot)com
Mike - 13 Dec 2005 15:17 GMT
Mark, I sent a reply to your message, but it never made the newsgroup.
Could it be that I should not quote your posts? I see that your posts
are not marked for archiving, perhaps that I quoted it caused a
problem?

Mike
Mark Thomas - 13 Dec 2005 17:08 GMT
> Mark, I sent a reply to your message, but it never made the newsgroup.
> Could it be that I should not quote your posts? I see that your posts
> are not marked for archiving, perhaps that I quoted it caused a
> problem?
>
> Mike

Hi Mike - I'm not aware of any difference between my posts and others,
but then I'm no expert in the mysteries of usenet.  I had to give up on
one email address due to spam, but if you need to write to me use mark
at highland dot f9 dot co dot uk.

Mark
Mike - 13 Dec 2005 18:44 GMT
> > Mark, I sent a reply to your message, but it never made the newsgroup.
> > Could it be that I should not quote your posts? I see that your posts
[quoted text clipped - 5 lines]
> one email address due to spam, but if you need to write to me use mark
> at highland dot f9 dot co dot uk.

My apologies. I was addressing Mark Haase.

Mike
Roedy Green - 11 Dec 2005 20:03 GMT
>Based on what you showed me, I went back to my textbook and re-read the
>bits about static methods and variables. Basically, what I understand
>is that a non-static method must be instantiated (as you did) before it
>can be used. Alternatively, I can make the method static and then I
>don't have to instantiate it.

not quite.

Let's say you had a TV class. There are two kinds of variables static
variable that track facts about all televisions, e.g. total sold, a
list of manufacturers,  and facts about individual televisions, e.g.
manufacturer, serial number, diagonal, type LCD/CRT...

The facts about televisions in general are stored in static variables,
one per class. The facts about individual televisions are stored in TV
objects instantiated with new in instance variables.

Similarly there are static methods about televisions in general and
instance methods about particular televisions.

The terminology is you instantiate an object, then you can call the
instance methods on it.  You don't instantiate methods.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Roedy Green - 11 Dec 2005 20:16 GMT
On Sun, 11 Dec 2005 20:03:32 GMT, Roedy Green
<my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or
indirectly quoted someone who said :

>Let's say you had a TV class. There are two kinds of variables static
>variable that track facts about all televisions, e.g. total sold, a
[quoted text clipped - 7 lines]
>Similarly there are static methods about televisions in general and
>instance methods about particular televisions.

let me try that again, quoting from
http://mindprod.com/jgloss/class.html

Let's say you had a TV class to deal with television sales. There are
two kinds of variables:

1. static variables that track facts about all televisions in general,
e.g. total sold or a list of manufacturers.

2. instance (non-static) variables that track facts about individual
televisions, e.g. manufacturer, serial number, diagonal, type LCD/CRT
etc.

The facts about televisions in general are stored in static variables,
only one copy of the variable for the whole TV class. The facts about
individual televisions are stored in instance variables TV objects
instantiated with new. There is one copy of each instance field per TV
object.

Similarly, there are static methods about televisions in general and
instance methods about particular televisions. Unless you have a TV
object, you can't call any of the instance methods. You don't need a
TV object to call one of the TV static methods.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.