Welcome to AddressOf.com Sign in | Join | Help

Solitaire (written in VB.NET)

I've finished working through the existing issues list for the C# version (available GotDotNet) for bugs and missing features.  I've implemented the missing features in my VB.NET version (although, they may not be feature complete due to the .NET Frameworks limited functionality in the help system arena).  I've also compiled it with some of my “enhanced” features enabled.  The only bugs I didn't work on were ones that I was unable to reproduce.

Here's a quick list of some differences:

  • Added XP Visual Styles support.

  • Added persistent storage (code is capable of using Windows logo compliant storage or Isolated storage)

  • Fixed: When less than three cards remaining on the left and then clicking to see them, some cards from below in the pile show through.

  • Added context help on the dialogs and integration with the associated Windows help files (Not sure if this will work on Windows 98 or not).

  • Added checking the minimum size to the main window.

  • Added persisting location and size of the main window.

So what does this mean?  Well, I suppose it's time for me to release the code into the wild.

Just keep in mind that I've only spent two nights on the coding and I spent an hour or so getting the help system integrated.  I've made a pretty good attempt at refactoring the code so that it looks and feels like VB.NET, so be kind if you find areas that I missed ;-)

I am interested in continue to improve this.  Like stated previously, I think this will make an excellent application to demo coding techniques when I'm doing presentations at user group meetings.  I also think there's an opportunity to extend it by turning it into a “smart client”.  I have a few ideas in this area and will continue moving forward.  As such, I'm not abandoning it and would appreciate any feedback, whether it be improvements to the code or reporting “bugs”. 

What I do ask is that you don't put this code for download elsewhere, let AddressOf.com be the source for the VB.NET version and, if you do want to contribute, just send me what you've done.  I'll be happy to incorporate it within the codebase.

So, without further ado...

Download Executable (zipfile)
Download Source (zipfile)

Published Thursday, March 17, 2005 2:11 AM by CorySmith
Filed under: , ,

Comments

# re: Solitaire (written in VB.NET)

Thursday, March 17, 2005 2:18 PM by Christopher Lewis
Hi -

Slight conversion error from C# to VB. the problem is that CInt() <> (int)

Here's some sample code:
imports System
public module MyModule
sub Main
Dim m_score as integer = -1

Console.WriteLine("double: {0}", CDbl(m_score))
Console.WriteLine("Log10: {0}", Math.Log10(CDbl(m_score)))
Console.WriteLine("Floor: {0}", Math.Floor(Math.Log10(CDbl(m_score))))
Try
Console.WriteLine("int: {0}", CInt(Math.Floor(Math.Log10(CDbl(m_score)))))
Catch ex as OverflowException
Console.WriteLine("int: OverFlow")
End Try
Console.WriteLine("Press Enter")
Console.ReadLine()
end sub
end module

Output:
double: -1
Log10: NaN
Floor: NaN
int: OverFlow
Press Enter

VS
using System;
public class MyClass
{
public static void Main()
{
int m_score = -1;
Console.WriteLine("double: {0}", (double) m_score);
Console.WriteLine("Log10: {0}", Math.Log10((double) m_score));
Console.WriteLine("Floor: {0}", Math.Floor(Math.Log10((double) m_score)));
try {
Console.WriteLine("int: {0}", (int) Math.Floor(Math.Log10((double) m_score)));
} catch (OverflowException ex) {
Console.WriteLine("int: OverFlow");
}
Console.WriteLine("Press Enter");
Console.ReadLine();
}
}

Output:
double: -1
Log10: NaN
Floor: NaN
int: -2147483648
Press Enter



