トップページ > 過去ログ > 記事閲覧
オセロゲームの作成で・・・
名前:NEFT 日時: 2008/09/17 01:07

C++の入門書を初歩的な部分だけ読み進め、手始めにDXライブラリでオセロゲームの作成に挑戦しているものです。 (オセロゲームに下のは私に絵画の才能が無かったこと、シューティングやRPGルールより馴染みがあった事に起因します。。) ところがコマをひっくり返すプログラム云々を考える前に、自分のコマを置く段階で不具合が生じてしまいました。 予期しないマスにコマが表示されたり、右下のマスをクリックすると盤面が消えてしまったり・・・ C++の本やネット上の資料は一通り調べたのですが、原因・解決策が見当たりません。お教え願えますでしょうか また、初めてのC++で不慣れなため、間違った箇所や効率の悪い書き方をしているかと思いますので、そういった点もご指摘いただけると嬉しいです。 以下、プログラムの中身です #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; SetMouseDispFlag(true ); SetDrawScreen( DX_SCREEN_BACK ) ; if( DxLib_Init() == -1 ) return -1; int white=GetColor(255,255,255); int cel[7][7]={{0}},MouseX,MouseY; int handx,handy; cel[3][3]=2;cel[4][4]=2;cel[3][4]=1;cel[4][3]=1; //初期配置 while(1) { ClearDrawScreen(); handx=100,handy=100; for(int xy=40;xy<=440;xy=xy+50) //盤の絵画開始 { DrawLine(40,xy,440,xy,white); DrawLine(xy,40,xy,440,white); } for(int cnx=0;cnx<=7;cnx++) { for(int cny=0;cny<=7;cny++) { if(cel[cnx][cny]==1) DrawCircle(65+cnx*50,65+cny*50,18,white,false); else if(cel[cnx][cny]==2) DrawCircle(65+cnx*50,65+cny*50,18,white,true); } } if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) //マウスのクリック判定 { GetMousePoint( &MouseX , &MouseY ) ; } if(MouseX>=40&&MouseX<440&&MouseY>=40&&MouseY<440&&( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0) //クリックを離した時 { handx=MouseX-40; handx/=50; handy=MouseY-40; handy/=50; cel[handx][handy]=1; } DrawFormatString( 0, 0, white , "x=%d" , MouseX ); //マウスの座標 DrawFormatString( 0, 15, white , "y=%d" , MouseY ); DrawFormatString( 0, 30, white , "clickx=%d" , handx ); DrawFormatString( 0, 45, white , "clicky=%d" , handy ); ScreenFlip(); Sleep(61); if( ProcessMessage() == -1 ) break ; } WaitKey() ; DxLib_End() ; return 0 ; }

Page: 1 |

Re: オセロゲームの作成で・・・ ( No.1 )
名前:maki 日時:2008/09/17 12:43

・とりあえずSetDrawScreenはDxLib_Initの後に移動させましょう。 裏画面が有効になってないので画面がかなりちらつきます。。 ・画面のマスは8×8になっていますが、 上記コードだとint cel[7][7]で7×7マス分しか領域が確保されてません。 これだと右端と下端のマスをクリックした場合にアクセス違反になります。 int cel[8][8]にしましょう。
Re: オセロゲームの作成で・・・ ( No.2 )
名前:夢夢 日時:2008/09/17 13:51

makiさんの指摘された箇所を修正すればエラーは起きなくなるでしょう。 オセロのプログラミングをわかりやすく解説しているサイトがありますので、参考にどうぞ。(既にご存知でしたらすみません) ttp://www.geocities.co.jp/SiliconValley-Bay/4543/Osero/
Re: オセロゲームの作成で・・・ ( No.3 )
名前:NEFT 日時:2008/09/19 18:27

レス遅れてごめんなさい。週数回のペースでしかできないので・・・ >makiさん ありがとうございます! 通し番号が0〜7なので間違えてしまっていました。上記2ヵ所を訂正したらエラー起こらなくなりました。 >夢夢さん ありがとうございます。 システムはできるだけ自力で考えようとしてたのですが、教えて頂いたサイトがわかりやすいのでついカンニングしてしまいそうです(笑)
Re: オセロゲームの作成で・・・ ( No.4 )
名前:NEFT 日時:2008/09/26 13:59

