Type in a type
Blitz3D Forums/Blitz3D Beginners Area/Type in a type
| ||
Heh. I've got more silly type problems. I can't figure out the syntax for creating a type within a type. I'm trying something like this:- Type badger field var End Type Type sheep field var2 End Type s\sheep = new sheep s\var2.badger = new badger Basically I want multiple badgers inside a sheep. Can someone please assist? :) |
| ||
Type sheep field var2.badger End Type |
| ||
> field var2.badger AAAAAAAAAARRGGGGGGGGH!!!!!!! It's always so obvious when someone shows you. Thanks very much GitTech. That's a great help :) |
| ||
EEK! Ok, I've got even more Or perhaps I'm totally misusing the reason for types. Well ok. I'm got my badgers inside my sheep. Trouble is when I create two sheeps any new badgers that I create appear in both sheep instances. Infact no matter where I create badgers in my entire program, they all appear in I'm basically trying to do something like this |- badger1 | sheep1 --- badger2 | |- badger3 |- badger4 | sheep2 --- badger5 | |- badge6 At the moment it's like this:- |- badger1 | sheep1-| badger2 | |- badger3 | |- badger4 | sheep2-|- badger5 | |- badge6 Also I can't create any badgers at all inside functions, only globally otherwise it tells me off for using my type incorrectly. So I can't do b\sheep.badger = new badger What in the hell is going wrong? I am so thick! HELP ME!! :) |
| ||
Type badger Field var Field sheepFlag End Type Type sheep Field var2.badger End Type global sheep1.sheep = New sheep sheep1\var2.badger = New badger sheep1\var2\sheepFlag=1 sheep1\var2.badger = New badger sheep1\var2\sheepFlag=1 sheep1\var2.badger = New badger sheep1\var2\sheepFlag=1 global sheep2.sheep = New sheep sheep2\var2.badger = New badger sheep2\var2\sheepFlag=2 sheep2\var2.badger = New badger sheep2\var2\sheepFlag=2 sheep2\var2.badger = New badger sheep2\var2\sheepFlag=2 For b.badger=Each badger If b\sheepFlag=1 Then ;do something EndIf Next For b.badger=Each badger If b\sheepFlag=2 Then ;do something EndIf Next |
| ||
Hi again GitTech. Just looking at your code, I'm guessing that it's impossible to prevent merging types within types? Just like C++ objects |
| ||
No, afaik, every type is ONE big list. So, with your types, you have two lists: a "sheep" list, and a "badger" list. |
| ||
You can do exactly what you are trying to do. Heres an example now. I have made a flock of 3 sheep (an array) and each sheep contains exactly 3 distinct badgersDim flock.sheep(3) Type sheep Field b1.badger Field b2.badger Field b3.badger End Type Type badger Field name$ End Type Function makeBadger.badger() Local name$ Read name$ b.badger=New badger b\name=name Return b End Function Function makeSheep.sheep() s.sheep=New sheep s\b1=makeBadger() s\b2=makeBadger() s\b3=makeBadger() Return s End Function Function initFlock() Restore names For f=1 To 3 flock(f)=makeSheep() Next End Function Function describeFlock() For f= 1 To 3 out$="Sheep"+f+" ("+flock(f)\b1\name+","+flock(f)\b2\name+","+flock(f)\b3\name+")" Print out$ Next End Function initFlock() describeFlock() WaitKey .names Data "Ralph","Oswald","Brian","Gertrude","Emily","Frank","William","Sharon","Barry" hope this helps :) |
| ||
You cant do sheep\b1.badger = new badger because if your sheep is Type sheep Field b1 field b2 Field b3 End type you have already declared b1 to be an int if however the fields were Field b1.badger you still cant do that because you have already declared the field type to be a badger and therefore dont need to *edit* oh apparently you can becuase gitTechs code does exactly that, however you dont need to */edit* the correct syntax in this instance would be sheep\badger = new badger (because the compiler already knows that sheep contain badgers) Types can quite happily be created inside functions as I have already demonstrated and you dont need to rely on the internal lists of types provided by blitz my code above is quite elaborate but its like that to show you that you can reduce the main program to just a few function calls. Yes, I am breaking my own rules on "good form here" (posted in another thread) but umm who in the world strictly practices what they preach :D |
| ||
Final Word Basically I want multiple badgers inside a sheep. Can someone please assist? :) You're very strange. Good work. |
| ||
Thanks LukeSkywalker, That's a great help. I have discovered that I could have an array of badgers inside each sheep, which is kind of what I'm trying to get away from. I don't want to have any arrays at all if I can help it. But I will look at your code and I shall be having a right old fiddle with it this morning. > You're very strange. Thanks :) > Bannana Banana! ;) |
| ||
Try this:Type badger Field var Field nextBadger.badger End Type Type sheep Field firstBadger.badger Field lastBadger.badger End Type Function AddBadger.badger(sheep.sheep) badger.badger=New badger If sheep\firstBadger=Null Then sheep\firstBadger=badger Else sheep\lastBadger\nextBadger=badger EndIf sheep\lastBadger=badger Return badger End Function sheep1.sheep=New sheep newbadger.badger=AddBadger(sheep1) newbadger.badger=AddBadger(sheep1) newbadger.badger=AddBadger(sheep1) sheep2.sheep=New sheep newbadger.badger=AddBadger(sheep2) newbadger.badger=AddBadger(sheep2) newbadger.badger=AddBadger(sheep2) currentBadger.badger=sheep1\firstBadger While currentBadger<>Null ;do something currentBadger=currentBadger\nextBadger Wend currentBadger.badger=sheep2\firstBadger While currentBadger<>Null ;do something currentBadger=currentBadger\nextBadger Wend |
| ||
Enay Please do because Im not using an array within a type :) I simply used an array to make a "flock" of sheep However look at gittechs code.. you could mod that to have a linked list of sheep each containing 3 badgers although, GitTech, you dont need to keep doig newbadger.badger= after declaring newbadger as a type badger also why return the badger when you pass in a sheep to store the reference anway and then never use the return value ("because you can" is an acceptable answer, its possible you may which to simultaneously store and return a reference to the last badger created) |
| ||
Because you can :P |
| ||
Dont be afraid of arrays tho enay, arrays can be your friend even if they do have to be global and fixed size. But no not a lot of use for storing an arbitraty number of objects at runtime. For that a linked list is far more useful. Hope Marc isnt offended by this but I have some old LL code too with loads of convenience functions added. it was written for someone trying to create a card game but Im sure you will see how it can be adapted ( change deck to sheep and your halfway there) Type element Field value Field linkedelement.element ;add in any other data you feel is necessary End Type Type list Field Total Field start.element Field finish.element End Type Function prependList(elmnt.element, lst.list) elmnt\linkedelement=lst\start lst\start=elmnt If lst\Total=0 Then lst\finish=elmnt lst\Total=lst\Total+1 End Function Function appendList(elmnt.element,lst.list) If lst\Total=0 lst\start=elmnt Else lst\finish\linkedElement=elmnt End If lst\finish=elmnt lst\Total=lst\Total+1 End Function Function insertElement( elmnt.element,lst.list,index) Local current.element=lst\start ;if we are adding the element at position 1 then we need to change the ;list's starting element If index<=1 Then prependList(elmnt,lst) Else If index>lst\Total appendList(elmnt,lst) Else ;iterate through the list untill we reach ;the position _before_ we want to insert the element For f=2 To index-1 current=current\linkedelement Next ;insert the element into the list elmnt\linkedelement=current\linkedelement current\linkedelement=elmnt lst\Total=lst\Total+1 End If End Function Function removeElementFromList.element(lst.list,index) Local current.element=lst\start Local previous.element count=1 While count < index previous=current current=current\linkedelement count=count+1 Wend ;special case if the element is the starting element of the deck If current=lst\start Then ;set the start element of the list to the element lst\start=current\linkedelement lst\Total=lst\Total-1 Else ;make the previous element in the list link to the element which the current element links to previous\linkedelement=current\linkedelement ;break the chain on the current element to stop cross linking, this is now an orphaned element current\linkedelement=Null lst\Total=lst\Total-1 End If ;return the element we have just removed Return current End Function Function shuffleList(lst1.list) ;create a temporarly linked list to use as a holder Local lst2.list=New list ;take a random element from lst1 and and put it at the start of lst2 ;keep doing this untill lst1 is empty While lst1\Total >0 insertElement(removeelementFromList(lst1,Rand(1,lst1\Total)),lst2,1) Wend ;now do it again but the other way around While lst2\Total >0 insertElement(removeelementFromList(lst2,Rand(1,lst2\Total)),lst1,1) Wend ;lst 1 is now shuffled End Function ;this is just a convenient way of viewing the whole list and its contents ;best only use it with short lists as long ones will be wider than the screen Function showlist$(lst.list) ret$="("+lst\Total+" elements) Values {" elmnt.element=lst\start ret=ret+elmnt\value While elmnt\linkedelement<>Null elmnt=elmnt\linkedelement ret=ret+","+elmnt\value Wend ret=ret+"}" Return ret End Function ;**************** TEST CODE **************************************** Graphics 800,600,32,2 deck.list=New list Print "Creating 10 elements and adding them to the list" Print For f=1 To 20 c.element=New element c\value=f insertElement(c,deck,-100) Next Print "List is now: "+ showlist(deck) Print Print "Removing element with index 3" Print removed.element=removeelementFromlist(deck,3) Print "Removed element's value is: "+ removed\value Print Print "List is now: "+showlist(deck) Print Print "Adding the removed element back in at index 7" Print insertElement(removed,deck,7) Print "List is now: "+showlist(deck) Print Print "Shuffling list" Print shuffleList(deck) Print "List is now: "+showlist(deck) WaitKey ;********************************************************************* |
| ||
A bit ot .. but check this out ... www.badgerbadgerbadger.com |
| ||
Hope Marc isnt offended by this but I have some old LL code too with loads of convenience functions added. No problemo Luke :) |
| ||
Thanks for all the help guys. I think I'm starting to get my head around this stuff. > Dont be afraid of arrays tho enay, arrays can be your > friend even if they do have to be global and fixed size. That's the thing, I'm the array master. I love them. My last 5 blitz games have all been created using arrays. But I felt like having a go with types for a change since I've recently mastered the art of OOP in C++ and I kind of want to design my code better. Unfortunately I've now get myself stuck a bit, well not stuck. But I feel I'm doing things wrong. So onto my next quick questions :) Can I loop backwards like for loop = 2000 to 1 step -1 I've seen all this Insert Before and After commands but I can't figure out how to start at the back of a list. In my code I want to start at the last entry. Like a LIFO badger. But at the moment I have to do this:- moo=0 For b.badger Each badger moo=moo+1 Next spamflan = 0 For b.badger Each badger if moo=spamflan then endif Next Like:- For Last b.badger To First b.badger Next Also I want to do the same but start in the middle. With a normal for loop and an array I'd just do this:- for loop=low_num to high_num badgers(loop) next Or something. for loop =high_num to low_num step -1 badgers(loop) next Basically, I want to access a group of badgers inside a sheep with a pointer and then scan consecutive badgers in either direction, just like I've shown above with my array of badgers. Anyway, thanks in advance for trying to help (again) :) I appreciate it. |
| ||
To access your badgers in reverse order (LIFO), you can:this.badger = Last badger while this<>Null ;do stuff to badger! this = Before this wend To access badgers 'somewhere' in the middle of the list, you need the handle of the badger you want to start with, and the use Before and After to access the ones connected to it. |
| ||
Dont forget tho that while you are using the internal collections of Badger you are accessing ALL the badgers in the order they were created (first to last ) regardless of which sheep contains references to them. To see which sheep contains which badgers you must ask the sheep. eg print sheep\badger1\name fetches the variable value of the field "name" in the type badger (assuming you gave it one in the first place) |