Shots distribution

For topics that do not fit in another sub-forum.

Moderator: Oberlus

Post Reply
Message
Author
User avatar
Oberlus
Cosmic Dragon
Posts: 5715
Joined: Mon Apr 10, 2017 4:25 pm

Shots distribution

#1 Post by Oberlus »

The following piece of C code delivers S shots among T targets N times and calculates the probability distribution: /Edit: now it also takes damage per shot and structure of targets to give an estimation of kills per round/

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;
}
With it I calculated shot distribution for {20,40,60,80,100} shots over 20 targets and this is what I got:
shot_distrib_20-100_20_100k.png
shot_distrib_20-100_20_100k.png (18.37 KiB) Viewed 7273 times
X axis are the targets (20th target is the one getting more shots), Y axis are the shots the ship gets.

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.

Ophiuchus
Programmer
Posts: 3433
Joined: Tue Sep 30, 2014 10:01 am
Location: Wall IV

Re: Shots distribution

#2 Post by Ophiuchus »

If I got you right you sorted the ships by the number of hits they got after all 100 shots and you marked the state after 20,40,60,80,100 shots in different colours?
And you repeated this X times and took averages?

If that so one can see how the lucky ones running out of special luck ;)
So in average none got hit more ten times and the luckiest one got hit about one and a half times if distributing 100 shots?
Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.

Look, ma... four combat bouts!

User avatar
Oberlus
Cosmic Dragon
Posts: 5715
Joined: Mon Apr 10, 2017 4:25 pm

Re: Shots distribution

#3 Post by Oberlus »

Yes, for 100 shots on 20 targets, the unlucky one gets roughly 9.5 hits.
Looks like the shot distribution is the same for scenarios with same ratio shots/target. This makes things easier.
The following table reads as follows:

If we have 2 shots at 3 targets, the first target (the lucky one) will expect 0 hits, the second 2/3, and the third (the unlucky one) 4/3.
With 30 shots, it would be 7.38, 9.9 and 12.71 (that is, 7, 10 and 13).

Shots Targets 1st third 2nd third 3rd third
2 3 0 0.67 1.33
3 3 0.22 0.89 1.89
4 3 0.46 1.18 2.36
5 3 0.62 1.6 2.78
6 3 0.87 1.9 3.24
7 3 1.11 2.2 3.68
8 3 1.34 2.58 4.08
9 3 1.59 2.91 4.5
10 3 1.86 3.22 4.92
12 3 2.36 3.89 5.74
15 3 3.15 4.91 6.94
20 3 4.51 6.59 8.9
30 3 7.38 9.9 12.71
40 3 10.31 13.24 16.45
50 3 13.27 16.6 20.13

If we were talking of 6 shots for 9 targets (same ratio than 2 for 3), the unlucky third of the targets would be getting on average 1.33 shots each (i.e., for the 3 ships with more hits, we could expect two getting 1 hit and one getting 2).
This table is useful when targets are multiples of 3. Good for small battles.
The following two tables are for multiples of 5 and 10, for medium and bigger battles.

Shots Targets 1st fifth 2nd fifth 3rd fifth 4th fifth 5th fifth
2 5 0 0 0 0.8 1.2
3 5 0 0 0.47 0.96 1.57
4 5 0 0.19 0.76 1.09 1.96
5 5 0.04 0.42 0.9 1.36 2.29
6 5 0.11 0.62 1.02 1.68 2.58
7 5 0.21 0.75 1.22 1.94 2.88
8 5 0.32 0.88 1.48 2.13 3.19
9 5 0.43 1.04 1.71 2.36 3.47
10 5 0.53 1.22 1.87 2.61 3.76
12 5 0.77 1.56 2.26 3.1 4.31
15 5 1.16 2.06 2.88 3.78 5.13
20 5 1.84 2.93 3.88 4.91 6.45
30 5 3.31 4.73 5.87 7.13 8.96
40 5 4.86 6.52 7.88 9.34 11.4
50 5 6.47 8.38 9.87 11.5 13.78

Shots Targets 1st tenth 2nd tenth 3rd tenth 4th tenth 5th tenth 6th tenth 7th tenth 8th tenth 9th tenth 10th tenth
2 10 0 0 0 0 0 0 0 0 0.89 1.11
4 10 0 0 0 0 0 0 0.49 0.93 1.02 1.55
6 10 0 0 0 0 0.15 0.6 0.93 1.01 1.29 2.03
8 10 0 0 0.02 0.18 0.59 0.9 1 1.18 1.73 2.4
10 10 0 0.01 0.15 0.5 0.85 0.98 1.12 1.58 2.04 2.75
12 10 0.01 0.09 0.38 0.76 0.96 1.07 1.46 1.91 2.28 3.1
15 10 0.05 0.28 0.68 0.94 1.12 1.51 1.9 2.18 2.74 3.6
20 10 0.22 0.65 0.99 1.32 1.73 2.01 2.38 2.88 3.42 4.42
30 10 0.7 1.32 1.81 2.22 2.67 3.05 3.51 4.06 4.75 5.92
40 10 1.27 2.04 2.62 3.12 3.62 4.1 4.62 5.24 6.02 7.34
50 10 1.91 2.81 3.48 4.05 4.58 5.12 5.71 6.39 7.25 8.69
70 10 3.26 4.4 5.2 5.89 6.53 7.19 7.89 8.65 9.66 11.33
100 10 5.47 6.88 7.87 8.7 9.47 10.23 11.06 11.99 13.19 15.14
150 10 9.33 11.17 12.4 13.43 14.38 15.33 16.34 17.48 18.92 21.22
200 10 13.44 15.55 17 18.18 19.3 20.42 21.57 22.87 24.53 27.13

User avatar
swaq
Space Dragon
Posts: 384
Joined: Tue Aug 20, 2019 1:56 pm

Re: Shots distribution

#4 Post by swaq »

I feel like this would be better visualized with something more like a bell curve.

User avatar
Oberlus
Cosmic Dragon
Posts: 5715
Joined: Mon Apr 10, 2017 4:25 pm

Re: Shots distribution

#5 Post by Oberlus »

swaq wrote: Tue Oct 22, 2019 6:19 pmI feel like this would be better visualized with something more like a bell curve.
Well, shots distribution does not follow a normal distrubution. The curves you get are like the ones showed in the OP.

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Shots distribution

#6 Post by alleryn »

Oberlus wrote: Tue Oct 22, 2019 6:55 pm
swaq wrote: Tue Oct 22, 2019 6:19 pmI feel like this would be better visualized with something more like a bell curve.
Well, shots distribution does not follow a normal distrubution. The curves you get are like the ones showed in the OP.
Well, another way to plot data would be to look at the probability of a given ship taking n hits. It wouldn't be a bell curve, but it would be a curve that starts at zero on the y-axis (-1 hits taken out of, say, 20 shots), gets higher, and then comes back down to zero on the y-axis (21 hits taken out of 20 shots), similar in that sense to a bell curve. I guess it would be called a continuous probability distribution or something like that.

Morlic
AI Contributor
Posts: 296
Joined: Tue Feb 17, 2015 11:54 am

Re: Shots distribution

#7 Post by Morlic »

alleryn wrote: Tue Oct 22, 2019 7:45 pm
Oberlus wrote: Tue Oct 22, 2019 6:55 pm
swaq wrote: Tue Oct 22, 2019 6:19 pmI feel like this would be better visualized with something more like a bell curve.
Well, shots distribution does not follow a normal distrubution. The curves you get are like the ones showed in the OP.
Well, another way to plot data would be to look at the probability of a given ship taking n hits.
You would have to plot N curves for N ships though - in the experiment here each ship has a different probability distribution (of which the EV has been plotted by Oberlus).
If I provided any code, scripts or other content here, it's released under GPL 2.0 and CC-BY-SA 3.0

User avatar
Oberlus
Cosmic Dragon
Posts: 5715
Joined: Mon Apr 10, 2017 4:25 pm

Re: Shots distribution

#8 Post by Oberlus »

swaq wrote: Tue Oct 22, 2019 6:19 pmI feel like this would be better visualized with something more like a bell curve.
alleryn wrote: Tue Oct 22, 2019 7:45 pmWell, another way to plot data would be to look at the probability of a given ship taking n hits. It wouldn't be a bell curve, but it would be a curve that starts at zero on the y-axis (-1 hits taken out of, say, 20 shots), gets higher, and then comes back down to zero on the y-axis (21 hits taken out of 20 shots), similar in that sense to a bell curve. I guess it would be called a continuous probability distribution or something like that.
Morlic wrote: Tue Oct 22, 2019 8:14 pmYou would have to plot N curves for N ships though - in the experiment here each ship has a different probability distribution (of which the EV has been plotted by Oberlus).
Ah, thank you, guys, now I get it.

Some experimentation with your idea (X is number of shots, Y probability):
prob_get_X_shots.png
prob_get_X_shots.png (141.37 KiB) Viewed 7191 times

User avatar
Oberlus
Cosmic Dragon
Posts: 5715
Joined: Mon Apr 10, 2017 4:25 pm

Re: Shots distribution

#9 Post by Oberlus »

I've updated the C code (and the snipped in the OP) to show the probabilities of getting N shots and a simple estimation of dead ships depending on damage and structure.
In no way is this a combat simulator, it only allows to get results for all shots with the same damage spread among targets with same structure.

Say we were comparing a a fleet of 10 robos with two plasmas (18), shield level 2 (5) and two plates of 18 (total structure 51 IIRC) with the +5 structure tech, against the same composition. Each ship takes 5 shots to die.
We can run this (damage is 13=18-5, structure 56):

Code: Select all

~$ ./FOShotDistrib 20 10 10000 13 56
EV_ShotsPerTarget	20	10	10000	0.22	0.66	1.00	1.33	1.73	2.00	2.37	2.87	3.42	4.40
Prob_GetXShots	20	10	10000	0.12	0.27	0.29	0.19	0.09	0.03	0.01	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00	0.00
Kills: avg. 0.427700, min. 0, max. 3
So most probably none or one targets will die after round one of combat.

Post Reply