ページ 1 / 1
五目並べを作っているんですが…
Posted: 2010年8月14日(土) 11:44
by 南瓜
いつもお世話になっています。 南瓜です。
まず最初に、前回のポーカーで一応?完成したのに
ちゃんとしたお礼を言ってなかったと思うので…
ポーカーのプログラムでアドバイスを下さった皆さんありがとうございますm(_ _)m
で、今回は五目並べを作っているのですが
勝敗を決める所がうまく出来ずにいます
どちらかが一手を入力すると勝敗がついてしまいます
原因は
if(r != 0) {
break;
}
とint judge (void) {以降の所がうまく処理出来ていないからだと考えているのですが
どのように改善すればいいのか判らないのでアドバイスをお願いします
いつも通りソースはテキストファイルに貼付けますが
Macは文字化けするんですが、windowsは文字化けするときしないとき
があってそうなる基準がよく判りません
これはC言語と関係ないですが、解決策が判る方お願いします
Re:五目並べを作っているんですが…
Posted: 2010年8月14日(土) 13:17
by 蓮
>>判定の件
出先で時間がないので間違えてたらすみません。
簡単にソースを作ってみました。
下記のソースでは配列のアクセスしてはいけない位置にも
アクセスしてしまうので範囲をもう少し小さくするか改良をしてください。
counterなる変数を用意して隣が白なら+1します
この変数の値が5になると一列揃ったことになります。
又、斜め等の判定は書かないでいいのでしょうか?
// 白 横のみの判定 (かなり非効率なのでもう少し改良してください。)
int judge (void) {
int i, j;
int counter = 0;
bool winFlag = false;
/*横方向チェック*/
for(i = 0; i <= BOARD; i++) {
for(j = 0; j <= BOARD; j++) {
if(board[j] == WHITE) counter++;
if(board[j+1] == WHITE) counter++;
if(board[j+2] == WHITE) counter++;
if(board[j+3] == WHITE) counter++;
if(board[j+4] == WHITE) counter++;
if(counter == 5) winFlag = true;
else{
counter = 0;
winFlag = false;
}
}
}
}
>>文字化けの件
文字コードの問題かと思います。
Windows標準のメモ帳ではShift-JISが初期なのに対して
MacではUTF-8(BOM無?)だったかと思います。
文字化けで十字架みたいなのが出てしまっていたら改行コードも違うかもしれません。
LF+RF等
アクマで意見ですので参考程度にしてください。
Re:五目並べを作っているんですが…
Posted: 2010年8月14日(土) 23:19
by 南瓜
返信ありがとうございます。
ですが、変数counterを使った書き方だと、自分の書き方が悪かったために
自分と相手両方が入力する度にカウントされてしまうのと
ボードの範囲内に押さえるのが出来なかったため
int j_maru = board[p_j-1][p_i-1];/*揃ったかどうか判定するマーク*/
for(i = 1; i <= LINE; i++) {
if(board[p_j-1][i-1] != j_maru) { r = 0; break; }
}
if(r) { return 1; }
の所を
for(i = 1; r = 1; i <= LINE; i++) {
にして5列分全部同じマークだったらreturn 1を返す
と言う風にしたいのですがr = 1;を書き足すと
gomoku.c: In function ‘judge’:
gomoku.c:232: error: syntax error before ‘;’ token
gomoku.c:232: error: syntax error before ‘)’ token
gomoku.c:233: error: break statement not within loop or switch
gomoku.c: At top level:
gomoku.c:234: error: syntax error before ‘}’ token
とエラーが出てしまいます。
breakがループ内やスイッチ文内で使われていません
とは r の初期化の書き方が悪いためにbreakが機能しないと言うことですか?
ソースの貼付けに使うテキストエディタの環境設定のHTML保存オプションを見ると
エンコーディングが 日本語(Shift JIS)となっているのですが
見る所が違うのかな?
Re:五目並べを作っているんですが…
Posted: 2010年8月14日(土) 23:31
by box
> for(i = 1; r = 1; i <= LINE; i++) {
;(セミコロン)が3個登場してはいけません。2個です。
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 10:51
by 南瓜
気づかなかったorz ありがとうございます
これで、勝敗がうまくつくと思ったんですが
やっぱり一手入力した方が勝ちに成ってしまいます
judgeの戻り値が行けないのか mainの書き方が悪いのか
それともそれ以外なのか ちょっと検討がつきません
原因が判る方アドバイスをお願いします
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 11:16
by h2so5
/*あいこ*/
for(j =1, r = -1; j <= LINE; j++) {
for(i = 1; i <= LINE; i++) {
if(board[j-1][i-1] == 0) { return 0; } //←変更箇所
}
}
が正しいのではないでしょうか。
マスに空きがまだあった場合は継続しないといけないので0を返さなくてはいけないはずです。
あと思ったんですが一々マスを全部検査するより、
プレイヤーとコンピュータが打った数を記録してマスの数と等しくなったら引き分け、
という処理のほうが簡単なのでは?
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 11:38
by 初級者
× 検討がつかない
◎ 見当がつかない
正しい日本語を使おうではありませんか。
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 12:38
by softya
今までの南瓜さんのやりとりを見ていて思ったんですが、一度ちゃんとデバッグする技法を身につけられた方が良いかと思いまして書かせてもらいます。基本的な技法としては、思ったルートを通っているかデバッグ用のprintfを埋め込みます。
例えば、
>judgeの戻り値が行けないのか mainの書き方が悪いのか
>それともそれ以外なのか ちょっと検討がつきません
と書かれていますので、どのルートを通っているか自信がないんだと思いますが、
r = judge();
if(r != 0) {
break;
}
の所を
r = judge();
if(r != 0) {
printf( "break r=%d\n,r);
break;
}
と書けば、break;で抜けたことが分かります。
あとは、judgeの中の
/*横方向チェック*/
for(i = 1, r = 1; i <= LINE; i++) {
if(board[p_j-1][i-1] != j_maru) { r = 0; break; }
}
if(r) { return 1; }
とかを
/*横方向チェック*/
for(i = 1, r = 1; i <= LINE; i++) {
if(board[p_j-1][i-1] != j_maru) { r = 0; printf("横方向break borad[%d][%d] != %d\n",p_j-1,i-1,j_maru); break; }
}
if(r) { printf("横方向return 1;\n"); return 1; }
などとすればjudgeされた条件も分かります。
闇雲にやるよりプログラムの学習になると思いますので、ぜひ試されることをお勧めします。それに、回答者もバグ原因が追求しやすくなります。
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 16:41
by 南瓜
h2so5さん> 勝敗がすぐつく原因はそこでしたorz
コンピューターの入力を改良するのと同時に少しずつ
改良して行きます
初級者さん> どうもプログラムに限らずこの手のミスが多いな…
softyaさん> printfを使ってどのように処理されているかを確認するのがデバッグなんですね
確かにこれなら何処でうまくいってる、いってないがすぐ確認できますね
これからのプログラムの学習に役立てます!
5列揃ったら勝敗がつくようになりましたが
コンピューターの入力がランダムなのを改良するのに
また詰まりそうなので解決はまだ押さないでおきます
Re:五目並べを作っているんですが…
Posted: 2010年8月15日(日) 17:04
by softya
>printfを使ってどのように処理されているかを確認するのがデバッグなんですね
これは、printfデバッグと呼ばれるデバッグのごく基本的な手法の一つです。
デバッグの技法にはデバッガでブレーク・トレースしたりデバッガだけでも色々と手法がありまして、更に高度なのはテスト専用のツールを使ったりする方法です。
大きなプログラムになってくるとワケの分からないエラーが出たりするので、そのバグの原因を見つけるための方法を考えるのもプログラマーの大事な仕事・技術になります。
まぁ、デバッグ自体は専門書籍が出るほど色々あるんですが。
http://www.oreilly.co.jp/books/9784873114064/
基本的なデバッグの方法。デバッグ入門 [VC++の使い方]
http://www.nitoyon.com/vc/tutorial/debug/
Visual Studio でのデバッグ
http://msdn.microsoft.com/ja-jp/library ... 80%29.aspx
【余談】
私の経験の最悪のデバッグ経験は、一週間かかってハードが原因だと分かった配列の内容化けバグ。最後のほうでは、Linuxのメモリー保護機能でメモリの書き換えを禁止してソフトが書き換えたらメモリ保護例外になるように設定した上でCPUが書き換えていないのにメモリ内容が書き換わったことをハード担当に証明するはめに。原因はバス・ノイズでのメモリ化けでした。
Re:五目並べを作っているんですが…
Posted: 2010年8月16日(月) 14:32
by 南瓜
デバッグの方法はいろいろあるんですね
自分はまだまだ未熟なんで、そんな恐ろしいバグに遭遇したくないですね^^;
コンピューターの入力パターンは、今の所リーチを阻止するくらいで
まだまだ弱いんですが、これを強くするのに調べた所
ミニマックス法やゲーム木などを勉強した方がいいなと思ったんですが
これらの理論はボードゲームはこれ、パズルゲームはあれみたいに決まっているのか
作りたいゲームに合わせてよって使い分けているのか、どうなんでしょうか?
五目並べというよりボードゲームでコンピューターを強くするには
どの理論を勉強した方がいいですか?
あと、関係ないんですがMacではDXライブラリが使えなかったと
思うので、類似の性能を持つものってありますか?
vectorで調べたんですが一杯ありすぎてどれを使えばいいのか
よくわかりませんでしたorz
Re:五目並べを作っているんですが…
Posted: 2010年8月16日(月) 15:04
by softya
>ミニマックス法やゲーム木などを勉強した方がいいなと思ったんですが
>これらの理論はボードゲームはこれ、パズルゲームはあれみたいに決まっているのか作りたいゲームに合わせて>よって使い分けているのか、どうなんでしょうか?
最適なものはゲームによって違うでしょうね。
ちなみに、ミニマックス法でゲーム木を使うので別のものじゃないですね。
>五目並べというよりボードゲームでコンピューターを強くするにはどの理論を勉強した方がいいですか?
色んな手法を組み合わせて作られていると思ったほうが良いです。1つの理論では、やはりクセというか弱点が出てきますので、なるべくいろんなのを組み合わせて最適な物を局面に合わせて使い分けましょう。人間も無意識に思考アルゴリズムを切り替えてますよ。
MACのライブラリは詳しくないのでごめんなさい。
ボードゲームやパズルに使えそうなサイトや本を紹介しておきます。
●サイト(C言語じゃないものも含んでいます)
ジャンル別ゲームの作り方とアルゴリズムまとめ
http://d.hatena.ne.jp/seikenn/20090627/1246028707
パズル問題解法のアルゴリズム講座
http://www.ic-net.or.jp/home/takaken/pz/index.html
地球にやさしいアルゴリズム
http://itpro.nikkeibp.co.jp/article/COL ... ST=develop
シミュレーションゲーム作成工房
http://www.jyouhoukaiseki.com/
●書籍
リバーシのアルゴリズム C++&Java対応―「探索アルゴリズム」「評価関数」の設計と実装 (I・O BOOKS)
http://www.amazon.co.jp/dp/4875934289/
ゲームのアルゴリズム 改訂版 思考ルーチンと物理シミュレーション
http://www.sbcr.jp/products/4797359251.html
Re:五目並べを作っているんですが…
Posted: 2010年8月16日(月) 19:01
by 南瓜
なるほど、複合させて使い分けて行くんですね
少しずついろんな理論を勉強していこうと思います
そうですか。ライブラリの件は、また別にスレを立てようと思います
コメント下さった皆さんありがとうございます!