Here's your code fix, at line 1263
If m_score < 0 Then
'Math code for VB is quite different then C#...
'VB.NET C#
'Math.Log10(-x) => NaN Math.Log10(-x) => NaN
'Math.Floor(NaN) => NaN Math.Floor(NaN) => NaN
'CInt(NaN) => OverflowException (int) NaN => -2147483648
rect.Width -= 64 + (CInt(Math.Floor(Math.Log10(CDbl(Math.Abs(m_score)))) + 1) * charSpace) + (CInt(Math.Floor(Math.Log10(CDbl(m_time)))) * charSpace)
Else
rect.Width -= 64 + (CInt(Math.Floor(Math.Log10(CDbl(m_score)))) * charSpace) + (CInt(Math.Floor(Math.Log10(CDbl(m_time)))) * charSpace)
End If

And at 1275
If m_score = 0 Then
rect.Width -= 20
Else
If m_score < 0 Then
rect.Width -= 20 + CInt(Math.Floor(Math.Log10(CDbl(Math.Abs(m_score)))) + 1) * charSpace
Else
rect.Width -= 20 + CInt(Math.Floor(Math.Log10(CDbl(m_score)))) * charSpace
End If
End If

# re: Solitaire (written in VB.NET)

Thursday, March 17, 2005 2:58 PM by Cory Smith
Thanks for pointing this out. I missed the fact of negatives (I did correct it for 0 as you can see).. it was 3 in the morning after all ;-)

Although your suggestion would correct the problem, after reviewing the code; or more specifically the intent of the code, I found that all that math is overkill. Basically, it's trying to figure out how many characters the number contains.

That can easily be determined by using (m_score.ToString.Length -1). Yes, it will create a temporary string (in scope), but I have a sneaky suspicion that that may be faster than all the floating point math taking place and since it's only happening once per second not really going to be taxing the GC in any way. In the end, it's easier to read what the intent of the code is doing it this way as well.

Also, as a side note: I discussed all of this in a recent post ;-) The code would work if you compile it with the "Remove integer overflow checks" option enabled. For more information, refer to my this post: http://addressof.com/blog/archive/2005/03/16/1469.aspx

# re: Solitaire (written in VB.NET)

Friday, March 18, 2005 4:31 PM by Jeff Reser
Cory -- thanks for posting the source, I think that is more important for learning then the exe. I could not find the gotdotnet project for the cSharp version, I was interested in comparing them.

# re: Solitaire (written in VB.NET)

Friday, March 18, 2005 4:35 PM by Christopher Lewis
I agree that the math is overkill, and your simple ToString().Length() is the way to go.

I'm a little surprised that all of this is being used in a timer. I can understand a timer for, well, the timer :-), but since score is event driven (placing a card) I'd think that it would be simpler to not update it each refresh.

I'm also a little curious as to why this isn't using a status bar? Isn't that more along the lines of Windows GUI standards these days? (I'm perfectly happy with inertia as an answer)

The funny thing is that I remember reading about the CINT vs (int) issues, and did some RSSbandit searches, but couldn't remember where it was. Go figure it was your blog :-)



# re: Solitaire (written in VB.NET)

Friday, March 18, 2005 4:48 PM by Cory Smith
Jeff, to find that on GotDotNet, you would go to the workspaces directory (http://www.gotdotnet.com/workspaces/directory.aspx) and type in "Solitaire" (removing the quotes of course) in the search field.

# re: Solitaire (written in VB.NET)

Friday, March 18, 2005 4:58 PM by Cory Smith
Christopher,

Yeah, I have to agree with you that there are instances in the code that could be done better (at least in my oppinion).

For example, in the code where it is drawing the drawn cards, it actually loops through all of the drawn cards... so if you have 21 cards stacked there, it draws all of them. My point is that I would have definately done a few things different and will probably make most of those changes as I continue working on this. The goal for this release was to get a working version that was:

1. In VB.NET.
2. Working.
3. More feature complete than the original.

I think that I've accomplished that and now it's time to improve upon it, be that code, performance and/or features.

As for use of a status bar, that is what is being used. However, it's being ownerdrawn to mimic the original version shipped with Windows.

Your last sentence made me laugh so hard, it took a moment to recover so I could respond. ;-)

# re: Solitaire (written in VB.NET)

Thursday, May 12, 2005 4:10 PM by mag
thanks a lot
Anonymous comments are disabled