ページ 11

80行目が二つ。。。?

Posted: 2015年7月23日(木) 15:09
by kiruru
こちらを参考にしてC++番にしてみたものです。
がしかし。。。実際に動かしてみると80行目が二つ出てくることがあるんです。
どうしましょう・・・

以下にソースを示します。(適当にメモ帳にり貼り付けて試してみてください。)

osero.h

コード:

#include <iostream>
using namespace std ;
#define BOARD 8
#define NONE 0
#define BLACK 1
#define WHITE 2

class osero {

	private :

		char board [BOARD] [BOARD] ;
		
	public :

		void setboard () ;

		void disp () ;

		int checkFlip( int y, int x, int turn, int vec ) ;

		int check ( int y, int x, int turn ) ;

		void input ( int turn ) ;

		void Flip ( int y, int x, int turn, int vec ) ;

		int put ( int y, int x, int turn ) ;

		int checkEnd (int turn) ;

		void checkWinner () ;
		
} ;

osero.cpp
[code = Cpp]
#include <iostream>
using namespace std ;
#include "osero.h"

void osero :: setboard ()

{

int i ;

for (i = 0 ; i < BOARD*BOARD ; i ++)

{

board [i / BOARD][i % BOARD] = NONE ;

}

board [3] [4] = BLACK ;
board [4] [3] = BLACK ;

board [3] [3] = WHITE ;
board [4] [4] = WHITE ;


}


void osero :: disp ()

{

int i, j ;

cout << " " ;

for ( i = 0 ; i < BOARD ; i++)

{

cout << i + 1 << " " ;

}

cout << "\n" ;

for ( i = 0 ; i < BOARD ; i++)

{

cout << (i + 1) * 10 ;

for (j = 0 ; j < BOARD ; j ++)

{

switch (board [j])

{

case NONE :

cout << "□" ;

break ;

case WHITE :

cout << "●" ;

break ;

case BLACK :

cout << "○" ;

break ;

default :

cout << "エラーなの。\n" ;

break ;
}

}
cout << "\n" ;

}

}

int osero :: checkFlip ( int y, int x, int turn, int vec )

{

int vec_y [] = { -1, -1, 0, 1, 1, 1, 0, -1 } ;
int vec_x [] = { 0, 1, 1, 1, 0, -1, -1, -1 } ;

int flag = 0 ;

while (1)

{

y += vec_y [vec] ;

x += vec_x [vec] ;

if ( x < 0 || y < 0 || x > BOARD - 1 || y > BOARD - 1 )

{

return 0 ;

}

if ( board [y][x] == NONE )

{

return 0 ;

}

if (board [y][x] == (turn ? WHITE : BLACK) )

{

flag = 1 ;

continue ;

}

if ( flag == 1 )

{

break ;

}

return 0 ;

}

return 1 ;

}

int osero :: check ( int y, int x, int turn )

{

int vec ;

for ( vec = 0 ; vec < 8 ; ++ vec )

{

if ( checkFlip (y, x, turn, vec) == 1 )

{

return 1 ;

}

}

return 0 ;

}

void osero :: input ( int turn )

{

int place = 0 ;

int x, y ;

while (1)

{

cout << "縦+横の合計値を半角で入力:" ;

cin >> place ;

if (place == 0)

{

cout << "エラーなの。半角で入力してなの。\n" ;

place = 0 ;

continue ;

}

if (place < 11 || place > 88)

{

cout << "エラーなの。\n" ;

place = 0 ;

continue ;

}

y = place / 10 ;
x = place % 10 ;

if ( x < 1 || y < 1 || x > 8 || y > 8)

{

cout << "エラーなの。\n" ;

place = 0 ;

continue ;

}

if ( put ( y - 1 , x - 1, turn ) == 1 )

{

break ;

}

else

{

cout << "そこは置けないの。\n" ;


}

place = 0 ;

}

}

void osero :: Flip ( int y, int x, int turn, int vec )

