Skip to content

Instantly share code, notes, and snippets.

@triplog
Last active August 29, 2015 13:59
Show Gist options
  • Save triplog/10847572 to your computer and use it in GitHub Desktop.
Save triplog/10847572 to your computer and use it in GitHub Desktop.
血の教誨師ドティのコンピュータの強さをシミュレートするためのプログラム. http://www55.atpages.jp/triplog/pg/monthly/1404/index.php
#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