Welcome, Guest. Please Login or Register.  • Help
SMF Underground
+ SHMUP-DEV » SHMUP DEV FORUMS » Assistance
|-+ A Code Generator

Pages: [1]   Go Down
0 Members and 1 Guest are viewing this topic. Topic Tools  
Read January 02, 2006, 01:22:49 AM #0
solidcube

A Code Generator

Something I thought of last week when faced with programming yet another class, was the fact that so much of the code we write is the same for different games and different parts of the same game.  Polymorphism eases this to a great extent but you still have to write base classes from scratch.

So instead of programming the class, I wrote a Python script to program the class for me.

What this program does is it takes a file from standard input like so:
classname
intvariable1 intvariable2 intvariable3
floatvar1 floatvar2 floatvar3...
funcname1 funcname2 funcname3

and it spits out a class with boilerplate functions designed to handle all the variables, as well as function prototypes and skeletons for the functions you specify.

Here is an example template:
Code:
jtObject
energy type damage number owner angle tilex tiley
x y z vx vy vz va
draw thrust fire left right die
and here is the code it produces:
Code:
/***************************************************
* jtObject.cpp
* Generated with
* Classgen.py by SolidCube
***************************************************/
class jtObject{
private:
    // ints
    int energy;
    int type;
    int damage;
    int number;
    int owner;
    int angle;
    int tilex;
    int tiley;
    // floats
    float x;
    float y;
    float z;
    float vx;
    float vy;
    float vz;
    float va;
public:

    //initialize
    void init();
    //setters
    void setenergy(int myenergy);
    void settype(int mytype);
    void setdamage(int mydamage);
    void setnumber(int mynumber);
    void setowner(int myowner);
    void setangle(int myangle);
    void settilex(int mytilex);
    void settiley(int mytiley);
    void setx(float myx);
    void sety(float myy);
    void setz(float myz);
    void setvx(float myvx);
    void setvy(float myvy);
    void setvz(float myvz);
    void setva(float myva);

    //getters
    int getenergy();
    int gettype();
    int getdamage();
    int getnumber();
    int getowner();
    int getangle();
    int gettilex();
    int gettiley();
    float getx();
    float gety();
    float getz();
    float getvx();
    float getvy();
    float getvz();
    float getva();

    void draw();
    void thrust();
    void fire();
    void left();
    void right();
    void die();
};
void jtObject::init()
{
    int energy = 0;
    int type = 0;
    int damage = 0;
    int number = 0;
    int owner = 0;
    int angle = 0;
    int tilex = 0;
    int tiley = 0;
    float x = 0;
    float y = 0;
    float z = 0;
    float vx = 0;
    float vy = 0;
    float vz = 0;
    float va = 0;
};
int jtObject::getenergy()
{
    return (energy);
}
int jtObject::gettype()
{
    return (type);
}
int jtObject::getdamage()
{
    return (damage);
}
int jtObject::getnumber()
{
    return (number);
}
int jtObject::getowner()
{
    return (owner);
}
int jtObject::getangle()
{
    return (angle);
}
int jtObject::gettilex()
{
    return (tilex);
}
int jtObject::gettiley()
{
    return (tiley);
}
float jtObject::getx()
{
    return (x);
}
float jtObject::gety()
{
    return (y);
}
float jtObject::getz()
{
    return (z);
}
float jtObject::getvx()
{
    return (vx);
}
float jtObject::getvy()
{
    return (vy);
}
float jtObject::getvz()
{
    return (vz);
}
float jtObject::getva()
{
    return (va);
}
void jtObject::setenergy(int myenergy)
{
    energy=myenergy;
}
void jtObject::settype(int mytype)
{
    type=mytype;
}
void jtObject::setdamage(int mydamage)
{
    damage=mydamage;
}
void jtObject::setnumber(int mynumber)
{
    number=mynumber;
}
void jtObject::setowner(int myowner)
{
    owner=myowner;
}
void jtObject::setangle(int myangle)
{
    angle=myangle;
}
void jtObject::settilex(int mytilex)
{
    tilex=mytilex;
}
void jtObject::settiley(int mytiley)
{
    tiley=mytiley;
}
void jtObject::setx(float myx)
{
    x=myx;
}
void jtObject::sety(float myy)
{
    y=myy;
}
void jtObject::setz(float myz)
{
    z=myz;
}
void jtObject::setvx(float myvx)
{
    vx=myvx;
}
void jtObject::setvy(float myvy)
{
    vy=myvy;
}
void jtObject::setvz(float myvz)
{
    vz=myvz;
}
void jtObject::setva(float myva)
{
    va=myva;
}
void jtObject::draw()
{
}
void jtObject::thrust()
{
}
void jtObject::fire()
{
}
void jtObject::left()
{
}
void jtObject::right()
{
}
void jtObject::die()
{
}

