The Tower OF Hanoi

  • Thread starter shaghayeghcute2003
  • Start date
S

shaghayeghcute2003

I'm currently trying to write The Tower Of Hanoi (http://
illuminations.nctm.org/ActivityDetail.aspx?ID=40) in C#.
I have a panel on the form and I draw pegs on the panel inside the
form class. I passed GraphicObject to drawDisk method in disk class to
draw disks' pictures.
I used MouseDown/Up/Move to move these disks on the panel.
I'm attaching some part of my code:

private void panel1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{

mouseLocation = new Point(e.X, e.Y);
drag = true;
}
private void panel1_MouseMove(object
sender,System.Windows.Forms.MouseEventArgs e)
{//p1 is the first peg
((Disc)p1.discsPile[0]).xLocation = e.X;
((Disc)p1.discsPile[0]).yLocation = e.Y;
this.Invalidate();
panel1.Invalidate();
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
When I try to move the disks on the panel, nothing happens
Could you please someone tell me what the mistake is?
I appreciate for your help in advance.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

I'm currently trying to write The Tower Of Hanoi (http://
illuminations.nctm.org/ActivityDetail.aspx?ID=40) in C#.
I have a panel on the form and I draw pegs on the panel inside the
form class. I passed GraphicObject to drawDisk method in disk class to
draw disks' pictures.
I used MouseDown/Up/Move to move these disks on the panel.
I'm attaching some part of my code:

