#include #include #include void hwsimple(int argc, char ** argv); void hwextend(int argc, char ** argv); void main(int argc, char ** argv) { for (int i=1;i][i] [M][+|-][?][_][~][T][!] etc. \n"); } } #pragma argsused void hwsimple(int argc, char ** argv) { long draws,losses,wins; draws=losses=wins=0; int skill1,skill2; int edge1,edge2; int mastery1,mastery2; int debug = 0; char * ptr; ptr=argv[1]+1; // past S indicator while (ptr[0] != '\0') { if (ptr[0] == 'D') debug++; ptr++; } skill1=int(strtol(argv[2],&ptr,10)); if (ptr[0]=='M') mastery1=int(strtol(ptr+1,&ptr,10)); else mastery1=0; if (ptr[0]=='+' || ptr[0]=='-') edge1=int(strtol(ptr,&ptr,10)); else edge1=0; skill2=int(strtol(argv[3],&ptr,10)); if (ptr[0]=='M') mastery2=int(strtol(ptr+1,&ptr,10)); else mastery2=0; if (ptr[0]=='+' || ptr[0]=='-') edge2=int(strtol(ptr,&ptr,10)); else edge2=0; int specialcase = (mastery1 > 0 && mastery1 == mastery2); while (mastery1 > 0 && mastery2 > 0) { mastery1--; mastery2--; } FILE *stream; /* open a file for update */ stream = fopen("results.txt", "w+"); printf("Skill1 = %dM%d+%d, Skill2 = %dM%d+%d\n",skill1,mastery1,edge1,skill2,mastery2,edge2); long contests = 20*20; int level1,level2; int roll1,roll2; for (roll1=1;roll1<21;roll1++) { /**/ if (roll1==1) level1=4; else if (roll1==20) level1=1; else if (roll1<=skill1) level1=3; else level1=2; level1 = min(level1+mastery1,4); for (roll2=1;roll2<21;roll2++) { /**/ if (roll2==1) level2=4; else if (roll2==20) level2=1; else if (roll2<=skill2) level2=3; else level2=2; level2 = min(level2+mastery2,4); if (debug) printf("%d=%d %d=%d ",roll1,level1,roll2,level2); fprintf(stream, "%d=%d %d=%d ",roll1,level1,roll2,level2); /**/ if (level1 > level2) { wins++; if(debug) printf("Win\n"); fprintf(stream,"Win\n"); } else if (level1 < level2) { losses++; if(debug) printf("Loss\n"); fprintf(stream,"Loss\n"); } else if (level1 == 4) { draws++; if(debug) printf("Draw\n"); fprintf(stream,"Draw\n"); } else if (level1 == 1) { draws++; if(debug) printf("Draw\n"); fprintf(stream,"Draw\n"); } else if (roll1 == roll2) { draws++; if(debug) printf("Draw\n"); fprintf(stream,"Draw\n"); } else if (!specialcase && level1==2) { draws++; if(debug) printf("Draw\n"); fprintf(stream,"Draw\n"); } else if (roll1 < roll2) { wins++; if(debug) printf("Win\n"); fprintf(stream,"Win\n"); } else if (roll1 > roll2) { losses++; if(debug) printf("Loss\n"); fprintf(stream,"Loss\n"); } else { printf("BUG: %dM%d, %dM%d\n",roll1,mastery1,roll2,mastery2); fprintf(stream,"BUG: %dM%d, %dM%d\n",roll1,mastery1,roll2,mastery2); } } } printf( "Wins : %4.4ld %3.2ld.%2.2ld\%\n",wins,(wins*100)/contests,((wins*10000)/contests)%100); fprintf(stream,"Wins : %4.4ld %3.2ld.%2.2ld\%\n",wins,(wins*100)/contests,((wins*10000)/contests)%100); printf( "Draws : %4.4ld %3.2ld.%2.2ld\%\n",draws,(draws*100)/contests,((draws*10000)/contests)%100); fprintf(stream,"Draws : %4.4ld %3.2ld.%2.2ld\%\n",draws,(draws*100)/contests,((draws*10000)/contests)%100); printf( "Losses: %4.4ld %3.2ld.%2.2ld\%\n",losses,(losses*100)/contests,((losses*10000)/contests)%100); fprintf(stream,"Losses: %4.4ld %3.2ld.%2.2ld\%\n",losses,(losses*100)/contests,((losses*10000)/contests)%100); printf( "Advantage: %3.2ld.%2.2ld\%\n",(wins*100)/max(wins+losses,1L),((wins*10000)/max(wins+losses,1L))%100); fprintf(stream,"Advantage: %3.2ld.%2.2ld\%\n",(wins*100)/max(wins+losses,1L),((wins*10000)/max(wins+losses,1L))%100); /* close the file */ fclose(stream); } void PARMS(char*& arg, /**/ int& skill, /**/ int& mastery, /**/ int& edge, /**/ int& stake, /**/ int& minstake, /**/ int& maxstake, /**/ int& splat, /**/ int& target, /**/ int& coup, /**/ int& SP, /**/ char*& ptr ) { skill=int(strtol(arg,&ptr,10)); mastery=0; edge=0; stake=3; minstake=1; maxstake=100; splat=0; target=0; coup=0; while (ptr[0] != '\0') { if (ptr[0]=='M') mastery=int(strtol(ptr+1,&ptr,10)); if (ptr[0]=='+' || ptr[0]=='-') edge=int(strtol(ptr,&ptr,10)); if (ptr[0]=='?') stake=int(strtol(ptr+1,&ptr,10)); if (ptr[0]=='_') minstake=int(strtol(ptr+1,&ptr,10)); if (ptr[0]=='~') maxstake=int(strtol(ptr+1,&ptr,10)); /* Stake Points Level As Target! */ /* If splat X the opponent's SP score is between min and max, */ /* then bid splat x his score */ if (ptr[0]=='#') splat++; /* How low do we want to get the opponent? */ if (ptr[0]=='T') target=-abs(int(strtol(ptr+1,&ptr,10))); /* Execute a coup after target reached? */ if (ptr[0]=='!') coup=int(strtol(ptr+1,&ptr,10)); } SP = skill + (20 * mastery); } void adjust(int& skill, int& mastery, int& oppmastery, int mod) { while (mod > 0) { skill--; if (skill == 0) { skill=20; if (mastery==0) oppmastery++; else mastery--; } mod--; } while (mod < 0) { skill++; if (skill == 21) { skill=1; if (oppmastery==0) mastery++; else oppmastery--; } mod++; } } #pragma argsused void hwextend(int argc, char ** argv) { long draws,losses,wins; draws=losses=wins=0; // int perms=0; int skill1,skill2; int mastery1,mastery2; int edge1,edge2; int stake1,stake2; int minstake1,minstake2; int maxstake1,maxstake2; int splat1,splat2; int target1,target2; int oskill1,oskill2; int omastery1,omastery2; int coup1,coup2; int ocoup1,ocoup2; int SP1,SP2; int OSP1,OSP2; int phils; int seed=0; int commentary=0; char * ptr; FILE *stream=NULL; long contests=1; int debug=0; phils=0; ptr=argv[1]+1; while (ptr[0] != '\0') { switch(ptr[0]) { case 'P': phils=1; ptr++; break; case 'I': contests=strtol(ptr+1,&ptr,10); break; case 'R': seed=int(strtol(ptr+1,&ptr,10)); break; case 'D': debug++; ptr++; break; case 'C': commentary++; ptr++; break; default: ptr++; } } if (seed) srand(seed); else randomize(); if (contests>0) /* open a file for update */ stream = fopen("results.txt", "w+"); else contests=-contests; PARMS(argv[2],skill1,mastery1,edge1,stake1,minstake1,maxstake1,splat1,target1,coup1,SP1,ptr); oskill1 = skill1; omastery1 = mastery1; OSP1 = SP1; ocoup1 = coup1; PARMS(argv[3],skill2,mastery2,edge2,stake2,minstake2,maxstake2,splat2,target2,coup2,SP2,ptr); oskill2 = skill2; omastery2 = mastery2; OSP2 = SP2; ocoup2 = coup2; int specialcase = (mastery1 > 0 && mastery1 == mastery2); while (mastery1 > 0 && mastery2 > 0) { mastery1--; mastery2--; } printf("Skill1 = %dM%d%c%d, Skill2 = %dM%d%c%d\n",skill1,mastery1,(edge1<0)?'-':'+',abs(edge1),skill2,mastery2,(edge2<0)?'-':'+',abs(edge2)); int level1,level2; int roll1,roll2; int delta1,delta2; int rollnum=0; int actor=0; long i; for (i=0;i 0 && (SP2 > target1 || coup1)) || /**/ (SP2 > 0 && (SP1 > target2 || coup2)) ) { if ((SP1<0 || SP2<0) && debug) { printf( "SP1=%d SP2=%d target1=%d target2=%d coup1=%d coup2=%d\n",SP1, SP2, target1, target2, coup1, coup2); fprintf(stream,"SP1=%d SP2=%d target1=%d target2=%d coup1=%d coup2=%d\n",SP1, SP2, target1, target2, coup1, coup2); } rollnum++; if (rollnum%2==0) actor=(actor==1)?2:1; else { actor=(SP2>SP1)?2:1; } if ((actor == 1 && SP1 <= 0) || (actor == 2 && SP2 <= 0)) continue; // Incapacitated int tstake1,tstake2; { // I don't want to use stake by accident later, so localise it int stake; if (actor == 1) stake = max(min(max(stake1,SP2*splat1),(SP1*maxstake1)/100),(SP1*minstake1)/100); else stake = max(min(max(stake2,SP1*splat2),(SP2*maxstake2)/100),(SP2*minstake2)/100); if (stake<1) stake=1; if (actor == 1 && SP2 <= target1 && SP1 > 0 && coup1) { coup1=0; if (SP2 <= coup1*stake) { stake = SP1/ocoup1; if (stake<1) continue; } } if (actor == 2 && SP1 <= target2 && SP2 > 0 && coup2) { coup2=0; if (SP1 <= coup2*stake) { stake = SP2/ocoup2; if (stake<1) continue; } } if (actor == 1) { tstake1 = stake; tstake2 = max(0,stake+edge1); } else { tstake1 = max(0,stake+edge2); tstake2 = stake; } } roll1 = random(20)+1; /**/ if (roll1==1) level1=4; else if (roll1==20) level1=1; else if (roll1<=skill1) level1=3; else level1=2; level1 = min(level1+mastery1,4); roll2 = random(20)+1; /**/ if (roll2==1) level2=4; else if (roll2==20) level2=1; else if (roll2<=skill2) level2=3; else level2=2; level2 = min(level2+mastery2,4); if (specialcase && level1==2 && level2==2) level1=level2=3; delta1=0; delta2=0; switch(level1) { case 1: switch(level2) { case 1: // Both BF delta1=-2*tstake1; delta2=-2*tstake2; break; case 2: delta1=-2*tstake1; delta2=-tstake2; break; case 3: delta1=-3*tstake1; break; default: delta1=-3*tstake1; delta2=3*tstake1; } break; case 2: switch(level2) { case 1: delta1=-tstake1; delta2=-2*tstake2; break; case 2: delta1=-tstake1; delta2=-tstake2; break; case 3: delta1=-2*tstake1; break; default: delta1=-2*tstake1; delta2=2*tstake1; break; } break; case 3: switch(level2) { case 1: delta2=-3*tstake2; break; case 2: delta2=-2*tstake2; break; case 3: if (roll1 < roll2) { delta2=-tstake2; } else if (roll1 > roll2) { delta1=-tstake1; } break; default: delta1=-1*tstake1; delta2=1*tstake1; } break; default: switch(level2) { case 1: delta1=3*tstake2; delta2=-3*tstake2; break; case 2: delta1=2*tstake2; delta2=-2*tstake2; break; case 3: delta1=tstake2; delta2=-tstake2; break; default: if (phils) { if (roll1 > roll2) { delta2=-tstake2; } else if (roll1 < roll2) { delta1=-tstake1; } } } } // Wound options go here! if (phils) { // Additional -5 if on negative, remember to undo it if APs go positive again if (SP1>0 && SP1+delta1<=0) adjust(skill1,mastery1,mastery2,-5); if (SP2>0 && SP2+delta2<=0) adjust(skill2,mastery2,mastery1,-5); if (SP1<=0 && SP1+delta1>0) adjust(skill1,mastery1,mastery2,+5); if (SP2<=0 && SP2+delta2>0) adjust(skill2,mastery2,mastery1,+5); } // *1/2 is too complicated, so below -10 = -1 per -1, ie. -15 = -5, -30 = -20 // You get them if you go down, but you don't get them back again if // you go back up and you only get to keep the largest penalty that you // got - so if you go down to -15, you get a -5, if you then bounce // back to +ve and then drop back down, you have to get to -16 before // you start getting more penalties if (SP1+delta1<-10) { int oldpenalty=min(0,(SP1+10)); int newpenalty=min(0,(SP1+delta1+10)); adjust(skill1,mastery1,mastery2,min(0,newpenalty-oldpenalty)); } if (SP2+delta2<-10) { int oldpenalty=min(0,(SP2+10)); int newpenalty=min(0,(SP2+delta2+10)); adjust(skill2,mastery2,mastery1,min(0,newpenalty-oldpenalty)); } SP1 += delta1; if (SP1 > 0) coup2 = ocoup2; SP2 += delta2; if (SP2 > 0) coup1 = ocoup1; if (debug) printf("%2.2d=%d %2.2d=%d 1%s%-2.2d=%2.2d%s 2%s%-2.2d=%2.2d\n",roll1,level1,roll2,level2,(delta1<0)?"":"+",delta1,SP1,(SP1<0)?"":" ",(delta2<0)?"":"+",delta2,SP2); fprintf(stream, "%2.2d=%d %2.2d=%d 1%s%-2.2d=%2.2d%s 2%s%-2.2d=%2.2d\n",roll1,level1,roll2,level2,(delta1<0)?"":"+",delta1,SP1,(SP1<0)?"":" ",(delta2<0)?"":"+",delta2,SP2); } if (SP1 <= 0 && SP2 <= 0) { if (debug) printf("Draw!\n"); fprintf(stream,"Draw!\n"); draws++; } if (SP1 <= 0 && SP2 > 0) { if (debug) printf("Lose!\n"); fprintf(stream,"Lose!\n"); losses++; } if (SP1 > 0 && SP2 <= 0) { if (debug) printf("Win!\n"); fprintf(stream,"Win!\n"); wins++; } if (commentary) { int chars; long j=i+1; printf("%3.2ld.%2.2ld%3.2ld.%2.2ld%3.2ld.%2.2ld%n",(wins*100)/j,((wins*10000)/j)%100,(draws*100)/j,((draws*10000)/j)%100,(losses*100)/j,((losses*10000)/j)%100,&chars); while (chars--) printf("\b"); } } if (commentary) { printf("\n"); } printf( "Wins : %4.4ld %3.2ld.%2.2ld\%\n",wins,(wins*100)/contests,((wins*10000)/contests)%100); fprintf(stream,"Wins : %4.4ld %3.2ld.%2.2ld\%\n",wins,(wins*100)/contests,((wins*10000)/contests)%100); printf( "Draws : %4.4ld %3.2ld.%2.2ld\%\n",draws,(draws*100)/contests,((draws*10000)/contests)%100); fprintf(stream,"Draws : %4.4ld %3.2ld.%2.2ld\%\n",draws,(draws*100)/contests,((draws*10000)/contests)%100); printf( "Losses: %4.4ld %3.2ld.%2.2ld\%\n",losses,(losses*100)/contests,((losses*10000)/contests)%100); fprintf(stream,"Losses: %4.4ld %3.2ld.%2.2ld\%\n",losses,(losses*100)/contests,((losses*10000)/contests)%100); printf( "Advantage: %3.2ld.%2.2ld\%\n",(wins*100)/max(wins+losses,1L),((wins*10000)/max(wins+losses,1L))%100); fprintf(stream,"Advantage: %3.2ld.%2.2ld\%\n",(wins*100)/max(wins+losses,1L),((wins*10000)/max(wins+losses,1L))%100); // printf("\nPerms : %4.4ld %3.2ld.%2.2ld\%\n",perms,(perms*100)/contests,((perms*10000)/contests)%100); /* close the file */ fclose(stream); }