ページ 11

オセロ

Posted: 2009年1月05日(月) 09:38
by ざこ
前にオセロについてご質問させていただきましたが
現在ではリバース可能な場所にのみ置けるように以下のように設定しています。
BOOL COseroView::CanDropDown( int x, int y, int vect_x, int vect_y )
{
    int put_stone;

    if( m_FlagForWhite )put_stone = WHITE_STONE;
    else put_stone = BLACK_STONE;

    x += vect_x;
    y += vect_y;
    if( x < 0 || x >= MASU_NUM || y < 0 || y >= MASU_NUM )return( FALSE );
    if( m_Board[x][y] == put_stone )return( FALSE );
    if( m_Board[x][y] == BLANK )return( FALSE );

    x += vect_x;
    y += vect_y;
    while( x >= 0 && x < MASU_NUM  &&  y >= 0 && y < MASU_NUM  )
    {
        if( m_Board[x][y] == BLANK )return( FALSE );
        if( m_Board[x][y] == put_stone )return( TRUE );
        x += vect_x;
        y += vect_y;
    }
    return( FALSE );
}

BOOL COseroView::CanDropDown( int x, int y )
{
    if( x >= MASU_NUM || y >= MASU_NUM )return( FALSE );
    if( m_Board[x][y] != BLANK )return( FALSE );

    if( CanDropDown( x, y,  1,  0 ) )return( TRUE );    //右
    if( CanDropDown( x, y,  0,  1 ) )return( TRUE );    //下
    if( CanDropDown( x, y, -1,  0 ) )return( TRUE );    //左
    if( CanDropDown( x, y,  0, -1 ) )return( TRUE );    //上
    if( CanDropDown( x, y,  1,  1 ) )return( TRUE );    //右下
    if( CanDropDown( x, y, -1, -1 ) )return( TRUE );    //左上
    if( CanDropDown( x, y,  1, -1 ) )return( TRUE );    //右上
    if( CanDropDown( x, y, -1,  1 ) )return( TRUE );    //左下

        return( FALSE );
}
これにリバースできる場所がない場合判定をしてゲームを終了したいのですが
どうすればいいのかわかりません。

Re:オセロ

Posted: 2009年1月05日(月) 10:17
by バグ
前箇所検索して、全部FALSEが返ってきたら、置ける場所が無いという事ですね。
一箇所でもTRUEが返った場合は、どこかに置ける場所があるという事です。

Re:オセロ

Posted: 2009年1月05日(月) 10:25
by ざこ
仰ることはわかるのですが・・
試しに
void Nothing()
{
  int x,y,no;
  for(x=0;x<MASU_NUM;x++){
    for(y=0;y<MASU_NUM;y++){
      if(CanDropDown(x,y)==FALSE
        no++;
    }
  }

  if(no==64){
  //ゲーム終了の処理
  }
}
という関数いれてみたのですが何の変化もありません。。
これは全マス調べて置ける所が無い場合ゲーム終了としているつもりなのですが。
マスを調べFALSEだった場合noを+1し全マス調べる。noが64個あった場合置ける所がない?ということですので
こうなってます。

Re:オセロ

Posted: 2009年1月05日(月) 10:30
by Mist
noを初期化してないからでしょ。

Re:オセロ

Posted: 2009年1月05日(月) 10:39
by Mist
こういう場合、関数が終了したときにnoがどんな値になっているかを調べるとか、CanDropDownがFALSEをきちんと返しているかどうかを確認すればすぐにわかることですよ。
デバッグですばやくバグを見つけられる力を上げていかないといいプログラマーにはなれません。

Re:オセロ

Posted: 2009年1月05日(月) 10:45
by ざこ
なんかそんな感じでした。きちんとできたと思います。ありがとうございました。

Re:オセロ

Posted: 2009年1月05日(月) 10:50
by バグ
私がやるならば、こんな感じかな?
// 置ける箇所がある場合はFALSEを、無い場合はTRUEを返す
BOOL Nothing()
{
	for(INT x = 0; x < MASU_NUM; x++)
	{
		for(INT y = 0; y < MASU_NUM; y++)
		{
			// TRUEが返ってきた場合は置ける箇所があるので、FALSEを返す
			if (CanDropDown(x, y) == TRUE)
			{
				return FALSE;
			}
		}
	}

	// 全箇所検査して、一度もTRUEが返ってこなかったので、置ける箇所は無かったと判断して、TRUEを返す
	return TRUE;
}