ページ 11

C言語でポーカーを作っているんですが その2

Posted: 2010年6月09日(水) 22:16
by 南瓜
関数を使ってある程度形になってから投稿しようとしたら流れてしまいました…
しかも、まだ関数に対する理解が中途半端なままです。
ですが、ストレートの判定はやり方を変えて、残す役判定は
ロイヤルストレートフラッシュだけです。
複数のフラグが立った時に該当する役全てが表示されるなど
まだ改善する点がありますが、少しずつ直していきます

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月09日(水) 22:23
by たかぎ
ざっと見ただけなので勘違いがあるかもしれませんが...

ジョーカー(ワイルドカード)が含まれていないように思います。
結果として、ファイブカード(five of a kind)の役に対応していませんね。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月10日(木) 22:34
by 南瓜
ワイルドカードは考えてなかったですね
実装したいですが、結構複雑な気がします^^;

あと、一応ロイヤルストレートフラッシュの判定が出来ました。
出来れば、Aの位置をずらしたくなかったですが…

次は、関数を使って見やすくするかAの位置をずらさないで
ロイヤルストレートフラッシュの判定を作るか、
どちらがやり易いでしょうか?

今、10日でわかるC言語入門教室と苦しんで覚えるC言語で
関数の勉強をしているんですが、現段階ではどちらも
このプログラムにどう利用しればいいのかよく判りません。
(何を関数にすればいいのか、何処を見易くすればいいのかが)

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月11日(金) 00:25
by たいちう
お久しぶりです。頑張りましたね。

ワイルドカードの使用はどちらかというとマイナールールなので、
後回しで良いのではないでしょうか。
http://ja.wikipedia.org/wiki/%E3%83%9D% ... B.E3.83.BC


> 次は、関数を使って見やすくするかA の位置をずらさないで
> ロイヤルストレートフラッシュの判定を作るか、
> どちらがやり易いでしょうか?

私の定石としては、プログラムの構造を良くしてから機能追加(or 改善)ですが、
今更、、、という感じがします。

Aの位置を元に戻せば、A2345をストレートと判定することができますので、
現状の判定が一通り終わり、ストレートでなかった場合に、A10JQKかどうかを
判定するだけで完成だと思います。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月12日(土) 21:46
by 南瓜
やり方が異なるかもしれませんが、判定が出来ました。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月12日(土) 21:57
by たいちう
次のデータが役なしになってしまうようです。

int n_hand[5] = {0,9,10,11,12};/*5枚の数字の手札*/
int m_hand[5] = {0,3,3,3,3};/*5枚のマークの手札*/

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月13日(日) 11:47
by 南瓜
>int n_hand[5] = {0,9,10,11,12};/*5枚の数字の手札*/
>int m_hand[5] = {0,3,3,3,3};/*5枚のマークの手札*/
でストレートの役が出るように直しました

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月13日(日) 13:25
by たいちう
フルハウスの時にスリーオブカインドとも表示されてしまいます。
私は丁寧にテストしたわけではないですが、
それ以外は大体できたのではないでしょうか。

まだ続けますか?
続けるならばまずは役判定を関数にするのが良いと思いますが。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月13日(日) 14:05
by 南瓜
昨日、ワンペアから役がうまく判定されるかやっていって
(全部確認出来た訳じゃありませんが)
指摘された所を直しても別の所でまた指摘されるんじゃないかと
うすうす感じてました。

関数にして判り易くしようと思います

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月14日(月) 21:15
by 南瓜
関数を利用するのが初めてなので
何もかもグダグダで、どこをどう直せばいいのか
わかりません
助言をお願いします

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月14日(月) 22:43
by たいちう
C言語の入門書を持っていないのですか?
関数に配列を引数として渡す方法が必ず載っているはずですが。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月15日(火) 16:09
by 南瓜
C言語の本で探しながら修正していってだいぶエラーが出なくなりましたが
まだまだわからない所だらけです
13行目のエラーは、ストレート系の判定に必要だし
149行目のエラーは、関数についてよく判ってないから
どのように直せばいいのか判りません

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月15日(火) 16:32
by たいちう
変数を全部グローバルにしてしまったのですね。
エラーが減ったとしても、No. 54375のプログラムと比較して、
改悪されたという印象を受けます。

