RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
I am Har har har
Slightly Deformed Faerie Princess


Joined: 08 Jan 2004
Posts: 33
Location: America.

PostPosted: Tue Mar 23, 2004 1:58 pm    Post subject: Question: String accessing variables [quote]

I have a problem. I want to be able to modify game variables with my scripting engine. The problem is that I have to reference the variable by its name from a string variable. An example would be something like this:

Avariable% = 5
RefString$ = "Avariable%"
RefString$ = RefString$ + 1

Now, I know that this code won't work, but I want to make a way to access a variable through its identifier. Anyone that knows anything about this that could help would be greatly appreciated.
-ImHhh
_________________
I do what I like. Do you have a problem with that?
Back to top  
white_door
Icemonkey


Joined: 30 May 2002
Posts: 243
Location: New Zealand

PostPosted: Tue Mar 23, 2004 8:43 pm    Post subject: [quote]

You will not be able to do it the way you are thinking, referencing a variable by a string name is not possible in most languages.. However you have several options about other ways of doing it, here are a few:

1. have a massive if then construction, checking if the string is equal to the name of a variable then setting it.

2. Use a big array for all your variables then access it with numbers from the scripting engine. "1%=4" in the script might references script_vars%(1)=4 or however you do it in basic

3. You could have a array of strings and use a loop to compare the name of a variable in a script to each in the array.. then access a second array with the same element.

4. Similar to the idea from 3 but faster, you could hash the variable name (convert the name into a number using math) and use number to reference a variable in a big array
Back to top  
valderman
Mage


Joined: 29 Aug 2002
Posts: 334
Location: Gothenburg, Sweden

PostPosted: Tue Mar 23, 2004 8:53 pm    Post subject: [quote]

I made a tree for the purpose. Basically, you use the first char as an index into an array, then the second, etc. until you reach \0.

It eats a lot of memory, and my implementation isn't the best (supporting ASCII chars 0 through 256, using recursion, etc.), but I believe it would be the fastest way, at least if you have a lot of variables.
_________________
http://www.weeaboo.se
Back to top  
LeoDraco
Demon Hunter


Joined: 24 Jun 2003
Posts: 584
Location: Riverside, South Cali

PostPosted: Tue Mar 23, 2004 10:14 pm    Post subject: [quote]

In a good language, this is what a symbol table is used for. A symbol table can be anything, really, from a simple list or stack, to something semi-complex, like a map. What you would want to do is associate an offset in memory, in which you store whatever value you're playing with in your scripting language, with the identifier you are using in your scripting language.

In C++, you could use something simple, like an STL map (a heap or a hash-table would also work; maps are often stored internally via either of these constructs) to store your symbol table. The key for the map would simply be strings (which would match your identifier), and the associated value would be the value you wanted to store in you scripting language. Course, there are some problems that come into play: if you want different levels of scope, you'll more than likely have to rename variables by some scheme, so that you do not loose anything. Also, if you want to store all forms of variables in your engine in one convenient map, then you would have to store values as a super-class and such. But, these are all minor problems.

And alternative method would be to have an Identifier class, which stores inside of it a string, representing its textual reference, and its value; you could then store these in a list or a stack, and easily access them that way. A lot of this is simple applications of compiler concepts.

Course, all of this is, relatively speaking, moot, as you are, apparently, using a BASIC flavor. So, you have options: stop using BASIC, and pick up a real language; create an object pattern in BASIC that can be used to create the objects mentioned above (which would be a headache, as you would have to fake memory addressing to do anything useful); or create a few simple structures that can fake the above concepts.

Now, my BASIC syntax is a bit rusty, as I haven't touched the language in several years, but what I would do is create a Record structure, which stored three pieces of data: the string name of variable you wish to create in your scripting language, a bit flag that represents what type of variable you are creating, and a LUT offset variable, that would keep track of which offset in a global array this record is referencing. You could then have a global array for each of the types you wished to support, as well as a Record array, which would store a reference to each variable you create in your scripting engine. This isn't terribly efficient, but it would work, and is a rather nice abstraction.

