PDA

View Full Version : Who wants to help me with some code?



John Cribati
2013-11-23, 01:25 PM
So... like many members of this forum, I run a game. And like many members of the human race, I am lazy. So lazy that I'm writing a decently complicated program that will run all of the required calculations for the game for me. I know, it's paradoxical. Welcome to my life.

I already plan to release the program so like-minded individuals can use it to run their calculations as well. I'll even help you out if anyone needs to alter it for their own game (My game is Fire-Emblem based, but it can easily be altered for use with D&D, M&M, and what have you).

I've just hit a bit of a roadblock on that front that you guys can help me out with. It's not very difficult, really, just that it's a lot of typing. But that's just it... Typing. You can be a huge help to me without knowing a single thing about coding! And if you do, well, I want to code the thing myself, but you guys can critique it all you want.


I have to stat out all of the weapons. All of them. You can find them Here (http://www.giantitp.com/forums/showpost.php?p=14360623&postcount=2).
I already created a new type of object called Item that has 2 Variables: maxDur for the maximum duration and currDur for the current duration.

I then created a type of Item called Weapon that inherited from Item, so it has those variables, plus a bunch of others.

Then I have Sword, Axe, Lance, Bow, etc, etc, which inherit from Weapon, with an defined variable for wherever on the triangle it's placed.

So to stat out an Iron Sword, I had to take this:

{table=head]|Dur|Rank|Rng|Wgt|Mgt|Hit|Crit|Cost|Other
Iron Sword|50|E|1|7|5|90|0|500|[/table]

and make 2 files out of it:

a file with an extension of .h (IronSword.h)
and a file with an extension of .cpp (IronSword.cpp)


IronSword.h has this information:

#ifndef IRONSWORD_H
#define IRONSWORD_H
#include "Sword.h"

class IronSword : public Sword{
public:
inline IronSword();
private:
string Name;

};
#endif
Meanwhile IronSword.cpp has this information:


#include "IronSword.h"

IronSword::IronSword()
{
setMt(5);
setWt(7);
setHit(90);
setCrit(0);
setDur(50);
setRank('E');
setEffective(0);
}

All you guys would have to do is open up Notepad and type up the .h and .cpp files for me. Just replace what's bold with the weapon name and stats. So if you wanted to make a Steel Axe, it would be

SteelAxe.h

#ifndef STEELAXE_H
#define STEELAXE_H
#include "Axe.h"

class SteelAxe : public Axe{
public:
inline SteelAxe();
private:
string Name;

};
#endif
SteelAxe.cpp


#include "SteelAxe.h"

SteelAxe::SteelAxe()
{
setMt(11);
setWt(15);
setHit(65);
setCrit(0);
setDur(30);
setRank('D');
EFFECTIVE=0;
}


So who's willing to help me out?

FLHerne
2013-11-23, 03:01 PM
That looks like a rather odd way to code it - IIUC XSword will have the same functions and variables as YAxe and all other Weapon subclasses?

Also, what creates new Weapon [subclass] objects and how? In particular, how does whatever it is know what subclasses of Weapon exist?

I'd have a struct WeaponType containing variables for each of your stats, a function to create instances of it from data in a file, and have the Weapon constructor take a WeaponType pointer as an argument. That way you can avoid storing numerous copies of the same data.



#ifndef WEAPONSTUFF_H
#define WEAPONSTUFF_H

struct WeaponType {
string _name;
int _dur;
char _rank;
int _rng;
[etc]
}

vector<WeaponType*> loadTypes([filename/pointer]) {
[do stuff I'm to lazy to care about just now - Dr Who is on]
}

class Weapon : public Item {
public:
Weapon(WeaponType *in_type) { _type = in_type; } //const? Probably.
int rng() const { return _type->_rng; }
[etc]
private:
WeaponType* _type;
[etc]
}
#endif


Then you have a vector (or something else) containing the stats for every type of weapon, you can look at it to see what types of weapon can be created, and you can easily add new weapon types by adding them to a file without recompiling the program.

I'm only a hobbyist programmer though, so please do correct me if I'm being a total idiot somehow. :smallconfused:

John Cribati
2013-11-23, 03:33 PM
That looks like a rather odd way to code it - IIUC XSword will have the same functions and variables as YAxe and all other Weapon subclasses?

Yeah, it will. It's just how Fire Emblem works.


Also, what creates new Weapon [subclass] objects and how? In particular, how does whatever it is know what subclasses of Weapon exist?

The Weapon class contains an integer called Triangle that determines that. Sword and its descendants will automatically have their Triangle variable set to 1, Axe and its descendants has it set to 2, and so on.


I'd have a struct WeaponType containing variables for each of your stats, a function to create instances of it from data in a file, and have the Weapon constructor take a WeaponType pointer as an argument. That way you can avoid storing numerous copies of the same data

But I will need to have numerous copies of everything, because a character can have more than one Iron Sword in his inventory, or more than one character can each have an Iron Sword in their inventory. They obviously can't be the same sword.


Then you have a vector (or something else) containing the stats for every type of weapon, you can look at it to see what types of weapon can be created, and you can easily add new weapon types by adding them to a file without recompiling the program.

Which would work, if I were any good at File I/O.


I'm only a hobbyist programmer though, so please do correct me if I'm being a total idiot somehow. :smallconfused:

I didn't really listen in class, so you probably know more than me anyway.

FLHerne
2013-11-23, 03:53 PM
But I will need to have numerous copies of everything, because a character can have more than one Iron Sword in his inventory, or more than one character can each have an Iron Sword in their inventory. They obviously can't be the same sword.All Iron Swords will have the same range, rank and so on. Clearly the current duration (and anything else that can be different between instances of the same type of weapon) has to be a member of the Weapon class though.


Which would work, if I were any good at File I/O.It should be really simple I/O - the data file would be your own, so you could be really lazy and leave out the error checking. :smalltongue:

John Cribati
2013-11-23, 04:18 PM
All Iron Swords will have the same range, rank and so on. Clearly the current duration (and anything else that can be different between instances of the same type of weapon) has to be a member of the Weapon class though.

That's... exactly what I was going for. All Iron Swords have the same Maximum duration, but the current duration can change. Unless I missed a step in this conversation.


It should be really simple I/O - the data file would be your own, so you could be really lazy and leave out the error checking. :smalltongue:

Yeah, but then I'd have to compile the data myself, which means going for that Forum Post with all the linked weapons and altering it.

And as I said before, I am very, very lazy.

Teddy
2013-11-23, 05:41 PM
That seems like a very, very inefficient way of doing it. If every weapon is identical apart from a few numbers (i.e. all their calculations are identical), instead of making a new class for every weapon, save their stats in a struct and store every weapons' struct in an array (or hash table, depending on how you want to index it). When you need a new instance of a weapon, just create a new instance fo the class Weapon, and pass its stats struct as a parameter to its constructor. The only thing you'll need to type in will be a copy of the weapons table you're interested in, which will be a little task, but nothing so large that making a post asking for help on it will save you any time... :smallwink:

valadil
2013-11-23, 05:54 PM
I'm very familiar with your problem of spending a ton of effort to reduce the effort of a repetitive task.


Which would work, if I were any good at File I/O.

Sounds like it's time to brush up on your file IO.

Ok, if you're intent on sticking with this approach, why not write a program that generates the C files you want? I'll generalize in bash.



#!/bin/bash

#name0, parent1, dur2, rank3, rng4, wgt5, mgt6, hit7, crit8, cost9, effective10
WEAPONS=$(cat <<EOW
IronSword Sword 50 E 1 7 5 90 0 500 0
EOW
)

echo $WEAPONS | while read -a line ; do
HEADER=$(cat <<EOH
#ifndef ${line[0]}_H
#define ${line[0]}_H
#include "${line[1]}.h"

class ${line[0]} : public ${line[1]}{
public:
inline ${line[0]}();
private:
string Name;

};
#endif

EOH
)

CPP=$(cat << EOCPP
#include "${line[0]}"

${line[0]}::${line[0]}()
{
setMt(${line[6]});
setWt(${line[5]});
setHit(${line[7]});
setCrit(${line[8]});
setDur(${line[2]});
setRank(${line[3]});
setEffective(${line[10]});
}
EOCPP
)
echo "$HEADER" > ${line[0]}.h
echo "$CPP" > ${line[0]}.cpp

done




I apologize for the use of heredocs if you're not used to them. They make it easy to write templates though.

The first heredoc defines your weapons. Each weapon gets a line. I had to add a parent property so that they knew what to inherit from. I copied the values from your post and put them here. Also added a comment so I knew which col was which.

The while read line business reads the weapons var one line at a time and converts it into an array. The syntax for bash arrays is unfortunate. ${line[0]} gives you the 0th element from the $line array.

The headers and cpp heredocs each apply the values from the line array. Here it's just subbing in the values from each of the lines.

Finally the script creates each .cpp and .h file. I ran the script and got back each of your initial files. If you want it to do more than that, add another line to weapons. Each line up there gives you a new weapon.

Cerussite
2013-11-23, 06:04 PM
I'll second the suggestion to not subclass everything: vanilla items that have the same behavior definitely shouldn't be standalone classes. If you're willing to model effectiveness against armored as separate properties, for example, you can also relieve yourself from making the more special weapons as standalone classes as well.

Then, you can index all your prototype weapons by name in a hashtable (or, speaking C++, std::unordered_map or boost::unordered_map), clone them when you need an "Iron Sword", for example, and set it's current duration to what it should be.

If you don't want to put your data in a free-form text file, you could use something like Mongo or SQLite to structure your data.

Grinner
2013-11-23, 06:27 PM
Which would work, if I were any good at File I/O.

You could literally do this with a text file.

The first few lines would be a header describing the number of weapons in each category. Something like:


Swords = 19
Axes = 19
Lances = 17
Bows = 9

Read those into separate variables and then create a for-loop for each one.

Then, the attributes of each weapon would be printed on their own line each, like so:



IronSword //you could use this in the program or just discard it after reading it
Mt = 5
Wt = 7
Hit = 90
Crit = 0
Dur = 50
Rank = E
Effective = 0

In the loops, you'd just have a few functions for loading these attributes. In C, you'd probably want to use something like fscanf(fp, "Mt = %i", Mt), where "fp" is the file pointer and "Mt" is a variable. I don't know what the C++ equivalent would be, but it couldn't be too hard to figure out. Or you could try using the C function.


That seems like a very, very inefficient way of doing it. If every weapon is identical apart from a few numbers (i.e. all their calculations are identical), instead of making a new class for every weapon, save their stats in a struct and store every weapons' struct in an array (or hash table, depending on how you want to index it). When you need a new instance of a weapon, just create a new instance fo the class Weapon, and pass its stats struct as a parameter to its constructor. The only thing you'll need to type in will be a copy of the weapons table you're interested in, which will be a little task, but nothing so large that making a post asking for help on it will save you any time... :smallwink:

Seconding this.

FLHerne
2013-11-23, 07:54 PM
Yeah, but then I'd have to compile the data myself, which means going for that Forum Post with all the linked weapons and altering it.
And as I said before, I am very, very lazy.
Lazy people should write code that makes their lives easier. :smallwink:

Well, I got bored and decided to learn Python. :smallcool:
And this seemed like a nice easy thing to play with.
So I turned your big table into easier-to-parse text.
I don't know what '1-2' or '-' are supposed to mean, so I left them in. You'll have to change those before or in the process of sticking data into your system.



SlimSword 35 E 1 3 2 100 5 560
Boomerang 40 E 1-2 4 5 90 0 550
BronzeSword 50 E 1 5 3 95 - 350
IronSword 50 E 1 7 5 90 0 500
Armorslayer 18 D 1 14 8 80 0 1260
Longsword 18 D 1 12 6 80 0 1260
HeavenSword 18 D 1 13 7 80 0 1260
Wyrmslayer 18 D 1 14 8 80 0 1260
FeatherBlade 18 D 1 13 6 80 0 1260
SteelSword 40 D 1 11 8 85 0 800
VeninEdge 40 D 1 7 4 70 0 520
IronBlade 45 D 1 13 9 70 0 900
Lancereaver 15 C 1 9 9 75 5 1800
KillingEdge 20 C 1 8 9 75 30 1300
SteelBlade 35 C 1 15 11 65 0 1400
BraveSword 30 B 1 14 9 75 0 5400
Chakram 20 A 1-2 8 12 80 0 2500
SilverBlade 25 A 1 14 15 60 0 3000
SilverSword 30 A 1 9 13 80 0 1800

Hatchet 50 E 1-2 5 4 85 0 300
BronzeAxe 50 E 1 5 5 80 - 350
IronAxe 45 E 1 10 8 75 0 270
HandAxe 20 E 1-2 9 7 60 0 300
SteelAxe 30 D 1 15 11 65 0 360
Hammer 20 D 1 15 10 55 0 800
Halberd 18 D 1 15 10 60 0 810
AsgardAxe 18 D 1 11 7 80 0 1260
DragonAxe 18 D 1 10 8 80 0 1260
WingShredder 18 D 1 11 6 80 0 1260
PoisonAxe 40 D 1 10 4 60 0 310
Magic*Axe 20 D 1-2 6 11 80 0 2300
SteelBlade 35 C 1 15 11 65 0 1400
KillerAxe 20 C 1 11 11 65 30 1000
Swordreaver 15 C 1 13 11 65 5 2100
BraveAxe 30 B 1 16 10 65 0 7500
Battleaxe 20 B 1 15 13 65 0 1000
SIlverAxe 20 A 1 13 15 70 0 1000
Tomahawk 15 A 1-2 11 13 65 0 3000

SlimLance 50 E 1 4 4 85 5 420
BronzeLance 45 E 1 6 5 80 - 390
IronLance 45 E 1 8 7 80 0 360
Javelin 20 E 1-2 6 6 65 0 400
SteelLance 30 D 1 13 10 70 0 480
HeavySpear 16 D 1 14 9 70 0 1200
Horseslayer 16 D 1 13 7 70 0 1040
OlympusLance 16 D 1 12 8 70 0 1100
Dragonspear 16 D 1 11 9 70 0 1100
FlyersBane 16 D 1 12 7 70 0 1100
ToxinLance 40 D 1 8 4 65 0 400
ShortSpear 18 C 1-2 7 9 60 0 900
KillerLance 20 C 1 9 10 70 30 1200
Axereaver 15 C 1 11 10 5 5 2100
BraveLance 30 B 1 14 10 70 0 7500
SilverLance 20 A 1 10 14 75 0 1500
Spear 15 A 1-2 8 12 70 0 5000

IronBow 45 E 2 5 6 85 5 540
BronzeBow 50 E 2 4 5 90 - 500
ShortBow 40 D 1-2 3 5 85 10 1760
SteelBow 30 D 2 9 9 70 5 720
VenomBow 40 D 2 5 4 65 5 400
Longbow 20 D 2-3 10 5 65 5 2000
KillerBow 20 C 2 7 9 75 30 1400
BraveBow 30 B 2 12 10 70 10 7500
SilverBow 20 A 2 6 13 75 10 1600


EDIT: Fixed a couple of mistakes (from your original table :smallyuk:)
EDIT2: Added quote, some notes.

John Cribati
2013-11-23, 08:09 PM
Lazy people should write code that makes their lives easier. :smallwink:

Well, I got bored and decided to learn Python. :smallcool:
And this seemed like a nice easy thing to play with.
So I turned your big table into easier-to-parse text.

-snip-
EDIT: Fixed a couple of mistakes (from your original table :smallyuk:)

Oh, that is Beautiful.

And what mistakes, may I ask?

Anyways, thanks to all of you for the help. My mind tends to go for the most complicated solution first for some reason.

Looks like it's back to the drawing board for me.

FLHerne
2013-11-23, 08:32 PM
And what mistakes, may I ask?Just a couple of obvious typos in the Swords table (http://www.giantitp.com/forums/showpost.php?p=14360623&postcount=2). They were quite conspicuous because there were too few fields and my hacky script produced a bunch of gibberish. :smallconfused:

GM.Casper
2013-11-30, 11:43 PM
Interesting. What kind of interface are you planing? An actual game board or just a list of PCs and NPCs?

John Cribati
2013-12-01, 08:31 AM
Interesting. What kind of interface are you planing? An actual game board or just a list of PCs and NPCs?

Eventually, I want it to spit out something like this (http://www.giantitp.com/forums/showpost.php?p=15906824&postcount=124) (I already draw the map myself, so it won't have to do that though), but for right now I’m content with just doin calculations.