Last active
August 29, 2015 13:59
-
-
Save triplog/10847572 to your computer and use it in GitHub Desktop.
血の教誨師ドティのコンピュータの強さをシミュレートするためのプログラム. http://www55.atpages.jp/triplog/pg/monthly/1404/index.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include<string.h> | |
#include<stdlib.h> | |
#include "MT.h" | |
/* | |
基本的な処理の関数 | |
*/ | |
//min~maxの乱数発生 | |
int dice(int min, int max){ | |
if(min>max){ | |
int temp = min; | |
min = max ; | |
max = temp; | |
} | |
return genrand_int32()%(max-min+1)+min; | |
} | |
//int→char(一桁) | |
char num2char(int input){ | |
if(input<10) | |
return '0' + input; | |
else | |
return 'a' + input - 10; | |
} | |
//char→int(一文字) | |
int char2num(const char* input){ | |
if(*input>='a') | |
return (int)((*input-'a') + 10); | |
else | |
return (int)(*input-'0'); | |
return 11; | |
} | |
//recordから相手のデータだけ抜き出す | |
int readEneRec(const char* record, char* eneRec){ | |
int i=0; | |
//recordが空なら-1 | |
if(strlen(record)==0) | |
return -1; | |
//相手が後攻=自分が先行 | |
else if(strlen(record)%2==0) | |
for(i=0;i<strlen(record)/2+1;i++) | |
eneRec[i]=record[2*i+1]; | |
//相手が先攻=自分が後攻 | |
else | |
for(i=0;i<strlen(record)/2+1;i++) | |
eneRec[i]=record[2*i]; | |
eneRec[i] = '\0'; | |
return 0; | |
} | |
//文字列から最大のものを選ぶ | |
int maxEneRec(const char* eneRec){ | |
int i,c=0; | |
for(i=0;i<strlen(eneRec);i++) | |
if(eneRec[c]<eneRec[i]) | |
c=i; | |
return char2num(&eneRec[c]); | |
} | |
//文字列から最小のものを選ぶ | |
int minEneRec(const char* eneRec){ | |
int i,c=0; | |
for(i=0;i<strlen(eneRec);i++) | |
if(eneRec[c]>eneRec[i]) | |
c=i; | |
return char2num(&eneRec[c]); | |
} | |
/* | |
回答キャラクターの関数 | |
*/ | |
//単純にランダム | |
int ansA(){ | |
return dice(2,20); | |
} | |
//回答範囲内ランダム | |
int ansB(int myNum){ | |
return dice(myNum+1,myNum+10); | |
} | |
//過去の答えは出さない | |
int ansC(int myNum, const char* record){ | |
int answer = 0; | |
char temp[2]=""; | |
while((answer<myNum+1)||(myNum+10<answer)||(strstr(record,temp))!=NULL){ | |
answer = dice(1,10) + dice(1,10); | |
temp[0] = num2char(answer); | |
} | |
return answer; | |
} | |
//相手の回答から絞込 | |
int ansD(int myNum,const char* record){ | |
int min=1, max=10; | |
int i,answer=0; | |
char temp[2]=""; | |
char eneRec[100]=""; | |
if(readEneRec(record,eneRec)!=-1){ | |
min = (maxEneRec(eneRec)>11)?maxEneRec(eneRec)-10:1; | |
max = (minEneRec(eneRec)<11)?minEneRec(eneRec)-1:10; | |
} | |
while((answer<myNum+min)||(myNum+max<answer)||(strstr(record,temp))!=NULL){ | |
answer = dice(1,10) + dice(1,10); | |
temp[0] = num2char(answer); | |
} | |
return answer; | |
} | |
//11~正答からランダム | |
int ansE(int answer){ | |
if(answer>11) | |
return dice(11,answer); | |
else | |
return dice(answer,11); | |
} | |
//11~正答範囲,回答絞込 | |
int ansF(int myNum, int enNum, const char* record){ | |
int answer; | |
if(myNum+enNum>11) | |
while(1){ | |
answer = ansD(myNum,record); | |
if(answer>=11 && answer<=myNum+enNum) | |
return answer; | |
} | |
else | |
while(1){ | |
answer = ansD(myNum,record); | |
if(answer<=11 && answer>=myNum+enNum) | |
return answer; | |
} | |
} | |
/* | |
プログラムの中枢の関数 | |
*/ | |
int simulation(int offset,int* total){ | |
//開始前 | |
char record[1000]=""; | |
int numX,numY,turn; | |
init_genrand((unsigned)time(NULL)+offset); | |
numX = dice(1,10); | |
numY = dice(1,10); | |
turn = dice(0,1); | |
printf("X:%2d Y:%2d A:%c :",numX,numY,num2char(numX+numY)); | |
//開始 | |
int answer=0; | |
int i=0; | |
while(answer!=numX+numY){ | |
//プレイヤーX | |
if(turn==0){ | |
// printf("X"); | |
// answer = ansA(); | |
// answer = ansB(numX); | |
// answer = ansC(numX,record); | |
answer = ansD(numX,record); | |
// answer = ansE(numX+numY); | |
// answer = ansF(numX,numY,record); | |
} | |
//プレイヤーY | |
else{ | |
// printf("Y"); | |
// answer = ansA(); | |
// answer = ansB(numX); | |
// answer = ansC(numY,record); | |
answer = ansD(numY,record); | |
// answer = ansE(numX+numY); | |
// answer = ansF(numY,numX,record); | |
} | |
turn = 1 - turn; | |
record[i]=num2char(answer); | |
i++; | |
} | |
record[i+1]='\0'; | |
//終了後 | |
printf("%2d %s", strlen(record),record); | |
*total += strlen(record); | |
//敗者を返す | |
return turn; | |
} | |
int main(void){ | |
int i; | |
int loop=1000; | |
int win=0; | |
int total=0; | |
init_genrand((unsigned)time(NULL)); | |
for(i=0;i<loop;i++){ | |
// system("cls"); | |
printf("[%2d]",i); | |
win += simulation(i,&total); | |
printf("\n"); | |
} | |
printf("%d-%d %lf",win,loop-win,(double)(total)/(double)(loop)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment