Newer
Older
DeltaGo_gcc / main.c
@Motoki Motoki 12 days ago 4 KB init
/* Copyright (C) 2016  Otsuki Tomoshi <tomoshi@m00.itscom.net> */
#include "go.h"
#include <stdarg.h>
#ifdef _WIN32
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #include <limits.h>
    #define GetCurrentDir getcwd
#endif

const char *X_CORD = {"-ABCDEFGHJKLMNOPQRST-\0"};
const char *(Y_CORD[BOARD_EDGE_SIZE + 2]) = {"-",
	 "1",    "2",  "3",   "4",  "5",  "6",  "7",  "8",  "9", "10",  "11",  "12", "13",  "14", "15", "16", "17", "18", "19"
};

void send_gtp(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	vfprintf(stdout, fmt, ap );  // 標準出力に書き出す
	va_end(ap);
}

// 相手の手を受信 "play W D17" のように来る
int get_receive_pos(int *tbn, char *str)
{
	int pos_x = 0, pos_y = 0, x, y, y2;

	if (!strncmp(&str[5], "W", 1)){
		*tbn = TBN_WH;
	} else if (!strncmp(&str[5], "B", 1)){
		*tbn = TBN_BK;
	} else {
		fprintf(stderr, "tbn_err\n");
	}
	for (x = 1; x <= BOARD_EDGE_SIZE; x++){
		if (!strncmp(&str[7], &X_CORD[x], 1)){
			pos_x = x;
			break;
		}
	}

	for (y = 1; y <= 9; y++){ /* 1 keta me */
		if (!strncmp(&str[8], Y_CORD[y], 1)){
			if (y == 1){
				for (y2 = 10; y2 <= 19; y2++){  /* 2 keta me */
					if (!strncmp(&str[8], Y_CORD[y2], 2)){
						y = y2;
						break;
					}
				}
			}
			pos_y = BOARD_EDGE_SIZE + 1 - y;
			break;
		}
	}

	fprintf(stderr, "x = %d, y = %d\n", pos_x, pos_y);
	return X_Y_TO_POS(pos_x, pos_y);
}


int gtp(game_hdl_t *hdl)
{
	char str[FRAME];
	goban_t *ban = hdl->ban;

	// stdoutをバッファリングしないように。GTPで通信に失敗するので。
	setbuf(stdout, NULL);
	setbuf(stderr, NULL);  // stderrに書くとGoGuiに表示される。
	while (1) {
		writeBan(ban);

		fprintf(stderr, "  NOW: tesuu: %d, tbn: %.1s,  (PREV): ", ban->tesuu, &COLOR_NAME[TBN2COLOR(ban->tbn)]);
		outPos(ban->histInfo[ban->tesuu - 1].pos), fprintf(stderr, "\n");

		if (fgets(str, FRAME, stdin)==NULL ) break;  // 標準入力から読む

		if (strstr(str,"boardsize")) {
			send_gtp("= \n\n");    // "boardsize 19": 19路盤
			if (atoi(&str[10]) != BOARD_EDGE_SIZE){
				fprintf(stderr, "illegal boardsize (%d != %d)\n", atoi(&str[10]), BOARD_EDGE_SIZE);
			}
			fprintf( stderr, "if you write in stderr, output into gogui\n");
		} else if (strstr(str,"clear_board")){
			set_initial_pos(ban);
			send_gtp("= \n\n");
		} else if (strstr(str,"komi")){
			ban->komi  = atof(&str[5]);
			fprintf(stderr, "komi = %f\n", ban->komi);
			send_gtp("= \n\n");
		} else if (strstr(str,"undo")){
			if (ban->tesuu >= 3){
				unmake_move(ban);
				unmake_move(ban);
			}
			send_gtp("= \n\n");
		} else if (strstr(str,"name")){
			send_gtp("= deltaGo\n\n");
		} else if ( strstr(str,"protocol_version")){
			send_gtp("= 2\n\n");
		} else if ( strstr(str,"version")){
			send_gtp("= 1.0.0\n\n");
		} else if ( strstr(str,"genmove w") || strstr(str,"genmove b")){
 			int x, y, pos;
			double pos2prob[XY_SIZE];
			fprintf( stderr, "I'm thinking... \n");
			double time_s = Tool_GetTimeNow();
			
			get_feature(NULL, 0, ban->tesuu - 1, ban);
			pos = get_cnn_prob(ban, hdl, pos2prob);
			if (pos == 0){
				fprintf(stderr, "PASS\n\n");
				send_gtp("= PASS\n\n");
			} else {
				x = POS_TO_X(pos);
				y = POS_TO_Y(pos);
				fprintf(stderr, "%.1s%s\n\n", &X_CORD[x], Y_CORD[y]);
				send_gtp("= %.1s%s\n\n", &X_CORD[x], Y_CORD[BOARD_EDGE_SIZE + 1  - y]);
			}
			outPos(pos);
			fprintf(stderr, "\ntime = %f\n", Tool_GetTimeNow() - time_s);
			make_move(pos, ban);
		} else if ( strstr(str,"play")){ // 相手の手を受信 "play W D17" のように来る
			int tbn;
			int pos = get_receive_pos(&tbn, str);
			if (tbn == ban->tbn){
				make_move(pos, ban);
			} else {  // 置き碁の場合?はPASSを挿入
				make_move(0, ban);
				make_move(pos, ban);
			}
			send_gtp("= \n\n");
		} else {
			send_gtp("= \n\n");  // それ以外のコマンドにはOKを返す
		}
	}
	return 0;
}

int main(int argc, char **argv)
{
	game_hdl_t *hdl;
	if ((hdl = open_game_hdl(argc, argv)) == NULL){
		fprintf(stderr, "open game_hdl error\n");
		return 0;
	}
	// read cnn parameter
	FILE *fp_in;
	if ((fp_in = fopen("paramter.bin","rb")) == NULL){
		fprintf(stderr, "file open error: %s\n", "paramter.bin");
		char path[260];
		if (GetCurrentDir(path, sizeof(path)) != NULL) {
			printf("please put paramter.bin into the directory: %s\n", path);
		} else {
			perror("getcwd");
		}
		return 0;
	}
	int n = fread(cnn_param,sizeof(cnn_t), sizeof(parameter_t)/sizeof(cnn_t), fp_in); 
	gtp(hdl);
	return 0;
}