I had a professor whom was fond of quoting, "There is no problem in systems design that cannot be solved by adding another layer of abstraction." So yeah: put a few layers of abstraction on that, and you should be okay.
_________________
"...LeoDraco is a pompus git..." -- Mandrake
Back to top  
janus
Mage


Joined: 29 Jun 2002
Posts: 464
Location: Issaquah, WA

PostPosted: Tue Mar 23, 2004 11:17 pm    Post subject: [quote]

If you use VB, you can just use CallByName to access methods and properties in your classes. But I assume that you're using QB, so no luck there.
Back to top  
I am Har har har
Slightly Deformed Faerie Princess


Joined: 08 Jan 2004
Posts: 33
Location: America.

PostPosted: Wed Mar 24, 2004 9:17 pm    Post subject: [quote]

1. Yes, I am using QB.
2. Thanks for your advice. Soon after I posted this, however, I found a way that might work. Using Varseg and Varptr, I can find the location of the variable in memory. Then, I output the variable names and their locations to a file. Then, I set up a sub like this:

SUB MODVAR(SEG%, OFFS%, VAL1%, VAL2%)

INPUT #FILE%, SEG%, OFFS%, VAL%
DEF SEG = SEG%
POKE OFFS%, VAL1%
POKE OFFS% + 1, VAL2%

END SUB

Or, If I wanted to add or subtract:

ADDITION:
POKE OFFS%, PEEK(OFFS%) + VAL1% 'VAL1 >= 1
SUBTRACTION:
POKE OFFS%, PEEK(OFFS%) + VAL1% 'VAL1 <= -1

Please tell me if this code will not work, but from all of the tests I've run, the program stores the variable in the same segment/offset every time it runs.
Thank you for your time
_________________
I do what I like. Do you have a problem with that?
Back to top  
LeoDraco
Demon Hunter


Joined: 24 Jun 2003
Posts: 584
Location: Riverside, South Cali

PostPosted: Wed Mar 24, 2004 11:18 pm    Post subject: [quote]

Again, my QB syntax/semantics/logic is a bit fuzzy, as I haven't used it in a long time. (Let that stand as a standard disclaimer.) It's never a good idea to assume a location in memory, for anything really, as it might be something the interpreter is doing that is specific to your box. Place an executable on somebody elses, and you don't know what will happen.

That said, this would more than likely work, as you are hopefully dumping the memory locations at runtime into a file. I say hopefully because in this way, you are technically not assuming locations.

Here's a different idea: since your modvar sub accepts parameters anyway, why not send it directly the segment and offset of the variable? That way, you're avoiding the necessity of having to preform a write and read from a file, which can be a slow process. And, you wouldn't have to be assuming locations for variables (if you are). It would be something to mess around with.
_________________
"...LeoDraco is a pompus git..." -- Mandrake
Back to top  
DrunkenCoder
Demon Hunter


Joined: 29 May 2002
Posts: 559

PostPosted: Thu Mar 25, 2004 5:08 pm    Post subject: [quote]

why not go the compiler route and build a proper symboltable?

If you use hashing or some other sane technique performance shouldn't be too bad, maybe some sort of tree would suite
you better since youre using QB I haven't used the langauge
myself.

Oh, and about CallByName... that can quite easily be simulated in C/C++ on windows as long as you know what properties and functions you want to expose.
_________________
If there's life after death there is no death, if there's no death we never live. | ENTP
Back to top  
MadQB
I wanna be a ballerina!


Joined: 31 May 2002
Posts: 24

PostPosted: Fri Mar 26, 2004 2:22 pm    Post subject: [quote]

First, I use a system similar to white_door's #2, it goes like this:

'******In the script file********
FLAG 001,04



IF 001,04,27
'****
that sets flag # 001 to a value of 04 then later on i check to see if flag # 001 has a value of 04, if it does, GOTO line label 27 in the script.

this is what my code looks like:
'*******QB Program (script parser)******
ScriptFlags(001)=04



IF ScriptFlags(001)=04 THEN &&&&&&

'***************************
Substitute &&&&&& with code for finding a line label in the script. This works good, but after you get 10 or fifteen number defined variables things get confusing.

So to answer your question, take a look at the following snippets:

'**********Script suggestion***********
MAKEVAR PlayerX INT
MAKEVAR PlayerName STRING

