ページ 1 / 1
C言語でポーカーを作っているんですが
Posted: 2010年4月06日(火) 17:46
by 南瓜
いつもお世話になってます。今、C言語でポーカーもどき(ディーラーや対戦相手、ベッドなし)を作っているんですが
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int card[4][13];
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
char *mark[4] = {"♥","♦","♠","♣"};
int main (void) {
int i;
int draw_number;/*引いたカードの数*/
int draw_mark;/*引いたカードのマーク*/
char y_n;/*カードを引くか引かないかを判断*/
int hand[5];/*自分の手札*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("プレイヤーのカードは\n");
for(i = 0; i < 5; i++) {
int draw_number, draw_mark;
draw_mark = rand() % 4 + 1;
draw_number = rand() % 13 + 1;
printf("%s %s ", mark[draw_mark-1], number[draw_number-1]);
}
printf("\n");
while(1) {
printf("カードを交換しますか? > y/n \n");
scanf("%c", &y_n);
// printf("交換するカードを選んで下さい >(1~5) \n");
while (getchar() != '\n') { }
if (y_n == 'y') {
for(i = 0; i < 5; i++) {
int draw_number, draw_mark;
draw_mark = rand() % 4 + 1;
draw_number = rand() % 13 + 1;
printf("%s %s ", mark[draw_mark-1], number[draw_number-1]);
}
printf("\n");
} else if (y_n == 'n') { break; }
}
switch (draw_number) {
case 1: printf("ワンペア\n");
break;
case 2: printf("ツーペア\n");
break;
case 3: printf("スリーペア\n");
break;
case 4: printf("フォーペア\n");
break;
default: printf("他の役\n");
break;
}
return 0;
}
上のコードの(30行目くらい)「//printf("交換するカードを選んで下さい >(1~5) \n");」
の交換するカードが1~5枚ある場合交換するには、どのように書けばいいの
(int hand[5]を利用するんじゃないかと考えているんですが)と
役を判定するやり方(swithよりifやelse、int draw_number, draw_markを利用すると思うんですが)がわかりません
特に役を判定するやり方の考え方が聞きたいです
グローバル変数、構造体やヘッダー?を使えばより見やすく、わかりやすいソースができると
思うんですが、まだ良く判らないため、今はなるべく使わずに作りたいと思っています
OS:Mac OS X コンパイル:gcc バージョン4.0.1
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月06日(火) 18:06
by たいちう
なかなか面白そうな課題(?)ですね。
> の交換するカードが1~5枚ある場合交換するには、どのように書けばいいの
例えば次の様な入力方法はいかがですか?
0 : 交換なし
4 : 4枚目を交換
135 : 1枚目・3枚目・5枚目を交換
12345 : 全部交換
> 役を判定するやり方(swithより ifやelse、int draw_number,
> draw_markを利用すると思うんですが)がわかりません
少しずつ作りましょう。
フラッシュかどうかは判定できますか?
> グローバル変数、構造体やヘッダー?を使えばより見やすく、わかりやすいソースができると
> 思うんですが、まだ良く判らないため、今はなるべく使わずに作りたいと思っています
グローバル変数は、見にくくわかりにくいソースができやすいとされています。
↓この部分がグローバル変数です。
> int card[4][13];
> char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
> char *mark[4] = {"e&","f&","`&","c&"};
細かい指摘も沢山ありますが、とりあえずここまで。
頑張って下さい。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月06日(火) 21:53
by box
ポーカーで
> case 3: printf("スリーペア\n");
> break;
> case 4: printf("フォーペア\n");
> break;
こういう状況ってあるんでしょうか?
カードは5枚しかないのに…。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月07日(水) 00:06
by 南瓜
ご指摘ありがとうございます
とりあえず
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int card[4][13];
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
char *mark[4] = {"♥","♦","♠","♣"};
int main (void) {
int i;
int r;/*カードを引く時の選ぶ番号を入れる*/
int draw_number;/*引いたカードの数*/
int draw_mark;/*引いたカードのマーク*/
int array_mark[4];
char y_n;/*カードを引くか引かないかを判断*/
char change;/*選んだ枚数分カードを替える*/
int hand[5];/*自分の手札*/
int flash;/*役のフラッシュを確認する*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("プレイヤーのカードは\n");
for(i = 0; i < 5; i++) {
int draw_number, draw_mark;
r = 0;
draw_mark = rand() % 4 + 1;
draw_number = rand() % 13 + 1;
printf("%s %s ", mark[draw_mark-1], number[draw_number-1]);
}
printf("\n");
while(1) {
printf("カードを交換しますか? > y/n (control + c で強制終了)\n");
scanf("%c", &y_n);
if (y_n == 'y') {
printf("交換するカードを選んで下さい >(1~5) \n");
scanf("%c", &change);
while (getchar() != '\n') { }
for(i = 0; i < 5 - change; i++) {
int draw_number, draw_mark;
draw_mark = rand() % 4 + 1;
draw_number = rand() % 13 + 1;
printf("%s %s ", mark[draw_mark-1], number[draw_number-1]);
}
printf("\n");
} else if (y_n == 'n') { break; }
}
flash = 0;
switch(array_mark[4]) {
for(i = 0; i < 4; i++) {
if (array_mark == 5) {
flash = 1;
printf("フラッシュ");
} break; {
}
}
}
return 0;
}
上記のソースに交換する回数をscanfで入力して、for文で繰り返す回数を引けば
交換だけはされるんじゃないかなと思ったんですが、うまくいかずorz
フラッシュの役の確認に関しては、
”マーク”を確認する配列と”フラッシュ”の変数を作り、"フラッシュ"を初期化して
”マーク”を確認する作業をfor文で行って、それが5個あるなら”フラッシュ”は”真”である
(正しいのかこの説明?)でループを脱出して”フラッシュ”が表示されるはずなんですが
表示されません。現時点では、これ以上案が出てきませんorz
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月07日(水) 09:33
by たいちう
フラッシュの判定が一番簡単だと思ったのですが、
役の評価よりも先にやることがありますね。
ちょっとルールを簡単にして試作しませんか?
【変更点】
1.手の変更はしない
2.役の評価はしない
【新しい仕様】
1.forループでカードを配ります(randで数字とスートを決定するということ)。
2.5枚のカードを配り終えてから、その5枚のカードを表示します。
まずはこれを作ってみてください。その後でだんだんと発展させましょう。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月07日(水) 19:09
by 南瓜
新しく作り直しました
#include <stdio.h>
#include <time.h>
int main (void) {
int card_total[4][13];/*全カードの枚数*/
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/
int i;
int draw_number;
int draw_mark;
srand(time(NULL));
printf("[ポーカー]\n");
printf("あなたの手札は\n");
for(i = 0; i < 5; i++) {
int draw_number, draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);
}
printf("\n");
return 0;
}
ただ、言われた仕様とズレてる気がします・・・
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月07日(水) 23:58
by たいちう
> ただ、言われた仕様とズレてる気がします・・・
はい。肝心な点でずれています。
配り終えてから表示です。
/* 五枚のカードをrandで決定 */
...
printf("決定しました。手札はこうです。\n");
/* 五枚のカードを表示 */
...
printf("念のため、もう一度同じ5枚をお見せします。\n");
/* さっきと同じ五枚のカードを表示 */
...
ということです。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月08日(木) 08:29
by 南瓜
やっぱりズレてましたか・・・
#include <stdio.h>
#include <time.h>
int main (void) {
int card_total[4][13];/*全カードの枚数*/
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/
int i;
int draw_number;
int draw_mark;
int n_hand[5];/*手札の数字を入れる配列*/
int m_hand[5];/*手札のマークを入れる配列*/
int display;/*手札を再表示する*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("あなたの手札は\n");
/* 五枚のカードをrandで決定 */
for(i = 0; i < 5; i++) {
int draw_number, draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを表示 */
}
printf("\n");
printf("念のため、もう一度5枚をお見せます。\n");
n_hand[5] = draw_number;
m_hand[5] = draw_mark;
printf("%s %s\n", n_hand, m_hand);/* さっきと同じ五枚のカードを表示 */
printf("\n");
return 0;
}
これがうまくいけば、仕様通りに成るはず?ですが、コンパイルして実行すると
(null)(null)と表示されてしまいうまく行きません
何がいけないんでしょうか?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月08日(木) 08:57
by バグ
n_hand[5] = draw_number;
m_hand[5] = draw_mark;
この部分おかしくないですか?
n_handとm_handは要素数が5の配列ですよね?
ならば、範囲は0~4ですから…
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月08日(木) 08:59
by たいちう
まず前半ですが、私の書いた仕様では、「5枚決定」→「5枚表示」です。
南瓜さんのソースでは、(「1枚決定」→「1枚表示」)を5回繰り返しています。
これを解決すれば後半も多分わかるでしょう。
> int n_hand[5];/*手札の数字を入れる配列*/
...
> n_hand[5] = draw_number;
あと↑も致命的です。
n_handで使用してよいインデックスは0~4です。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月08日(木) 22:33
by 南瓜
#include <stdio.h>
#include <time.h>
int main (void) {
int card_total[4][13];/*全カードの枚数*/
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/
int i;
int draw_number;
int draw_mark;
int hand[5];/*5枚の手札*/
int display;/*手札を再表示する*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("あなたの手札は\n");
/* 五枚のカードをrandで決定 */
for(i = 0; i < 5; i++) {
hand = draw_number, draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを表示 */
}
printf("\n");
printf("念のため、もう一度5枚をお見せます。\n");
for(i = 0; i < 5; i++) {
hand = draw_number, draw_mark;
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを再表示 */
}
printf("\n");
return 0;
}
書き直しました。これで5枚決定→5枚表示の仕様になったはず・・・
ただ、再表示のほうは、最期のカードのマークと数字の5回繰り返しになってしまいましたが
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月09日(金) 01:01
by たいちう
> 書き直しました。これで5枚決定→5 枚表示の仕様になったはず・・・
なってないです。
インデントを正しくすると、次のように書かれています。
for(i = 0; i < 5; i++) {
hand = draw_number, draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを表示 */
}
つまり、次の形です。
for(5回繰り返す) {
1枚のカードを決定する
1枚のカードを表示する
}
私の言う「5枚決定→5枚表示」は、次の形です。
for(5回繰り返す) {(このループでprintfは使わない)
1枚のカードを決定する
}
for(5回繰り返す) {(このループでrandは使わない)
1枚のカードを表示する
}
これができていないことに気付いてもらうために、
再表示も仕様に含めたのです。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月09日(金) 18:30
by 南瓜
#include <stdio.h>
#include <time.h>
int main (void) {
int card_total[4][13];/*全カードの枚数*/
char *number[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};/*カードの番号*/
char *mark[4] = {"♥","♦","♠","♣"};/*カードのマーク*/
int i;
int draw_number;
int draw_mark;
int hand[5];/*5枚の手札*/
int display;/*手札を再表示する*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("あなたの手札は\n");
/* 五枚のカードをrandで決定 */
for(i = 0; i < 5; i++) {
hand = draw_number, draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
}
for(i = 0; i < 5; i++) {
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを表示 */
}
printf("\n");
printf("念のため、もう一度5枚をお見せます。\n");
for(i = 0; i < 5; i++) {
printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを再表示 */
}
printf("\n");
return 0;
}
なるほど、しかし気づかなかったorz
書き直しましたが、同じ5枚が表示されるだけで
5回分カードを選ぶためには、あとどこをどう書き足せばいいですか?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月09日(金) 22:06
by box
> hand = draw_number, draw_mark;
これは何がしたいのですか?
日本語の文章で説明してみてください。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月10日(土) 00:56
by 南瓜
それは、5枚の手札を入れる配列hand[5]に、for文で5枚分用意して数字とマークをrandで決定してから
printfで5枚分表示してもらってると思ったんですが違いますか?
handなのは、多めに配列を用意しておけば表示されないことは無いだろうと思ってです
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月10日(土) 09:06
by たいちう
> それは、5枚の手札を入れる配列 hand[5]に、
> for文で5枚分用意して数字とマークをrandで決定してから
> printfで5枚分表示してもらってると思ったんですが違いますか?
違うのです。
もしも手札が「スペードのストレートフラッシュ」だった場合、
配列 hand[5] には、具体的に何の値が入ると思いますか?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月10日(土) 16:57
by 南瓜
hand[5]には♠が五つ(フラッシュ)と1,2,3,4,5みたいなストレートになる値が入っていていると思います。
hand[5] ={♠ 1, ♠ 2, ♠ 3, ♠ 4, ♠ 5}みたいな感じだと思います
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月10日(土) 17:17
by たいちう
int hand[5]; と宣言されています。
hand[0]に入るのは1つの整数値なので、1とか、12とか、100とか、-1とかが入りうるわけです。
スペードの1は、どんな数値として入りますか?
hand[1]~hand[4]は?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月10日(土) 23:30
by 南瓜
まず、rand関数で選ばれた数をマークの数4で割るので0,1,2,3が出て、これに1を足して
1,2,3,4となり、♠は3つ目に設定したのでdraw_mark = rand() % 4 + 1の結果が3になった時に
♠が選ばれて、
数字も同じように13で割って0~12が出て、1を足して1~13になり、draw_number = rand() % 13 + 1
で1が選ばれた時に1になると思います。
だから、hand[0] = マークの"1"と数字の"1"が数値として入っていて、
for文でhand[1]~hand[4]が決定されていくと思います
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 00:13
by たいちう
> だから、hand[0] = マークの"1"と数字の"1"が数値として入っていて、
> for文でhand[1]~hand[4]が決定されていくと思います
そこを間違えているからプログラムが思う通りに動かないのです。
int x;
x = 5;
と書いた場合、xに入っているのは数値の5です。
int y;
y = 2, 3;
と書いた場合、yに2と3が入っているわけではありません。
次のプログラムを結果を予想してから実行してください。
#include <stdio.h>
int main() {
int y;
y = 2, 3;
printf("x = %d\n", x);
return 0;
}
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 00:38
by box
> printf("x = %d\n", x);
コンパイルエラーが出ます。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 00:45
by 南瓜
y = 2, 3;
printf("x = %d\n", x);
なので、実行できないと思い、コンパイルしたら
やはり実行できませんでした
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 01:08
by conio
printf("x = %d\n", x);
この部分は、
---------------------------
printf("y = %d\n", y);
---------------------------
の誤植であると思われます。
まぁ、それはともかく、コードを修正して
「1、2」と表示されるのかどうか?
を調べてみてはどうでしょう。
ついでに、結果を見た後に『コンマ演算子』で調べてみるのもいいかな と思います。

Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 01:09
by Ma
>なので、実行できないと思い、コンパイルしたら
>やはり実行できませんでした
x と y をうちまちがえているだけ。
そこは自分で修正して、実行してください。
*追記
C言語かC++言語入門の配列を読み直してらいかがでしょうか?

Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 10:04
by たいちう
とほほ。つまらんミスで混乱させてしまいましたね。
失礼しました。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 11:18
by 南瓜
こういうことでしょうか?
#include <stdio.h>
int main() {
int x, y;
x = 2;
y = 3;
printf("y = %d,%d\n",x, y);
return 0;
}
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 11:33
by たいちう
> こういうことでしょうか?
そうです。これを踏まえて、↓が間違いなのは判りますか?
> hand = draw_number, draw_mark;
...
> だから、 hand[0] = マークの"1"と数字の"1"が数値として入っていて、
> for文でhand[1]~hand[4]が決定されていくと思います
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 11:41
by 南瓜
handのの部分と
hand = draw_number, draw_mark; に
変数が2つあるのが間違い
でいいでしょうか?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 12:10
by Ma
結論
マーク用と数値用の変数を別々に用意するか、変換式をつくる などの対処が必要。
変換式なら
100*マークの値+数字の値
など。
混乱しにくい点で前者推奨。

Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 19:53
by 南瓜
int i;
int draw_number;
int draw_mark;
int n_hand[5];/*5枚の数字の手札*/
int m_hand[5];/*5枚のマークの手札*/
int display;/*手札を再表示する*/
srand(time(NULL));
printf("[ポーカー]\n");
printf("あなたの手札は\n");
/* 五枚のカードをrandで決定 */
for(i = 0; i < 5; i++) {
n_hand[5] = draw_number;
m_hand[5] = draw_mark;
draw_number = rand() % 13 + 1;/*数字を出す*/
draw_mark = rand() % 4 + 1;/*マークを出す*/
// printf("%s %s", m_hand[5], n_hand[5]);
printf("%s %s", mark[draw_mark-1], number[draw_number-1]);/* 五枚のカードを表示 */
}
printf("\n");
printf("念のため、もう一度5枚をお見せます。\n");
// for(i = 0; i < 5; i++) {
// printf("%s %s",draw_mark[mark-1], draw_number[number-1]);/* 五枚のカードを再表示 */
// }
printf("\n");
return 0;
}
数字用とマーク用に変数を新たに書き足したんですが(同じ部分は省略しました)上記の様にコメントしないと
うまく作動しません。
特にprintf("%s %s", m_hand[5], n_hand[5]);を書けば、printf("%s %s", mark[draw_mark-1], number[draw_number-1]);は
いらないと思ったんですが、printf("%s %s", m_hand[5], n_hand[5]);のみにするとBus Errorとやらが
出てしまい、うまく行きません
どこがいけないんでしょうか?
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 20:18
by たいちう
> for(i = 0; i < 5; i++) {
> n_hand[5] = draw_number;
> m_hand[5] = draw_mark;
> draw_number = rand() % 13 + 1;/*数字を出す*/
> draw_mark = rand() % 4 + 1;/*マークを出す*/
> }
1つ目のループについて説明します。
まず、int n_hand[5]; と定義したいるので、
n_hand[0] から n_hand[4]が使用できます。
n_hand[5]というのは宣言した配列の範囲を超えているので不正アクセスです。
またループで5回繰り返しますが、計算結果を配列に順番に代入するためには、
for (i = 0; i < 5; i++) {
n_hand = ...;
}
と書きます。
最後に、draw_number[5]をn_handに代入したいようですが、
ループの1回目では、draw_numberは初期化すらされていません。
ループの5回目で計算したdraw_numberの値は、配列に代入されません。
配列の基本を全く理解できていないようです。
この問題を一時中断して、配列の復習をすることをお勧めします。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月11日(日) 21:18
by 南瓜
わかりました。ご指摘ありがとうございますm(_ _)m
復習をし直して、もう少しマトモなポーカープログラムが
書けてからまた質問します
ありがとうございました。
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月12日(月) 00:53
by たいちう
配列の例題として、1~5の2乗を計算して表示しましょうか。
for(5回繰り返す) {(このループでprintfは使わない)
2乗の計算をする
}
for(5回繰り返す) {(このループで2乗の計算は行わない)
計算結果を表示
}
実行結果を次のようにしましょう。
1
4
9
16
25
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月14日(水) 15:45
by 南瓜
#include <stdio.h>
int main (void) {
int i;
int hako[5];
for(i = 0; i < 5; i++) {
hako = (i+1) *(i+1);
}
for(i = 0; i < 5; i++) {
printf("%d\n", hako);
}
return 0;
}
わざわざ例題までありがとうございます。
ただ、解決!を押してしまったのでここに載せていいのか
迷いました^^;
Re:C言語でポーカーを作っているんですが
Posted: 2010年4月14日(水) 16:13
by たいちう
OKです。
これを踏まえて、No. 50464を直せますか?
難しければスートをなくして数字だけでも結構です。