473,386 Members | 1,830 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

OO in C

I'm doing an adventure game.

Objects naturally lend themselves to C++, but I decided to implement the
thing in C.

The idea was that each object is identified by an id. These are stored in a
big array, indexed by id number.

To use an object, you convert the id to an OBJECT *.

typedef struct object
{
int id;
void * (*hasattribute)(struct object *obj, const char *name)
void *data;
} OBJECT;

Now the idea is that each object implements interfaces. So for instance a
sword would have the interfaces "ITEM" (it is a named item in the game),
"PORTABLE" (you can pick it up an carry it), and "WEAPON" (you can use it to
attack people with). You would set the hasattribute member to a function to
return these interfaces. So for instance "PORTABLE" has a member labelled
"weight", since all portable items weigh something.

One problem is that this rapidly gets ugly. For instance to get the weight
of a sword you would have to write

sword = getobject(swordid);
portable = sword->hasattribute(sword, "PORTABLE"):
if(portable)
sword->getweight(sword, portable);

Why is this necessary, since we are probably returning a single variable?
The answer is that a bag would weight the weight of a bag plus the weight of
any contents.

Another problem is that the attributes just represent interfaces, weapons,
containers, decorations, and so on. If I want a "dancing sword" then really
I want some type of inheritance to extend the "sword" code. However with the
current setup I don't have this. Instead I have to re-implement all of the
interfaces.

Has anyone any experience doing this sort of thing?
Nov 14 '05 #1
2 1345
In article <cj**********@news7.svr.pol.co.uk>,
Malcolm <ma*****@55bank.freeserve.co.uk> wrote:
I'm doing an adventure game.

Objects naturally lend themselves to C++, but I decided to implement the
thing in C.

The idea was that each object is identified by an id. These are stored in a
big array, indexed by id number.

To use an object, you convert the id to an OBJECT *.
Is there a good reason to not just store it as a pointer, rather than
as an index into a pointer table?

typedef struct object
{
int id;
void * (*hasattribute)(struct object *obj, const char *name)
I'm not sure why you're returning a pointer to void here. 'Tmight be
easier to do something like:

/*returns nonzero if we can get the value for this attribute*/
int (*has_attribute)(struct object *,const char *);
/*Returns the attribute value, appropriately encoded*/
MAGIC_COOKIE (*get_attribute)(struct object *,const char *);
void *data;
} OBJECT;
MAGIC_COOKIE can be anything that can represent all attribute values.
int might be a good choice if you're only doing numbers, pointer to static
string buffer ("extract the value of the appropriate type from this string
before getting another attribute") would be a good choice otherwise.

Now the idea is that each object implements interfaces. So for instance a
sword would have the interfaces "ITEM" (it is a named item in the game),
"PORTABLE" (you can pick it up an carry it), and "WEAPON" (you can use it to
attack people with). You would set the hasattribute member to a function to
return these interfaces. So for instance "PORTABLE" has a member labelled
"weight", since all portable items weigh something.

One problem is that this rapidly gets ugly. For instance to get the weight
of a sword you would have to write

sword = getobject(swordid);
portable = sword->hasattribute(sword, "PORTABLE"):
if(portable)
sword->getweight(sword, portable);

Why is this necessary, since we are probably returning a single variable?
The answer is that a bag would weight the weight of a bag plus the weight of
any contents.
'Tmight be easier to set things up so you can do:
--------
if(!(sword->has_interface(sword,"PORTABLE")))
/*Handle type error - we're trying to work with a nonportable sword?*/
if(!(sword->has_attribute(sword,"weight")))
/*Handle internal error - claims to be portable, but has no weight?*/
/*the above code is just internal consistency checking, these two lines
are all that's really needed
*/
my_cookie=sword->get_attribute(sword,"weight")
weight=unpack_weight_cookie(my_cookie);
--------

Then the sword's get_attribute function, if it's asked for weight, can
just do "return ((sword_data *)(obj->data))->weight" (optionally packing
it into an appropriate magic cookie first), and the bag's get_attribute
function can walk through the collection of stuff in the bag and return
the sum of the weights.

Another problem is that the attributes just represent interfaces, weapons,
containers, decorations, and so on. If I want a "dancing sword" then really
I want some type of inheritance to extend the "sword" code. However with the
current setup I don't have this. Instead I have to re-implement all of the
interfaces.
If you have a single pointer to get-named-attribute function, you can
write a new function that handles more attributes (optionally passing
existing attributes on to the existing function), add the appropriate
attributes to whatever your data pointer is pointing at, and just change
the get_attribute pointer you stuff into the struct when you create the
object. So your dancing sword object's {get|has}_attribute function can
check for the can_dance attribute, and if that's not the one the caller is
looking for pass the request on to the normal sword's attribute function.

If you really want to get clever, you can add attributes at runtime.
If the player learns how to control objects remotely, he can add a
remote_controllable attribute to his weapons.

Has anyone any experience doing this sort of thing?


See if you can find a Smalltalk implementor; this is beginning to look
not entirely unlike the Smalltalk dynamic dispatch system.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
[i]f such an implementation existed, probably this entire newsgroup's
readership would hunt down, torture and kill the thoughtless bastard
from which it originated. --Micah Cowan in comp.lang.c
Nov 14 '05 #2
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote:
I'm doing an adventure game.

Objects naturally lend themselves to C++, but I decided to implement the
thing in C.


Do yourself a favour and use a specialised language. All the problems
you describe have already been solved. I recommend Inform.

Richard
Nov 14 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: William C. White | last post by:
Does anyone know of a way to use PHP /w Authorize.net AIM without using cURL? Our website is hosted on a shared drive and the webhost company doesn't installed additional software (such as cURL)...
2
by: Albert Ahtenberg | last post by:
Hello, I don't know if it is only me but I was sure that header("Location:url") redirects the browser instantly to URL, or at least stops the execution of the code. But appearantely it continues...
3
by: James | last post by:
Hi, I have a form with 2 fields. 'A' 'B' The user completes one of the fields and the form is submitted. On the results page I want to run a query, but this will change subject to which...
0
by: Ollivier Robert | last post by:
Hello, I'm trying to link PHP with Oracle 9.2.0/OCI8 with gcc 3.2.3 on a Solaris9 system. The link succeeds but everytime I try to run php, I get a SEGV from inside the libcnltsh.so library. ...
1
by: Richard Galli | last post by:
I want viewers to compare state laws on a single subject. Imagine a three-column table with a drop-down box on the top. A viewer selects a state from the list, and that state's text fills the...
4
by: Albert Ahtenberg | last post by:
Hello, I have two questions. 1. When the user presses the back button and returns to a form he filled the form is reseted. How do I leave there the values he inserted? 2. When the...
1
by: inderjit S Gabrie | last post by:
Hi all Here is the scenerio ...is it possibly to do this... i am getting valid course dates output on to a web which i have designed ....all is okay so far , look at the following web url ...
2
by: Jack | last post by:
Hi All, What is the PHP equivilent of Oracle bind variables in a SQL statement, e.g. select x from y where z=:parameter Which in asp/jsp would be followed by some statements to bind a value...
3
by: Sandwick | last post by:
I am trying to change the size of a drawing so they are all 3x3. the script below is what i was trying to use to cut it in half ... I get errors. I can display the normal picture but not the...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.