Here is the Python code:
Code:
#!/usr/bin/python
#classgen.cpp
#takes  4 line file from stdin that looks like this:

#classname
#intname intname intname...
#floatx y z vx vy vz
#func fnc fnc

#// load template
#// from line starting with class, get classname
#// when line starts with ints, get list of intnames
#// when line starts with floats, get list of floatnames
#// when line starts with functions, get list of funcnames
#*/
import string
classname=raw_input()
ints = raw_input()
floats = raw_input()
funcs = raw_input()
intlist = ints.split(' ')
floatlist = floats.split(' ')
funclist = funcs.split(' ')
print "/***************************************************"
print "* " + classname +".cpp"
print "* Generated with "
print "* Classgen.py by SolidCube"
print "***************************************************/"
print "class " + classname + "{"
print "private:"
print "// ints"
for i in range(len(intlist)):
print " int " + intlist[i] +";"
print "// floats"
for i in range(len(floatlist)):
print " float " + floatlist[i]+";"

print "public:"
print "\n//initialize"
print " void init();"
print "//setters"
for i in range(len(intlist)):
print " void set" +intlist[i] + "(int my" + intlist[i]+");"
for i in range(len(floatlist)):
print " void set" +floatlist[i]+ "(float my" + floatlist[i]+");"
print " "
print "//getters"
for i in range(len(intlist)):
print " int get" +intlist[i] + "();"
for i in range(len(floatlist)):
print " float get" +floatlist[i]+ "();"

print ""
for i in range(len(funclist)):
print " void " + funclist[i]+ "();"
print "};"

print " void "+classname+"::init()"
print "{"
for i in range(len(intlist)):
print " int " + intlist[i] + " = 0;"
for i in range(len(floatlist)):
print " float " + floatlist[i] + " = 0;"
print "};"

for i in range(len(intlist)):
print " int " + classname + "::get" + intlist[i] + "()"
print "{"
print "return (" + intlist[i] + ");"
print "}"

for i in range(len(floatlist)):
print " float " + classname + "::get" + floatlist[i] + "()"
print "{"
print "return (" + floatlist[i] + ");"
print "}"

for i in range(len(intlist)):
print "void " + classname + "::set" + intlist[i] + "(int my" + intlist[i] +")"
print "{"
print intlist[i] + "=my" + intlist[i]+";"
print "}"

for i in range(len(floatlist)):
print "void " + classname + "::set" + floatlist[i] + "(float my" + floatlist[i] +")"
print "{"
print floatlist[i] + "=my" + floatlist[i]+";"
print "}"

for i in range(len(funclist)):
print "void " + classname + "::" + funclist[i] + "()"
print "{"
print "}"

I wrote this under UNIX; it expects to receive the template from STDIN and spit to STDOUT, but you should be able to run it from the Windows command prompt or better yet a Cygwin prompt (www.cygwin.com for a UNIX-alike that runs under Windows, get it right now!) I spit it to a C style prettifier so that my boilerplate is all nice and properly indented.

You should be able to change or rewrite this to spit out Darkbasic, Duckbasic or whatever it is you guys are writing in.