度々の質問で申し訳ありませんが・・・ 上記の方のアドバイスのおかげでエラーも起こらなくなり、続きを作っていたところ、コマを反転させる際にまたしても予期しない動きをするようになってしまいました。 盤の端近辺をクリックしたときなので、また配列関係のミスだろうと予想はついているのですが、自力では何度目を通してもわからず・・・ご教授頂けると幸いです。 相手がコマを置く場所は、単純に一番多く反転できる場所を選ぶようにしてみました。出来るだけ単純な構造にしようとしているのですが、まだムダだらけな気がします・・・T_T #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; SetMouseDispFlag(true ); if( DxLib_Init() == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ) ; int white=GetColor(255,255,255); int cel[8][8]={{0}},tc[8][8]={{0}},MouseX,MouseY,bl,wh; int handx,handy,changex,changey,ps,ws,turnc=0,tmax,tmx,tmy; cel[3][3]=2;cel[4][4]=2;cel[3][4]=1;cel[4][3]=1; //初期配置 while(1) { ClearDrawScreen(); handx=100,handy=100; for(int xy=40;xy<=440;xy=xy+50) //盤の絵画開始 { DrawLine(40,xy,440,xy,white); DrawLine(xy,40,xy,440,white); } for(int cnx=0;cnx<=7;cnx++) { for(int cny=0;cny<=7;cny++) { if(cel[cnx][cny]==1) DrawCircle(65+cnx*50,65+cny*50,18,white,false); else if(cel[cnx][cny]==2) DrawCircle(65+cnx*50,65+cny*50,18,white,true); } } DrawBox(460,160,550,190,white,false); //盤の絵画終了 DrawString( 465 , 168 , " パ ス" , white ); //パスボタン、後で作る bl=0; //個数を数える wh=0; for(int i=0;i<=7;i++){ for(int j=0;j<=7;j++){ if(cel[i][j]==1) bl++; if(cel[i][j]==2) wh++;}} DrawFormatString( 460, 100, white , "黒=%d" , bl ); DrawFormatString( 460, 115, white , "白=%d" , wh ); if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) //マウスのクリック判定 { GetMousePoint( &MouseX , &MouseY ) ; } if(MouseX>=40&&MouseX<440&&MouseY>=40&&MouseY<440&&( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0) //クリックを離した時 { //反転できる数のカウントリセット turnc=0; //座標をセルNo.に変換 handx=MouseX-40; handx/=50; handy=MouseY-40; handy/=50; if(cel[handx][handy]==0) //セルが空白の時 { ws=2; ps=1; changex=handx; changey=handy; while(cel[1+changex][changey]==ws) //反転可能数のチェック { changex++; } if(cel[1+changex][changey]==ps&&changex!=handx) //終点が黒ならカウント { turnc+=changex-handx; for(int i=1;i<=changex-handx;i++) cel[i+handx][handy]=3; } changex=handx; changey=handy; while(cel[1+changex][1+changey]==ws) { changex++; changey++; } if(cel[1+changex][1+changey]==ps&&changex!=handx) { turnc+=changex-handx; for(int i=1;i<=changex-handx;i++) cel[i+handx][i+handy]=3; } changex=handx; changey=handy; while(cel[changex][1+changey]==ws) { changey++; } if(cel[changex][1+changey]==ps&&changey!=handy) { turnc+=changey-handy; for(int i=1;i<=changey-handy;i++) cel[handx][i+handy]=3; } changex=handx; changey=handy; while(cel[-1+changex][1+changey]==ws) { changex--; changey++; } if(cel[-1+changex][1+changey]==ps&&changex!=handx) { turnc+=changey-handy; for(int i=1;i<=changey-handy;i++) cel[-i+handx][i+handy]=3; } changex=handx; changey=handy; while(cel[-1+changex][changey]==ws) { changex--; } if(cel[-1+changex][changey]==ps&&changex!=handx) { turnc+=handx-changex; for(int i=1;i<=handx-changex;i++) cel[-i+handx][handy]=3; } changex=handx; changey=handy; while(cel[-1+changex][-1+changey]==ws) { changex--; changey--; } if(cel[-1+changex][-1+changey]==ps&&changex!=handx) { turnc+=handx-changex; for(int i=1;i<=handx-changex;i++) cel[-i+handx][-i+handy]=3; } changex=handx; changey=handy; while(cel[changex][-1+changey]==ws) { changey--; } if(cel[changex][-1+changey]==ps&&changey!=handy) { turnc+=handy-changey; for(int i=1;i<=handy-changey;i++) cel[handx][-i+handy]=3; } changex=handx; changey=handy; while(cel[1+changex][-1+changey]==ws) { changex++; changey--; } if(cel[1+changex][-1+changey]==ps&&changex!=handx) { turnc+=changex-handx; for(int i=1;i<=changex-handx;i++) cel[i+handx][-i+handy]=3; } if(turnc!=0) //プレイヤー、turncが1以上なら置く { cel[handx][handy]=ps; for(int j=0;j<=7;j++) { for(int k=0;k<=7;k++) if(cel[j][k]==3) cel[j][k]=ps; } ClearDrawScreen(); for(int xy=40;xy<=440;xy=xy+50) //盤の絵画開始 { DrawLine(40,xy,440,xy,white); DrawLine(xy,40,xy,440,white); } for(int cnx=0;cnx<=7;cnx++) { for(int cny=0;cny<=7;cny++) { if(cel[cnx][cny]==1) DrawCircle(65+cnx*50,65+cny*50,18,white,false); else if(cel[cnx][cny]==2) DrawCircle(65+cnx*50,65+cny*50,18,white,true); } } ScreenFlip(); //盤の絵画終了 //相手の手探索開始 ps=2; ws=1; tmax=0; for(int jx=0;jx<=7;jx++){ for(int jy=0;jy<=7;jy++){ changex=jx; changey=jy; while(cel[1+changex][changey]==ws) //反転可能数のチェック { changex++; } if(cel[1+changex][changey]==ps&&changex!=jx) //終点が白ならカウント tc[jx][jy]+=changex-jx; changex=jx; changey=jy; while(cel[1+changex][1+changey]==ws) { changex++; changey++; } if(cel[1+changex][1+changey]==ps&&changex!=jx) tc[jx][jy]+=changex-jx; changex=jx; changey=jy; while(cel[changex][1+changey]==ws) { changey++; } if(cel[changex][1+changey]==ps&&changey!=jy) tc[jx][jy]+=changey-jy; changex=jx; changey=jy; while(cel[-1+changex][1+changey]==ws) { changex--; changey++; } if(cel[-1+changex][1+changey]==ps&&changex!=jx) tc[jx][jy]+=changey-jy; changex=jx; changey=jy; while(cel[-1+changex][changey]==ws) { changex--; } if(cel[-1+changex][changey]==ps&&changex!=jx) tc[jx][jy]+=jx-changex; changex=jx; changey=jy; while(cel[-1+changex][-1+changey]==ws) { changex--; changey--; } if(cel[-1+changex][-1+changey]==ps&&changex!=jx) tc[jx][jy]+=jx-changex; changex=jx; changey=jy; while(cel[changex][-1+changey]==ws) { changey--; } if(cel[changex][-1+changey]==ps&&changey!=jy) tc[jx][jy]+=jy-changey; changex=jx; changey=jy; while(cel[1+changex][-1+changey]==ws) { changex++; changey--; } if(cel[1+changex][-1+changey]==ps&&changex!=jx) tc[jx][jy]+=changex-jx; if(tc[jx][jy]>tmax&&cel[jx][jy]==0){ //tcの最大値と座標を代入 tmax=tc[jx][jy]; tmx=jx; tmy=jy; } tc[jx][jy]=0; }} //相手の手探索終了 if(tmax!=0) //turnが1以上なら置く { cel[tmx][tmy]=ps; Sleep(1000); ClearDrawScreen(); for(int xy=40;xy<=440;xy=xy+50) //盤の絵画開始 { DrawLine(40,xy,440,xy,white); DrawLine(xy,40,xy,440,white); } for(int cnx=0;cnx<=7;cnx++) { for(int cny=0;cny<=7;cny++) { if(cel[cnx][cny]==1) DrawCircle(65+cnx*50,65+cny*50,18,white,false); else if(cel[cnx][cny]==2) DrawCircle(65+cnx*50,65+cny*50,18,white,true); } } ScreenFlip(); Sleep(1000); changex=tmx; changey=tmy; while(cel[1+changex][changey]==ws) { changex++; } if(cel[1+changex][changey]==ps&&changex!=tmx) { for(int i=1;i<=changex-tmx;i++) cel[i+tmx][tmy]=3; } changex=tmx; changey=tmy; while(cel[1+changex][1+changey]==ws) { changex++; changey++; } if(cel[1+changex][1+changey]==ps&&changex!=tmx) { for(int i=1;i<=changex-tmx;i++) cel[i+tmx][i+tmy]=3; } changex=tmx; changey=tmy; while(cel[changex][1+changey]==ws) { changey++; } if(cel[changex][1+changey]==ps&&changey!=tmy) { for(int i=1;i<=changey-tmy;i++) cel[tmx][i+tmy]=3; } changex=tmx; changey=tmy; while(cel[-1+changex][1+changey]==ws) { changex--; changey++; } if(cel[-1+changex][1+changey]==ps&&changex!=tmx) { for(int i=1;i<=changey-tmy;i++) cel[-i+tmx][i+tmy]=3; } changex=tmx; changey=tmy; while(cel[-1+changex][changey]==ws) { changex--; } if(cel[-1+changex][changey]==ps&&changex!=tmx) { for(int i=1;i<=tmx-changex;i++) cel[-i+tmx][tmy]=3; } changex=tmx; changey=tmy; while(cel[-1+changex][-1+changey]==ws) { changex--; changey--; } if(cel[-1+changex][-1+changey]==ps&&changex!=tmx) { for(int i=1;i<=tmx-changex;i++) cel[-i+tmx][-i+tmy]=3; } changex=tmx; changey=tmy; while(cel[changex][-1+changey]==ws) { changey--; } if(cel[changex][-1+changey]==ps&&changey!=tmy) { for(int i=1;i<=tmy-changey;i++) cel[tmx][-i+tmy]=3; } changex=tmx; changey=tmy; while(cel[1+changex][-1+changey]==ws) { changex++; changey--; } if(cel[1+changex][-1+changey]==ps&&changex!=tmx) { for(int i=1;i<=changex-tmx;i++) cel[i+tmx][-i+tmy]=3; } for(int j=0;j<=7;j++) { for(int k=0;k<=7;k++) if(cel[j][k]==3) cel[j][k]=ps; } } else { handx=100; handy=100; for(int j=0;j<=7;j++) { for(int k=0;k<=7;k++) if(cel[j][k]==3) cel[j][k]=0; } } //相手の手終了 } else { handx=100; handy=100; for(int j=0;j<=7;j++) { for(int k=0;k<=7;k++) if(cel[j][k]==3) cel[j][k]=0; } } } } DrawFormatString( 550, 0, white , "x=%d" , MouseX ); //マウスの座標 DrawFormatString( 550, 15, white , "y=%d" , MouseY ); DrawFormatString( 550, 30, white , "handx=%d" , handx ); DrawFormatString( 550, 45, white , "handy=%d" , handy ); DrawFormatString( 550, 60, white , "turnc=%d" , turnc ); ScreenFlip(); Sleep(60); if( ProcessMessage() == -1 ) break ; } WaitKey() ; DxLib_End() ; return 0 ; }
Re: オセロゲームの作成で・・・ ( No.5 )
名前:夢夢 日時:2008/09/27 02:41

盤の一番外側(0,0や7,7)に置いたときに、それより外側のセルを検索したりしていませんか? 決まって外側で起きているので、恐らくそこかと思います。 NEFTさんが察しているように配列の外にアクセスしてしまっているのが原因だと思いますよ。

Page: 1 |