C言語関係掲示板

過去ログ

No.1080 トランプカードのシャッフルと表示

[戻る] [ホームページ]
No.14185

トランプのカードを表す構造体について教えて下さい。
投稿者---tomo(2004/05/23 17:32:33)


/* トランプカード */

#include <stdio.h>
#include <stdlib.h>

#define SPADE 1
#define CLUB 2
#define HEART 3
#define DIAMOND 4

struct card
{
    int type;   // 種類
    int value;  // 値
};

void init( struct card * );
void prCard( struct card * );
void shutfle( struct card * );

int main( void )
{
    struct card cards[52];  // 52枚分のカード情報を格納
    int i;
    
    init( cards );
    prCard( cards );
    
    printf( "\n--- shutfle!! ---\n" );
    for ( i = 0; i < 100; i++ )
    {
        shutfle(cards);
    }
    
    prCard( cards );
    
    return 0;
}
                    // カードを初期化
void init( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 13; i++ )
    {
        (pCard + i)->type = SPADE;
        (pCard + i)->value = i+1;
        (pCard + i + 13)->type = CLUB;
        (pCard + i + 13)->value = i+1;    
        (pCard + i + 26)->type = HEART;
        (pCard + i + 26)->value = i+1;    
        (pCard + i + 39)->type = DIAMOND;
        (pCard + i + 39)->value = i+1;    
    }
}

                    // カードを表示
void prCard( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 5; i++ )
        printf("pCard[%d] : type %d value %2d\n",
            i ,(pCard + i)->type, (pCard + i)->value );
}

                    // カードをシャッフル
void shutfle( struct card *pCard )
{
        struct card work;
        int num1, num2,i;
    
        for ( i = 0; i < 3000; i++ ) 
        {
                    // 乱数を発生    
            num1 = rand() % 52; // ---( 1 )
            num2 = rand() % 52;
            
            if ( num1 != num2 )
             {
                work = *(pCard + num1); // ---( 2 )
                *(pCard + num1) = *(pCard + num2);
                *(pCard + num2) = work;
             }
        }
} 



質問:1 
init関数内で
(pCard + i)-&gt;type = SPADE;
(pCard + i)-&gt;value = i+1;
,鉢△篭饌療に何を表しているのでしょうか。
,SPADE(タイプ)を13枚分初期化しているのですか?
△SPADE(値)を13枚分初期化しているのですか?
あまり理解できていません。どうぞ宜しくお願いします。
初心者すぎる質問ですいません。



No.14186

Re:トランプのカードを表す構造体について教えて下さい。
投稿者---ぽこ(2004/05/23 17:47:55)


>質問:1 
>init関数内で
>(pCard + i)-&gt;type = SPADE;
>(pCard + i)-&gt;value = i+1;
>,鉢△篭饌療に何を表しているのでしょうか。
>,SPADE(タイプ)を13枚分初期化しているのですか?
>△SPADE(値)を13枚分初期化しているのですか?
>あまり理解できていません。どうぞ宜しくお願いします。
>初心者すぎる質問ですいません。

微妙に違います。
(1)(2)はスペードのカード1枚分を初期化しています。
それをfor文で13回ループさせてスペードのカードを13枚分初期化しています。
(pCard + i)をpCard[i]と置き換えてみれば読み易くなるかもしれません。



No.14206

Re:トランプのカードを表す構造体について教えて下さい。
投稿者---tomo(2004/05/24 22:53:53)


どうもありがとうございます。理解できました。
また質問ですが・・。

main()関数内の下記の関数の呼び出しで以下の(cards)は
何を指しているのでしょうか?

init( cards );
prCard( cards );
shutfle(cards);

main関数内で→prCard( cards );が2回でてくるのはなぜですか?



/*init( cards );
prCard( cards );

printf( &quot;\n--- shutfle!! ---\n&quot; );
for ( i = 0; i &lt; 100; i++ )
{
shutfle(cards);
}

prCard( cards );*/

prCard( struct card *pCard )←カードを表示する関数の定義で
26回ループしているのはなぜでしょうか?

なんど見ても理解ができません。,亮遡笋呂个げているかもしれませんが
どうか教えて下さい。宜しくお願い致します。








/* トランプカード */

#include <stdio.h>
#include <stdlib.h>

#define SPADE 1
#define CLUB 2
#define HEART 3
#define DIAMOND 4

struct card
{
    int type;   // 種類
    int value;  // 値
};

void init( struct card * );
void prCard( struct card * );
void shutfle( struct card * );

int main( void )
{
    struct card cards[52];  // 52枚分のカード情報を格納
    int i;
    
    init( cards );
    prCard( cards );
    
    printf( "\n--- shutfle!! ---\n" );
    for ( i = 0; i < 100; i++ )
    {
        shutfle(cards);
    }
    
    prCard( cards );
    
    return 0;
}
                    // カードを初期化
void init( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 13; i++ )
    {
        (pCard + i)->type = SPADE;
        printf("%d\n",(pCard + i)->type);
        (pCard + i)->value = i+1;
        printf("%d\n",(pCard + i)->value);
        (pCard + i + 13)->type = CLUB;
        (pCard + i + 13)->value = i+1;    
        (pCard + i + 26)->type = HEART;
        (pCard + i + 26)->value = i+1;    
        (pCard + i + 39)->type = DIAMOND;
        (pCard + i + 39)->value = i+1;    
    }
}

                    // カードを表示
void prCard( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 26; i++ )
        printf("pCard[%d] : type %d value %2d\n",
            i ,(pCard + i)->type, (pCard + i)->value );
}

                    // カードをシャッフル
void shutfle( struct card *pCard )
{
        struct card work;
        int num1, num2,i;
    
        for ( i = 0; i < 3000; i++ ) 
        {
                    // 乱数を発生    
            num1 = rand() % 52; // ---( 1 )
            num2 = rand() % 52;
            
            if ( num1 != num2 )
             {
                work = *(pCard + num1); // ---( 2 )
                *(pCard + num1) = *(pCard + num2);
                *(pCard + num2) = work;
             }
        }
} 




No.14214

Re:トランプのカードを表す構造体について教えて下さい。
投稿者---ぽこ(2004/05/25 04:08:23)


>main()関数内の下記の関数の呼び出しで以下の(cards)は
>何を指しているのでしょうか?

main()関数内で定義されているstruct card cards[52]の先頭を
指します。&cards[0]と同義です。

>main関数内で→prCard( cards );が2回でてくるのはなぜですか?

これは、プログラムを作成した人に聞くしか正解は判らないと思いますが、
1回目のprCard()の呼び出しでinit()によって変化したであろうcards[]の
内容を表示します。これは初期化が上手く行ったかどうかの確認を行って
いるのかと思います。

2回目のprCard()はshutfle()によって変化したであろうcards[]の内容を
確認するためではないでしょうか?

>prCard( struct card *pCard )←カードを表示する関数の定義で
>26回ループしているのはなぜでしょうか?

これもプログラム作成者に意図を聞かないと正解は判らないと思います。
関数の振る舞い自体は"cards[]の先頭から26個の要素を出力する"ように
なっています。
この振る舞いがプログラム作成者の意図に沿うものであれば、プログラム
作成者に質問するのが一番だと思います。

#コメントが"「すべての」カードを表示"となっていれば、
#26回ループじゃなくて52回ループじゃないの?と突っ込めるのですが。。
#この場合もコメントが正しいのか、プログラムが正しいのか判断つきませんが。。



No.14232

Re:トランプのカードを表す構造体について教えて下さい。
投稿者---tomo(2004/05/25 19:22:06)


ぽこさん。。。

本当にご丁寧にご返信頂きまして本当にありがとうございます。
とてもわかりやすく感激です。。
ひとつひとつプログラムを理解しようと必死ですが・・
ほんと難しいですね。。
このプログラムで初めて乱数が発生するプログラムをみましたが
やっぱわからないのでこれから乱数についてすこし勉強してから
質問しようと思います。。
ほんと感謝です!!
納得いくまでがんばりま〜す^^



No.14235

やはり理解できません。。
投稿者---tomo(2004/05/25 21:22:56)


shutfle関数内の

num1 = rand() % 52; // ---( 1 )
num2 = rand() % 52;

rand()←は具体的に何なのでしょうか?
数値的にあらわすと??
rand()関数は乱数を使用する関数とはわかったのですが・・・。



/* トランプカード */

#include <stdio.h>
#include <stdlib.h>

#define SPADE 1
#define CLUB 2
#define HEART 3
#define DIAMOND 4

struct card
{
    int type;   // 種類
    int value;  // 値
};

void init( struct card * );
void prCard( struct card * );
void shutfle( struct card * );

int main( void )
{
    struct card cards[52];  // 52枚分のカード情報を格納
    int i;
    
    init( cards );
    prCard( cards );
    
    printf( "\n--- shutfle!! ---\n" );
    for ( i = 0; i < 100; i++ )
    {
        shutfle(cards);
    }
    
    prCard( cards );
    
    return 0;
}
                    // カードを初期化
void init( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 13; i++ )
    {
        (pCard + i)->type = SPADE;
        printf("%d\n",(pCard + i)->type);
        (pCard + i)->value = i+1;
        printf("%d\n",(pCard + i)->value);
        (pCard + i + 13)->type = CLUB;
        (pCard + i + 13)->value = i+1;    
        (pCard + i + 26)->type = HEART;
        (pCard + i + 26)->value = i+1;    
        (pCard + i + 39)->type = DIAMOND;
        (pCard + i + 39)->value = i+1;    
    }
}

                    // カードを表示
void prCard( struct card *pCard )
{
    int i;
    
    for ( i = 0; i < 5; i++ )
        printf("pCard[%d] : type %d value %2d\n",
            i ,(pCard + i)->type, (pCard + i)->value );
}

                    // カードをシャッフル
void shutfle( struct card *pCard )
{
        struct card work;
        int num1, num2,i;
    
        for ( i = 0; i < 3000; i++ ) 
        {
                    // 乱数を発生    
            num1 = rand() % 52; // ---( 1 )
            num2 = rand() % 52;
            
            if ( num1 != num2 )
             {
                work = *(pCard + num1); // ---( 2 )
                *(pCard + num1) = *(pCard + num2);
                *(pCard + num2) = work;
             }
        }
} 




No.14236

Re:やはり理解できません。。
投稿者---monkey(2004/05/25 21:31:44)


>rand()←は具体的に何なのでしょうか?

ここの管理者様のホームページは参照しましたか?
http://www9.plala.or.jp/sgwr-t/lib/rand.html


No.14244

Re:やはり理解できません。。
投稿者---tomo(2004/05/25 23:31:36)


どうもありがとうございます。。

やはりこの式が printf→(rand()%10+1)
具体的にあの結果になっているのかが
よくわかりません。。
rand()%10+1はなぜ剰余演算子を使用していて
10+1??なのでしょうか・・。
頭悪すぎてすみません。



#include        <stdio.h>
#include        <stdlib.h>

int main(void)
{
        int i;

        /* 1〜10の擬似乱数を100個発生 */
        for (i=0; i<100; i++) {
                printf("%3d ",rand()%10+1);
        }
        printf("\n");

        return 0;
}




No.14246

Re:やはり理解できません。。
投稿者---ぽこ(2004/05/25 23:41:01)


>rand()%10+1はなぜ剰余演算子を使用していて
>10+1??なのでしょうか・・。

ある数字を10で割ったときの余りの最小値は何になると思いますか?
最大値は何になると思いますか?


No.14272

Re:やはり理解できません。。
投稿者---tomo(2004/05/26 22:38:00)


>>rand()%10+1はなぜ剰余演算子を使用していて
>>10+1??なのでしょうか・・。
>
>ある数字を10で割ったときの余りの最小値は何になると思いますか?
>最大値は何になると思いますか?

最小値が0で、最大値が9。。
+1をしないと1〜10まで表せないということですね。。
納得です。。ありがとうございました。。


No.14260

Re:やはり理解できません。。
投稿者---nop(2004/05/26 13:00:43)


>rand()%10+1はなぜ剰余演算子を使用していて
>10+1??なのでしょうか・・。

演算子の優先順位を考えると

 ( rand()%10 ) +1

となります。
で、何故この様な演算をしているかと言うと、
まず、「rand()%10」は、
「0〜RAND_MAX」までの疑似乱数を 10 で割った余りを求めます。
これは、疑似乱数の値が何であっても、
10 で割った余りは 0〜9 になるためです。
そして、「+1」しているのは、
求めたい数値の範囲が 1〜10 なので、
0〜9 の範囲の値に +1 すると 1〜10 の値が求まる訳です。


No.14296

Re:やはり理解できません。。
投稿者---tomo(2004/05/28 22:35:19)


nopさん大変わかりやすく説明して頂きまして
本当にありがとうございます。
頭の悪い私でも完璧に理解できました。。
前回、返信したはずなのですが何故か、
返信されていませんでした。本当にありがとう御座いました。。