「役判定」を関数化する前に、もっと簡単な「カードの表示」について
関数にしてみると良いのではないでしょうか。
No. 54195か、その直後のフルハウスを正しく表示できるプログラムに戻るか、
一旦役判定に関する部分を削除してしまっても良いです。

一応制約として、グローバル変数を使ってはいけない、としておきますが、
どうしても無理ならば使っても良いです。後で改善すればよいので。


何行目のエラーと言われても判りません。
今後はエラーメッセージを貼り付けてください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月15日(火) 17:56
by 南瓜
グローバル変数のままですが、表示→役判定ができました
>printf("%s ", hands[judgment(number)]);
の部分がhands[judgment(mark)]でも役が表示されたんですが
どのように記述するのが正しいのでしょうか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月15日(火) 20:02
by たいちう
先にグローバル変数を使わずに表示を完成させましょう。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月16日(水) 22:41
by 南瓜
ちょっと見にくいですが、ローカル変数に変更しました

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月16日(水) 23:50
by たいちう
n_handとm_handが最重要のデータです。
mainの中で管理し、少なくともこれらはshowに渡すようにしましょう。
また、showの中ではソートをしてはいけません。
どこでソートすべきだと思いますか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月18日(金) 19:52
by 南瓜
ソートは、main関数か新しい関数で管理するのかなと思い
新しい関数を作りました
ただ、引数の書き方がわからず、number[n_handを(char *number[/url], int n_hand[/url]])と
書くとtoo few arguments to functionとエラーが出てしまうので
n_hand, m_handの変数を
mainで管理し切れてないです

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月18日(金) 20:51
by たいちう
できないならば最低限のことだけ実装しましょう。
今はソートは必要ありません。ついでにm_handも忘れましょう。

main関数で代入した配列n_handを、show関数の中で表示しましょう。
numberは表示の為だけに必要なので、main関数に持つ必要はありません。

これでも難しいならば、配列の受け渡しについて十分練習してください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月19日(土) 18:52
by 南瓜
とりあえず表示が出来たので、次に役の表示をやろうとしたんですが
表示が「U??WS?Ā?」とバグってしまいます。
これも配列の受け渡しですか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月19日(土) 19:07
by たいちう
> printf("%s\n", judgment);

これがだめですね。
配列の受け渡しも何も、judgmentに引数を渡していません。
int sum(int a, int b) {
    return a + b;
}

...

int a = 3, b = 5;
print("sum = %d\n", sum(a, b));
このようなサンプルと比較して考えて下さい。
printfの書式指定も確認してください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月19日(土) 22:17
by 南瓜
No:54634でhands[judgment(number)]の形でうまくいってたので
引数が増えているにhands[judgment(n_hand)]にしてたから
エラーが出てしまったんだと理解しました
(しかしNo:54757はひどいな…)

printfは文字列なので%sにしました

次は、m_handやsort関数を加える事でしょうか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月19日(土) 23:09
by たいちう
> (しかしNo:54757はひどいな…)

落ち着いて良く考えたら自分で分かる事ですよね。
まず落ち着きましょう。

その上で考えても分からないことを掲示板で質問し、
私や他の方の回答で分かったとしたら、
自分に何が足りなかったのかを良く考えましょう。
成長のチャンスです。


> 次は、m_handやsort関数を加える事でしょうか?

私が決めることじゃないでしょ?
壁にぶつかった場合に、こういう順番で取り組んだら?という、
提案をしているだけです。

どこかで行き詰ったら、また質問してください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月21日(月) 22:18
by 南瓜
役判定で一通り確認したんですが、フラッシュが関わると役の表示がうまくいきません

・フラッシュならば上位の役であろうと問答無用でフラッシュになってしまう点
・ロイヤルストレートとストレートフラッシュでもフラッシュになってしまう点

この問題を解決するために&&や!=を使って判定すると
またゴチャゴチャになりそうなので出来れば使わずに解決したいです

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月21日(月) 22:33
by Poco
役判定用のif文の順番を変えれば良いのでは?
現状
・先にフラッシュの判定
・次にストレートフラッシュの判定

修正版
上記の順序を変更。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月22日(火) 22:31
by 南瓜
うまくいきました!ありがとうございます

