Code: Select all
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
///////////////////////////////////////////////////////////////////////////////
inline long randi(const int min, const int max) {
if(min==max)
return min;
double c = max - min + 1;
return (min + (int) (c * (rand() / (RAND_MAX + 1.0))));
}
///////////////////////////////////////////////////////////////////////////////
inline int partitioni( int a[], int l, int r) {
int pivot, t;
int i, j;
pivot = a[l];
i = l; j = r+1;
while(1) {
do ++i; while( a[i] <= pivot && i <= r );
do --j; while( a[j] > pivot );
if( i >= j ) break;
t = a[i]; a[i] = a[j]; a[j] = t;
}
t = a[l]; a[l] = a[j]; a[j] = t;
return j;
}
void quicksorti( int a[], int l, int r) {
int j;
if( l < r ) {
// divide and conquer
j = partitioni( a, l, r);
quicksorti( a, l, j-1);
quicksorti( a, j+1, r);
}
}
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
int S = atoi(argv[1]);
int T = atoi(argv[2]);
int N = atoi(argv[3]);
int DMG = atoi(argv[4]);
int HP = atoi(argv[5]);
float hitsTotal[T];
int hitsRound[T];
int timesTargetGetsXShoots[S];
int t, n, s;
for(t=0; t<T; t++)
hitsTotal[t]=0.0;
for(s=0; s<S; s++)
timesTargetGetsXShoots[s]=0;
int killsRound=0;
int killsTotal=0;
int killsMax=0;
int killsMin=T;
// Seed RNG
struct timeval tv;
gettimeofday(&tv, NULL);
srand((tv.tv_usec<<(rand()%28)) + (tv.tv_sec>>(rand()%8-2)));
for(n=0; n<N; n++) {
killsRound=0;
for(t=0; t<T; t++)
hitsRound[t]=0;
// Deliver round of shots
for(s=0; s<S; s++)
hitsRound[randi(0,T-1)]++;
// Sort them
quicksorti(hitsRound,0,T-1);
// Record ocurrences of a target getting X shots
for(t=0; t<T; t++) {
if(hitsRound[t]<0 || hitsRound[t]>S) {
fprintf(stderr,"Check this out: a target says he got hitted %d times in a round when there are %d shots per round.\n",hitsRound[t],S);
return EXIT_FAILURE;
}
timesTargetGetsXShoots[hitsRound[t]]++;
if(hitsRound[t]*DMG>=HP)
killsRound++;
}
// Add to totals
for(t=0; t<T; t++)
hitsTotal[t]+=hitsRound[t];
killsTotal+=killsRound;
if(killsRound>killsMax)
killsMax=killsRound;
if(killsRound<killsMin)
killsMin=killsRound;
}
// Get the average over all repetitions
for(t=0; t<T; t++)
hitsTotal[t]/=(float)N;
float killsAvg = (float)killsTotal/(float)N;
// Print expected shots per target
fprintf(stdout,"EV_ShotsPerTarget\t%d\t%d\t%d\t",S,T,N);
for(t=0; t<T-1; t++)
fprintf(stdout,"%.2f\t",hitsTotal[t]);
fprintf(stdout,"%.2f\n",hitsTotal[T-1]);
fprintf(stdout,"Prob_GetXShots\t%d\t%d\t%d\t",S,T,N);
// Print... ¿expected number of targets that gets X shots?
for(s=0; s<S-1; s++)
fprintf(stdout,"%.2f\t",(float)timesTargetGetsXShoots[s]/(float)(T*N));
fprintf(stdout,"%.2f\n",(float)timesTargetGetsXShoots[s]/(float)(T*N));
fprintf(stdout,"Kills: avg. %f, min. %d, max. %d\n",killsAvg,killsMin,killsMax);
return EXIT_SUCCESS;
}
My plan is to use this to compose some kind of standard shot distribution depending on S and T to help me measure efficiency of hulls, armours, shields and weapons (hopefully, I'll get stuff like wasted shots, PP loss, etc. to compose more elaborated indicators).
Looks like a linear distribution could suffice. E.g. for 100 shots over 20 targets it would be 0.3x+1.7 (overestimates shots on left and underestimate on right). Maybe tweak it to add some extra shots for the right extreme and some less shots for the left extreme. I also got the cubic regression curves (e.g., for 100 shots over 20 targets it's 0.002x^3 - 0.055x^2 + 0.75x + 0.7, coefficients rounded).
Just for the record, I don't really know what I'm doing, but it's interesting.