オセロのパスの仕方がわかりません

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

オセロのパスの仕方がわかりません

#1

投稿記事 by sadora3 » 9年前

オセロで詰んだときのターンのスキップのさせ方が分かりません。
どうすればいいのでしょうか?
OS:Windows7
コンパイラ:Visual Studio 2010
ライブラリ:DXライブラリ
言語:C
C++はできないです。Cは一通り勉強済みです。

今ソースコードはこんな感じになっています。

コード:

#include"DxLib.h"

#define WALL -1
#define BAN 0
#define SIRO 1
#define KURO 2
#define FLASH_SIRO 3
#define FLASH_KURO 4
#define FLASH_MIX 7

int masuX;
int masuY;
int VecX[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int VecY[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int turn = 1;

int BanData[10][10] = {
	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,0,0,0,1,2,0,0,0,-1},
	{-1,0,0,0,2,1,0,0,0,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,0,0,0,0,0,0,0,0,-1},
	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
};

void DrawBoard();
void MouseOperation();
int CeackLine(int, int, int, int, int, int);
void PutFlash();
int PutLine(int, int, int, int, int, int);
void AllWayStonePut(int, int);
void FlashClear();

int ProcessLoop(){
	if(ProcessMessage() != 0){	return -1;	}
	if(ClearDrawScreen() != 0){	return -1;	}
	return 0;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE);
	SetGraphMode(640,640,16);
	if(DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0){	return -1;	}
	while(ProcessLoop() == 0){
		DrawBoard();
		MouseOperation();
		PutFlash();
		ScreenFlip();
	}
	DxLib_End();
	return 0;
}

void DrawBoard(){
	DrawBox(0, 0, 640, 640, GetColor(255,200,140), TRUE);
	for(int x = 1; x < 9; x++){
		for(int y = 1; y < 9; y++){
			switch(BanData[y][x]){
			case BAN:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && (masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				break;
			case SIRO:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && (masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				DrawCircle(x * 64 + 32, y * 64 + 32, 25, GetColor(255,255,255), TRUE);
				break;
			case KURO:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && ( masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				DrawCircle(x * 64 + 32, y * 64 + 32, 25, GetColor(0,0,0), TRUE);
				break;
			case FLASH_SIRO:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && ( masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				DrawCircle(x * 64 + 32, y * 64 + 32, 25, GetColor(210,210,210), TRUE);
				break;
			case FLASH_KURO:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && ( masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				DrawCircle(x * 64 + 32, y * 64 + 32, 25, GetColor(70,70,70), TRUE);
				break;
			case FLASH_MIX:
				DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(0,0,0), FALSE);
				if((masuY == y) && ( masuX == x)){
					DrawBox(x * 64, y * 64, x * 64 + 64, y * 64 + 64, GetColor(255,220,160), TRUE);
				}
				DrawCircle(x * 64 + 32, y * 64 + 32, 25, GetColor(180,0,0), TRUE);
				break;
			}
		}
	}
}

void MouseOperation(){
	int mouseX, mouseY;
	GetMousePoint(&mouseX, &mouseY);
	masuX = mouseX / 64;
	masuY = mouseY / 64;
	if((GetMouseInput() & MOUSE_INPUT_LEFT) != 0){
		if(turn % 2 == 0){	AllWayStonePut(SIRO, KURO);	}
		if(turn % 2 == 1){	AllWayStonePut(KURO, SIRO);	}
		FlashClear();
	}
}

int CheakLine( int x, int y, int Way_x, int Way_y, int Color, int EnemyColor ){
	if(BanData[y][x] == EnemyColor){
		if( BanData[y + Way_y][x + Way_x] == Color){	return 1;	}
		if( BanData[y + Way_y][x + Way_x] == EnemyColor){
			CheakLine(x + Way_x, y + Way_y, Way_x, Way_y, Color, EnemyColor);
		}
	}
	else{	return 0;	}
	return CheakLine(x + Way_x, y + Way_y, Way_x, Way_y, Color, EnemyColor);
}

void PutFlash(){
	for(int y = 1; y < 9; y++){
		for(int x = 1; x < 9; x++){
			if(BanData[y][x] == BAN || BanData[y][x] == FLASH_SIRO || BanData[y][x] == FLASH_KURO){
				for(int i = 0; i < 8; i++){
					if(CheakLine(x + VecX[i], y + VecY[i], VecX[i], VecY[i], SIRO, KURO) == 1){
						if(BanData[y][x] == FLASH_KURO){	BanData[y][x] = FLASH_MIX;	}
						else{	BanData[y][x] = FLASH_SIRO;	}
					}
					if(CheakLine(x + VecX[i], y + VecY[i], VecX[i], VecY[i], KURO, SIRO) == 1){
						if(BanData[y][x] == FLASH_SIRO){	BanData[y][x] = FLASH_MIX;	}
						else{	BanData[y][x] = FLASH_KURO;	}
					}
				}
			}
		}
	}
}

int PutLine( int x, int y, int Way_x, int Way_y, int Color, int count ){
	if( BanData[ y ][ x ] == BAN ){   return count;   }
	else if( BanData[ y ][ x ] == Color ){	return count;   }
	else if( BanData[ y ][ x ] == WALL ){	 return count;   }
	else if( BanData[ y ][ x ] != Color ){	BanData[ y ][ x ] = Color;	}
	return PutLine( x + Way_x, y + Way_y, Way_x, Way_y, Color, count + 1 );
}

void AllWayStonePut(int Color, int EnemyColor){
	int StoneCount = 0;
	if(BanData[masuY][masuX] >= 3 ){
		BanData[masuY][masuX] = Color;
		for(int i = 0; i < 8; i++){
			if(CheakLine(masuX + VecX[i], masuY + VecY[i], VecX[i], VecY[i], Color, EnemyColor) == 1){
				StoneCount += PutLine(masuX + VecX[i], masuY + VecY[i], VecX[i], VecY[i], Color, 0);
			}
		}
		if(StoneCount == 0){
			BanData[masuY][masuX] = BAN;
		}
		else{
			turn++;
		}
	}
}

void FlashClear(){
	for(int y = 1; y < 9; y++){
		for(int x = 1; x < 9; x++){
			if( BanData[y][x] == FLASH_SIRO || BanData[y][x] == FLASH_KURO || BanData[y][x] == FLASH_MIX){
				BanData[y][x] = BAN;
			}
		}
	}
}

※漢字に誤字があったので修正しました。積んだ→詰んだ

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: オセロのパスの仕方がわかりません

#2

投稿記事 by softya(ソフト屋) » 9年前

すいません時間がないので長くなりそうなものに回答できません。
質問される場合、もう少し噛み砕いて問題点を説明しないと答えが付きづらいです。
どこで、どのように問題が生じていて、このように対策してみたがうまく行かなかったなど細かく説明をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

sadora3
記事: 175
登録日時: 11年前

Re: オセロのパスの仕方がわかりません

#3

投稿記事 by sadora3 » 9年前

申し訳ありません!自己解決しましたorz
貴重なお時間を奪ってしまってすみませんでした・・・。
軽率な行動をお許しください。

それとこのような丸投げに近い質問は確かによくないですよね。
今後質問をさせていただくときは、ちゃんと噛み砕いて質問します。

アバター
lbfuvab
記事: 72
登録日時: 13年前

Re: オセロのパスの仕方がわかりません

#4

投稿記事 by lbfuvab » 9年前

コード書く前に適当にフローチャートを書いておくとよいかもしれないですね。
詳しくは添付ファイルを参照してください。
添付ファイル
flow.png
flow.png (54.47 KiB) 閲覧数: 3010 回

アバター
lbfuvab
記事: 72
登録日時: 13年前

Re: オセロのパスの仕方がわかりません

#5

投稿記事 by lbfuvab » 9年前

書き忘れた点をいくつか補足します。
・GUIなので手が打たれなかったら何もしません
・bFinishedは試合が終了しているかの変数です
・bSkippedは「直前に」パスがあったかの変数です
・この流れでは空きマスがなくなっての試合終了はパス2回を挟みます。
・↑を改良したい場合は「打てる手があるか」の判定の前に「空きマスがあるか」の判定を挟んで下さい

アバター
lbfuvab
記事: 72
登録日時: 13年前

Re: オセロのパスの仕方がわかりません

#6

投稿記事 by lbfuvab » 9年前

ミスがあったので、ついでにもう少し改良しました。
つながっていない矢印はループ終端につながっている事にしてください。
添付ファイル
flow_R.png

閉鎖

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