Hope you get some use out of it.  I'm not going to provide much tech support for it so don't even ask, the code should be self explanatory and if you can't get it running, you need to learn to fish rather than have me give you one.
« Last Edit: January 02, 2006, 01:25:02 AM by solidcube »
Offline  
Read January 02, 2006, 01:44:19 AM #1
Matt McFarland

Re: A Code Generator

Hey this looks really cool, I think it can speed up some coding time perhaps?  Would be interesting to see it done for BlitzMax too.  BlitzMax uses classes too, but defines them just slightly differently and they're called "types" instead.


<a href="http://www.mattmcfarland.com/flash/myFlashSig.swf" target="_blank">http://www.mattmcfarland.com/flash/myFlashSig.swf</a>
Offline  
Read January 02, 2006, 01:58:36 AM #2
solidcube

Re: A Code Generator

Oh HELL YES it speeds up coding. 

This is the second one of these that I've written.  The first one was in C and it was much longer and more convoluted because you had to escape all of the quotes, et cetera when printing out functions while Python does it on its own.

The thing is, getters and setters, function declarations et cetera are very tedious to program and error prone.  With this, I can spit out a huge file in 30 seconds that would take me a day to program.  I know that it's all correct, and I know how to use the class right away because it's stylistically familiar and consistent.

One good exercise would be to have it spit out a test main() loop that uses the function and throw that in its own file.  A class.dump() method that dumps out all the variables and their values would be handy too for testing, to make sure it works.

Would you rather type "float x; float y; float z; float vx; float vy; float vz" a thousand times, or would you rather do it my way? Smiley

If you want to change it for blintzbasic, do it yourself.  It would take you probably 10 minutes.
Offline  
Read January 02, 2006, 01:59:18 AM #3
Matt McFarland

Re: A Code Generator

Here's an example of a BlitzMax type:

Code:

Type SpaceShip

    Field Power:Int, HitPoints:Int, Shields:Int, Armor:Int
    Field x:Float, y:Float, xSpeed:Float, ySpeed:Float

    Method Shoot(shootrelatedvars)
         Shootcode, etc
    End Method

    Function Spawn(x:Float,y:Float)
        Spawn code, blah blah blah
    End Function

End Type

« Last Edit: January 02, 2006, 02:01:25 AM by Matt McFarland »

<a href="http://www.mattmcfarland.com/flash/myFlashSig.swf" target="_blank">http://www.mattmcfarland.com/flash/myFlashSig.swf</a>
Offline  
Read January 02, 2006, 08:24:33 AM #4
TheColonial

Re: A Code Generator

Looks like a cool script, but most of the editors that you can use out there have some form of template mechanism that you can use to do just this kind of thing.  VS.NET, VIM, UEDIT, etc all have this kind of feature.  I'm not bursting your bubble Smiley I just thought I'd mention it since any time spent on tools that you don't need to build is time you could spend on your game!

I do have a question about the code it generates though, and that is why do you have an init() function?  The code you're generating looks like C++ to me, so how come you're not using and abusing constructors and initialisation lists ?

Cheers.
TC.


In order to understand recursion, one must first understand recursion.
Offline  
Read January 02, 2006, 11:17:36 AM #5
solidcube

Re: A Code Generator

Because I have something in my object manager that likes to call init()  Grin

I wasn't aware that VIM had template generation.  I'll have to check into that.  My idea of an IDE is gedit... haven't used a microsoft IDE since the mid 90s and I don't intend to start.
Offline  
Read January 05, 2006, 08:04:36 AM #6
abhinavvaid

Re: A Code Generator

I've been silently watching this discussion, and getting more and more excited day by day. This is a fantastic effort. Although I had a couple of querries which I might as well post, if I am not able to find the solution.

Something I thought of last week when faced with programming yet another class, was the fact that so much of the code we write is the same for different games and different parts of the same game.  Polymorphism eases this to a great extent but you still have to write base classes from scratch.