PlayerX=5
PlayerName=John Doe
'**********

That would tell the parser to make an integer variable called 'PlayerX' and a string variable and call it 'PlayerName'. Then Set PlayerX to 5 and PlayerName to 'John Doe'.

'********QB Code************
TYPE ScriptINTS
IntName as STRING * 12
IntValue as INTEGER
END TYPE

TYPE ScriptSTRINGS
StrName as STRING * 12
StrValue as STRING * 30
END TYPE

DIM SHARED ScriptIntVars(100) as ScriptINTS
DIM SHARED ScriptStrVars(100) as ScriptSTRINGS

'Parser Code

'Add a variable

'IntName$="nameofintvar"
'IntVal%=Value
'StrName$="nameofstrvar"
'StrVal$=string

IF ScriptIntVars(I).IntName="" THEN
ScriptIntVars(I).IntName=IntName$
ScriptIntVars(I).IntValue=IntVal%
END IF

IF ScriptStrVars(I).IntName="" THEN
ScriptStrVars(I).StrName=StrName$
ScriptStrVars(I).StrValue=StrVal%
END IF

'**********************
Then to check or change a value you just check the name of ScriptStrVars(I).StrName or ScriptIntVars(I).IntName and see if it is consistent with your variable's name, if so change the value, if not go to I+1 and do it again. Hope that helps!

EDIT: Now of course the above code would only allow 100 ints and 100 strings, so if you needed more you would have to change the DIM ScriptStrVars(100) to 150 or 200 or whatever you wanted. I would think that if you had too many you would want to store them in extended memory to save stack space, but maybe there is enough room.
_________________
yep...
Back to top  
valderman
Mage


Joined: 29 Aug 2002
Posts: 334
Location: Gothenburg, Sweden

PostPosted: Fri Mar 26, 2004 3:18 pm    Post subject: [quote]

I think it'd be mighty slow if you had to compare 100 strings everytime you wanted to use the last variable.
_________________
http://www.weeaboo.se
Back to top  
MadQB
I wanna be a ballerina!


Joined: 31 May 2002
Posts: 24

PostPosted: Fri Mar 26, 2004 6:57 pm    Post subject: [quote]

Quote:
I think it'd be mighty slow if you had to compare 100 strings everytime you wanted to use the last variable.


Actually in QB it's not that slow since the compiler does all the comparing for you. And it was just a suggestion anyway, in the user defined typedef, it could store a memory address instead of using a string. That would be quicker and he could just POKE any new values into memory, and PEEK it every time he needed the current value.
_________________
yep...
Back to top  
LeoDraco
Demon Hunter


Joined: 24 Jun 2003
Posts: 584
Location: Riverside, South Cali

PostPosted: Sat Mar 27, 2004 12:00 am    Post subject: [quote]

Valderman wrote:
I think it'd be mighty slow if you had to compare 100 strings everytime you wanted to use the last variable.


This is where having a stack of activation records lying around would be handy. Rather than having to, more often than not, fruitlessly search several different arrays for the appropriate storage container, you'd just have to search the activation record array.
_________________
"...LeoDraco is a pompus git..." -- Mandrake
Back to top  
therabidwombat
Sick of Being A Fairy Princess Yet?


Joined: 08 Mar 2004
Posts: 14
Location: Canada

PostPosted: Tue Mar 30, 2004 2:26 pm    Post subject: [quote]

If you were using GameMaker, then there's actually a function to refer to a variable by a string the same as the variables name. I can't remember exactly what it's called. If it can be done in GameMaker, I'm sure you can do it.
_________________
How much crap would a wombat bat if a wombat could bat crap?

---------
Head Programmer on Worlds Beyond; Possibly entire EAA saga
Progress: ~40% done engine
Back to top  
js71
Wandering DJ


Joined: 22 Nov 2002
Posts: 815

PostPosted: Tue Mar 30, 2004 6:14 pm    Post subject: [quote]

Well, Game Maker code is pretty much stripped down C++. Emphasizing the 'stripped down' here... True, there's a function to do that in Game Maker, but plain C++ doesn't have a lot of the premade things game maker does-- You have to do a lot yourself.
Back to top  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum