ゲーム木の探索で

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nokia

ゲーム木の探索で

#1

投稿記事 by nokia » 14年前

三目ならべで,現在の局面を表すPHASE型の構造体p,
着手を表す整数値move,
自分の手番を表す整数値myturnを引数として,
その着手を行った後の局面が必勝局面であるか否かを求める関数check_win
を定義しようとしているんですが,自分の内容だとどうしても構造体が
壊れているとでてしまいます. 
どう直せばよいでしょうか?
戻り値は,pが必勝局面であれば1,そうでなければ0です.

コード:

 
#include<stdio.h>
#include<stdlib.h>
#define WIDTH  3
#define HEIGHT  3

typedef struct {
	int board[HEIGHT*WIDTH];		
	int turn;
} PHASE;

int init_board(PHASE *p);
int print_board(PHASE *p);
int check_move(PHASE *p, int move);
int change_phase(PHASE *p, int move);
int check_end(PHASE *p, int move);
void find_move(PHASE *p, int moves[]);
int check_win( PHASE p, int move, int myturn );
int tree;
int num;

int main(){
	PHASE board;
	PHASE *p;
	p = &board;
	int move;
	int moves[WIDTH*HEIGHT];
    init_board(p);
    print_board(p);
	while(1){
	while(1){
	printf("置く場所を入力してください\n");
	scanf("%d",&move);
	if (check_move(p,move) == 1){
		int a = check_win(*p,move, p->turn %2 );
		printf("%d\n",a);
	    change_phase(p,move);
		break;}
	else printf("そこには置けません. もう一度\n");}
	print_board(p);
	if(check_end(p,move) == 1){
		printf("先手の勝ちです\n");
	    break;}
	if(check_end(p,move) == 2){
		printf("後手の勝ちです\n");
	    break;}
	if(check_end(p,move) == 3){
		printf("引き分けです\n");
	    break;}
	}
    getchar();
    getchar();
    return 0;}

int init_board(PHASE *p){
	p->turn = 1;
	for(int i = 0; i < HEIGHT*WIDTH; i++){
			p->board[i] = 0;}
   return 1;}

int print_board(PHASE *p){
	for(int i = 1; i  < HEIGHT*WIDTH+1; i++){
	if(i % HEIGHT == 1)
				printf("|");
		if(p->board[i-1] == 1)
			printf("●|");
			else if(p->board[i-1] == -1)
			printf("○|");
			else 
			 printf("%2d|",i);
		if(i % WIDTH == 0 && i != 0){
				printf("\n");
}
	}
	return 1;
}

int check_move(PHASE *p, int move){
	move--;
	if (p->board[move]==0 && 0 <= move < (HEIGHT*WIDTH)-1){
			return 1;}
		return 0;}

int change_phase(PHASE *p, int move){
	if(p->turn %2 == 1)
	p->board[move-1] = -1;
	else 	p->board[move-1] = 1;
	p->turn++;
	return 1;}

int check_end(PHASE *p, int move){
	for(int i = 1; i+4  < HEIGHT*WIDTH+1; i++){
		if(p->board[i-1] == 1 &&  p->board[i] == 1 && p->board[i+1] == 1)
			return 2;
		if(p->board[2] == 1 &&  p->board[4] == 1 && p->board[6] == 1)
			return 2;
		if(p->board[i-1] == 1 &&  p->board[i+2] == 1 && p->board[i+5] == 1)
			return 2;
		if(p->board[0]  == 1 &&  p->board[4]  == 1 && p->board[9]  == 1)
			return 2;
		if(p->board[i-1] == -1 &&  p->board[i] == -1 && p->board[i+1] == -1)
			return 1;
		if(p->board[2] == -1 &&  p->board[4] == -1 && p->board[6] == -1)
			return 1;
		if(p->board[i-1] == -1 &&  p->board[i+2] == -1 && p->board[i+5] == -1)
			return 1;
		if(p->board[0]  == -1 &&  p->board[4]  == -1 && p->board[9]  == -1)
			return 1;}
	if(p->turn == 10)
		return 3;
	else return 0;}

void find_move( PHASE *p, int moves[] ){
	int i,j=0;
	for( i=0; i<WIDTH*HEIGHT; i++ ){
		if( p->board[i] == 0 ){
			moves[j] = i;
			j++;}}
	num = j;
}

int check_win( PHASE p, int move, int myturn ){
	
	int i=0, count1=0,count2=0;
	int moves[WIDTH*HEIGHT];
	PHASE game_tree;
	game_tree = p;
	change_phase( &game_tree, move );


	if( check_end( &game_tree, move) == 0 ){			
		find_move( &game_tree, moves );							
		if( game_tree.turn%2 == myturn ){							
			for( i=0; i<num; i++ ){				
				if( check_win( game_tree, i, myturn) == 1 ){ return 1; }
			}
		}else{
			for( i=0; i<num; i++ ){							
				if( check_win( game_tree, i, myturn) == 0 ){ return 0; }
			}
			return 1;		
		}
	}
	else if( check_end( &game_tree, move) == myturn ){ return 1; }
	return 0;
}


 

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: ゲーム木の探索で

#2

投稿記事 by beatle » 14年前

nokia さんが書きました:自分の内容だとどうしても構造体が
壊れているとでてしまいます. 
エラーメッセージが出力されるということでしょうか.だとしたら,エラーメッセージを「すべて,そのまま」貼り付けて下さい.

non
記事: 1097
登録日時: 15年前

Re: ゲーム木の探索で

#3

投稿記事 by non » 14年前

80行目

コード:

if (p->board[move]==0 && 0 <= move < (HEIGHT*WIDTH)-1){
恐らく間違いだろう。

コード:

int check_end(PHASE *p, int move){
    for(int i = 1; i+4  < HEIGHT*WIDTH+1; i++){
        if(p->board[i-1] == 1 &&  p->board[i] == 1 && p->board[i+1] == 1)
            return 2;
        if(p->board[2] == 1 &&  p->board[4] == 1 && p->board[6] == 1)
            return 2;
        if(p->board[i-1] == 1 &&  p->board[i+2] == 1 && p->board[i+5] == 1)
            return 2;
        if(p->board[0]  == 1 &&  p->board[4]  == 1 && p->board[9]  == 1)
            return 2;
        if(p->board[i-1] == -1 &&  p->board[i] == -1 && p->board[i+1] == -1)
            return 1;
        if(p->board[2] == -1 &&  p->board[4] == -1 && p->board[6] == -1)
            return 1;
        if(p->board[i-1] == -1 &&  p->board[i+2] == -1 && p->board[i+5] == -1)
            return 1;
        if(p->board[0]  == -1 &&  p->board[4]  == -1 && p->board[9]  == -1)
            return 1;}
    if(p->turn == 10)
        return 3;
    else return 0;}
ここもおかしい。forのループの意味がわからん。
p->board[9] なんて場所は存在しないし。

他にもあるかもしれないけど、プログラムが見にくいので、一度インデントをやり直してください。
閉じ括弧 } の場所が一般的でなく、私は嫌いです。
non

閉鎖

“C言語何でも質問掲示板” へ戻る