Data Management for Management Game

Blitz3D Forums/Blitz3D Beginners Area/Data Management for Management Game

.rIKmAN.(Posted 2005) [#1]
I am just looking at the best possible way to setup datatypes for a football management game.

After some digging around forums and such I *think* this is the best way to do it, and link all the entities (leagues->clubs->players) in the correct order.
; Type setup
Type game
	Field league.league[2]
End Type

Type league
	Field team.team[10]
	Field name$
End Type

Type team
	Field player.player[20]
	Field name$
End Type

Type player
	Field name$
End Type

This gives me 2 leagues, 10 teams in each, each team has 20 players.
It means each player is linked to a club, is linked to a league.... (expandable in future for each league to a country, each country to a continent etc)

I can then create a "new game" type which kicks off all the rest ready to be initialised and assigned values:
Global p.game=New game
p\league[0]=New league
p\league[0]\team[0]=New team
p\league[0]\team[0]\player[0]=New player
p\league[0]\team[0]\player[0]\name="Peter Shilton"


Is there a better way to do this as I kind of think I am hard coding it by using BlitzArrays[], although I will know the max limits of all the arrays (leagues,clubs,players).

The other way I was thinking of doing it was by assigning each player a teamID, and each team a leagueID and doing it that way, but then I`d have to search through the whole database of players just to display the players that play for Swansea (search all players clubID field for a match)

I have to think about players transferring as well, which is why I had the "clubID field" idea, but I guess as each team has a max squad of 20 (in the above code) then if u buy or sell a player (both teams must have space) then u simply move the player and slot him into the new slot with the new club values...?
ie:
p\league[0]\team[0]\player[0]=p\league[1]\team[12]\player[18]

But - how would I then delete the original reference to the player, whilst not deleting the "space" so to speak...
I have tried making it =NULL and using Delete, but then I get "Object does not exist" errors....I don`t really want to delete it, I guess just wipe it clean ready for the next player....

I also notice that copying the player the way I have in the code above means that when I blank or delete the original (0,0,0) then it also affects the new one.
Do you have to manually copy every field or is there a workaround for copying the entire type like I have above and still being individual?

I`m beginning to ramble so I`ll wait for some reply if I`ve missed out any info.

Basically - is there another better way?

Cheers!


octothorpe(Posted 2005) [#2]
Ahh, containers.

This problem can be solved effectively with either vectors (arrays) or linked lists. Your solution is the simplest for Blitz Basic.

Note that if you want to allow less than the maximum number of items per array (e.g. a league with only 9 teams) you can either leave the unused slots NULL, or have an "exists" field for each object. Don't forget you'll need to test for unused slots anytime you loop through your objects.

You may also consider adding "parent" references. Being able to find out which team a player is on (given only a player object) or which team a league belongs to may be useful.

Given what you've told us you need to be able to do with your objects, there wouldn't be much benefit to using linked lists. There wouldn't be any drawbacks either, except for the added complexity involved in getting them to work in Blitz Basic. Personally, I'd use them anyways, but that's a matter of taste.


octothorpe(Posted 2005) [#3]
But - how would I then delete the original reference to the player, whilst not deleting the "space" so to speak...


If you're going to use NULL to represent unused elements in your array, you need to test for NULL every time you access an element.

e.g.

for league_index = 0 to MAX_LEAGUES-1
	this_league.league = p\league[league_index]
	if this_league <> NULL then

		print this_league\name$
		for team_index = 0 to MAX_TEAMS-1
			this_team.team = this_league\team[team_index]
			if this_team <> NULL then

				print "  " + this_team\name$
				for player_index = 0 to MAX_PLAYERS-1
					this_player.player = this_team\player[player_index]
					if this_player <> NULL then

						print "    " + this_player\name$

					endif
				next

			endif
		next

	endif
next


I also notice that copying the player the way I have in the code above means that when I blank or delete the original (0,0,0) then it also affects the new one.


That's because you're copying the pointer. If you actually want to copy an object, yes - you must create a New object and copy all the fields individually. If you're simply moving the object, make sure to remove the old pointer and you'll be fine.

; moving an object
p\league[0]\team[0]\player[0]=p\league[1]\team[12]\player[18]
p\league[1]\team[12]\player[18] = NULL



.rIKmAN.(Posted 2005) [#4]
Hey octothorpe, you`ve been most helpful mate.
As you say, I don`t really think I need the added complexity of linked lists, and it`d only add to the clutter of an already complex problem (bigger picture).

I like the idea of using "parent" fields so you can trace back given any player object - I hadn`t really thought about that before, and I`m not sure that situation will actually arise - but it`s good to have all bases covered.
I may implement the teamID idea, so if I am given any player (ie. player[1276]) I`ll be able to lookup the teamID associated to that player object, and instantly know what team he is at. Then same for team, they will have a leagueID, which will tell me which league they belong to, so traversing shouldn`t be a problem.

I actually did try the NULL thing (setting to null once I`ve copied it) but it calls an error when i was trying to output the values of [0,0,0] to screen, rather than printing nothing.
I got around it using this:
;remove orig data
Delete p\league[0]\team[0]\player[0]
p\league[0]\team[0]\player[0]=New player

