Sudoku Solver question...

T

Terry Holland

I am writing a Sudoku Solver application as an excersise for learning about
some VB.Net objects and it has thrown up a few questions

The model I am using for my business objects is as follows:
I have the following classes:
Grid
Cell
Row
Column
Block

Ive also got a Range class from which Row, Column & Block are derived.

The Grid contains 81 cells labelled 1-81

The grid also contains
9 Row objects, each of which contain 9 Cell objects
9 Column objects, each of which contain 9 Cell objects
9 Block objects, each of which contain 9 Cell objects

Each cell is contained by 1 Row, 1 Column & 1 Block (as well as the Grid)
When a value changes in a Cell, this has an impact on the other cells in the
Row, Column and Block that contains this Cell

Im having difficulty understanding how to do the following:
When a value in a cell changes, how do I inform other related objects
ie Cell 1 is in Row 1, Column 1 & Block 1. If Cell 1 is set to value 6 then
every other Cell in Row 1, Column 1 & Block 1 needs to know about this.

I have been trying to model this by having a Range class as follows

Public Class Range
Inherits Collections.Generic.List(Of Cell)

...
End Class

Public Class Cell
...
End Class

and Row, Column and Block classes as follows:

Public Class Row
Inherits Range

...
End Class

Public Class Column
Inherits Range

...
End Class

Public Class Block
Inherits Range

...
End Class

I was hoping that I could have an event in my Cell class that i could raise
whenever a Cell value changed, and then respond to that event in the Range
class and make necessary modifications to all other Cell objects contained in
the Range but I dont see any mechanism for detecting an event in a Cell class
from the Range class.

Any suggestions?

