C言語の入門書等読んで少しずつ学んできたのですが、
今後どういったことをしていけば上達できるのかわからず
困っています。
今回はポーカーゲームを作ってみました。ので、
そのソースから僕のレベルを判断してください。
一応、入門書片手に作りました。ただ、アルゴリズムに
ついてはすべて自分で考えたつもりです。
プログラミングにおいて目指す方向は、
・プログラミングは趣味であり仕事等では使わない
・win32API?やネットワークプログラミングに興味あり
・ゲーム等よりメモ帳等の実用的?なアプリを作りたい
これらの点も考慮して
「○○という本をやったほうがいい」とか
「△△という課題に挑戦してみては?」等の
アドバイスいただけるとありがたいです。
環境 winXP VC++2008
ソースの評価と今後へのアドバイスをお願いします
Re:ソースの評価と今後へのアドバイスをお願いします
■この else if のスタイルは気持ち悪いので、やめた方が良いかと思います。
> if(sf == 2 && ff == 1){
> puts("ロイヤルストレートフラッシュ");
> return 10;
> }else{if(sf == 1 && ff == 1){
> puts("ストレートフラッシュ");
> return 9;
> }else{if(four == 1){
> puts("4カード");
> return 8;
> }else{if(three == 1 && two ==1){
> puts("フルハウス");
> return 7;
> }else{if(ff == 1){
> puts("フラッシュ");
> return 6;
> }else{if(sf == 1 || sf == 2){
> puts("ストレート");
> return 5;
> }else{if(three == 1 && two == 0){ //上で先にフルハウスの判定をしているから別に必要ないtwo == 2は
> puts("3カード");
> return 4;
> }else{if(two == 2){
> puts("2ペア");
> return 3;
> }else{if(two == 1){
> puts("1ペア");
> return 2;
> }else{
> puts("ノーペア");
> }}}}}}}}}
直すなら、こんな感じです。
if(sf == 2 && ff == 1){
puts("ロイヤルストレートフラッシュ");
return 10;
}else if(sf == 1 && ff == 1){
puts("ストレートフラッシュ");
return 9;
}else if(four == 1){
puts("4カード");
return 8;
}else if(three == 1 && two ==1){
puts("フルハウス");
return 7;
}else if(ff == 1){
puts("フラッシュ");
return 6;
}else if(sf == 1 || sf == 2){
puts("ストレート");
return 5;
}else if(three == 1 && two == 0){ //上で先にフルハウスの判定をしているから別に必要ないtwo == 2は
puts("3カード");
return 4;
}else if(two == 2){
puts("2ペア");
return 3;
}else if(two == 1){
puts("1ペア");
return 2;
}else{
puts("ノーペア");
}
■構造体のswapは、
> buf.mark = yamafuda[saki].mark;
> buf.suu = yamafuda[saki].suu;
>
> yamafuda[saki].mark = yamafuda[moto].mark;
> yamafuda[saki].suu = yamafuda[moto].suu;
>
> yamafuda[moto].mark = buf.mark;
> yamafuda[moto].suu = buf.suu;
直すと、
buf = yamafuda[saki];
yamafuda[saki] = yamafuda[moto];
yamafuda[moto] = buf;
と言う感じに、簡潔に書けますよ。
■山札が無くなった時の処理が見当たりません。
■謎のコメント
> int tmp1 = test1.suu; /* b を基準とする */
b が何なのか不明です。
■疑問
C言語か、C++言語のどちらで書いているつもりなのか、不明ですが、
C言語では通らない構文を使われているみたいなので、C++言語なのでしょう。
C++を使うなら、またC++をさらに勉強すると、もっとC++らしい記述のしかた
があるかと思います。
■全体的に、よく書けていると思います。
■今後の課題
WIN32APIや、ライブラリのチュートリアルを進めてみるなり、
C++ や OOP(オブジェクト指向プログラミング)の勉強をしてみるなり、
ソースコードをたくさん読んで、たくさん書くと良いかと思います。
> if(sf == 2 && ff == 1){
> puts("ロイヤルストレートフラッシュ");
> return 10;
> }else{if(sf == 1 && ff == 1){
> puts("ストレートフラッシュ");
> return 9;
> }else{if(four == 1){
> puts("4カード");
> return 8;
> }else{if(three == 1 && two ==1){
> puts("フルハウス");
> return 7;
> }else{if(ff == 1){
> puts("フラッシュ");
> return 6;
> }else{if(sf == 1 || sf == 2){
> puts("ストレート");
> return 5;
> }else{if(three == 1 && two == 0){ //上で先にフルハウスの判定をしているから別に必要ないtwo == 2は
> puts("3カード");
> return 4;
> }else{if(two == 2){
> puts("2ペア");
> return 3;
> }else{if(two == 1){
> puts("1ペア");
> return 2;
> }else{
> puts("ノーペア");
> }}}}}}}}}
直すなら、こんな感じです。
if(sf == 2 && ff == 1){
puts("ロイヤルストレートフラッシュ");
return 10;
}else if(sf == 1 && ff == 1){
puts("ストレートフラッシュ");
return 9;
}else if(four == 1){
puts("4カード");
return 8;
}else if(three == 1 && two ==1){
puts("フルハウス");
return 7;
}else if(ff == 1){
puts("フラッシュ");
return 6;
}else if(sf == 1 || sf == 2){
puts("ストレート");
return 5;
}else if(three == 1 && two == 0){ //上で先にフルハウスの判定をしているから別に必要ないtwo == 2は
puts("3カード");
return 4;
}else if(two == 2){
puts("2ペア");
return 3;
}else if(two == 1){
puts("1ペア");
return 2;
}else{
puts("ノーペア");
}
■構造体のswapは、
> buf.mark = yamafuda[saki].mark;
> buf.suu = yamafuda[saki].suu;
>
> yamafuda[saki].mark = yamafuda[moto].mark;
> yamafuda[saki].suu = yamafuda[moto].suu;
>
> yamafuda[moto].mark = buf.mark;
> yamafuda[moto].suu = buf.suu;
直すと、
buf = yamafuda[saki];
yamafuda[saki] = yamafuda[moto];
yamafuda[moto] = buf;
と言う感じに、簡潔に書けますよ。
■山札が無くなった時の処理が見当たりません。
■謎のコメント
> int tmp1 = test1.suu; /* b を基準とする */
b が何なのか不明です。
■疑問
C言語か、C++言語のどちらで書いているつもりなのか、不明ですが、
C言語では通らない構文を使われているみたいなので、C++言語なのでしょう。
C++を使うなら、またC++をさらに勉強すると、もっとC++らしい記述のしかた
があるかと思います。
■全体的に、よく書けていると思います。
■今後の課題
WIN32APIや、ライブラリのチュートリアルを進めてみるなり、
C++ や OOP(オブジェクト指向プログラミング)の勉強をしてみるなり、
ソースコードをたくさん読んで、たくさん書くと良いかと思います。
Re:ソースの評価と今後へのアドバイスをお願いします
私見ですが、初心者というレベルは脱していると思います。
これから先は、白さんの作りたいものを作ればいいと思います。
その過程で自分の知らない知識に関する本を購入していけば良いのでは
ないでしょうか。
プログラムを作るという行為の中で、覚えた方が良いことがあります。
それは、
・プログラムの書き方
・デバッグの仕方(デバッガの使い方)
です。
この辺りはプログラムを仕上げる速度に直結します。
プログラムの書き方に関しては、私は「プログラミング作法」をお勧めします。
デバッグの仕方に関しては、、、よくわかりません^^;
「C言語 入門書の次に読む本」とかも入門書では書かれていないが、
ちょっと大きなプログラムを書く時のお作法が載っています。
#Amazonの評価あんまり良くないですね、これ。脱初心者にはお薦めなんですが。。
これから先は、白さんの作りたいものを作ればいいと思います。
その過程で自分の知らない知識に関する本を購入していけば良いのでは
ないでしょうか。
プログラムを作るという行為の中で、覚えた方が良いことがあります。
それは、
・プログラムの書き方
・デバッグの仕方(デバッガの使い方)
です。
この辺りはプログラムを仕上げる速度に直結します。
プログラムの書き方に関しては、私は「プログラミング作法」をお勧めします。
デバッグの仕方に関しては、、、よくわかりません^^;
「C言語 入門書の次に読む本」とかも入門書では書かれていないが、
ちょっと大きなプログラムを書く時のお作法が載っています。
#Amazonの評価あんまり良くないですね、これ。脱初心者にはお薦めなんですが。。