So instead of programming the class, I wrote a Python script to program the class for me.

What this program does is it takes a file from standard input like so:
classname
intvariable1 intvariable2 intvariable3
floatvar1 floatvar2 floatvar3...
funcname1 funcname2 funcname3

and it spits out a class with boilerplate functions designed to handle all the variables, as well as function prototypes and skeletons for the functions you specify.

Here is an example template:
Code:
jtObject
energy type damage number owner angle tilex tiley
x y z vx vy vz va
draw thrust fire left right die
and here is the code it produces:
Code:
/***************************************************
* jtObject.cpp
* Generated with
* Classgen.py by SolidCube
***************************************************/
class jtObject{
private:
    // ints
    int energy;
    int type;
    int damage;
    int number;
    int owner;
    int angle;
    int tilex;
    int tiley;
    // floats
    float x;
    float y;
    float z;
    float vx;
    float vy;
    float vz;
    float va;
public:

    //initialize
    void init();
    //setters
    void setenergy(int myenergy);
    void settype(int mytype);
    void setdamage(int mydamage);
    void setnumber(int mynumber);
    void setowner(int myowner);
    void setangle(int myangle);
    void settilex(int mytilex);
    void settiley(int mytiley);
    void setx(float myx);
    void sety(float myy);
    void setz(float myz);
    void setvx(float myvx);
    void setvy(float myvy);
    void setvz(float myvz);
    void setva(float myva);

    //getters
    int getenergy();
    int gettype();
    int getdamage();
    int getnumber();
    int getowner();
    int getangle();
    int gettilex();
    int gettiley();
    float getx();
    float gety();
    float getz();
    float getvx();
    float getvy();
    float getvz();
    float getva();

    void draw();
    void thrust();
    void fire();
    void left();
    void right();
    void die();
};
void jtObject::init()
{
    int energy = 0;
    int type = 0;
    int damage = 0;
    int number = 0;
    int owner = 0;
    int angle = 0;
    int tilex = 0;
    int tiley = 0;
    float x = 0;
    float y = 0;
    float z = 0;
    float vx = 0;
    float vy = 0;
    float vz = 0;
    float va = 0;
};
int jtObject::getenergy()
{
    return (energy);
}
int jtObject::gettype()
{
    return (type);
}
int jtObject::getdamage()
{
    return (damage);
}
int jtObject::getnumber()
{
    return (number);
}
int jtObject::getowner()
{
    return (owner);
}
int jtObject::getangle()
{
    return (angle);
}
int jtObject::gettilex()
{
    return (tilex);
}
int jtObject::gettiley()
{
    return (tiley);
}
float jtObject::getx()
{
    return (x);
}
float jtObject::gety()
{
    return (y);
}
float jtObject::getz()
{
    return (z);
}
float jtObject::getvx()
{
    return (vx);
}
float jtObject::getvy()
{
    return (vy);
}
float jtObject::getvz()
{
    return (vz);
}
float jtObject::getva()
{
    return (va);
}
void jtObject::setenergy(int myenergy)
{
    energy=myenergy;
}
void jtObject::settype(int mytype)
{
    type=mytype;
}
void jtObject::setdamage(int mydamage)
{
    damage=mydamage;
}
void jtObject::setnumber(int mynumber)
{
    number=mynumber;
}
void jtObject::setowner(int myowner)
{
    owner=myowner;
}
void jtObject::setangle(int myangle)
{
    angle=myangle;
}
void jtObject::settilex(int mytilex)
{
    tilex=mytilex;
}
void jtObject::settiley(int mytiley)
{
    tiley=mytiley;
}
void jtObject::setx(float myx)
{
    x=myx;
}
void jtObject::sety(float myy)
{
    y=myy;
}
void jtObject::setz(float myz)
{
    z=myz;
}
void jtObject::setvx(float myvx)
{
    vx=myvx;
}
void jtObject::setvy(float myvy)
{
    vy=myvy;
}
void jtObject::setvz(float myvz)
{
    vz=myvz;
}
void jtObject::setva(float myva)
{
    va=myva;
}
void jtObject::draw()
{
}
void jtObject::thrust()
{
}
void jtObject::fire()
{
}
void jtObject::left()
{
}
void jtObject::right()
{
}
void jtObject::die()
{
}

