Server Help

Bot Questions - Math Question muahaha

50% Packetloss - Thu Mar 11, 2004 1:14 pm
Post subject: Math Question muahaha
I am creating a plugin that will save prizes that a player gets so that they can be reprized back to thier ship when they die, change ship, ect.

Code: Show/Hide

struct ShipSaved
{
   unsigned Prizes : 28;
   Uint16 Items[15];
};

struct pSave
{
   char name[20];
   ShipSaved Ship[8];
};


This is the idea, the bot will keep track of all the prizes that a player recieves for each ship. The prizes each are 1 bit which are stored in *psave->Ship[#].Prizes . The 1 issue is that there are 15 prizes on the prize list that need to be stored by how many there are of them. These prizes are # 1,2,3,8,9,11,12,29,21,22,23,24,26,27,28 , all of which will need to be stored by how many that player has. I am looking for a formula to change these numbers to index values, instead of me having to use a huge switch().
The code will go into TM-mer bot so that prizes can be saved by which items someone purchases. It seems that Event_PlayerPrize only picks up on greens that a player grabs and not on any *prize # commands, so I placed some code in sendPrivate() function to cut out any *prize # numbers that are sent private to the player and then to save them in that player's pSave datatype.
So here is the list of prizes that Im looking for a formula for so that i dont have to use the huge switch I made. So for people that are unfamiliar with programming in c++, im trying to turn the numbers on the top into the numbers on the bottom in 1 formula, ex= 28 into 14 and 11 into 5

Prize #: 1,2,3,8,9,11,12,29,21,22,23,24,26,27,28
Index#: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
CypherJF - Thu Mar 11, 2004 1:55 pm
Post subject:
bummers.. maybe something like this

You might as well hardcode the first 7 indicies... then

21-28
if (id >= 21 && id <= 2icon_cool.gif
index = id - 14;

perhaps lol.. dunno its just a spin off my head
50% Packetloss - Thu Mar 11, 2004 3:40 pm
Post subject:
21-28 but it skips over #25 because mulitprizes wouldnt need to be recorded.
Cyan~Fire - Thu Mar 11, 2004 4:51 pm
Post subject:
Instead of having one lump number, why not split it up into little bits?

Like:
Code: Show/Hide
typedef unsigned char bits_t;   //just for laziness :-P

struct ShipSaved
{
   bits_t Unknown  : 1;
   bits_t Recharge : 5;   //or however many you need
   bits_t Energy   : 5;
   //and so on
   Uint16 Items[15];
};

Dustpuppy - Thu Mar 11, 2004 10:09 pm
Post subject:
Well in the time it took you to write this post you could have just written the switch, but whatever.

Why don't you just treat the storage as if you were storing data on all prizes to 29. The ones you don't want just won't be used, since they can't be bought.
50% Packetloss - Thu Mar 11, 2004 11:44 pm
Post subject:
the plan is to use little memory as possible. I have the switch written but a formula is always better.
With the way I have the variables setup, I can check each bit with a simple shift << and a & bitwise comparison. Like so,
Uint32 PrizeBit=(1<<(PrizeNum-1));
PrizeNum would be the prize # and then I could bitwise OR this with the Ship[p->ship].Prizes variable to store the prize.
Smong - Fri Mar 12, 2004 5:53 am
Post subject:
I've changed the struct to take as little memory as possible. I haven't got a formula, but here is an alternative to a switch().

Code: Show/Hide
struct pSave
{
   char name[20];
   unsigned char items[15];
};

int prize_to_index(int prize)
{
   if (prize > 28)
   {
      prize = 7;
   }
   else if (prize > 25)
   {
      prize = prize - 14;
   }
   else if (prize > 20)
   {
      prize = prize - 13;
   }
   else if (prize > 10)
   {
      prize = prize - 6;
   }
   else if (prize > 7)
   {
      prize = prize - 5;
   }
   else if (prize > 0)
   {
      prize = prize - 1;
   }

   return prize;
}

void add_prize(struct pSave *psave, int prize, int amount)
{
   index = prize_to_index(prize);
   if (index != prize)
      psave->items[index] += amount;
}

Mr Ekted - Fri Mar 12, 2004 8:01 am
Post subject:
Code: Show/Hide
BYTE prize[] = {1,2,3,8,9,11,12,29,21,22,23,24,26,27,28};


No nested if's, no testing, no math, much smaller.
Dustpuppy - Fri Mar 12, 2004 12:48 pm
Post subject:
Holy crap that's beautiful tongue.gif
CypherJF - Fri Mar 12, 2004 1:14 pm
Post subject:
rotfl...
50% Packetloss - Fri Mar 12, 2004 2:45 pm
Post subject:
Code: Show/Hide

const Uint16 ItemNum[15]={1,2,3,8,9,11,12,19,21,22,23,24,26,27,28};
void botInfo::GivePrizes(Player *p)
{
   String Message;
   pSave *theSave=FindSave(p->name);
   if(theSave!=NULL && p->ship<8)
   {
      Uint16 j;
      Uint32 PrizeBit=1;
      for(Uint16 i=1;i<=28;i++)
      {
         if(theSave->Ship[p->ship].Prizes & PrizeBit)
         {   
            if(PrizeBit & 0xEF40D87)
            {
               for(j=0;j<15;j++)
               {
                  if(ItemNum[j]==i)
                  {
                     j=theSave->Ship[p->ship].Items[j];
                     break;
                  }
               }
            }
            else
            {j=1;}
               
            Message="*prize #";
            Message+=i;
            while(j-->0)
            {   
               sendPrivate(p,0,Message.msg);
            }
         }
         PrizeBit<<=1;
      }
   }
}

Mr Ekted - Fri Mar 12, 2004 6:11 pm
Post subject:
50% Packetloss wrote:
Doing it that way is the exact same as a switch.


OMG no it's not. Your solution is a ton of useless code. Mine is almost zero code and zero time. Learn to program.
50% Packetloss - Fri Mar 12, 2004 7:07 pm
Post subject:
yes, the dissembly will be different and more efficient the way you suggested but its the same exact idea as the switch. I was asking if anyone saw any relationship between those numbers so that a equation could be made instead of doing it the uneffient way. Forget I asked, I dont want to turn this into an argument, I appritiate your help ekted but maybe you should reserve your insults for someone who is attacking you.
Mr Ekted - Fri Mar 12, 2004 8:56 pm
Post subject:
Sorry to insult, but my "code" is not the same idea as a switch. A switch is a code-based selection based on an input value. This means it must test, jump, and execute code to reach some final output. My solution takes the input value and does a simple table lookup (data-based selection). It is 100x faster and uses easily 1/10 of the bytes. This problem is something that a good programmer would take about 10 seconds to figure out how to solve, and here we are spending days arguing about giant switch statements and encoding prizes in bits. If people are not willing to learn, what's the point?
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group