PDA

View Full Version : multi-file named constants


DNAunion2000
12-03-2003, 11:01 PM
/*DNAunion*/ How do I setup multi-file named constants in VB? I realize that it is probably going to be very easy, but I don’t work that much with VB and my inexperience is telling.

I am working on a multi-file chess-playing program where certain values continue to be used over and over: for example, the value of a white rook. Since I am just starting, I’ve hard coded the values in everywhere they are used. But now I am wanting to eliminate those “magic numbers” by using named constants.

The main() function creates a Position object which requires it to specify what Piece (including no Piece) it wants to place on each of the 64 squares. So I have the code in main() currently setup like this:


Dim GamePositions(500) As Position
GamePositions(1) = New Position

GamePositions(1).SetSquare(1, 1, New ChessPiece(25))
GamePositions(1).SetSquare(2, 1, New ChessPiece(15))


That works, but is poor programming style. What I want to do is to set it up using named constants like this:


Dim GamePositions(500) As Position
GamePositions(1) = New Position

GamePositions(1).SetSquare(1, 1, New ChessPiece(WHITE_ROOK))
GamePositions(1).SetSquare(2, 1, New ChessPiece(WHITE_KNIGHT))


But when I do I get errors. In C++ I’d simply define the named constants in the header file that most directly uses them:


// ChessPiece.h

#define WHITE_ROOK 25
#define WHITE_KNIGHT 15



Then in the main program just include that header file:



#include “ChessPiece.h”
int main()
{

}


But I can’t figure out how to do it in VB. Here’s what I’ve tried.

1) Added the following In the ChessPiece.vb file above the class definition, mimicking what I would do in C++. Using the Public access specifier should make the variable accessible from anywhere in the solution.


Public Const WHITE_ROOK As Integer = 25
Public Const WHITE_KNIGHT As Integer = 15

That didn’t work. I got a compile-time error stating, “Statement is not valid in a namespace”.

2) So I moved the statements into the class definition.


Public Class ChessPiece
Public Const WHITE_ROOK As Integer = 25
Public Const WHITE_KNIGHT As Integer = 15
...
End Class

That compiled with fewer errors, but still no clean compile. This time the error was “Name ‘WHITE_ROOK’ is not declared” in the line of code in main() that attempts to use it.

3) My next thought was to make the constant Shared (static to the C++/C# people) so that I could use it from outside the class as ChessPiece.WHITE_KNIGHT. So I tried:


Public Class ChessPiece
Shared Const WHITE_ROOK As Integer = 25
Shared Const WHITE_KNIGHT As Integer = 15
...
End Class

But received a “’Shared’ is not valid on a constant declaration” error.

4) I finally got it to work but the workaround seems clunky and weird.


Public Class ChessPiece
Private Const WHITE_ROOK As Integer = 25
Private Const WHITE_KNIGHT As Integer = 15

Public Function WhiteRook() As Integer
Return WHITE_ROOK
End Function
...
End Class


Then to use that WhiteRook() method in main() to get the value of the named constant I have to have a bogus object of type ChessPiece before I create a Position.


Dim bogus As New ChessPiece

Dim GamePositions(500) As Position
GamePositions(1) = New Position

GamePositions(1).SetSquare(1, 1, New ChessPiece(bogus.WhiteRook()))


This works but surely there’s a better way.

PS: I found this, but it seems to be what I tried that failed.

"Like variables, constants can be of any access level. If you want your constant to be available to all users of your application or component, you can declare it with the Public (public) keyword..."

Didn't seem to work for me.

DNAunion2000
12-04-2003, 10:58 AM
/*DNAunion*/ Figured it out. #2 from above was closest.

The thing is that VB.NET implicitly creates a namespace for each vb source file. Therefore, the two files - the main program and the chesspiece "header" - are in different two different namespaces and that prevents simple access across the files.

For some reason, VB.NET automatically implicitly prepends the namespace ChessPiece to the class, so it can find it. But it can't find the Public variables inside that class. This is confusing. It seems to me that either VB.NET should be able to see everything in that file or nothing. Anyway..

The solutions are either to fully qualify the named constants or to use an Imports statement. This following works.


Imports ConsoleApplication5.ChessPiece

Module Module1
Sub Main()
Dim file, rank As Integer

Dim GamePositions(500) As Position
GamePositions(1) = New Position

GamePositions(1).SetSquare(1, 1, New ChessPiece(WHITE_ROOK))
GamePositions(1).SetSquare(1, 2, New ChessPiece(WHITE_KNIGHT))
GamePositions(1).SetSquare(1, 3, New ChessPiece(WHITE_BISHOP))


For file = 1 To 8
For rank = 1 To 8
Console.WriteLine(GamePositions(1).GetSquare(file, rank).Value)
Next rank
Console.WriteLine("")
Next file

Console.WriteLine("Press Enter to continue...")
Console.ReadLine()

End Sub

End Module


and


Public Class ChessPiece
Public Const WHITE_ROOK As Integer = 25
Public Const WHITE_KNIGHT As Integer = 15
Public Const WHITE_BISHOP As Integer = 17

Private mValue As Integer
Private mTimesMoved As Integer
Public Property Value()
Get
Return mValue
End Get
Set(ByVal Value)
Select Case Value
Case 0
Case 5
Case -5
Case WHITE_KNIGHT
Case WHITE_KNIGHT * -1
Case WHITE_BISHOP
Case WHITE_BISHOP * -1
Case WHITE_ROOK
Case WHITE_ROOK * -1
Case 47
Case -47
Case 5000
Case -5000
Case Else
' Error
Value = 0
End Select
mValue = Value
End Set
End Property

...

Public Sub New(ByVal val As Integer)
Value = val
TimesMoved = 0
End Sub
End Class


Remember, this is a very early "just get it working" program: I know there is plenty of room for improvement.