あと直したい所はchange関数のchar *number、char *markのローカル変数を
書かないで引数として渡すにはどう書けばいいのかと

最期にカードの引ける回数を3回にして、0を押したらまだ引けても
ゲームを終了させるという仕様にしたいです
(カウントダウンがうまくいかないかカウントダウンはうまくいっても
交換したカードが表示されず、0になってもループしてしまう)
(上のソースは、カウントダウンがうまくいかないやつです)

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月22日(火) 23:22
by たいちう
void show_a_card(int m_hand, int n_hand); という関数を作りましょうか。
numberやmarkの配列はこの関数だけが持ちます。

show()からは、この関数を5回連続で呼び出し、
change()からは、交換の前後にこの関数を2回呼び出します。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月23日(水) 02:28
by 白い時空
こんにちは。
自分も気になったところがあるので、アドバイスを。

change関数の中身が見づらかったので、見やすくしてみました。

これを見るとわかりますが、i が重複しています。
そのせいで、おかしなことになっていますね。
カウントダウンを付ける以前に見直しが必要です。

カードを引く処理(下側のfor文の中)は多分問題ないと思います。
他の部分を見直してみてください。

大変ですが頑張ってください。
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
char *mark[4] = {"♥","♦","♠","♣"};
char change[10];/*カードを交換する*/

int i;
int limit = 3;

printf("カードを交換する場合1~5を入力して下さい (0は交換しない) > ");
scanf("%s", change);

while (getchar() != '\n') { }

for(i = 0; i < strlen(change); i++) {
    int n = change - '0';
    while ((n < 0) || (5 < n)) {
        printf("3回まで交換できます\n");
        printf("0または1~5を入力して下さい (0は交換しない) > ");
        scanf("%s", change);
        int n = change - '0';
        if((1 <= n) && (n <= 5) || (n == 0)) 
        break;
    }

    limit--;

    for(i = 0; i < strlen(change); i++) {
        int n = change - '0';
        if ((1 <= n) && (n <= 5)) {
            printf("%d枚目のカードを交換します。%s - %s\n", n, mark[m_hand[n-1]], number[n_hand[n-1]]);
            int index = n -1;
            do {
                n_hand[index]= rand() % 13;
                m_hand[index] = rand() % 4;
            } while (card[m_hand[index]][n_hand[index]] == 1);
            card[m_hand[index]][n_hand[index]] = 1;
            printf("%d枚目のカードを交換しました。%s - %s\n",n,mark[m_hand[n-1]],number[n_hand[n-1]]);
        } else if (n == 0) {
            printf("0なので交換しません。\n");
        }
    }
    
    printf("0または1~5を入力して下さい (0は交換しない)\n");
    if (limit != 0) {
        printf("あと%d回交換できます ", limit);
    } else {
        printf("もうカードは交換できません\n");
    }
}

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月24日(木) 23:03
by 南瓜
iが重複しているというのが判りませんでしたが、
(何回もi = 0で初期化はよくないのかな?)
白い時空さんのように見やすくしたら
3回云々の処理がすんなりうまくいきました

void show_a_card(int m_hand, int n_hand);を作りましたが
change関数の所がshow_a_card (m_hand[n-1], n_hand[n-1]);
と書くと passing argument 1 of ‘show_a_card’ makes pointer from integer without a cast
と出てしまうため、仕様通りに出来ませんでした

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月25日(金) 00:17
by たいちう
> iが重複しているというのが判りませんでしたが、

インデントがずれているので分かりにくいですが、
iをループ変数にしたforが二重になってしまっています。


> void show_a_card(int m_hand, int n_hand); を作りましたが
> change関数の所がshow_a_card (m_hand[n-1], n_hand[n-1]);
> と書くと passing argument 1 of ‘show_a_card’ makes pointer from integer without a cast
> と出てしまうため、仕様通りに出来ませんでした

これではアドバイスできません。
コンパイルエラーを引き起こした部分を載せて下さい。
最低でも関数宣言と関数を呼び出している部分を。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月25日(金) 02:59
by 白い時空
show_a_card関数の所、おしいですね。
問題点としては、

・show_a_card関数では1枚のカードを表示するので、for文を使う必要はなく、配列をわたす必要もありません。
・show関数では5枚のカードを表示するので、show_a_card関数を5回行えばいいはずです。