{

int vec_y [] = { -1, -1, 0, 1, 1, 1, 0, -1 } ;
int vec_x [] = { 0, 1, 1, 1, 0, -1, -1, -1 } ;

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 osero :: put ( int y, int x, int turn )

{

int vec ;

int flag = 0 ;

if ( board [y][x] != NONE )

{

return 0 ;

}

for ( vec = 0 ; vec < BOARD ; vec++)

{

if ( checkFlip ( 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 ;

}

int osero :: checkEnd ( int turn )

{

int i, j ;

for ( i = 0 ; i < BOARD ; i ++)

{

for ( j = 0 ; j < BOARD ; j ++)

{

if ( board [j] == NONE && check ( i, j, turn ) == 1 )

{

return 0 ;

}

}

}

turn = ( ( turn + 1 ) % 2 ) ;

for ( i = 0 ; i < BOARD ; i ++ )

{

for ( j = 0 ; j < BOARD ; j ++)

{

if ( board [j] == NONE && check ( i, j, turn ) == 1 )

{

return 0 ;

}

}

}

return 2 ;

}

void osero :: checkWinner ()

{

int i, j ;

int b = 0 ;
int w = 0 ;

for ( i = 0 ; i < BOARD ; i ++)

{

for ( j = 0 ; j < BOARD ; j ++ )

{

switch ( board [j])

{

case BLACK :

++b ;

break ;

case WHITE :

++ w ;

break ;

default :

break ;

}

}

}

disp () ;

if ( b > w )

{

cout << "黒が勝ったの。\n" ;

}

else if ( w > b )

{

cout << "白が勝ったの。\n" ;

}

else

{

cout << "引き分けなの。\n" ;

}

}
[/code]

TestOsero.cpp
[code = Cpp]
#include "osero.h"
#include <iostream>
using namespace std ;

int main()
{

osero ob ;

int turn = 0 ;

ob.setboard () ;

while ( turn < 2 )

{

if ( turn == 0 )

{

cout << "白の番なの。\n" ;

}

else

{

cout << "黒の番なの。\n" ;

}

ob.disp () ;

ob.input ( turn ) ;

turn = ( turn + 1 ) % 2 ;

switch ( ob.checkEnd ( turn ) )

{

case 1 :

cout << "パスなの。\n" ;

turn = ( turn + 1 ) % 2 ;

break ;

case 2 :

cout << "ゲームは終わりなの。\n" ;

turn = 2 ;

break ;

default :

break ;

}

}

ob.checkWinner () ;

return 0 ;

}
[/code]

Re: 80行目が二つ。。。?

Posted: 2015年7月23日(木) 17:16
by みけCAT
kiruru さんが書きました:実際に動かしてみると80行目が二つ出てくることがあるんです。
どうしましょう・・・
適当に実行してみましたが、再現できない(具体的にどういう現象かよくわからない)し、コンパイラの警告も出ませんでした。
この現象が発生する具体的な入力を教えていただけますか?
kiruru さんが書きました:適当にメモ帳にり貼り付けて試してみてください。
無駄に特定のテキストエディタを使用させるのは、宗教戦争の原因になる可能性があり、よくないかもしれません。

Re: 80行目が二つ。。。?

Posted: 2015年7月23日(木) 21:35
by kiruru
[quote=みけCAT]この現象が発生する具体的な入力を教えていただけますか?[/quote]

この場合にこうなる!っていうのが未だ発見できていない状態なのです・・・

1 2 3 4 5 6 7 8
10 □ □ □ □ □ □ □ □
20 □ □ □ □ □ □ □ □
30 □ □ □ □ □ □ □ □
40 □ □ □ □ □ □ □ □
50 □ □ □ □ □ □ □ □
80 □ □ □ □ □ □ □ □
60 □ □ □ □ □ □ □ □
70 □ □ □ □ □ □ □ □
80 □ □ □ □ □ □ □ □

一例としてはこんな感じです

あと規則性てしては、必ず50行目と60行目に現れます。

[quote=みけCAT]宗教戦争の原因になる可能性があり、よくないかもしれません。[/quote]

すみません。 知りませんでした。

Re: 80行目が二つ。。。?

Posted: 2015年7月23日(木) 22:29
by box
kiruru さんが書きました: この場合にこうなる!っていうのが未だ発見できていない状態なのです・・・
1 2 3 4 5 6 7 8
10 □ □ □ □ □ □ □ □
20 □ □ □ □ □ □ □ □
30 □ □ □ □ □ □ □ □
40 □ □ □ □ □ □ □ □
50 □ □ □ □ □ □ □ □
80 □ □ □ □ □ □ □ □
60 □ □ □ □ □ □ □ □
70 □ □ □ □ □ □ □ □
80 □ □ □ □ □ □ □ □

一例としてはこんな感じです
オセロ(othelloです。oseroではなくて)の盤面が上記のようになることは絶対にないはずです。
少なくとも、初期状態において、黒2個、白2個が置いてある状態のはずです。
現在陥っている状況を、もっと正確に書いてください。