private void panel1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{

mouseLocation = new Point(e.X, e.Y);
drag = true;
}
private void panel1_MouseMove(object
sender,System.Windows.Forms.MouseEventArgs e)
{//p1 is the first peg
((Disc)p1.discsPile[0]).xLocation = e.X;
((Disc)p1.discsPile[0]).yLocation = e.Y;
this.Invalidate();
panel1.Invalidate();
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
When I try to move the disks on the panel, nothing happens

Standard question #4:
No, "nothing" never happens. Exactly what is happening?
Could you please someone tell me what the mistake is?
I appreciate for your help in advance.

Have you verified that the xLocation and yLocation properties actually
change? Do you actually use the xLocation and yLocation properties when
drawing the discs? What does the Disc class and the xLocation and
yLocation properties look like?
 
S

shaghayeghcute2003

I'm currently trying to write The Tower Of Hanoi (http://
illuminations.nctm.org/ActivityDetail.aspx?ID=40) in C#.
I have a panel on the form and I draw pegs on the panel inside the
form class. I passed GraphicObject to drawDisk method in disk class to
draw disks' pictures.
I used MouseDown/Up/Move to move these disks on the panel.
I'm attaching some part of my code:
private void panel1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
mouseLocation = new Point(e.X, e.Y);
drag = true;
}
private void panel1_MouseMove(object
sender,System.Windows.Forms.MouseEventArgs e)
{//p1 is the first peg
((Disc)p1.discsPile[0]).xLocation = e.X;
((Disc)p1.discsPile[0]).yLocation = e.Y;
this.Invalidate();
panel1.Invalidate();
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
When I try to move the disks on the panel, nothing happens

Standard question #4:
No, "nothing" never happens. Exactly what is happening?
Could you please someone tell me what the mistake is?
I appreciate for your help in advance.

Have you verified that the xLocation and yLocation properties actually
change? Do you actually use the xLocation and yLocation properties when
drawing the discs? What does the Disc class and the xLocation and
yLocation properties look like?

--
Göran Andersson
_____http://www.guffa.com- Hide quoted text -

- Show quoted text -

Hi dear Andersson;
Thanks for your quick respond.
I put messgasebox.show inside the Panel1_MouseMove to show me the
xlocation and ylocation but it didn't print anything.
It seems MouseMove/Up/Down arenot executed at all.
I changed System.windows.Form.MouseEventArgs to MouseEventArgs, but it
didn't make difference.
What is your next suggestion?
Thanks;
Shaghayegh
 
P

Peter Duniho

[...]
When I try to move the disks on the panel, nothing happens
Could you please someone tell me what the mistake is?

Well, it's hard to say, since you didn't post minimal-but-complete code.
Given the code that you did post, my first suspicion is that you didn't
actually subscribe those event handlers to correct events. I admit, that
doesn't seem plausible at the face of it, because your event handlers are
named exactly as they would be if you'd double-clicked on the panel
instance's events for them in the designer. But the MouseMove handler in
particular should definitely be changing the coordinates of the discs.
The code's wrong, but _something_ should be happening.

Basically, the only way I see for _nothing_ to happen is if that event
handler isn't called at all.

That said, you do have some other problems. The two that specifically
stand out are:

* You don't use "mouseLocation" when changing the coordinates of the
disc in question. Consequence: the disc will "snap" to the mouse
location, rather than just "sticking" to the mouse cursor wherever it
happens to be
* You don't check "drag" before changing the coordinates.
Consequence: any movement of the mouse over the control will result in
movement of a disc, whether the mouse button was pressed or not.

A third issue that will be a problem when you get around to actually
trying to make this work correctly is that you aren't doing any
hit-testing in MouseDown to figure out _which_ disc you should actually be
moving. I will assume for the moment that you're aware of that, and that
the code is currently the way it is just so you can figure the other stuff
out.

Now, all that said, here's the basic idea of how I think this should be
done:

private List<Peg> _pegs = new List<Peg>();
Disc _discDragging;
Peg _pegFrom;
Point _pointDragStart;

private void panel1_MouseDown(object sender, MouseEventArgs e)
{
foreach (Peg peg in _pegs)
{
// assumption: the Disc at index 0 is the top disc. Check
// only that disc, because you can't drag any other disc other
// than the top one anyway
Disc disc = peg.discsPile[0];

// assumption: the Disc class has a property Bounds that gets
// a Rectangle that is the extent of the Disc graphically.
if (disc.Bounds.Contains(e.Location))
{
_discDragging = disc;
_pegFrom = peg;
_pointDragStart = e.Location;
break;
}
}
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (_discDragging != null)
{
// assumption: the Disc class has a property Location that
gets/sets
// the position of the Disc graphically (most likely the
upper-left
// corner of the Bounds rectangle, but that's not actually
important
// here)
Point ptNew = _discDragging.Location;

// offset the position by the same distance that the mouse has
moved
// since our last mouse event
ptNew.Offset(e.Location - _pointDragStart);
_discDragging.Location = ptNew;

// update the "last mouse event" position
_pointDragStart = e.Location;

// Signal the panel to redraw
panel1.Invalidate();
}
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (_discDragging != null)
{
// I'm going to leave a lot of stuff out here. Hopefully, you
can see
// the basic idea from the code I did include and take it from
here.
// When the MouseUp event happens, you have to do some things:
// -- compare the disc's position to the peg locations,to
figure
// out which peg the disc is being dragged to
// -- check the existing discs on that peg to make sure
that the
// peg is a valid peg on which the disc can be dropped
// -- depending on the previous check, either remove the
disc from
// its current peg (my field named "_pegFrom"),
calculate the
// correct graphical position for the new peg, set it
to that
// position and add it to the new peg, or simply
calculate the
// correct graphical position for the original peg and
put it back
// there.
// -- if you want to provide the user feedback regarding
whether they
// have succesfully moved the discs from one peg to the
other, this
// would be a good place to check that too

_discDragging = null;
}
}

This is by no means the canonical way to do this. There are variations on
this theme that are all valid, depending on how you like the code to look
and what specifically you are doing with the code. But I think the above
solution is pretty appropriate given your goals.

One thing I will mention: you appear to be storing your list of discs on
each peg with the disc at index 0 being the top disc. IMHO, it makes more
sense to store the discs bottom-up, with the disc at index 0 being the
bottom disc. The reason being that it is more efficient when dealing with
an array to add and remove things at the end, rather than the beginning,
and all of the adding and removing happens at the disc that's at the top
of the peg. So making the disc at the top of the peg being the last in
the array rather than the first is more efficient.

Pete
 

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