change関数の所ですが、
for文について簡単に言えば、上側のfor文は必要ありません。無くても問題ないはずです。
他にも問題点があります。

・scanfが2つある。(1つで十分なはずです。どちらか無駄な可能性があります)
・scanfの入力が正しいかの判定をchange[ i ]の1文字しかしていない。(1文字だけ判定すれば十分ですか?)
・int n;の宣言が複数ある。(ややこしくなるので、宣言は最初にしておくべき)

問題点多いですが頑張ってください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月25日(金) 13:32
by 南瓜
先にたいちうさんの方から
void show_a_card (int m_hand[/url], int n_hand[/url]) {
    
    char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
    char *mark[4] = {"&#9829;","&#9830;","&#9824;","&#9827;"};/*カードのマーク*/
    
    int i; 
    
    for(i = 0; i < 5;  i++) {
        printf("%s - %s ",  mark[m_hand], number[n_hand]);/* 五枚のカードを表示 */ 
    }
    printf("\n");
}

void show (int m_hand[/url], int n_hand[/url]) {
    
    show_a_card (m_hand, n_hand);/* 五枚のカードを表示 */ 
}

void change (int card[/url][13], int m_hand[/url], int n_hand[/url]) {

for(i = 0; i < strlen(change); i++) {
                int n = change - '0';
                if ((1 <= n) && (n <= 5)) {
                    printf("%d枚目のカードを交換します。%s  \n", n, show_a_card (m_hand[n-1], n_hand[n-1]));
                    show_a_card (m_hand, n_hand);
                    int index = n -1;
                    do {
                        n_hand[index]= rand() % 13;
                        m_hand[index] = rand() % 4;
                    } while (card[m_hand[index]][n_hand[index]] == 1);
                    card[m_hand[index]][n_hand[index]] = 1;
                    printf("%d枚目のカードを交換しました。%s  \n", n, show_a_card (m_hand[n-1], n_hand[n-1]));
                    show_a_card (m_hand, n_hand);
                } else if (n == 0) {
                    printf("0なので交換しません。\n");
                    limit = 0;
                }
            }


kansu.c:117: warning: passing argument 1 of ‘show_a_card’ makes pointer from integer without a cast
kansu.c:117: warning: passing argument 2 of ‘show_a_card’ makes pointer from integer without a cast
kansu.c:117: error: invalid use of void expression
kansu.c:125: warning: passing argument 1 of ‘show_a_card’ makes pointer from integer without a cast
kansu.c:125: warning: passing argument 2 of ‘show_a_card’ makes pointer from integer without a cast
と表示されます

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月25日(金) 17:48
by ドラ
>printf("%d枚目のカードを交換します。%s \n", n, show_a_card (m_hand[n-1], n_hand[n-1]));
%s は対応する引数に char*型を要求しますが、show_a_card関数の返却値の型は何ですか?

show_a_card関数に渡された実引数、m_hand[n-1]とn_hand[n-1]の型は何ですか?
それに対して、show_a_card関数の仮引数の型は何ですか?

・・・と言うか、それ以前に
show_a_card関数の役割は何ですか?
show関数の役割は何ですか?


実装詳細に意識をとらわれすぎていて、大雑把なレベルでの処理の流れを整理できないまま
なんとなくコードを書いてしまっているような気がします。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月25日(金) 23:26
by たいちう
> ・・・と言うか、それ以前に
> show_a_card関数の役割は何ですか?
> show関数の役割は何ですか?

私も同じ意見です。
私は↓のような仕様を書いていたはずです。

> show()からは、この関数を5回連続で呼び出し、
> change()からは、交換の前後にこの関数を2回呼び出します。

なぜ、私はこのような仕様を書いたのでしょうか?
何となく言われるままにプログラムを作ろうとして、
作りきれずに適当な妥協をしていませんか?

以前に比べると確実に前進しています。
焦らず、南瓜さんのペースで進めればよいので、
掲示板に書くべきことが十分まとまってから書いてください。

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月26日(土) 22:44
by 南瓜
質問したいことがいくつかありますが、まず表示のことで
今までprintf("%s - %s ", mark[m_hand], number[n_hand]);
で表示がうまくいきましたが、これだとSegmentation faultと出てしまいます
markやnumberは表示に必要だし、m_handなどもrandで選んだ数を
代入してるから必要だし、どちらか片方だけだと表示がバグるし…
根本的な所が間違ってるんでしょうか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月26日(土) 22:52
by Poco
> 質問したいことがいくつかありますが、まず表示のことで
> 今までprintf("%s - %s ", mark[m_hand], number[n_hand]);
> で表示がうまくいきましたが、これだとSegmentation faultと出てしまいます

関数show_a_card()の中の変数iの値が不定です。
show_a_card()にshow()のiを渡さないといけないんじゃないですか?

void show_a_card (int m_hand[/url], int n_hand[/url]) {

char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
char *mark[4] = {"&#9829;","&#9830;","&#9824;","&#9827;"};/*カードのマーク*/

int i;/*ここの値はなんじゃらほい?*/

printf("%s - %s ", mark[m_hand], number[n_hand]);/* 一枚のカードを表示 */
}

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月26日(土) 23:59
by たいちう
No:55095を良く読んでください。

void show_a_card (int m_hand[/url], int n_hand[/url]); ではなく、
void show_a_card (int m_hand, int n_hand); です。

↓のように呼び出します。

for (i = 0; i < 5; i++) {
    show_a_card (m_hand, n_hand);
}

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月27日(日) 19:31
by 南瓜
引数の書き方が間違っていたのか…
ひとまず完成したのかな?(修正点はまだあるでしょうが)

int n = change - '0';とint index = n - 1;は
下手に移動すると交換がうまくいかなくなるので
そのままにしてあります

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月29日(火) 21:24
by 南瓜
レスがないから平気だったのかな?(遊んだ感じでは平気でした)
もしプログラムに問題ないようならいくつか質問させて下さい

自分は、最終的にRPGやら公開されている龍神録などのゲームを
作れるようになりたいです。

が!配列(というより全体的なC言語)の知識が足りない事を痛感しました
あと、国語力不足も…
授業でC言語を習った時は、あまり興味が無かったんですが
ここで公開されているゲームや「10日で覚えるC言語教室」をみて
C言語でこんなことが出来るのかと感動しました
そして、C言語教室も一通り勉強したので、ポーカーを作ってみよう
と思い、つまずいたのでここで質問させてもらいました。

で、いきなりRPGを作り出したら絶対挫折するのが目に見えているので
徐々にステップアップしていきたいのですが
(ぷよぷよ→テトリス→…みたいに)順番にやっていくなら
次は何がいいでしょうか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月29日(火) 21:26
by 組木紙織
オセロはどうでしょうか

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月30日(水) 09:27
by たいちう
> レスがないから平気だったのかな?(遊んだ感じでは平気でした)
> もしプログラムに問題ないようならいくつか質問させて下さい

私がレスをしなかったのは、具体的な質問が無かったからです。
忙しかったのもあるけど。
役判定の部分が未完成です。次のデータはフラッシュのはずですよね?

int n_hand[5] = { 1, 8, 10, 11, 12 }; /*5枚の数字の手札*/
int m_hand[5] = { 0, 0, 0, 0, 0 }; /*5枚のマークの手札*/

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年6月30日(水) 19:50
by 白い時空
問題はまだ少しありますね。

たいちうさんの言う通り
int n_hand[5] = { 1, 8, 10, 11, 12 };
int m_hand[5] = { 0, 0, 0, 0, 0 };
これだと、sum==42 でロイヤルストレートフラッシュ扱いになってますね。

他には
・main関数で宣言されたlimitは使われていない。
・judgment関数にhandsを渡す必要はない。
くらいですかね。

あとjudgment関数での役の判定ですが、役の強いものから順に判定するべきだと思います。


次のステップですか。
配列の理解がまだなら、理解してから次に進んでくださいね。
C言語を一通り覚えたら、後は実践あるのみだと思います。
ゲームを作りたいなら、このサイトの「ゲームプログラミングの館」をやってみてはどうでしょうか?

Re:C言語でポーカーを作っているんですが その2

Posted: 2010年7月02日(金) 22:15
by 南瓜
返信遅れました
ロイヤルストレートフラッシュの修正と他の細かい修正をしました

オセロですか、C言語をより理解したら作ってみます

MacでもDXライブラリは使えますか?