Does this cause any problems I`m not aware of, memory etc?


Thanks for your advice, time and effort...much appreciated :)


octothorpe(Posted 2005) [#5]
You don't need IDs, you can simply store pointers.

p\league[0]\team[0]\player[0]\team = p\league[0]\team[0]


I actually did try the NULL thing (setting to null once I`ve copied it) but it calls an error when i was trying to output the values of [0,0,0] to screen, rather than printing nothing.


The problem is with your display code. Your display code should check if the player object it's given to display is NULL or not. If it's NULL, display nothing. Just like my FOR..NEXT loop example above checks for NULL for every object it loops over.

function display_player_by_indices(league_index, team_index, player_index)
	found_player = false
	this_league.league = p\league[league_index]
	if this_league <> NULL then
		this_team.team = this_league\team[team_index]
		if this_team <> NULL then
			this_player.player = this_team\player[player_index]
			if this_player <> NULL then
				found_player = true
				print this_player\name$
			endif
		endif
	endif
	if found_player = false then
		print ""
	endif
end function


;remove orig data
Delete p\league[0]\team[0]\player[0]
p\league[0]\team[0]\player[0]=New player
Does this cause any problems I`m not aware of, memory etc?


Yes, it'll blow away the data you're trying to copy because you're passing the pointer to the copied data to Delete. Check out the following example - there is only one object created (New foo), but three pointers (a, b, c) which all point to it. When Delete is called, the object is destroyed and the pointers will all point to nothing.

type foo
	field name$
end type

a.foo = new foo
a\name$ = "red"

b.foo = a
c.foo = a

print a\name$

b\name$ = "yellow"
print a\name$

b=null
print a\name$

delete c
print a\name$		; error!



octothorpe(Posted 2005) [#6]
I was thinking about it, and now think that representing unused array elements would be simpler using "blank" objects rather than NULLs.

To move a player from one team to another:

delete p\league[1]\team[12]\player[18]
p\league[1]\team[12]\player[18] = p\league[0]\team[0]\player[0]
p\league[0]\team[0]\player[0] = new player
; update parent pointers
p\league[0]\team[0]\player[0]\team = p\league[0]\team[0]
p\league[1]\team[12]\player[18]\team = p\league[1]\team[12]


or, alternately you could simply swap the pointers if you know there's already a blank object at the destination:

temp.player = p\league[1]\team[12]\player[18]
p\league[1]\team[12]\player[18] = p\league[0]\team[0]\player[0]
p\league[0]\team[0]\player[0] = temp
; update parent pointers
p\league[0]\team[0]\player[0]\team = p\league[0]\team[0]
p\league[1]\team[12]\player[18]\team = p\league[1]\team[12]


This last snippet will also trade two players between two teams.


.rIKmAN.(Posted 2005) [#7]
I`ll give this a whirl tomorrow (off to bed now) and let you know how things go.

Thanks again (again) :)

PS. Looking at the code again, is it OK to create NEW [0,0,0] without first deleting it?
I guess it will NEW all the associated fields for that object, leaving it blank, rather than creating junk in memory?

Also:
;--- update parent pointers
;p\league[0]\team[0]\player[0]\team = p\league[0]\team[0]

will not work as it gives a Type conversion error from trying to cast Team[0] into the "team" field of the player object - which won`t work.

Do I need to do anything special to get it to work?


octothorpe(Posted 2005) [#8]
Yes, you need to type the \team field as a pointer to a team object:

Type team
	Field player.player[10]
End Type

Type player
	Field team.team
End Type

t.team = New team
t\player[0] = New player
t\player[0]\team = t



octothorpe(Posted 2005) [#9]
PS. Looking at the code again, is it OK to create NEW [0,0,0] without first deleting it?
I guess it will NEW all the associated fields for that object, leaving it blank, rather than creating junk in memory?



No, New() doesn't affect existing objects, it creates new ones. You don't need to delete the object pointed to by [0,0,0] because you've copied the pointer elsewhere - that object will still be used.

I think you need to read up on pointers and objects. Make sure you understand exactly what's going on in the "type foo" example of pointer assignment I typed up for you above.