初心者です。教えてください

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
マルコMAX
記事: 2
登録日時: 4年前

初心者です。教えてください

#1

投稿記事 by マルコMAX » 4年前

ネットで見つけたオセロゲームですが、真似したつもりでもうまくいきません。
色々試した結果、このエラーが残っています。
どなたかわかりやすく教えてください。
コンパイルエラーrandは再定義されています。異なるリンケージです。
と出ます。

コード:

#define BOARDSIZE 8
//状態を定義
#define NONE 0
#define BLACK 1
#define WHITE 2
//盤面
char board[BOARDSIZE][BOARDSIZE];
//初期化関数
void setBOARD(void)
{
	int i;/*今BOARDSIZEは 8なのでループはiが~63まで繰り返す*/
	for (i = 0; i < BOARDSIZE*BOARDSIZE; i++)
	{
		board[i / BOARDSIZE][i%BOARDSIZE] = NONE;
	}
	board[BOARDSIZE / 2 - 1][BOARDSIZE / 2] = BLACK;//[3][4]
	board[BOARDSIZE / 2][BOARDSIZE / 2 - 1] = BLACK;//[4][3]
	board[BOARDSIZE / 2][BOARDSIZE / 2] = WHITE;//[4][4]
	board[BOARDSIZE / 2 - 1][BOARDSIZE / 2 - 1] = WHITE;//[3][3]
}
#include<stdio.h> //盤面表示関数
void disp(void)
{
	int i, j;
	printf(" ");
	for (i = 0; i < BOARDSIZE; i++)
	{
		printf("%d", i + 1);
		printf("\n");
		for (i = 0; i < BOARDSIZE; i++)
		{
			printf("%d", (i + 1) * 10);
		}
		for (j = 0; j < BOARDSIZE; j++)
			switch (board[i][j])
			{
			case NONE:
				printf("□");
				break;
			case BLACK:
				printf("○");
				break;
			case WHITE:
				printf("●");
				break;
			default:
				printf("er");
				break;
			}
	}
	printf("\n");
}
int check(int y, int x, int turn)	//その場に置けるかどうかの関数
{
	int vec;	//どこか一方でもひっくり返せるかの確認
	for (vec = 0; vec < 8; vec++)
	{
		if (checkFrip(y, x, turn, vec) == 1)
			return 1;
	}
	return 0;
}
vec_y[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
vec_x[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
//vecで指定された向きについて返せる駒があるか確認する
int checkFrip(int y, int x, int turn, int vec)
{
	int flag = 0;
	while (1) {
		y += vec_y[vec];
		x += vec_x[vec];	//盤面の外に出ていたら終了
		if (x <0 || y < 0 || x > BOARDSIZE - 1 || y >BOARDSIZE - 1)
			return 0;
		//空きマスだったら終了
		if (board[x][y] == NONE)
			return 0;
		//相手の駒があったらフラグを立てる
		if (board[y][x] == (turn ? BLACK : WHITE))
		{
			flag = 1;
			continue;
		}
		//もしフラグが立っていればループ脱出いなければ終了
		if (flag == 1)
			break;
		return 0;
	}
}
//入力関数 scanf関数
void input(int turn)
{
	int place = 0, y, x;
	while (1)
	{
		//適当に決める
		place = rand() % 89;

		//数値が範囲内か確認
		if (place < 11 || place > 88)
		{
			place = 0;
			continue;

			printf("input[%d]:error\n,place");
			continue;
		}
		y = place / 10;
		x = place / 10;//もう少し詳しく確認
		
		if (x < 1 || y < 1 || x > 8 || y > 8)
		{
			printf(">%d\n", place);
			break;
		}
			place = 0;
			
	}
}
//実際に裏返す関数
void flip(int y, int x, int turn, int vec)
{
	while (1)
	{
		y += vec_y[vec];
		x += vec_x[vec];
		//自分の駒があったら終了
		if (board[y][x] == (turn ? BLACK : WHITE))
			break;
		//それ以外なら自分の駒で塗りつぶす
		board[y][x] = (turn ? BLACK : WHITE);
	}
}
//入力を受けて裏返すか確かめる関数
int put(int y, int x, int turn)
{
	int vec, flag = 0;
	//空白でなければ終了
	if (board[y][x] != NONE)
		return 0;
	//全方向について確認
	for (vec = 0; vec < 8; vec++)
	{
		if (checkFrip(y, x, turn, vec) == 1)
		{
			flip(y, x, turn, vec);
			flag = 1;
		}
	}

	if(flag == 1)
	{
		board[y][x] = ((turn ? BLACK : WHITE));
		return 1;
	}
	return 0;
}
#include<time.h>
#include<stdlib.h>
int main()
{
	int turn = 0;
	//盤面初期化
	setBOARD();
	//乱数初期化
	srand(time(NULL));
	//ゲームのメインループ
	while (turn < 2)	//どちらの手番か表示
	{
		if (turn == 0)
			printf("turn:○\n");
		else 
			printf("turn:●\n");
		//盤面表示
		disp();
		//入力
		switch (turn)
		{
		case 0:
			input (turn);
			break;
		case 1:
			ai_rand(turn);
			break;
		default:
			printf("errer\n");
			return-1;	
		}
		input (turn);
		//手番交代
		turn = (turn + 1) % 2;
		//終了判定
		switch (checkEnd(turn))
		{
		case 1:
			printf("pass\n");
			turn = (turn + 1)%2;
		case 2:
			printf("game end\n");
			turn = 2;
		default:
			break;
		}
	}checkWinner();
	return 0;
}
int checkEnd(int turn)
{
	int i,j;	
								//置ける場所があるか確認
	for (i = 0; i < BOARDSIZE; i++)
	{
		for (j = 0; j < BOARDSIZE; j++) //あればパスして続行
		if (board[i][j] == NONE && check(i, j, turn) == 1)
		{
			return 0;
		}
	}
	turn = (turn + 1) % 2;			//場所がないので交替して探す
	
	{
		if (board[i][j] == NONE && check(i, j, turn) == 1)
			return 1;
		//なかったら終了
		return 2;
	}
}
//勝者判定
/*void checkWinner()
{
	int i, j, b = 0, w = 0;
	//駒を数える
	for (i = 0; i < BOARDSIZE; i++)
	{
		for (j = 0; j < BOARDSIZE; j++)
		{
			switch (board[i][j])
			{
			case BLACK:
				++b;
				break;
			case WHITE:
				++w;
				break;
			default:
				break;
			}
		}
	}
	
	//最後に盤面表示
	disp();
	//勝者表示
	if (b > w)printf("○:winner BLACK!");
	else if (b < w)printf("●:winner WHITE!");
	else printf("Drawn game");
}

void ai_rand(int turn)
{
	int place = 0, y, x;
	while (1)
	{
		//適当に決める
		place = rand() % 89;

		//数値が範囲内か確認
		if (place < 11 || place > 88)
		{
			place = 0;
			continue;

			printf("input[%d]:error\n,place");
				continue;
		}
		y = place / 10;
		x = place / 10;//もう少し詳しく確認
		if (x < 1 || y < 1 || x > 8 || y > 8)
		{
			printf("input[%d]:error\n,place");
			place = 0;
			continue;
		}
		if (put(y - 1, x - 1, turn) == 1)
		{
			printf(">%d\n", place);
			break;
		}
		place = 0;
	}//成功以外のprintfを削除
}
*/

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 初心者です。教えてください

#2

投稿記事 by みけCAT » 4年前

Wandboxでコンパイルしたところ、以下の警告が出ました。

コード:

prog.c: In function 'check':
prog.c:58:7: warning: implicit declaration of function 'checkFrip' [-Wimplicit-function-declaration]
   58 |   if (checkFrip(y, x, turn, vec) == 1)
      |       ^~~~~~~~~
prog.c: At top level:
prog.c:63:1: warning: data definition has no type or storage class
   63 | vec_y[] = { -1, -1, 0, 1, 1, 1, 0, -1 };
      | ^~~~~
prog.c:63:1: warning: type defaults to 'int' in declaration of 'vec_y' [-Wimplicit-int]
prog.c:64:1: warning: data definition has no type or storage class
   64 | vec_x[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
      | ^~~~~
prog.c:64:1: warning: type defaults to 'int' in declaration of 'vec_x' [-Wimplicit-int]
prog.c: In function 'input':
prog.c:96:11: warning: implicit declaration of function 'rand' [-Wimplicit-function-declaration]
   96 |   place = rand() % 89;
      |           ^~~~
prog.c:104:19: warning: format '%d' expects a matching 'int' argument [-Wformat=]
  104 |    printf("input[%d]:error\n,place");
      |                  ~^
      |                   |
      |                   int
prog.c:90:16: warning: unused parameter 'turn' [-Wunused-parameter]
   90 | void input(int turn)
      |            ~~~~^~~~
prog.c: In function 'main':
prog.c:182:4: warning: implicit declaration of function 'ai_rand'; did you mean 'srand'? [-Wimplicit-function-declaration]
  182 |    ai_rand(turn);
      |    ^~~~~~~
      |    srand
prog.c:192:11: warning: implicit declaration of function 'checkEnd'; did you mean 'check'? [-Wimplicit-function-declaration]
  192 |   switch (checkEnd(turn))
      |           ^~~~~~~~
      |           check
prog.c:203:3: warning: implicit declaration of function 'checkWinner' [-Wimplicit-function-declaration]
  203 |  }checkWinner();
      |   ^~~~~~~~~~~
prog.c: In function 'checkFrip':
prog.c:88:1: warning: control reaches end of non-void function [-Wreturn-type]
   88 | }
      | ^
prog.c: In function 'main':
prog.c:196:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
  196 |    turn = (turn + 1)%2;
      |    ~~~~~^~~~~~~~~~~~~~
prog.c:197:3: note: here
  197 |   case 2:
      |   ^~~~
提示されたエラーの原因と考えられる
・rand関数の宣言(宣言を含むstdlib.hのインクルードを含む)が使っている場所の前に無い
という問題以外にも、
・checkFrip関数、ai_rand関数、checkEnd関数、checkWinner関数の宣言が使っている場所の前に無い
・変数?vec_yおよびvec_xの型が書かれていない
・printfの書式文字列に%dが含まれているのに、対応するデータが無い (未定義動作)
・checkFrip関数にreturn文を通らないパスがあり、かつその戻り値が使われる (未定義動作)
・main関数内のswitchで、書くべきbreak文を書いていない可能性がある
という問題もあるようですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

マルコMAX
記事: 2
登録日時: 4年前

Re: 初心者です。教えてください

#3

投稿記事 by マルコMAX » 4年前

早速の対応ありがとうございます。とにかく問題だらけということがわかりました。
もう少し頑張ってみます。

返信

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