Logic question...

Discussion in 'C++' started by JoeC, Sep 4, 2006.

  1. JoeC

    JoeC Guest

    I am writing a game and I am having a challenge with my combat
    function. All I want to do is find out how to group pieces that are in
    the same space. There are two sides and all the units that are in the
    same space fight. I want to add up the attack factors and defending
    factors in the same space then figure out the odds so I can roll
    against an odds table. Basically each piece holds its own x and y loc.


    Here is what I have right now:

    void fight(vector<unit>& at, vector<unit>& dt,
    board * b , terrain * trn ){

    vector<fightclass> fighting;

    /* adds attacking units to the fightclass vector if units are in the
    same space they are to grouped in the same fight class elemet of
    the
    vector. */

    for(int atu = 0; atu != at.size(); atu++){
    if(fighting.size() == 0){
    fightclass ft;
    ft.addAu(at[atu]);
    fighting.push_back(ft);
    } else {
    for(int lp = 0; lp != fighting.size(); lp++){
    if(at[atu].getXloc() != fighting[lp].getX() &&
    at[atu].getYloc() != fighting[lp].getY()){
    fightclass ft;
    ft.addAu(at[atu]);
    fighting.push_back(ft);
    } else {
    fighting[lp].addAu(at[atu]);
    }
    }
    }
    }
    /* Adds defending units to the fightclass array. If x and y locs are
    the same as attacking locations (are in the same space) they are
    added to array for combat */

    for(int dtu = 0; dtu != dt.size(); dtu++){
    for(int lp = 0; lp != fighting.size(); lp++){
    if(dt[dtu].getXloc() == fighting[lp].getX() &&
    dt[dtu].getYloc() == fighting[lp].getY()){
    fighting[lp].addDu(dt[dtu]);
    }
    }
    }

    // Combat routine

    for(int lp = 0; lp != fighting.size(); lp++){ //handles combat
    if(fighting[lp].canfight()){
    int df = b->GetSpace(fighting[lp].getX(), fighting[lp].getY());
    float odds =
    fighting[lp].getAtk()/fighting[lp].getDef();
    //gets the defense bonus for the terrain in the space where
    //combat takes place
    int roll = rand() - trn[df].defend();
    //get the die roll modified for terrain
    odds = fighting[lp].getAtk() / fighting[lp].getDef();
    //gets the attack to defence ratio.
    if(odds < .5){
    MessageBox(NULL, "Fighting! 1:3", "Info!", MB_OK);
    return;
    }
    if(odds < 1){
    MessageBox(NULL, "Fighting! 1:2", "Info!", MB_OK);
    return;
    }
    if(odds < 2){
    MessageBox(NULL, "Fighting! 1:1", "Info!", MB_OK);
    return;
    }
    if(odds < 3){
    MessageBox(NULL, "Fighting! 2:1", "Info!", MB_OK);
    return;
    }
    if(odds < 4){
    MessageBox(NULL, "Fighting! 3:1", "Info!", MB_OK);
    return;
    }
    if(odds < 5){
    MessageBox(NULL, "Fighting! 4:1", "Info!", MB_OK);
    return;
    }
    if(odds < 6){
    MessageBox(NULL, "Fighting! 5:1", "Info!", MB_OK);
    return;
    }

    }
    }
    for(int lp = 0; lp != fighting.size(); lp++){
    fighting[lp].done();
    }
    fighting.clear();
    }

    class fightclass{
    /* Fightclass holds two arrays of units. The two arrays represent
    units
    in the same space elgible for combat. Array at represents the
    attacking
    forces and dt represents the defending units */


    int xl;
    int yl;

    bool sides2; /* indicates if there are units in both attack and
    defend
    if there are units in both attack and defend then
    combat
    is to take place between the opposing sides. */

    vector<unit>at; //attack units
    vector<unit>dt; //defending units

    public:
    fightclass();
    void addAu(unit au); //adds an addacking unit
    void addDu(unit du); //adds a defending unit
    int getX(){return xl;} //return the x coord
    int getY(){return yl;} //returns the y coord
    float getAtk(); //returns the total attack factors for one space
    float getDef(); //returns the total defending factors for one space
    bool canfight(); //if there are both attacking and defending units
    void done(); //clears vectores after the turn

    };

    fightclass::fightclass(){
    xl = 0;
    yl = 0;
    }

    void fightclass::addAu(unit u){
    at.push_back(u);
    xl = u.getXloc();
    yl = u.getYloc();

    }

    void fightclass::addDu(unit u){

    dt.push_back(u);

    }

    bool fightclass::canfight(){
    if(at.size() && dt.size()){
    return true;
    }else {return false;}
    }

    float fightclass::getAtk(){
    float total;
    for(int lp = 0; lp != at.size(); lp++){
    total +=at[lp].getAttack();
    }
    return total;
    }

    I know the logic is not the best but it is the best I can do. This is
    tricky and I am pretty confused. I would like to find some way of
    making the logic steps easier. There may be some simple error that I
    overlooked or it can be totally screwed up.
    JoeC, Sep 4, 2006
    #1
    1. Advertising

  2. JoeC

    Moonlit Guest

    Hi,

    comp.games.development.programming is probably more appropiate for this
    question.

    --


    Regards, Ron AF Greve

    http://moonlit.xs4all.nl

    "JoeC" <> wrote in message
    news:...
    >I am writing a game and I am having a challenge with my combat
    > function. All I want to do is find out how to group pieces that are in
    > the same space. There are two sides and all the units that are in the
    > same space fight. I want to add up the attack factors and defending
    > factors in the same space then figure out the odds so I can roll
    > against an odds table. Basically each piece holds its own x and y loc.
    >
    >
    > Here is what I have right now:
    >
    > void fight(vector<unit>& at, vector<unit>& dt,
    > board * b , terrain * trn ){
    >
    > vector<fightclass> fighting;
    >
    > /* adds attacking units to the fightclass vector if units are in the
    > same space they are to grouped in the same fight class elemet of
    > the
    > vector. */
    >
    > for(int atu = 0; atu != at.size(); atu++){
    > if(fighting.size() == 0){
    > fightclass ft;
    > ft.addAu(at[atu]);
    > fighting.push_back(ft);
    > } else {
    > for(int lp = 0; lp != fighting.size(); lp++){
    > if(at[atu].getXloc() != fighting[lp].getX() &&
    > at[atu].getYloc() != fighting[lp].getY()){
    > fightclass ft;
    > ft.addAu(at[atu]);
    > fighting.push_back(ft);
    > } else {
    > fighting[lp].addAu(at[atu]);
    > }
    > }
    > }
    > }
    > /* Adds defending units to the fightclass array. If x and y locs are
    > the same as attacking locations (are in the same space) they are
    > added to array for combat */
    >
    > for(int dtu = 0; dtu != dt.size(); dtu++){
    > for(int lp = 0; lp != fighting.size(); lp++){
    > if(dt[dtu].getXloc() == fighting[lp].getX() &&
    > dt[dtu].getYloc() == fighting[lp].getY()){
    > fighting[lp].addDu(dt[dtu]);
    > }
    > }
    > }
    >
    > // Combat routine
    >
    > for(int lp = 0; lp != fighting.size(); lp++){ //handles combat
    > if(fighting[lp].canfight()){
    > int df = b->GetSpace(fighting[lp].getX(), fighting[lp].getY());
    > float odds =
    > fighting[lp].getAtk()/fighting[lp].getDef();
    > //gets the defense bonus for the terrain in the space where
    > //combat takes place
    > int roll = rand() - trn[df].defend();
    > //get the die roll modified for terrain
    > odds = fighting[lp].getAtk() / fighting[lp].getDef();
    > //gets the attack to defence ratio.
    > if(odds < .5){
    > MessageBox(NULL, "Fighting! 1:3", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 1){
    > MessageBox(NULL, "Fighting! 1:2", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 2){
    > MessageBox(NULL, "Fighting! 1:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 3){
    > MessageBox(NULL, "Fighting! 2:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 4){
    > MessageBox(NULL, "Fighting! 3:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 5){
    > MessageBox(NULL, "Fighting! 4:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 6){
    > MessageBox(NULL, "Fighting! 5:1", "Info!", MB_OK);
    > return;
    > }
    >
    > }
    > }
    > for(int lp = 0; lp != fighting.size(); lp++){
    > fighting[lp].done();
    > }
    > fighting.clear();
    > }
    >
    > class fightclass{
    > /* Fightclass holds two arrays of units. The two arrays represent
    > units
    > in the same space elgible for combat. Array at represents the
    > attacking
    > forces and dt represents the defending units */
    >
    >
    > int xl;
    > int yl;
    >
    > bool sides2; /* indicates if there are units in both attack and
    > defend
    > if there are units in both attack and defend then
    > combat
    > is to take place between the opposing sides. */
    >
    > vector<unit>at; //attack units
    > vector<unit>dt; //defending units
    >
    > public:
    > fightclass();
    > void addAu(unit au); //adds an addacking unit
    > void addDu(unit du); //adds a defending unit
    > int getX(){return xl;} //return the x coord
    > int getY(){return yl;} //returns the y coord
    > float getAtk(); //returns the total attack factors for one space
    > float getDef(); //returns the total defending factors for one space
    > bool canfight(); //if there are both attacking and defending units
    > void done(); //clears vectores after the turn
    >
    > };
    >
    > fightclass::fightclass(){
    > xl = 0;
    > yl = 0;
    > }
    >
    > void fightclass::addAu(unit u){
    > at.push_back(u);
    > xl = u.getXloc();
    > yl = u.getYloc();
    >
    > }
    >
    > void fightclass::addDu(unit u){
    >
    > dt.push_back(u);
    >
    > }
    >
    > bool fightclass::canfight(){
    > if(at.size() && dt.size()){
    > return true;
    > }else {return false;}
    > }
    >
    > float fightclass::getAtk(){
    > float total;
    > for(int lp = 0; lp != at.size(); lp++){
    > total +=at[lp].getAttack();
    > }
    > return total;
    > }
    >
    > I know the logic is not the best but it is the best I can do. This is
    > tricky and I am pretty confused. I would like to find some way of
    > making the logic steps easier. There may be some simple error that I
    > overlooked or it can be totally screwed up.
    >
    Moonlit, Sep 4, 2006
    #2
    1. Advertising

  3. JoeC

    JoeC Guest

    Thanks, I didn't know about that group. I will ask the question there.
    Still it is programming and I am trying to learn programming by
    programming games.
    JoeC, Sep 4, 2006
    #3
  4. JoeC

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > void fight(vector<unit>& at, vector<unit>& dt,
    > board * b , terrain * trn ){
    >
    > vector<fightclass> fighting;
    >
    > /* adds attacking units to the fightclass vector if units are in the
    > same space they are to grouped in the same fight class elemet of
    > the
    > vector. */
    >
    > for(int atu = 0; atu != at.size(); atu++){
    > if(fighting.size() == 0){


    A minor detail, but this is better written as:
    if (fighting.empty()) {
    Given that this is a vector, it probably doesn't make any difference,
    but IMO, it's still worth doing.

    > fightclass ft;
    > ft.addAu(at[atu]);
    > fighting.push_back(ft);
    > } else {
    > for(int lp = 0; lp != fighting.size(); lp++){


    Looking just at the tiny bit starting here:

    > if(at[atu].getXloc() != fighting[lp].getX() &&
    > at[atu].getYloc() != fighting[lp].getY()){


    I see what looks like an opportunity for a bit of improvement: create a
    class (or struct) to represent a position, and then use it wherever you
    have positions. In that case, this would become:
    if (at[atu].pos == fighting[lp].pos)
    // do whatever

    I'd also attempt to use consistent naming -- whether you decide on
    'pos' or 'position' or 'location' or 'coordinate' or whatever, attempt
    to use the same name everywhere you have to deal with that kind of
    thing. In the code above, you've got getXloc and getX, both apparently
    doing the same kind of thing. While it's obvious after the fact that
    both do the same kinds of things, when you're writing code, it's nice if
    you can guess ahead of time what the name of a member is going to be
    instead of having to check every time whether it's location, position,
    etc. in this particular case.

    > fightclass ft;
    > ft.addAu(at[atu]);
    > fighting.push_back(ft);


    In this case, the 'whatever' part can be simplified a bit as well. I'd
    create a fightclass ctor that takes a unit as its argument, so it
    creates a fightclass object with a single attacking unit, and then use
    it here:
    fighting.push_back(fightclass(at[atu]));

    > } else {
    > fighting[lp].addAu(at[atu]);
    > }
    > }
    > }
    > }


    At least if I'm reading the intent correctly, I'd consider this much
    enough for one function, though the function might include the following
    chunk as well:

    > /* Adds defending units to the fightclass array. If x and y locs are
    > the same as attacking locations (are in the same space) they are
    > added to array for combat */
    >
    > for(int dtu = 0; dtu != dt.size(); dtu++){
    > for(int lp = 0; lp != fighting.size(); lp++){
    > if(dt[dtu].getXloc() == fighting[lp].getX() &&
    > dt[dtu].getYloc() == fighting[lp].getY()){
    > fighting[lp].addDu(dt[dtu]);
    > }
    > }
    > }


    Down to here. To implement the logic as I understand it, I'd make it two
    functions, but to implement the logic I think you really want, I'd make
    it one. See comments below for more on that.

    > // Combat routine
    >
    > for(int lp = 0; lp != fighting.size(); lp++){ //handles combat


    Starting from here:

    > if(fighting[lp].canfight()){
    > int df = b->GetSpace(fighting[lp].getX(), fighting[lp].getY());
    > float odds =
    > fighting[lp].getAtk()/fighting[lp].getDef();
    > //gets the defense bonus for the terrain in the space where
    > //combat takes place
    > int roll = rand() - trn[df].defend();
    > //get the die roll modified for terrain
    > odds = fighting[lp].getAtk() / fighting[lp].getDef();
    > //gets the attack to defence ratio.


    .... and going down to here probably deserves to be yet another function.

    > if(odds < .5){
    > MessageBox(NULL, "Fighting! 1:3", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 1){
    > MessageBox(NULL, "Fighting! 1:2", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 2){
    > MessageBox(NULL, "Fighting! 1:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 3){
    > MessageBox(NULL, "Fighting! 2:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 4){
    > MessageBox(NULL, "Fighting! 3:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 5){
    > MessageBox(NULL, "Fighting! 4:1", "Info!", MB_OK);
    > return;
    > }
    > if(odds < 6){
    > MessageBox(NULL, "Fighting! 5:1", "Info!", MB_OK);
    > return;
    > }


    This chunk probably also deserves to be a function -- but I'd write it a
    bit differently, something like:

    void show_odds(double odds) {
    //
    // For the moment I'm assuming that odds is always in the range 0..6.
    // For the moment, I've cheated, and conflated 1:3 and 1:2 together into
    // "outnumbered".
    //
    static char *strings[] = {
    "Outnumbered", "1:1", "2:1", "3:1", "4:1", "5:1"};

    string output("Fighting! ");
    output += strings[(int)odds];
    MessageBox(NULL, output, "Info!", MB_OK);
    }

    The following is meant primarily as pseudo-code, not really C++. Chances
    are that I've left out a few things that really need to be there (like
    the calls to fightclass::done). Still, adding things like that shouldn't
    be too horrible.

    void fight(vector<unit> &at, vector<unit> &dt, board *b, terrain *trn)
    {
    vector<fightclass> fighting;

    add_attacking_units(at.begin(), at.end(),
    std::back_inserter(fighting));

    add_defending_units(dt.begin(), dt.end(),
    std::back_inserter(fighting));

    std::vector<double> odds_values(fighting.size());

    std::transform(fighting.begin(), fighting.end(),
    odds_values.begin(), bind1st(figure_odds, trn));

    std::for_each(odd_values.begin(), odds_values.end(), show_odds);
    }

    For the moment, I've used your function signature, but chances are
    pretty good that (for example) all the parameters should refer to const
    values. Perhaps the attacking/defending forces can be killed so those
    vectors can be modified, but it's almost certain that the board and
    probably terrain as well shouldn't be changed -- unless you're getting a
    lot more sophisticated than most, and taking into account things like
    artillery changing the terrain slightly.

    At least as I undertand the idea here, I'd probably also change the
    basic algorithm a bit. Unless I'm misreadin it, right now you're adding
    a fightclass object to the fighting vector for every attacking unit,
    whether there's a defending unit at the same position or not. Then
    you're adding defending units everywhere there are attacking units. I
    believe your real intent is that units only fight each other where
    they're at the same location, so you really want an intersection of the
    two -- i.e. a set of fight objects representing those places there's
    both an attacker and a defender in the same place.

    If that's the case, I'd consider doing things a bit differently. One
    possibility would be to keep each force in a multiset, with the units
    sorted by position. To move a unit, you remove it from the multiset, and
    then insert it back in at the new position. In this case, finding the
    intersection between two forces (i.e. the units they have in the same
    positions) might be as simple as a single call to std:set_intersection.

    I'm not at all sure why board and/or terrain is a pointer either -- it
    appears these could be references to vectors, or something on that
    order. For the moment, I'm leaving the alone, but I suspect some
    reexamination of this point might be worthwhile.

    Applying those comments, we could end up with a function something like:

    void fight(multiset<unit> const &at, // attacking units
    multiset<unit> const &dt, // defending units
    board const *b,
    terrain const *trn)
    {
    vector<fightclass> fighting;

    find_fighting_units(at.begin(), at.end(),
    dt.begin(), dt.end(),
    std::back_inserter(fighting));

    vector<double> odds_values(fighting.size());

    transform(fighting.begin(), fighting.end(),
    odds_values.begin(), bind1st(figure_odds, trn));

    for_each(odd_values.begin(), odds_values.end(), show_odds);
    }

    Though it's more or less off-topic, it also seems like using MessageBox
    for showing the odds is a poor idea -- if there are many intersections
    between the forces, the user is going to have to click through a lot of
    boxes, and as soon as he clicks OK on one, he loses that information, so
    it's hard for him to any kind of overall picture.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Sep 5, 2006
    #4
  5. JoeC

    JoeC Guest

    Thank...


    Jerry Coffin wrote:
    > In article <>,
    > says...
    >
    > [ ... ]
    >
    > > void fight(vector<unit>& at, vector<unit>& dt,
    > > board * b , terrain * trn ){
    > >
    > > vector<fightclass> fighting;
    > >
    > > /* adds attacking units to the fightclass vector if units are in the
    > > same space they are to grouped in the same fight class elemet of
    > > the
    > > vector. */
    > >
    > > for(int atu = 0; atu != at.size(); atu++){
    > > if(fighting.size() == 0){

    >
    > A minor detail, but this is better written as:
    > if (fighting.empty()) {
    > Given that this is a vector, it probably doesn't make any difference,
    > but IMO, it's still worth doing.

    Thanks fixed that one.

    >
    > > fightclass ft;
    > > ft.addAu(at[atu]);
    > > fighting.push_back(ft);
    > > } else {
    > > for(int lp = 0; lp != fighting.size(); lp++){

    >
    > Looking just at the tiny bit starting here:
    >
    > > if(at[atu].getXloc() != fighting[lp].getX() &&
    > > at[atu].getYloc() != fighting[lp].getY()){

    >
    > I see what looks like an opportunity for a bit of improvement: create a
    > class (or struct) to represent a position, and then use it wherever you
    > have positions. In that case, this would become:
    > if (at[atu].pos == fighting[lp].pos)
    > // do whatever
    >

    I have been considering that.

    > I'd also attempt to use consistent naming -- whether you decide on
    > 'pos' or 'position' or 'location' or 'coordinate' or whatever, attempt
    > to use the same name everywhere you have to deal with that kind of
    > thing. In the code above, you've got getXloc and getX, both apparently
    > doing the same kind of thing. While it's obvious after the fact that
    > both do the same kinds of things, when you're writing code, it's nice if
    > you can guess ahead of time what the name of a member is going to be
    > instead of having to check every time whether it's location, position,
    > etc. in this particular case.


    That is true. Naming conventions are important. I just wrote this
    program at different times where some objects left over from older
    projects.
    >
    > > fightclass ft;
    > > ft.addAu(at[atu]);
    > > fighting.push_back(ft);

    >
    > In this case, the 'whatever' part can be simplified a bit as well. I'd
    > create a fightclass ctor that takes a unit as its argument, so it
    > creates a fightclass object with a single attacking unit, and then use
    > it here:
    > fighting.push_back(fightclass(at[atu]));
    >
    > > } else {
    > > fighting[lp].addAu(at[atu]);
    > > }
    > > }
    > > }
    > > }


    Intersting, I will have to look into that one. There are times I don't
    do that because it is easier for me to read. But yes, it is a good
    idea.
    >
    > At least if I'm reading the intent correctly, I'd consider this much
    > enough for one function, though the function might include the following
    > chunk as well:
    >
    > > /* Adds defending units to the fightclass array. If x and y locs are
    > > the same as attacking locations (are in the same space) they are
    > > added to array for combat */
    > >
    > > for(int dtu = 0; dtu != dt.size(); dtu++){
    > > for(int lp = 0; lp != fighting.size(); lp++){
    > > if(dt[dtu].getXloc() == fighting[lp].getX() &&
    > > dt[dtu].getYloc() == fighting[lp].getY()){
    > > fighting[lp].addDu(dt[dtu]);
    > > }
    > > }
    > > }

    >
    > Down to here. To implement the logic as I understand it, I'd make it two
    > functions, but to implement the logic I think you really want, I'd make
    > it one. See comments below for more on that.


    OK that was the intent of writing this. I couldn't figure out how to
    condense this to functions.

    >
    > > // Combat routine
    > >
    > > for(int lp = 0; lp != fighting.size(); lp++){ //handles combat

    >
    > Starting from here:
    >
    > > if(fighting[lp].canfight()){
    > > int df = b->GetSpace(fighting[lp].getX(), fighting[lp].getY());
    > > float odds =
    > > fighting[lp].getAtk()/fighting[lp].getDef();
    > > //gets the defense bonus for the terrain in the space where
    > > //combat takes place
    > > int roll = rand() - trn[df].defend();
    > > //get the die roll modified for terrain
    > > odds = fighting[lp].getAtk() / fighting[lp].getDef();
    > > //gets the attack to defence ratio.

    >
    > ... and going down to here probably deserves to be yet another function.
    >
    > > if(odds < .5){
    > > MessageBox(NULL, "Fighting! 1:3", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 1){
    > > MessageBox(NULL, "Fighting! 1:2", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 2){
    > > MessageBox(NULL, "Fighting! 1:1", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 3){
    > > MessageBox(NULL, "Fighting! 2:1", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 4){
    > > MessageBox(NULL, "Fighting! 3:1", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 5){
    > > MessageBox(NULL, "Fighting! 4:1", "Info!", MB_OK);
    > > return;
    > > }
    > > if(odds < 6){
    > > MessageBox(NULL, "Fighting! 5:1", "Info!", MB_OK);
    > > return;
    > > }

    >
    > This chunk probably also deserves to be a function -- but I'd write it a
    > bit differently, something like:


    This is all experiemtal. I am not sure how to implenmt an odds table.
    All this is just test to see if the prvious code worked. What I want
    to do is implemnt an odds table

    1:3 1:2 1:1 2:1 3:1 4:1 5:1
    0 ae ae ae ae ae ad ad
    1 ae ae ae ae ad ad dd
    2 ae ae ae ad ad dd dd
    3 ae ae ad ad dd dd de
    4 ae ae ad dd dd de de
    5 ae dd dd dd ad de de

    ae =attacker eliminated
    ad = attacker dispersed
    dd = defebder dispersed
    de = defender eliminated
    >
    > void show_odds(double odds) {
    > //
    > // For the moment I'm assuming that odds is always in the range 0..6.
    > // For the moment, I've cheated, and conflated 1:3 and 1:2 together into
    > // "outnumbered".
    > //
    > static char *strings[] = {
    > "Outnumbered", "1:1", "2:1", "3:1", "4:1", "5:1"};
    >
    > string output("Fighting! ");
    > output += strings[(int)odds];
    > MessageBox(NULL, output, "Info!", MB_OK);
    > }

    I have to lower odds for when I expand the game.

    >
    > The following is meant primarily as pseudo-code, not really C++. Chances
    > are that I've left out a few things that really need to be there (like
    > the calls to fightclass::done). Still, adding things like that shouldn't
    > be too horrible.
    >
    > void fight(vector<unit> &at, vector<unit> &dt, board *b, terrain *trn)
    > {
    > vector<fightclass> fighting;
    >
    > add_attacking_units(at.begin(), at.end(),
    > std::back_inserter(fighting));
    >
    > add_defending_units(dt.begin(), dt.end(),
    > std::back_inserter(fighting));
    >
    > std::vector<double> odds_values(fighting.size());
    >
    > std::transform(fighting.begin(), fighting.end(),
    > odds_values.begin(), bind1st(figure_odds, trn));
    >
    > std::for_each(odd_values.begin(), odds_values.end(), show_odds);
    > }
    >
    > For the moment, I've used your function signature, but chances are
    > pretty good that (for example) all the parameters should refer to const
    > values. Perhaps the attacking/defending forces can be killed so those
    > vectors can be modified, but it's almost certain that the board and
    > probably terrain as well shouldn't be changed -- unless you're getting a
    > lot more sophisticated than most, and taking into account things like
    > artillery changing the terrain slightly.


    I can see the differences from my code and can see the weakness of my
    programming. I am not fimilliar with this kind of programming. Are
    these algorithms? I am a bit confused and would have not come up with
    this. Are there smaller experiment programs I can write to better
    understand how to do things like that?
    >
    > At least as I undertand the idea here, I'd probably also change the
    > basic algorithm a bit. Unless I'm misreadin it, right now you're adding
    > a fightclass object to the fighting vector for every attacking unit,
    > whether there's a defending unit at the same position or not. Then
    > you're adding defending units everywhere there are attacking units. I
    > believe your real intent is that units only fight each other where
    > they're at the same location, so you really want an intersection of the
    > two -- i.e. a set of fight objects representing those places there's
    > both an attacker and a defender in the same place.


    Yes, I just couldn't figure out how to do that. I simply want units in
    the same space to add up attack factors then add up defedning factors
    then have them fight. I put each attaking unit in some vector. Then
    see it they were in the same locations as other units. Then I went to
    the defending units and compared them with the other array and if they
    are in the same location, put them together int he fightclass.
    >
    > If that's the case, I'd consider doing things a bit differently. One
    > possibility would be to keep each force in a multiset, with the units
    > sorted by position. To move a unit, you remove it from the multiset, and
    > then insert it back in at the new position. In this case, finding the
    > intersection between two forces (i.e. the units they have in the same
    > positions) might be as simple as a single call to std:set_intersection.


    Again, I am not a very good programmer and not awaire of many of these
    techniques. I wrote a dungeon program where my map was an array of
    spaces that could hole the graphic for the space, the character then
    potentially other things. That became overly complex and difficult to
    remove the player from one space then putting it in aother. Just
    having the units hold its own location then have them display themselvs
    is much simpler but grouping them togert for fighting is a real
    challenge.
    >
    > I'm not at all sure why board and/or terrain is a pointer either -- it
    > appears these could be references to vectors, or something on that
    > order. For the moment, I'm leaving the alone, but I suspect some
    > reexamination of this point might be worthwhile.
    >

    I don't need vectors because they don't change in size. I made them
    pointers because I want to create them in one file then use them in
    another. It is ieasier to pass them to functions than regular arrays.


    Still I am going to save this post in hopes that I can improve how I
    add

    > Applying those comments, we could end up with a function something like:
    >
    > void fight(multiset<unit> const &at, // attacking units
    > multiset<unit> const &dt, // defending units
    > board const *b,
    > terrain const *trn)
    > {
    > vector<fightclass> fighting;
    >
    > find_fighting_units(at.begin(), at.end(),
    > dt.begin(), dt.end(),
    > std::back_inserter(fighting));
    >
    > vector<double> odds_values(fighting.size());
    >
    > transform(fighting.begin(), fighting.end(),
    > odds_values.begin(), bind1st(figure_odds, trn));
    >
    > for_each(odd_values.begin(), odds_values.end(), show_odds);
    > }
    >
    > Though it's more or less off-topic, it also seems like using MessageBox
    > for showing the odds is a poor idea -- if there are many intersections
    > between the forces, the user is going to have to click through a lot of
    > boxes, and as soon as he clicks OK on one, he loses that information, so
    > it's hard for him to any kind of overall picture.
    >
    > --
    > Later,
    > Jerry.
    >
    > The universe is a figment of its own imagination.
    JoeC, Sep 5, 2006
    #5
  6. JoeC

    Bart Guest

    Moonlit wrote:
    > comp.games.development.programming is probably more appropiate for this
    > question.


    Why? His question was more or less about program logic, using mostly
    standard C++ (save for one function). That's more on-topic than many
    other posts here.

    Regards,
    Bart.
    Bart, Sep 5, 2006
    #6
  7. JoeC

    Phlip Guest

    Bart wrote:

    > Moonlit wrote:


    >> comp.games.development.programming is probably more appropiate for this
    >> question.

    >
    > Why? His question was more or less about program logic, using mostly
    > standard C++ (save for one function). That's more on-topic than many
    > other posts here.


    Only the OP should guess which group will provide the best answer.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, Sep 5, 2006
    #7
  8. JoeC

    Nathan Mates Guest

    In article <BUkLg.1693$>,
    Phlip <> wrote:
    >Only the OP should guess which group will provide the best answer.


    Posters are entitled to guess, true. But, correcting guesses is the
    job of newsgroup regulars, and prefectly reasonable.

    Nathan Mates
    --
    <*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
    # Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
    # NOT speaking for Pandemic Studios. "Care not what the neighbors
    # think. What are the facts, and to how many decimal places?" -R.A. Heinlein
    Nathan Mates, Sep 5, 2006
    #8
  9. JoeC

    Phlip Guest

    Nathan Mates wrote:

    >>Only the OP should guess which group will provide the best answer.

    >
    > Posters are entitled to guess, true. But, correcting guesses is the
    > job of newsgroup regulars, and prefectly reasonable.


    The only topicality criteria relevant to a questioner is what newsgroup will
    provide the best question. Once we suggestion one, we can no longer declare
    whether an equally topical question belongs here or there. That was the
    context.

    When you offer another newsgroup, always reinforce that topicality is in the
    poster's best interests. The answer "your question is off topic here go
    away" doesn't increase the odds of useful participation.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, Sep 5, 2006
    #9
  10. JoeC

    Phlip Guest

    Phlip wrote:

    > The only topicality criteria relevant to a questioner is what newsgroup
    > will provide the best question.


    answer.

    you know...

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, Sep 5, 2006
    #10
  11. JoeC

    JoeC Guest

    Phlip wrote:
    > Bart wrote:
    >
    > > Moonlit wrote:

    >
    > >> comp.games.development.programming is probably more appropiate for this
    > >> question.

    > >
    > > Why? His question was more or less about program logic, using mostly
    > > standard C++ (save for one function). That's more on-topic than many
    > > other posts here.

    >
    > Only the OP should guess which group will provide the best answer.
    >
    > --
    > Phlip
    > http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!


    I think MY code works. It is a bit more complex and cumbersom than I
    would like but I am pushing ahead on next part of the game.
    JoeC, Sep 6, 2006
    #11
  12. JoeC

    Moonlit Guest

    Thanks Nathan :)

    --


    Regards, Ron AF Greve

    http://moonlit.xs4all.nl

    "Nathan Mates" <> wrote in message
    news:...
    > In article <BUkLg.1693$>,
    > Phlip <> wrote:
    >>Only the OP should guess which group will provide the best answer.

    >
    > Posters are entitled to guess, true. But, correcting guesses is the
    > job of newsgroup regulars, and prefectly reasonable.
    >
    > Nathan Mates
    > --
    > <*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
    > # Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
    > # NOT speaking for Pandemic Studios. "Care not what the neighbors
    > # think. What are the facts, and to how many decimal places?" -R.A.
    > Heinlein
    Moonlit, Sep 7, 2006
    #12
  13. JoeC

    Phlip Guest

    Moonlit wrote:

    > Thanks Nathan :)


    You correctly indicated a good newsgroup. Nobody doubted that.

    Except Bart, who claimed you shouldn't have bounced.

    I defended you, by saying you didn't bounce, you suggested.

    Then Nathan attempted to refute my defense, which he didn't understand.

    So I think your thanks are due me, not Nathan. ;-)

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, Sep 7, 2006
    #13
  14. JoeC

    Moonlit Guest

    Hi,



    Regards, Ron AF Greve

    http://moonlit.xs4all.nl

    "Phlip" <> wrote in message
    news:zQlLg.8487$...
    > Nathan Mates wrote:
    >
    >>>Only the OP should guess which group will provide the best answer.

    >>
    >> Posters are entitled to guess, true. But, correcting guesses is the
    >> job of newsgroup regulars, and prefectly reasonable.

    >
    > The only topicality criteria relevant to a questioner is what newsgroup
    > will provide the best question. Once we suggestion one, we can no longer
    > declare whether an equally topical question belongs here or there. That
    > was the context.
    >
    > When you offer another newsgroup, always reinforce that topicality is in
    > the poster's best interests. The answer "your question is off topic here
    > go away" doesn't increase the odds of useful participation.

    I didn't see anyone say in this thread "your question is off topic here go
    away"
    I merely suggested a better newsgroup.

    And yes if I quote from the FAQ "Ultimately this means your question must be
    answerable by looking into the C++ language definition as determined by the
    ISO/ANSI C++ Standard document, and by planned extensions and adjustments".
    Well it isn't answerable by looking in the C++ language definition. So
    basically the question is off topic. Yet you didn't see an OT in my header,
    simply because I have better things to do than to police newsgroups. Besides
    that if you look at my responses in the past you will notice that I try to
    help whether OT or not OT.

    I suggested a better newsgroup and thats all there is, the rest is a result
    of your imagination, really.


    >
    > --
    > Phlip
    > http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    >
    >

    Regards, Ron AF Greve.
    Moonlit, Sep 7, 2006
    #14
  15. JoeC

    Phlip Guest

    Moonlit wrote:

    > I merely suggested a better newsgroup.


    I never said you didn't. However...

    > And yes if I quote from the FAQ "Ultimately this means your question must
    > be answerable by looking into the C++ language definition as determined by
    > the ISO/ANSI C++ Standard document, and by planned extensions and
    > adjustments". Well it isn't answerable by looking in the C++ language
    > definition. So basically the question is off topic. Yet you didn't see an
    > OT in my header, simply because I have better things to do than to police
    > newsgroups. Besides that if you look at my responses in the past you will
    > notice that I try to help whether OT or not OT.


    Ultimately, the FAQ was written by a human, and it is not authoritative.

    Ultimately, the term "ultimately" means "at the end of a chain of events".
    So if I ask about the Class Factory Pattern, or MVC, or huffman compression,
    and I ask in platform-neutral terms, then ultimately the exact answer will
    depend on the C++ ISO Standard. Hence, by the criteria of the
    non-authoritative FAQ, such questions are on-topic.

    This newsgroup is not news:comp.std.c++ , and posters should always pick the
    narrowest newsgroup for their questions. So questions that only relate to
    interpretation of The Standard belong there, not here.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
    Phlip, Sep 7, 2006
    #15
  16. JoeC

    Jerry Coffin Guest

    In article <44ff6e01$0$4516$4all.nl>, "Moonlit" <news
    moonlit xs4all nl> says...

    [ ... ]

    > I didn't see anyone say in this thread "your question is off topic here go
    > away"
    > I merely suggested a better newsgroup.


    I'm not even sure that's true -- at least to me, it seems that most of
    the discussion has centered primarily around how to express his ideas in
    C++, not so much about the fundamental design of the game itself. That
    being the case, I think the questions are really more topical here --
    though it may be that enough game programming is done in C++ that it
    would also fit well there.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Sep 7, 2006
    #16
  17. JoeC

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > This is all experiemtal. I am not sure how to implenmt an odds table.
    > All this is just test to see if the prvious code worked. What I want
    > to do is implemnt an odds table
    >
    > 1:3 1:2 1:1 2:1 3:1 4:1 5:1
    > 0 ae ae ae ae ae ad ad
    > 1 ae ae ae ae ad ad dd
    > 2 ae ae ae ad ad dd dd
    > 3 ae ae ad ad dd dd de
    > 4 ae ae ad dd dd de de
    > 5 ae dd dd dd ad de de
    >
    > ae =attacker eliminated
    > ad = attacker dispersed
    > dd = defebder dispersed
    > de = defender eliminated


    enum results { AttElim, AttDisp, DefDisp, DefElim };

    results table[5][7] = {
    { AttElim, AttElim, AttElim, AttElim, AttElim, AttDisp, AttDisp},
    { AttElim, AttElim, AttElim, AttElim, AttDisp, AttDisp, AttDisp},
    // ...

    At least as I understand it, you'd then have to convert your odds to an
    integer (something along the lines I used in show_odds might work).
    You'd apparently index into the array above using the value on the die
    in one dimension and the odds in the other dimension. Alternatively, you
    might be able to simply multiply the odds by the die throw, and figure
    out the result mathematically (your table looks like the relationship is
    basically linear, so this probably wouldn't be terribly difficult.

    > I can see the differences from my code and can see the weakness of my
    > programming. I am not fimilliar with this kind of programming. Are
    > these algorithms? I am a bit confused and would have not come up with
    > this. Are there smaller experiment programs I can write to better
    > understand how to do things like that?


    As it worked out, did this code more or less "bottom-up" -- i.e. looked
    at your one long function, broke it down into some smaller functions,
    and then composed a function that would call those in turn.

    Generally, I'd advise doing more or less the opposite of that: start by
    writing a description of what needs to happen in relatively general
    terms. Especially at first, I'd advise breaking out pencil and paper for
    this part of the task. Doing worry a lot about it being particular neat
    or tidy, just get the general ideas of what needs to happen. In a lot of
    cases, something on the order of an outline or bulleted list works
    reasoanbly -- i.e. try to come up with a _few_ works that generally
    describe a step.

    Then take each of those steps, and do roughly the same thing again --
    break it down into a number of simpler steps, each of which can still be
    described in a few words.

    When you've gotten to the point that everything is broken down into
    relatively simple steps, the coding is (hopefully) pretty easy. The top-
    level outline/list transforms more or less directly into the top-level
    function. Probably nearly every line there will end up as a function
    call. Each of the subordinate descriptions becomes another function as
    well -- until each function has been broken down to the point that it's
    a trivial little bit of code you can read/write/understand quite easily.

    A few points: I'm really serious about the pencil and paper part -- if
    you're at the computer, it's tempting to write code instead. At some
    point, you might consider using one of the cool Computer Aided Software
    Engineering (CASE) tools to draw UML or something like that -- but for
    the moment, I wouldn't advise it. Despite decades of work, CASE tools
    still really aren't the best for quickly roughing out a design; once you
    have a relatively complete design, they can work nicely for making
    incremental improvements, playing around with the effect of various
    changes, and so on -- but that comes a bit later as a rule.

    > Yes, I just couldn't figure out how to do that. I simply want units in
    > the same space to add up attack factors then add up defedning factors
    > then have them fight. I put each attaking unit in some vector. Then
    > see it they were in the same locations as other units. Then I went to
    > the defending units and compared them with the other array and if they
    > are in the same location, put them together int he fightclass.


    Okay -- for the moment, that's probably perfectly fine. One minor
    refinement that might be helpful would be after you've done the above,
    scan back through all the fightclass objects and simply remove any that
    have an empty defender vector. That may not be the most elegant way to
    produce the result, but at least that should be the result you're
    looking for -- sometime later you can come up with a cleaner way of
    getting the result.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Sep 7, 2006
    #17
  18. JoeC

    JoeC Guest

    Jerry Coffin wrote:
    > In article <44ff6e01$0$4516$4all.nl>, "Moonlit" <news
    > moonlit xs4all nl> says...
    >
    > [ ... ]
    >
    > > I didn't see anyone say in this thread "your question is off topic here go
    > > away"
    > > I merely suggested a better newsgroup.

    >
    > I'm not even sure that's true -- at least to me, it seems that most of
    > the discussion has centered primarily around how to express his ideas in
    > C++, not so much about the fundamental design of the game itself. That
    > being the case, I think the questions are really more topical here --
    > though it may be that enough game programming is done in C++ that it
    > would also fit well there.
    >
    > --
    > Later,
    > Jerry.


    Not the whole game but this function. I am not a profetional
    programmer but I do the best I can. I am wrighting this conbat routine
    and it seems very complex and I have trouble keeping track of what I am
    doing. That is not good. I am wondering if there is an easier way to
    do what I am doing. I have been adding to my game, what I am doing
    appears to work.
    >
    > The universe is a figment of its own imagination.
    JoeC, Sep 7, 2006
    #18
  19. JoeC

    JoeC Guest

    Phlip wrote:
    > Moonlit wrote:
    >
    > > I merely suggested a better newsgroup.

    >
    > I never said you didn't. However...
    >
    > > And yes if I quote from the FAQ "Ultimately this means your question must
    > > be answerable by looking into the C++ language definition as determined by
    > > the ISO/ANSI C++ Standard document, and by planned extensions and
    > > adjustments". Well it isn't answerable by looking in the C++ language
    > > definition. So basically the question is off topic. Yet you didn't see an
    > > OT in my header, simply because I have better things to do than to police
    > > newsgroups. Besides that if you look at my responses in the past you will
    > > notice that I try to help whether OT or not OT.

    >
    > Ultimately, the FAQ was written by a human, and it is not authoritative.
    >
    > Ultimately, the term "ultimately" means "at the end of a chain of events".
    > So if I ask about the Class Factory Pattern, or MVC, or huffman compression,
    > and I ask in platform-neutral terms, then ultimately the exact answer will
    > depend on the C++ ISO Standard. Hence, by the criteria of the
    > non-authoritative FAQ, such questions are on-topic.
    >
    > This newsgroup is not news:comp.std.c++ , and posters should always pick the
    > narrowest newsgroup for their questions. So questions that only relate to
    > interpretation of The Standard belong there, not here.
    >
    > --
    > Phlip
    > http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!


    I am just trying to write a game and I feel I am getting a bit over my
    head but still being a hard head, I make it work and push on. I am
    sure what most programmers do. The only way to get experience is to do
    it. It is one thing to learn syntax but it is another to apply good
    programming practice in large projects. What my problem is is that I
    program in a vaccuum, I don't have people with more experience letting
    me know that there are better ways to do what I am trying to do. So
    what I do is put this stuff out there and hope some one who has seen
    simmiliar problems can give me some advice. I have already gotten some
    good advice for other parts of the program. I would like to get this
    part done then the game will be complete and I can expand it or go back
    and improve the code so that it is easier to expand. If somone would
    like to see the whole program and I will send the
    latests version program out.
    JoeC, Sep 7, 2006
    #19
  20. JoeC

    Nathan Mates Guest

    In article <>,
    JoeC <> wrote:
    >Not the whole game but this function. I am not a profetional
    >programmer but I do the best I can. I am wrighting this conbat
    >routine and it seems very complex and I have trouble keeping track
    >of what I am doing. That is not good. I am wondering if there is
    >an easier way to do what I am doing. I have been adding to my game,
    >what I am doing appears to work.


    Managing "who's where" is best separated from the "combat routine."
    Most games have some code (and data structures) dedicated to keeping
    track of units on the map. This means that units know where they are,
    and the map manager also knows which units are where. If your map is
    just a 2D array of a fixed, "reasonable" size (under a million
    entries), you can just make a 2D array of entries, and each entry is
    just a linked list of all units in that cell. If you're working on
    PCs, just burn some memory upfront, and work on optimizing it later--
    plenty of data structures exist to manage sparse datasets.

    You should also separate out code to to map manager so that you can
    say "find all units within radius R of point X,Y" and it'll go do that
    for you. That's code for the map manager, not a "combat routine," as
    you'll probably want your UI code to be able to do the same thing--
    clicking on a square selects all units in that square, or shift-drag
    selects all units in a user-specified rectangle. If you're going to
    use the same kinds of functionality in multiple places, then break it
    out to a common place.

    Nathan Mates

    --
    <*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
    # Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
    # NOT speaking for Pandemic Studios. "Care not what the neighbors
    # think. What are the facts, and to how many decimal places?" -R.A. Heinlein
    Nathan Mates, Sep 7, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mca
    Replies:
    3
    Views:
    382
    ccallen
    May 6, 2004
  2. Igor
    Replies:
    2
    Views:
    2,807
  3. Sue

    simple logic question

    Sue, Apr 6, 2005, in forum: Java
    Replies:
    5
    Views:
    2,427
  4. javadude
    Replies:
    2
    Views:
    5,898
    Wendy Smoak
    Jun 30, 2005
  5. spike
    Replies:
    8
    Views:
    1,459
    Steve Holden
    Feb 9, 2010
Loading...

Share This Page