Creating defined type

BlitzMax Forums/BlitzMax Beginners Area/Creating defined type

Garns(Posted 2009) [#1]
Hi All,

I am writing by first BlizMax application and have what I am sure is a simple question.

I have a user defined type called TUnit representing the pieces of a board game I am writing and each side has 20 units. My units "class" has a function called "AddUnit" which basically adds the newly created unit into a TList using AddLast(Self) (so it is basically a list of TUnit objects).

When I am creating the unit object I am basically doing the following:

oUnit1 = New TUnit
oUnit1.AddUnit(gImage1, 10, 10)
oUnit2 = New TUnit
oUnit2.AddUnit(gImage2, 20, 20)
oUnit3 = New TUnit
oUnit3.AddUnit(gImage3, 30, 30)

This feels really cumbersome and so I have been trying to make this code much shorter. I have a list containing all of my unit objects, so these object variables are not really required as I can access my unit objects by iterating the TList containing the unit objects. I have tried the following, but it doesn't seem to work:

oUnitTemp = New TUnit
oUnitTemp.AddUnit(gImage1, 10, 10)
oUnitTemp.AddUnit(gImage2, 20, 20)
oUnitTemp.AddUnit(gImage3, 30, 30)

I end up with three objects in my list but they all have the same values (that of the last object created).

I am sure there is a shorter much more efficient way of doing this but I can't think of one.

Is anybody able to help?

Much appreciated

Mark


BladeRunner(Posted 2009) [#2]
type Ttest
    field blub:int
    global _list:tlist = new tlist

    function Create:Ttest(b:int)
        local t:Ttest = new TTest
        t.blub = b
        _list.addlast(t)
        return t
    end function
end type

- All Units are stored within the type itself.
- you can automate the creation Process:
for local i:int = 0 until 20
    TTest.Create(i)
next
'...
for local t:TTest = eachin TTest._list
    print t.blub
next



Czar Flavius(Posted 2009) [#3]
What are the three parameters for in AddUnit?

BladeRunners suggestion is a good idea - for each type you basically have a create function that takes all the parameters needed for the new type, and adds itself to the list automatically.


Warpy(Posted 2009) [#4]
What you're doing wrong in the second bit of code is only creating one TUnit object, and setting its field values three times.

You should rewrite AddUnit as a function instead of a method, and create the TUnit object inside that.

Something like:
Global units:TList = New TList	'create the list of units - it's a global so it can be accessed inside a function

Type TUnit
	Field img:TImage
	Field x:Int, y:Int
	
	Function AddUnit:TUnit(img:TImage, x:Int, y:Int)
		u:Tunit = New TUnit	'create a new unit object
		
		u.img = img			'set the unit's fields
		u.x = x
		u.y = y

		units.addlast u		'add the unit to the list of units
		
		Return u			'return the unit object in case you need to assign it to a variable elsewhere
	End Function
End Type


'create the units
TUnit.AddUnit(gImage1, 10, 10)
TUnit.AddUnit(gImage2, 20, 10)
TUnit.AddUnit(gImage3, 30, 10)


See this old post of mine for an explanation of variable scope, the difference between functions and methods, and all that jazz.


jsp(Posted 2009) [#5]
I would let the list stay inside the type and separate the creation, so here is another example:

Type TUnit
	Global units:TList = New TList	'Accessable for all instances, from outside use TUnit.units
	Field img:TImage
	Field X:Int, Y:Int
	
	Method New()
		units.AddLast(Self)		'add the unit to the list of units	, will automatically called when creating a TUnit via NEW
	End Method
	
	Method SetUnit:TUnit(img:TImage, X:Int, Y:Int)		
		Self.img = img			'set the unit's fields
		Self.X = X
		Self.Y = Y

		Return Self			'return the unit object in case you need to assign it to a variable elsewhere
	End Method
	
End Type


'create the units
New TUnit.SetUnit(gImage1, 10, 10)		'New creates the unit, SetUnit sets the parameter
New TUnit.SetUnit(gImage2, 20, 10)

Local MyUnit:TUnit = New TUnit.SetUnit(gImage3, 30, 10)	'if you need the unit itself
MyUnit.SetUnit(NewImage,NewX,NewY)		'Use the same method to set new parameters during runtime




_Skully(Posted 2009) [#6]
I'd do it Warpy's method... with a slight variance...

Type TUnit
	Global list:TList = New TList	'create a list for the units
	Field img:TImage
	Field x:Int, y:Int
	
	Method New()
		list.addlast self	'add the unit to the list of units
	End Method

	Function AddUnit:TUnit(img:TImage, x:Int, y:Int)
		u:TUnit = New TUnit	'create a new unit object
		u.img = img	'set the unit's fields
		u.x = x
		u.y = y		
		Return u	'return the unit object in case you need to assign it to a variable elsewhere
	End Function
End Type


'create the units
TUnit.AddUnit(gImage1, 10, 10)
TUnit.AddUnit(gImage2, 20, 10)
TUnit.AddUnit(gImage3, 30, 10)

'iterate
For local tu:TUnit=eachin TUnit.list
	'...
Next



Garns(Posted 2009) [#7]
Hi Guys,

Thanks heaps for the ideas. I think I will use Warpy's method as it will require only minimal changes to the TUnit object to implement.

Cheers

Mark


Garns(Posted 2009) [#8]
Hi Guys,

I just thought I would check back in and say that Warpy's solution worked a treat. The code is now much more compact and is more readable as a result. This is actually my first BlitzMax attempt after coming from a Delphi/C# background.

I am writing a Stratego clone which is coming along well, although my artistic abilities are worse than terrible! I have the GUI implemented with animated buttons and overcoming this last hurdle has allowed me to implement the unit/piece class much quicker than I had thought. I've got dragging and dropping of pieces implemented which makes game play pretty easy.

I need to pretty up the display...a lot! and implement an AI which I am really looking forward to. I also need to implement the rules to prevent illegal moves etc.

I'd post a screen shot but I am really embarrassed about the artwork. Some of it is public domain art, but for lower resolutions, so stretching the bitmaps has made them all look very grainy.

Anyway, cheers and thanks again for the help. This community is pretty top-notch for getting quick fire answers. I have a low post count because every other problem I have encountered was previously encountered by somebody else and solve, so searching these forums is a great resource.

Mark