GTPの解釈と適当な対局エンジン

前回,KGSのサーバに接続するところまで出来たので,次はいくつかのGTPコマンドに対応させて,適当に打つプログラムと対局させてみた.
GTPは"command arg\n\n"の形式で文字列として送られてくるので,strstr関数を使ってcommandを見つけ,返答を用意する.返答は文字列で"= response\n\n"(OKの場合) または"?\n\n"(未対応やエラーの場合)を返す."\n\n"が送られるまでが一つの返答とみなされる.プログラムは9路のみ受け付けて,打つ手はほとんどランダムにする.

ログインまで.対応できるGTPコマンドやプログラム名を聞かれる.

対局の申し込みや受付はkgsGtp.jarがやってくれる.対局開始前になぜか9路の確認(boardsize 9)が何度も送られてきた.

対局中.GTPでは手の位置を"c5"のような形式であらわすので,座標に変換する.
これで,KGSに接続して対局するまでの一連の動作を試すことが出来た.ちょっとでも予定外のことが起きたら対処できないので危険だが・・・

今回のソース

if(strstr(msg_recv,"list_commands") != NULL)
	{
	     strcpy_s(msg_send,256,"= name\nversion\nclear_board\nquit\nboardsize\nkomi\nplay\ngenmove\n\n");
	}
	else if(strstr(msg_recv,"name") != NULL)
	{
		strcpy_s(msg_send,256,"= testbot\n\n");
	}
	else if(strstr(msg_recv,"version") != NULL)
	{
		strcpy_s(msg_send,256,"= 1.0\n\n");
	}
	else if(strstr(msg_recv,"clear_board") != NULL)
	{
		engine_monte.board_initialize();
		strcpy_s(msg_send,256,"=\n\n");
	}
	else if(strstr(msg_recv,"quit") != NULL)
	{
		strcpy_s(msg_send,256,"=\n\n");
		flag_communicate = false;
	}
	else if(strstr(msg_recv,"boardsize") != NULL)
	{
		sscanf(msg_recv,"%s %d",arg_command,&arg_int);
		if(arg_int == 9)
	        {
			strcpy_s(msg_send,256,"=\n\n");
		}
		else
		{
			strcpy_s(msg_send,256,"?\n\n");
		}
	}
	else if(strstr(msg_recv,"komi") != NULL)
	{
		sscanf(msg_recv,"%s %f",arg_command,&arg_float);
		engine_monte.komi = arg_float;
		strcpy_s(msg_send,256,"=\n\n");
	}
	else if(strstr(msg_recv,"play") != NULL)
	{
		int vert_x,vert_y;
		sscanf(msg_recv,"%s %s %s",arg_command,arg_color,&arg_vertex);
		//相手の着手
		if(strstr(arg_vertex,"resign"))
		{
			flag_communicate = false;
		}
		else if(strstr(arg_vertex,"pass"))
		{
			engine_monte.move_or_pass(false,0,0);
		}
		else
		{
		move_CompfromGtp(arg_vertex,&vert_x,&vert_y);
		engine_monte.move_or_pass(true,vert_x,vert_y);
	    }
		strcpy_s(msg_send,256,"=\n\n");
	}
	else if(strstr(msg_recv,"genmove") != NULL)
	{
		char arg_compmove[8];
		sscanf(msg_recv,"%s %s",arg_command,arg_color);
		//着手生成
		engine_monte.comp_move();
		move_GtpfromComp(engine_monte.xlastmove,engine_monte.ylastmove,arg_compmove);
		strcpy_s(msg_send,256,"= ");
		strcat_s(msg_send,256,arg_compmove);
		strcat_s(msg_send,256,"\n\n");
	}
	else
	{
		strcpy_s(msg_send,256,"?\n\n");
	}

	send(sock_kgsGtp,msg_send,strlen(msg_send),0);
	fprintf(stdout,"to server:%s\n",msg_send);