1 /*
2  *
3  * Dave Ahn
4  *
5  * Leonard/Tom/Dave (LTD) Extended statistics.  For detailed info, read
6  * the README.LTD file.
7  *
8  * For inline optimization details, read the README.LTD and
9  * ltd_stats.c files.
10  *
11  * struct ltd_stats is a per-ship statistics group for each player.
12  * This means that the player DB will increase by several factors in
13  * size at the benefit of detailed stats that can be used to analyze
14  * individual play for clued games.
15  *
16  */
17 
18 #ifndef __INCLUDED_ltd_stats_h__
19 #define __INCLUDED_ltd_stats_h__
20 
21 #include "defs.h"	/* We need defines from this file */
22 
23 typedef enum {
24 
25   LTD_TZONE_0		= 0,	/* Zone 0 = backfield */
26   LTD_TZONE_1		= 1,	/* Zone 1 = core + 2 open side */
27   LTD_TZONE_2		= 2,	/* Zone 2 = front line */
28   LTD_TZONE_3		= 3,	/* Zone 3 = enemy front line */
29   LTD_TZONE_4		= 4,	/* Zone 4 = enemy core + 2 open side */
30   LTD_TZONE_5		= 5,	/* Zone 5 = enemy backfield */
31   LTD_TZONE_6		= 6,	/* Zone 6 = 3rd space */
32   LTD_TZONE_7		= 7,	/* Zone 7 = unknown/diag */
33   LTD_NUM_TZONES	= 8	/* number of zones */
34 
35 } LTD_TZONE_T;
36 
37 /* XXNOTE: find a better way to do the inlining
38    */
39 
40 #ifdef LTD_INLINE
41 #define __LTD_INLINE inline static
42 #else
43 #define __LTD_INLINE
44 #endif
45 
46 /* for extende stats, one struct for each ship except GA and AT, which
47    share the same slot */
48 
49 typedef enum {
50 
51   LTD_TOTAL	= 0,
52   LTD_SC	= 1,
53   LTD_DD	= 2,
54   LTD_CA	= 3,
55   LTD_BB	= 4,
56   LTD_AS	= 5,
57   LTD_SB	= 6,
58   LTD_GA	= 7,
59   LTD_AT	= 7,
60   LTD_NUM_SHIPS	= 8
61 
62 } LTD_SHIP_T;
63 
64 
65 #ifdef LTD_PER_RACE
66 
67 typedef enum {
68 
69   LTD_FED	= 0,
70   LTD_ROM	= 1,
71   LTD_KLI	= 2,
72   LTD_ORI	= 3,
73   LTD_NOBODY	= 4,
74   LTD_NUM_RACES	= 5
75 
76 } LTD_RACE_T;
77 
78 #else
79 
80 typedef enum {
81 
82   LTD_FED	= 0,
83   LTD_ROM	= 0,
84   LTD_KLI	= 0,
85   LTD_ORI	= 0,
86   LTD_NOBODY	= 0,
87   LTD_NUM_RACES	= 1
88 
89 } LTD_RACE_T;
90 
91 #endif /* LTD_PER_RACE */
92 
93 
94 /* LTD stats structure */
95 
96 struct ltd_stats {
97 
98   /* How many times have I killed in this ship */
99 
100   struct _kills {
101 
102     unsigned int total;			/* total number of kills ever */
103     double max;				/* max kills ever achieved */
104     unsigned int first;			/* number of first kills made */
105     unsigned int first_potential;	/* first kills that could be
106                                            converted to carries */
107     unsigned int first_converted;	/* first kills that actually were
108                                            converted to carries */
109     unsigned int second;		/* number of second kills made */
110     unsigned int second_potential;	/* second kills that could be
111                                            converted to carries */
112     unsigned int second_converted;	/* second kills that actually were
113                                            converted to carries */
114     unsigned int phasered;		/* number of kills made with a
115                                            phaser death blow */
116     unsigned int torped;		/* number of kills made with a
117                                            torp blow */
118     unsigned int plasmaed;		/* number of kills made with a
119                                            plamsa */
120 #if defined(_64BIT) && defined(linux)
121   } __attribute__((packed)) kills;
122 #else
123  } kills;
124 #endif
125 
126   /* How many times have I died in this ship */
127 
128   struct _deaths {
129 
130     unsigned int total;			/* total number of deaths ever */
131     unsigned int potential;		/* number of times died as a
132                                            potential carrier */
133     unsigned int converted;		/* number of times died as a
134                                            a converted carrier */
135     unsigned int dooshed;		/* number of times died while ++ */
136     unsigned int phasered;		/* number of times died from phaser */
137     unsigned int torped;		/* number of times died from torp */
138     unsigned int plasmaed;		/* number of times died from plasma */
139     unsigned int acc;			/* number of times you died, and
140                                            someone picked up armies with
141                                            the kill */
142 
143   } deaths;
144 
145 
146   /* How many planets have I destroyed or taken */
147 
148   struct _planets {
149 
150     unsigned int taken;			/* number of planets taken */
151     unsigned int destroyed;		/* number of planets destroyed */
152 
153   } planets;
154 
155 
156   /* How many enemy armies have you bombed */
157 
158   struct _bomb {
159 
160     unsigned int planets;		/* number of planets bombed */
161     unsigned int planets_8;		/* number of planets with <= 8
162                                            armies bombed */
163     unsigned int planets_core;		/* number of core planets bombed */
164     unsigned int armies;		/* total number of armies bombed */
165     unsigned int armies_8;		/* armies bombed where the planet
166                                            being bombed had <= 8 armies */
167     unsigned int armies_core;		/* armies bombed in a core planet */
168 
169   } bomb;
170 
171 
172   /* How many enemy carriers have you killed and armies ogged */
173 
174   struct _ogged {
175 
176     unsigned int armies;		/* number of enemy armies ogged */
177     unsigned int dooshed;		/* number of dooshed real carriers */
178     unsigned int converted;		/* number of converted enemy
179                                            carriers */
180     unsigned int potential;		/* number of potential enemy
181                                            carriers */
182     unsigned int bigger_ship;		/* number of times a real carrier
183                                            was in a bigger ship */
184     unsigned int same_ship;		/* number of times a real carrier
185                                            was in the same sized ship */
186     unsigned int smaller_ship;		/* number of times a real carrier
187                                            was in the same sized ship */
188     unsigned int sb_armies;		/* number of armies on enemy SB
189                                            ogged */
190     unsigned int friendly;		/* number of friendly carriers
191                                            you killed */
192     unsigned int friendly_armies;	/* number of friendly armies you
193                                            killed due to blatant stupidity */
194 
195   } ogged;
196 
197 
198   /* How many friendly armies have you carried */
199 
200   struct _armies {
201 
202     unsigned int total;			/* number of friendly armies carried */
203     unsigned int attack;		/* armies droped on enemy planets */
204     unsigned int reinforce;		/* armies used to reinforce friendly
205                                            planet < 4 */
206     unsigned int ferries;		/* armies ferried to friendly planet
207                                            >= 4 or SB */
208     unsigned int killed;		/* armies killed */
209 
210   } armies;
211 
212 
213   /* How many carries have you made */
214 
215   struct _carries {
216 
217     unsigned int total;			/* number of carries you attempted */
218     unsigned int partial;		/* number of times you delivered
219                                            at least 1 army before dying ++ */
220     unsigned int completed;		/* number of times you completed
221                                            your carry by delivering all
222                                            the armies */
223     unsigned int attack;		/* number of times you dropped on
224                                            a neutral or enemy planet */
225     unsigned int reinforce;		/* number of times you reinforced
226                                            a friendly planet < 4 */
227     unsigned int ferries;		/* number of times you ferried to
228                                            a friendly planet >= 4 or SB */
229 
230   } carries;
231 
232 
233   /* How much time we spent in relevant roles, modes or space */
234 
235   struct _ticks {
236 
237     unsigned int total;			/* total = green + yellow + red */
238     /* unsigned int green; */		/* time spent in green alert */
239     unsigned int yellow;		/* time spent in yellow alert */
240     unsigned int red;			/* time spent in red alert */
241 
242     unsigned int zone[LTD_NUM_TZONES];	/* time spent in a particular zone */
243 
244     unsigned int potential;		/* time spent as potential carrier */
245     unsigned int carrier;		/* time spent as carrier */
246     unsigned int repair;		/* time spent in repair mode */
247 
248   } ticks;
249 
250   unsigned int damage_repaired;		/* total damage repaired */
251 
252 
253   /* Weapon stats */
254 
255   struct _weapons {
256 
257     /* phasers */
258 
259     struct _phaser {
260 
261       unsigned int fired;		/* number of times the weapon was
262                                            fired */
263       unsigned int hit;			/* number of times the weapon hit */
264 
265       struct _damage {
266 
267         unsigned int inflicted;		/* damage inflicted with this weapon */
268         unsigned int taken;		/* damage taken from this weapon */
269 
270       } damage;
271 
272     } phaser;
273 
274     /* torps */
275 
276     struct _torp {
277 
278       unsigned int fired;		/* number of torps that were fired */
279       unsigned int hit;			/* number of torps hit */
280       unsigned int detted;		/* number of torps that were detted
281                                            by enemy */
282       unsigned int selfdetted;		/* number of torps self detted */
283       unsigned int wall;		/* number of torps that hit the wall */
284 
285       struct _damage damage;		/* damage inflicted/taken */
286 
287     } torps;
288 
289 
290     /* plasma */
291 
292     struct _plasma {
293 
294       unsigned int fired;		/* number of plasmas that were fired */
295       unsigned int hit;			/* number that hit */
296       unsigned int phasered;		/* number that were phasered */
297       unsigned int wall;		/* number that hit the wall */
298 
299       struct _damage damage;		/* damage inflicted/taken */
300 
301     } plasma;
302 
303     /* damage repaired */
304 
305   } weapons;
306 
307 #if defined(_64BIT) && defined(linux)
308 } __attribute__((packed));
309 #else
310 };
311 #endif
312 
313 /* LTD history structure - this is needed to calculate the LTD stats
314    every tick. */
315 
316 enum {
317   LTD_NUM_HIST = 5		/* keep track of up to 5 events */
318 };
319 
320 struct ltd_history {
321 
322   /* kill history */
323 
324   struct _kill {
325 
326     unsigned int tick;		/* tick kill was acquired */
327     char potential;		/* kill was retained long enough to
328                                    become potential or converted
329                                    carrier */
330     struct player *victim;	/* the player that was killed */
331     float before;		/* kills i had before this one, perhaps
332                                    from bombing, etc */
333     int ship;			/* ship type of the victim */
334 
335   } kills[LTD_NUM_HIST];
336 
337   int num_kills;		/* number of last_kills */
338 
339   char kill_potential;		/* i am a potential carrier
340                                    0 = no
341                                    1 = potential 1st kill
342                                    2 = potential 2nd kill
343                                    3 = converted 1st kill
344                                    4 = converted 2nd kill */
345 
346   /* bombing history */
347 
348   unsigned int last_bombed_tick;/* tick i bombed the last planet */
349   short last_bombed_planet;	/* last planet that i bombed */
350 
351   /* army/carries history */
352 
353   short last_beamup_planet;
354   short last_beamdown_planet;	/* last planet i beamed up/down armies from
355                                    value is planet number
356                                    -1 = SB
357                                    -2 = no planet */
358 
359   int enemy_team;		/* the enemy team, for ltd_zone */
360 
361 };
362 
363 
364 /* forward declarations of structs for function prototypes */
365 
366 struct player;
367 struct stats;
368 struct planet;
369 
370 /* function prototypes for non-inlined functions */
371 
372 void ltd_reset(struct player *);
373 void ltd_reset_struct(struct ltd_stats (*) [LTD_NUM_SHIPS]);
374 void ltd_reset_hist(struct player *);
375 int ltd_can_rank(struct player *);
376 void ltd_update_totals(struct player *);
377 
378 /* function prototypes for inlined functions */
379 
380 __LTD_INLINE float ltd_total_rating(struct player *);
381 __LTD_INLINE float ltd_bombing_rating(struct player *);
382 __LTD_INLINE float ltd_planet_rating(struct player *);
383 __LTD_INLINE float ltd_defense_rating(struct player *);
384 __LTD_INLINE float ltd_offense_rating(struct player *);
385 
386 __LTD_INLINE int ltd_kills(struct player *, const LTD_SHIP_T);
387 __LTD_INLINE int ltd_deaths(struct player *, const LTD_SHIP_T);
388 __LTD_INLINE int ltd_armies_bombed(struct player *, const LTD_SHIP_T);
389 __LTD_INLINE int ltd_planets_taken(struct player *, const LTD_SHIP_T);
390 __LTD_INLINE int ltd_ticks(struct player *, const LTD_SHIP_T);
391 __LTD_INLINE int ltd_kills_max(struct player *, const LTD_SHIP_T);
392 
393 __LTD_INLINE void ltd_update_ticks(struct player *);
394 __LTD_INLINE void ltd_update_kills(struct player *credit_killer,
395                                    struct player *actual_killer,
396                                    struct player *victim);
397 __LTD_INLINE void ltd_update_kills_max(struct player *);
398 __LTD_INLINE void ltd_update_deaths(struct player *victim,
399                                     struct player *actual_killer);
400 __LTD_INLINE void ltd_update_bomb(struct player *bomber,
401                                   struct planet *planet_bombed,
402                                   int armies_bombed);
403 __LTD_INLINE void ltd_update_planets(struct player *taker,
404                                      struct planet *planet);
405 __LTD_INLINE void ltd_update_armies(struct player *carrier,
406                                     struct planet *planet);
407 __LTD_INLINE void ltd_update_armies_carried(struct player *carrier,
408                                             struct player *sb);
409 __LTD_INLINE void ltd_update_armies_ferried(struct player *carrier,
410                                             struct player *sb);
411 __LTD_INLINE void ltd_update_repaired(struct player *, const int damage);
412 
413 __LTD_INLINE void ltd_update_phaser_fired(struct player *shooter);
414 __LTD_INLINE void ltd_update_phaser_hit(struct player *shooter);
415 __LTD_INLINE void ltd_update_phaser_damage(struct player *shooter,
416                                            struct player *victim,
417                                            const int damage);
418 
419 __LTD_INLINE void ltd_update_torp_fired(struct player *shooter);
420 __LTD_INLINE void ltd_update_torp_hit(struct player *shooter);
421 __LTD_INLINE void ltd_update_torp_detted(struct player *shooter);
422 __LTD_INLINE void ltd_update_torp_selfdetted(struct player *shooter);
423 __LTD_INLINE void ltd_update_torp_wall(struct player *shooter);
424 __LTD_INLINE void ltd_update_torp_damage(struct player *shooter,
425                                          struct player *victim,
426                                          const int damage);
427 
428 __LTD_INLINE void ltd_update_plasma_fired(struct player *shooter);
429 __LTD_INLINE void ltd_update_plasma_hit(struct player *shooter);
430 __LTD_INLINE void ltd_update_plasma_phasered(struct player *shooter);
431 __LTD_INLINE void ltd_update_plasma_wall(struct player *shooter);
432 __LTD_INLINE void ltd_update_plasma_damage(struct player *shooter,
433                                            struct player *victim,
434                                            const int damage);
435 
436 /* find a better way to do this inline stuff */
437 
438 #ifdef LTD_INLINE		/* this stuff is ugly */
439 #define __LTD_INCLUDE_SOURCE
440 #include "ltd_stats.c"
441 #undef  __LTD_INCLUDE_SOURCE
442 #endif
443 
444 
445 #ifdef LTD_PER_RACE
446 
ltd_race(const short team)447 static inline LTD_RACE_T ltd_race(const short team) {
448 
449   switch(team) {
450 
451     case FED:	return LTD_FED;
452     case ROM:	return LTD_ROM;
453     case KLI:	return LTD_KLI;
454     case ORI:	return LTD_ORI;
455     default:	return LTD_NOBODY;
456 
457   }
458 
459 }
460 
461 #else
462 
463 #define ltd_race(XXX) 0
464 
465 #endif /* LTD_PER_RACE */
466 
467 #endif /* __INCLUDED_ltd_stats_h__ */
468 
469