How to access many different classes to randomly select one.
Author |
Message |
Timothy Willard
|
Posted: Fri Oct 18, 2013 8:50 pm Post subject: How to access many different classes to randomly select one. |
|
|
What is it you are trying to achieve?
I am creating a text based game where the loot in each room is randomly generated. Each item has its own class which are all descended from the parent class Item. I create an instance of each class, and then copy that instance into an index of the array existingItems, which is of type ^Item.
I want to add modifiers to the items (for example, have inside the Item class a variable called "Modifier" which I then make one of the modifiers I have in a list when I generate the item).
What is the problem you are having?
I noticed that when I set existingItems (1) := anIntanceOfClassBronzeShield, it did not just copy the data from the instance and create a new location for existingItems (1), it linked existingItems (1) to the same data that the instance is using. If I change the modifier variable in the instance, it gets changed in the array. This essentially makes all "bronze shields" have the same modifier.
Describe what you have tried to solve this problem
If I call new anInstanceOfClassBronzeShield after setting existingItems (1) to be the instance, they are no longer using the same memory. However, I still use the array to randomly select an item, and then if I set the item in the room to be existingItems (1) then call new existingItems (1) I end up having existingItems (1) be a new instance of Item, not BronzeShield.
Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
Turing: |
var existingItems : array 1 .. 16 of ^Item
new bronzeShield
existingItems (1) := bronzeShield
new bronzeShield
|
Please specify what version of Turing you are using
4.1 |
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Dreadnought
|
Posted: Fri Oct 18, 2013 10:26 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
Timothy Willard wrote:
I noticed that when I set existingItems (1) := anIntanceOfClassBronzeShield, it did not just copy the data from the instance and create a new location for existingItems (1), it linked existingItems (1) to the same data that the instance is using. If I change the modifier variable in the instance, it gets changed in the array. This essentially makes all "bronze shields" have the same modifier.
Yes, what you are using are pointers which "point" to the object in memory instead of being an instance of the object, hence if you set one pointer equal to another they point to the same address in memory.
What you want is a function\procedure that copies the actual contents of the object pointed to by the pointer to a new object.
Timothy Willard wrote:
If I call new anInstanceOfClassBronzeShield after setting existingItems (1) to be the instance, they are no longer using the same memory. However, I still use the array to randomly select an item, and then if I set the item in the room to be existingItems (1) then call new existingItems (1) I end up having existingItems (1) be a new instance of Item, not BronzeShield.
I'm not sure why you want to create a new item after choosing it but you can specify the type of object for which to allocate memory in the following way
Turing: |
class Parent
export message
var message : string := "I'm a parent"
end Parent
class Child
inherit Parent
message := "I'm a child"
end Child
var pointerOne, pointerTwo : ^Parent := nil
new pointerOne
new Child, pointerTwo
put "pointerOne says: \"", pointerOne->message, "\""
put "pointerTwo says: \"", pointerTwo->message, "\""
free pointerOne
free pointerTwo
|
Hopefully this helps! |
|
|
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Fri Oct 18, 2013 10:27 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
THat is why they are called pointers. They do not have their own value, they point to something which has that value. If you set al your classes to be equal to another class, you're making them all connected to the same value. Modify one, and you mosify all of them. Instead you need to set their values the same, rather than their pointer values |
|
|
|
|
![](images/spacer.gif) |
Timothy Willard
|
Posted: Fri Oct 18, 2013 11:00 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
Dreadnought @ Fri Oct 18, 2013 10:26 pm wrote:
I'm not sure why you want to create a new item after choosing it but you can specify the type of object for which to allocate memory in the following way
The reason why I want to create a new item is in case someone runs into another bronzeshield in an alternate room. I needed some way to keep the bronzeshield in one room (which points to same data existingItems (1) does) from the bronzeshield in another room. As such, I couldn't just create another pointer in the second room, because then the two bronzeshields would always be the same, as opposed to one being "Heroic" while the other is "Lame." |
|
|
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Fri Oct 18, 2013 11:07 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
Is BronzeShield your actual class? You havea class specifically for a bronze shield? |
|
|
|
|
![](images/spacer.gif) |
Timothy Willard
|
Posted: Sat Oct 19, 2013 12:48 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
Yes, BronzeShield is my class, and originally I had just had a bunch of instances of Item that had different stats and names. However, I wanted to add an "ability" procedure to some items (potion that heals you, magical shields that have a chance of deflecting attacks, etc.) True, I could just change BronzeShield to be an instance of Item with the information filled in, it still doesn't solve the problem of the items with abilities. |
|
|
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Sat Oct 19, 2013 1:05 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
Ok, do NOT go down that path. If you're going to create a separate class for every single item type, there's no point in wasting your time using classes.
Look into inheritance on the Turing Walkthrough. This is what you're looking for. |
|
|
|
|
![](images/spacer.gif) |
Timothy Willard
|
Posted: Sat Oct 19, 2013 1:27 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
I did look at the walkthrough, and that is essentially what I am doing. All of my items inherit from the parent class "Item". Inside Item are variables for name, description, itemtype, minAttribute (attack for weapons, defense for armour, etc.), and maxAttribute. I also have a deferred procedure called "Ability" that just outputs "This item can't do anything." However, in the different items that inherit Item, I sometimes change Ability to actually do something.
The only problem that I can see is that I may not be correct in making classes for the 'regular' items without abilities, in which case I can just change them to be instances of Item. I still need classes for all items with abilities, and if I happen to have a 'magical sword' that has an ability, but I also want to change its values during runtime (i.e. give it a debuff or something), I don't know how to get multiple 'magical sword' instances. |
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Sat Oct 19, 2013 2:15 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
Turing: |
class Item
var hasAbility : boolean
proc attack ()
if hasability then
doAbility()
end if
end attack
end Item
|
If you want to do something like that, then even this would be a better way to go about it. Much less code repetition, and every class will still be connected. The way you're doing it, you wouldn't be able to pass your classes as parameters or anything |
|
|
|
|
![](images/spacer.gif) |
Timothy Willard
|
Posted: Sat Oct 19, 2013 3:12 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
The problem is that I want many abilities (poison, heal, etc.). This means that each ability would have to have its own function, and then when I use an item's ability I would have to run all of the procedures to check each boolean. I still think it would be better to make all "standard" items as instances of class Item, but have the items with abilities get their own class.
Again, it runs into the problem of how to randomly generate as many instances as is required without having them just be pointers to the same data. |
|
|
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Sat Oct 19, 2013 3:49 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
You could use this cool little trick. It might not be the best way to do it, but probably simpler thn what you are doing. You use procedures as variables and parameters, which you can do in many languages. Fairly useful; Run it and see what happens:
Turing: |
class Character
export var all
var health, speed : int
var name : string
proc create (health_, speed_ : int, name_ : string)
health := health_
speed := speed_
name := name_
end create
end Character
class Item
import Character
export var all
var effect : proc effectType (x : int, var reciever : ^Character)
var damage, effectValue : int
var name : string
proc create (damage_, effectValue_ : int, effect_ : proc effectType (x : int, var reciever : ^Character), name_ : string)
damage := damage_
effectValue := effectValue_
effect := effect_
name := name_
end create
proc hit (var sender, reciever : ^Character)
reciever -> health -= damage
put reciever -> name, " took ", damage, " damage from ", sender -> name, "'s ", name
if effectValue not= 0 then
effect (effectValue, reciever)
end if
put reciever -> name, " has ", reciever -> health, " health left."
end hit
end Item
type characterData :
record
character : ^Character
wep : ^Item
end record
%%%%%%%%%%%%%%%%%%%%%%%%%%%% LIST OF EFFECTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%
proc fire (damage : int, var reciever : ^Character)
reciever -> health -= damage
put reciever -> name, " also recieved ", damage, " fire damage."
end fire
proc slow (reduction : int, var reciever : ^Character)
reciever -> speed -= reduction
put reciever -> name, "'s speed was reduced by ", reduction, "."
end slow
proc normal (x : int, var reciever : ^Character)
%Does nothing
end normal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
var player, enemy : characterData
new player.character
new player.wep
new enemy.character
new enemy.wep
player.character -> create (10, 3, "George")
player.wep -> create (2, 1, fire, "Flaming Sword")
enemy.character -> create (7, 3, "Evil George")
enemy.wep -> create (1, 0, fire, "Rusty Axe")
player.wep -> hit (player.character, enemy.character)
put ""
enemy.wep -> hit (enemy.character, player.character)
|
|
|
|
|
|
![](images/spacer.gif) |
Timothy Willard
|
Posted: Sat Oct 19, 2013 4:06 pm Post subject: Re: How to access many different classes to randomly select one. |
|
|
Yes! This is exactly what I was looking for (I never knew you define a variable as a procedure, this makes things so much simpler). Thank you, this will work nicely. |
|
|
|
|
![](images/spacer.gif) |
Raknarg
![](http://compsci.ca/v3/uploads/user_avatars/3745510004d8be6689b92f.jpg)
|
Posted: Sat Oct 19, 2013 5:41 pm Post subject: RE:How to access many different classes to randomly select one. |
|
|
Yeah. I'll give the basics of it. You can do a procedure or a function.
var doSomething : proc x
You the name of the variable matters, but the name of the procedure doesn't. You can assign a procedure to it now. However, the procedure assigned cannot have any parameter.
var doSomething : proc x (y : int, s : string)
Now you can only assign procedures whose parameters are respectively an integer and a string.
var doSomething : fcn x (y : int) : string
Now you can only assign a function to it that takes in an integer and results a string.
SOmething I found useful:
Turing: |
var enemyDraw : array 1 .. 5 of proc x
proc e1
drawEnemy1 ()
end e1
proc e2
drawEnemy2 ()
end e2
proc e3
drawEnemy3 ()
end e3
proc e4
drawEnemy4 ()
end e4
proc e5
drawEnemy5 ()
end e5
enemyDraw (1) := e1
enemyDraw (2) := e2
enemyDraw (3) := e3
enemyDraw (4) := e4
enemyDraw (5) := e5
|
Think about this one |
|
|
|
|
![](images/spacer.gif) |
|
|