Sorry I dont have any real code but this is a bit conceptual at the moment &
I dont have Visual Studio on this machine :-(
 
G

Guest

Im having difficulty understanding how to do the following:
When a value in a cell changes, how do I inform other related objects
ie Cell 1 is in Row 1, Column 1 & Block 1. If Cell 1 is set to value
6 then every other Cell in Row 1, Column 1 & Block 1 needs to know
about this.

I would use a linked list for this sort of thing, each cell stores a
reference to the cells surround it. You can then easily traverse through
a row or column. i.e.

Cell.Previous
Cell.Next
Cell.Top
Cell.Bottom

A block would consist of multiple cells, you can either store the cells
in individual properties or use a 3x3 array to store all the cells.

Block.Cells(1,1)
or
Block.Cell1

I think building your Soduku program is primarily finding a way to
organize your objects in an easy to manage method.
 
M

Michael C

Terry Holland said:
I am writing a Sudoku Solver application as an excersise for learning about
some VB.Net objects and it has thrown up a few questions

The model I am using for my business objects is as follows:
I have the following classes:
Grid
Cell
Row
Column
Block

Ive also got a Range class from which Row, Column & Block are derived.

I'm doing pretty much exactly the same thing right now. I don't have a row,
column or block class, just a class I call CellGroup.
Im having difficulty understanding how to do the following:
When a value in a cell changes, how do I inform other related objects
ie Cell 1 is in Row 1, Column 1 & Block 1. If Cell 1 is set to value 6
then
every other Cell in Row 1, Column 1 & Block 1 needs to know about this.

I came up against the same issue. I realised that notifying the other cells
was completely unnecessary. If i've got a 6 in a cell and someone puts a 6
in the cell right next door then that's their own stoopid fault. I did
create a method on the Grid object which set a cell value and removed
possibilities from other cells. That way cells didn't need to know about
their neighbours.
 
T

Terry Holland

For me, the Sudoku problem is just a vehicle for playing with collections.
What I really want to understand is this:

If I have a collection C that contains a number of objects O, who can I
notify the collection C of any change that has occurred in any of the objects
contained within it? Furthermore, if an object O is a member of many
collections C1, C2, C3 etc, how do I notify all of these collections of
changes in object O?

It just happens that a Sudoku Solver problem allows me to explore these
questions.


The line Ive been thinking along is my Cell objects would have a Change
event and when the cell value changes it would raise the Change event.

If I had code similar to this

Public Class Row
Private WithEvents oCell1 as Cell
Private WithEvents oCell2 as Cell
...
Private WithEvents oCell9 as Cell
...

End Class

then any change in any of the Cell objects could be detected with the
following

Private Sub oCell1_Changed () Handles oCell1.Changed
...
End Sub

Private Sub oCell2_Changed () Handles oCell2.Changed
...
End Sub

and so on.

Of course this is very crude but would work if there were a fixed number of
objects that I needed to detect events on. In Sudoku this is the case, but I
need to come up with a solution that will cater for any number of objects.

So I was trying to come up with a solution that has a container class as
follows:

Public Class Range
Inherits Collections.Generic.List(Of Cell)

...

End Class


The trouble with this is I dont know how to notify a Range object that
changed have occurred in any of the Cell objects in its list.


Hope this explains my problem enough
 
M

Michael C

Terry Holland said:
For me, the Sudoku problem is just a vehicle for playing with collections.
What I really want to understand is this:

Fair enough. It's probably a really good place to start.
If I have a collection C that contains a number of objects O, who can I
notify the collection C of any change that has occurred in any of the
objects
contained within it? Furthermore, if an object O is a member of many
collections C1, C2, C3 etc, how do I notify all of these collections of
changes in object O?

Basically the cell has to call some sort of function to do this. That
function can be in the form of an event or just a plain simple function
call.
The line Ive been thinking along is my Cell objects would have a Change
event and when the cell value changes it would raise the Change event.

If I had code similar to this

Public Class Row
Private WithEvents oCell1 as Cell
Private WithEvents oCell2 as Cell
...
Private WithEvents oCell9 as Cell
...

End Class

As I'm sure you know, that is a REALLY REALLY bad idea. :) I'm not sure
about VB but in C# I would do this:

private Cell[] cells; // dim cells() as Cell
cells = new Cell[GridSize];// redim cells(GridSize)
for(int i =0; i < GridSize; i++)//for i = 0 to GridSize - 1
{
cells = new Cell(); //cells(i) = new Cell()
cells.Change += new EventHandler(cell_change);
}

That last line I don't know how to translate to VB but it does do it for
sure. I think you do something like AddHandler or something?
Of course this is very crude but would work if there were a fixed number
of
objects that I needed to detect events on. In Sudoku this is the case,
but I
need to come up with a solution that will cater for any number of objects.

There's no reason why Sudoku has to be 9x9. I've certainly created mine
where the size is passed in.
So I was trying to come up with a solution that has a container class as
follows:

The other option is for you the cell to keep a list of the Ranges that it is
in (It's quite common for a child object to keep a reference to its parent
or parents). Then it can just call a method on Range which could update all
the cells.

Michael
 
M

Michael C

Michael C said:
The other option is for you the cell to keep a list of the Ranges that it
is in (It's quite common for a child object to keep a reference to its
parent or parents). Then it can just call a method on Range which could
update all the cells.

Thinking about this, I think this is possibly the better option as the cells
will need to know what Ranges they are in for various reasons. For example,
if a user clicks on a cell they will need to find the row and column at
least.

Michael
 
T

Terry Holland

I think we have both arrived at the same solution..
The other option is for you the cell to keep a list of the Ranges that it is
in (It's quite common for a child object to keep a reference to its parent
or parents). Then it can just call a method on Range which could update all
the cells.

This is the route I decided to take as I find it easier to grasp (I guess
this is an example of the observer design pattern)


private Cell[] cells; // dim cells() as Cell
cells = new Cell[GridSize];// redim cells(GridSize)
for(int i =0; i < GridSize; i++)//for i = 0 to GridSize - 1
{
cells = new Cell(); //cells(i) = new Cell()
cells.Change += new EventHandler(cell_change);
}


Purely as an academic exercise ...
I see what you're suggesting here and I have tried to go down this path.
I am able to dynamically add the event to each Cell object but I dont knw
how or where to trap that event
 
M

Michael C

Terry Holland said:
private Cell[] cells; // dim cells() as Cell
cells = new Cell[GridSize];// redim cells(GridSize)
for(int i =0; i < GridSize; i++)//for i = 0 to GridSize - 1
{
cells = new Cell(); //cells(i) = new Cell()
cells.Change += new EventHandler(cell_change);
}


Purely as an academic exercise ...
I see what you're suggesting here and I have tried to go down this path.
I am able to dynamically add the event to each Cell object but I dont knw
how or where to trap that event


You would need to define a function as

private sub cell_change(ByVal Sender as object, ByVal e as EventArgs)

End Sub

and then do something like this:

cells.Change.AddHandler(AddressOf cell_change)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top