Re:ソースの評価と今後へのアドバイスをお願いします
ざっと見させていただきました。
気になったのは、CflushとかCstraightのj変数ですね。今後のことを考えてcountとかちゃんとした名前にした方が良いと思います。
あと指摘されていますが、struct cardのstructを省略するとC言語の文法では問題があります。VC++をお使いでしたら、拡張子を.cにするかコンパイルオプションを/Tcとしてください。
それとqsortを使ってらっしゃいますが、勉強のためには自前ソートした方が良いと思います。
それよりも気になるのは、ユーザーインターフェイスですね。
どのカードを捨てたとか、ちゃんと表示した方が良いと思います。今のままだと非常に分かりにくいんですよね。ユーザーインターフェイスの設計は、一般アプリを作る場合に最も重要な事項の一つです。少しコードを直してみましたので見てください。
あとは、たかぎさんも指摘さている誤操作に対するガードですね。同じカード番号を入れることが出来るとか色々問題があります。
最後に、今後の勉強になりそうなサイトや本をご紹介しますね。
●デバッグ
「C言語 デバッグ完全解説」
http://www.amazon.co.jp/dp/4774133620
●アルゴリズムなど
「アルゴリズムとデータ構造編」
http://www.geocities.jp/ky_webid/algorithm/index.html
「アルゴリズム研究室」
http://www1.cts.ne.jp/~clab/algorithm/algorithm.html
「地球にやさしいアルゴリズム」
http://itpro.nikkeibp.co.jp/article/COL ... ST=develop
「コーディングに役立つ! アルゴリズムの基本」
http://www.atmarkit.co.jp/fcoding/index/algorithm.html
●Win32API
「APIで学ぶWindows徹底理解」
http://software.nikkeibp.co.jp/software ... mook2.html
「猫でもわかるプログラミング」WindowsSDK編を御覧下さい。
http://www.kumei.ne.jp/c_lang/
「Win32API(C言語)編」
http://www.geocities.jp/ky_webid/win32c/index.html
「Win32 API入門」
http://wisdom.sakura.ne.jp/system/winapi/index.html
「超初心者のプログラム入門(C言語 Windows)」
http://www13.plala.or.jp/kmaeda/winc/winc.htm
気になったのは、CflushとかCstraightのj変数ですね。今後のことを考えてcountとかちゃんとした名前にした方が良いと思います。
あと指摘されていますが、struct cardのstructを省略するとC言語の文法では問題があります。VC++をお使いでしたら、拡張子を.cにするかコンパイルオプションを/Tcとしてください。
それとqsortを使ってらっしゃいますが、勉強のためには自前ソートした方が良いと思います。
それよりも気になるのは、ユーザーインターフェイスですね。
どのカードを捨てたとか、ちゃんと表示した方が良いと思います。今のままだと非常に分かりにくいんですよね。ユーザーインターフェイスの設計は、一般アプリを作る場合に最も重要な事項の一つです。少しコードを直してみましたので見てください。
あとは、たかぎさんも指摘さている誤操作に対するガードですね。同じカード番号を入れることが出来るとか色々問題があります。
最後に、今後の勉強になりそうなサイトや本をご紹介しますね。
●デバッグ
「C言語 デバッグ完全解説」
http://www.amazon.co.jp/dp/4774133620
●アルゴリズムなど
「アルゴリズムとデータ構造編」
http://www.geocities.jp/ky_webid/algorithm/index.html
「アルゴリズム研究室」
http://www1.cts.ne.jp/~clab/algorithm/algorithm.html
「地球にやさしいアルゴリズム」
http://itpro.nikkeibp.co.jp/article/COL ... ST=develop
「コーディングに役立つ! アルゴリズムの基本」
http://www.atmarkit.co.jp/fcoding/index/algorithm.html
●Win32API
「APIで学ぶWindows徹底理解」
http://software.nikkeibp.co.jp/software ... mook2.html
「猫でもわかるプログラミング」WindowsSDK編を御覧下さい。
http://www.kumei.ne.jp/c_lang/
「Win32API(C言語)編」
http://www.geocities.jp/ky_webid/win32c/index.html
「Win32 API入門」
http://wisdom.sakura.ne.jp/system/winapi/index.html
「超初心者のプログラム入門(C言語 Windows)」
http://www13.plala.or.jp/kmaeda/winc/winc.htm
Re:ソースの評価と今後へのアドバイスをお願いします
> それとqsortを使ってらっしゃいますが、勉強のためには自前ソートした方が良いと思います。
これについては必ずしも賛成できません。
確かに勉強のためには自作した方がよいのですが、それは別の機会で行うべきものです。
単にソートをしたいだけなら、既存のライブラリを使う方が得策です。
そして、C++を使うのであれば、qsortより優れたstd::sortやstd::stable_sortを使うべきです。
これについては必ずしも賛成できません。
確かに勉強のためには自作した方がよいのですが、それは別の機会で行うべきものです。
単にソートをしたいだけなら、既存のライブラリを使う方が得策です。
そして、C++を使うのであれば、qsortより優れたstd::sortやstd::stable_sortを使うべきです。
Re:ソースの評価と今後へのアドバイスをお願いします
実行していませんけど、Cstraightは誤判定しませんか?
例えば(3, 4, 5, 6, 10)をストレートと判定してしまうと思います。
Cpareは非常に良く書かれています。
自分でこれを思いつけるならば、センスは十分です。
(センスのないプロがどんなに多いことか)
その他、細かい指摘も色々ありますが、
大部分は今後の経験で改善されるでしょう。
今後についてですが、このプログラムを改善したいならば、
dicさんの書いているCPUとの対戦に賛成。
このプログラムに拘らないならば、softyaさんのお勧めにもある、
下記サイトを試してみてはいかがでしょうか。
「猫でもわかるプログラミング」
http://www.kumei.ne.jp/c_lang/
http://www.kumei.ne.jp/c_lang/index_sdk.html
例えば(3, 4, 5, 6, 10)をストレートと判定してしまうと思います。
Cpareは非常に良く書かれています。
自分でこれを思いつけるならば、センスは十分です。
(センスのないプロがどんなに多いことか)
その他、細かい指摘も色々ありますが、
大部分は今後の経験で改善されるでしょう。
今後についてですが、このプログラムを改善したいならば、
dicさんの書いているCPUとの対戦に賛成。
このプログラムに拘らないならば、softyaさんのお勧めにもある、
下記サイトを試してみてはいかがでしょうか。
「猫でもわかるプログラミング」
http://www.kumei.ne.jp/c_lang/
http://www.kumei.ne.jp/c_lang/index_sdk.html
Re:ソースの評価と今後へのアドバイスをお願いします
>>やんちさん
なるほど、else ifって括弧でいちいちまとめていかなくても大丈夫なんですね。
構造体のswapについても全く知りませんでした。これだけでも3行も短くなるとは、しかも読みやすくなっている。
山札は当初は5回しか繰り返さないつもりだったので、なくなったときの処理をいれていませんでした。対処としては、山札自体を2個3個として増やすこととして対処してみます。
謎のコメント…今見返してみると、自分でも謎です。一体なんなのでしょうかね…
c言語で書いているつもりだったのですが、vc++でc++としてコンパイルしていたようで、エラーが出なかったので、気にしたことがありませんでした。ご指摘ありがとうございます。
>>ぽこさん
>私見ですが、初心者というレベルは脱していると思います。
ありがとうございます。初心者を脱したかどうかは自分で判断がつかなかったので、うれしいかぎりです。
「プログラミング作法」と「C言語 入門書の次に読む本」ですか、amazon等を見てみるとずいぶんと興味をそそられる紹介文だったので、今週末にでも書店で見てきます。ただ、近くの図書館に置いてないのは、懐が痛いです…プログラミング関係の本ってどうしてこう高いのでしょうか…
>>たかぎさん
エラーチェックは全く気にしたことがありませんでした。そうですね、確かに自分が使うだけならエラーが出るような数値は入力しないですが、他人が使うこともあるわけで、そうなると、やはりエラーチェックも必要事項になってくるんですね。
ソートについては下に一応自分の考えたコードも載せてみましたので、見ていただけると嬉しいです。ただ、こういう頭の中だけで考えて、メモ帳がちょっとあれば考えたアルゴリズムをメモっておけるのは授業中の暇つぶしとしては結構いいので、自前でできるところはなるべく自前でしようかなと思います。
>>dicさん
対戦相手はこれから組み込んでみようと思います。ただ、ポーカーの場合はかなり運の要素が強いので、とりあえず、自分が普段やっている戦術?をそのまま実行させるような形になる気がします。はたしてこれはcpuと言えるのか…
>>softyaさん
変数名ですか、たしかにこのままj,k,l,m,n…と増えていったら区別がつかなくなりそうです。これからはちゃんと名前をつけるように気をつけます。
ソートも最初は自前でいろいろと考えてみたのですが、どうもうまくいかなくて、で、参考書見てみるとソート用の関数が合ったのでそれを使ってしまいました。
一応自分で考えてたのは
//インデントがおかしいかと思いますが、お許しください
ユーザーインターフェイスはそもそもcuiでゲーム作るのは実用性無視であくまでcの練習として組んでいたので、今回は全く考えていませんでした。今回指摘していただいた不備を直したらこれを今度はwin32APIを使って作ってみようと考えているので、そちらではしっかりとインターフェイスにもこだわりたいと思います。
9個もの参考サイトの紹介ありがとうございます。猫でもわかる以外はすべて初見のため大変ありがたいです。
>>たいちうさん
今確認してみましたが、Cstraightは誤判定していました。これから問題点と修正案考えてみます。
>Cpareは非常に良く書かれています。
ありがとうございます。なんか、ソースを他人に見せたことなんか一度もなくて当然ほめられた機会もなかったんで大変うれしいです。
ただ、個人的には変数は配列で13個も用意しなくても4個でいけるように感じたので、まだまだ無駄があるのかなと思ってます。
みなさん本当に丁寧な回答ありがとうございます。こんなにも多くの助言がいただけてうれしい限りです。
今後は、
1指摘された問題点の修正
2エラーチェックの導入
3CPUの導入
4win32APIを利用したGUI化
という風に進めていきたいと思います。これらの間に何か入れたほうがいいことがあれがまた、助言いただけるとありがたいです。
本当にありがとうございました。
なるほど、else ifって括弧でいちいちまとめていかなくても大丈夫なんですね。
構造体のswapについても全く知りませんでした。これだけでも3行も短くなるとは、しかも読みやすくなっている。
山札は当初は5回しか繰り返さないつもりだったので、なくなったときの処理をいれていませんでした。対処としては、山札自体を2個3個として増やすこととして対処してみます。
謎のコメント…今見返してみると、自分でも謎です。一体なんなのでしょうかね…
c言語で書いているつもりだったのですが、vc++でc++としてコンパイルしていたようで、エラーが出なかったので、気にしたことがありませんでした。ご指摘ありがとうございます。
>>ぽこさん
>私見ですが、初心者というレベルは脱していると思います。
ありがとうございます。初心者を脱したかどうかは自分で判断がつかなかったので、うれしいかぎりです。
「プログラミング作法」と「C言語 入門書の次に読む本」ですか、amazon等を見てみるとずいぶんと興味をそそられる紹介文だったので、今週末にでも書店で見てきます。ただ、近くの図書館に置いてないのは、懐が痛いです…プログラミング関係の本ってどうしてこう高いのでしょうか…
>>たかぎさん
エラーチェックは全く気にしたことがありませんでした。そうですね、確かに自分が使うだけならエラーが出るような数値は入力しないですが、他人が使うこともあるわけで、そうなると、やはりエラーチェックも必要事項になってくるんですね。
ソートについては下に一応自分の考えたコードも載せてみましたので、見ていただけると嬉しいです。ただ、こういう頭の中だけで考えて、メモ帳がちょっとあれば考えたアルゴリズムをメモっておけるのは授業中の暇つぶしとしては結構いいので、自前でできるところはなるべく自前でしようかなと思います。
>>dicさん
対戦相手はこれから組み込んでみようと思います。ただ、ポーカーの場合はかなり運の要素が強いので、とりあえず、自分が普段やっている戦術?をそのまま実行させるような形になる気がします。はたしてこれはcpuと言えるのか…
>>softyaさん
変数名ですか、たしかにこのままj,k,l,m,n…と増えていったら区別がつかなくなりそうです。これからはちゃんと名前をつけるように気をつけます。
ソートも最初は自前でいろいろと考えてみたのですが、どうもうまくいかなくて、で、参考書見てみるとソート用の関数が合ったのでそれを使ってしまいました。
一応自分で考えてたのは
struct card mycbuf[5]; int j,s; int buf = 20;int buf2 = 0; for(s = 0;s < 5;s++){ for(j = 0;j < 5;j++){ if(mycards.suu < buf && mycards.suu != buf2) buf = mycards } mycbuf = buf; buf2 = buf; }
//インデントがおかしいかと思いますが、お許しください
ユーザーインターフェイスはそもそもcuiでゲーム作るのは実用性無視であくまでcの練習として組んでいたので、今回は全く考えていませんでした。今回指摘していただいた不備を直したらこれを今度はwin32APIを使って作ってみようと考えているので、そちらではしっかりとインターフェイスにもこだわりたいと思います。
9個もの参考サイトの紹介ありがとうございます。猫でもわかる以外はすべて初見のため大変ありがたいです。
>>たいちうさん
今確認してみましたが、Cstraightは誤判定していました。これから問題点と修正案考えてみます。
>Cpareは非常に良く書かれています。
ありがとうございます。なんか、ソースを他人に見せたことなんか一度もなくて当然ほめられた機会もなかったんで大変うれしいです。
ただ、個人的には変数は配列で13個も用意しなくても4個でいけるように感じたので、まだまだ無駄があるのかなと思ってます。
みなさん本当に丁寧な回答ありがとうございます。こんなにも多くの助言がいただけてうれしい限りです。
今後は、
1指摘された問題点の修正
2エラーチェックの導入
3CPUの導入
4win32APIを利用したGUI化
という風に進めていきたいと思います。これらの間に何か入れたほうがいいことがあれがまた、助言いただけるとありがたいです。
本当にありがとうございました。