Here is the Python code:
Code:
#!/usr/bin/python
#classgen.cpp
#takes  4 line file from stdin that looks like this:

#classname
#intname intname intname...
#floatx y z vx vy vz
#func fnc fnc

#// load template
#// from line starting with class, get classname
#// when line starts with ints, get list of intnames
#// when line starts with floats, get list of floatnames
#// when line starts with functions, get list of funcnames
#*/
import string
classname=raw_input()
ints = raw_input()
floats = raw_input()
funcs = raw_input()
intlist = ints.split(' ')
floatlist = floats.split(' ')
funclist = funcs.split(' ')
print "/***************************************************"
print "* " + classname +".cpp"
print "* Generated with "
print "* Classgen.py by SolidCube"
print "***************************************************/"
print "class " + classname + "{"
print "private:"
print "// ints"
for i in range(len(intlist)):
print " int " + intlist[i] +";"
print "// floats"
for i in range(len(floatlist)):
print " float " + floatlist[i]+";"

print "public:"
print "\n//initialize"
print " void init();"
print "//setters"
for i in range(len(intlist)):
print " void set" +intlist[i] + "(int my" + intlist[i]+");"
for i in range(len(floatlist)):
print " void set" +floatlist[i]+ "(float my" + floatlist[i]+");"
print " "
print "//getters"
for i in range(len(intlist)):
print " int get" +intlist[i] + "();"
for i in range(len(floatlist)):
print " float get" +floatlist[i]+ "();"

print ""
for i in range(len(funclist)):
print " void " + funclist[i]+ "();"
print "};"

print " void "+classname+"::init()"
print "{"
for i in range(len(intlist)):
print " int " + intlist[i] + " = 0;"
for i in range(len(floatlist)):
print " float " + floatlist[i] + " = 0;"
print "};"

for i in range(len(intlist)):
print " int " + classname + "::get" + intlist[i] + "()"
print "{"
print "return (" + intlist[i] + ");"
print "}"

for i in range(len(floatlist)):
print " float " + classname + "::get" + floatlist[i] + "()"
print "{"
print "return (" + floatlist[i] + ");"
print "}"

for i in range(len(intlist)):
print "void " + classname + "::set" + intlist[i] + "(int my" + intlist[i] +")"
print "{"
print intlist[i] + "=my" + intlist[i]+";"
print "}"

for i in range(len(floatlist)):
print "void " + classname + "::set" + floatlist[i] + "(float my" + floatlist[i] +")"
print "{"
print floatlist[i] + "=my" + floatlist[i]+";"
print "}"

for i in range(len(funclist)):
print "void " + classname + "::" + funclist[i] + "()"
print "{"
print "}"

I wrote this under UNIX; it expects to receive the template from STDIN and spit to STDOUT, but you should be able to run it from the Windows command prompt or better yet a Cygwin prompt (www.cygwin.com for a UNIX-alike that runs under Windows, get it right now!) I spit it to a C style prettifier so that my boilerplate is all nice and properly indented.

You should be able to change or rewrite this to spit out Darkbasic, Duckbasic or whatever it is you guys are writing in.

Hope you get some use out of it.  I'm not going to provide much tech support for it so don't even ask, the code should be self explanatory and if you can't get it running, you need to learn to fish rather than have me give you one.
Offline  
Read January 05, 2006, 06:19:19 PM #7
solidcube

Re: A Code Generator

Wow, I'm glad someone got some benefit out of it.  If you have any questions go ahead and ask.
Offline  
Pages: [1]   Go Up
Jump to:  

Page created in 0.106 seconds with 18 queries.