質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

確率、乱数分布を再現したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 893

dskn1121

score 26

前提・実現したいこと

学校で現在armadilloを使った組込み課題をやっています。
わたしは1000円自販機を再現しようとプログラムを組んでいますが難しく、手詰まりの状態です。

確率を設けて豪華な賞品には低い確率を設けたいのですがどこにどういれていけばいいかわかりません。
最悪、乱数でやりますがその辺をぜひ教えてください、お願いします。

該当のソースコード

このメイン文を改造して実現させたいのでお力添えよろしくお願いします。

int main(void) {
    int fd;
    int i;
    int a;
    int ret;
    struct tsdev *ts;
    struct ts_sample samp;
    int enable = 1;
    int led_state = 0;

    int tmp;

    // フレームバッファをオープンします。
    // オープンに失敗した場合はエラーで終了します。
    if ((fd = open(FBDEV_FILE, O_RDWR)) < 0) {
        perror("open(fb)");
        return 1;
    }

    // mmapによりバッファの先頭アドレスを取得します。
    pfb = mmap(0, SCREENSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    // 取得に失敗した場合はエラーで終了します。
    if (pfb == MAP_FAILED){
        perror("mmap");
        return 1;
    }

    // LCDの画面表示を全て消去するために、
    // 取得したアドレスから確保領域を0で初期化します。
    for (i = 0; i < SCREENSIZE / BYTES_PER_PIXCEL; i++)
        pfb[i] = 0;

    // タッチスクリーンイベントファイルをオープンします。
    ts = ts_open(TSDEV_FILE, 0);
    // オープンに失敗した場合はエラーで終了します。
    if (!ts){
        perror("ts_open");
        return 1;
    }

    // コンフィグファイルを読み込み、フィルタモジュールをロードします。
    ret = ts_config(ts);
    // ロードに失敗した場合はエラーで終了します。
    if (ret){
        perror("ts_config");
        return 1;
    }



    // 画像データを読み込み、ボタンのカラーデータを取得します。
    if (ret = load_bmp())
        return ret;
/////////////////////////////////////////////////
    // LCDに各種ボタンを表示します。
//    update_button(BTN_deru, BTN_kieru);


    update_button(BTN_LIGHT1, BTN_OFF);
    update_button(BTN_LIGHT2, BTN_OFF);
    update_button(BTN_LIGHT3, BTN_OFF);
    update_button(BTN_LIGHT4, BTN_OFF);
    update_button(BTN_LIGHT5, BTN_OFF);
    update_button(BTN_LIGHT6, BTN_OFF);
    update_button(BTN_LIGHT7, BTN_OFF);
    update_button(BTN_LIGHT8, BTN_OFF);


//////////////////////////////////////////////////


    // タッチスクリーンイベントを受け付ける間ループさせます。
    for(;;){
        // タッチスクリーンイベントから、圧力・x座標・y座標を読み込みます。
        ret = ts_read(ts, &samp, 1);
        // 読み込みに失敗した場合はエラーで終了します。
        if (ret < 0){
            perror("ts_read");
            return 1;
        }

        // タッチイベントが1個以外の場合は無視します。
        if (ret != 1)
            continue;

        // 圧力がなくなったら、次に圧力がかかった初回のみ処理を実行するように、
        // enable に 1を設定します。
        if (samp.pressure == 0){
            enable = 1;
            continue;
        }



////////////////////////////////////////////////////////////////////////////////////////////////


        // タッチされたボタンに該当する処理を実行します。
        if (enable){
            // タッチされた座標を調べ、識別子を取得します。
            ret =  xy2button(samp.x, samp.y);


/*            while(0){
                //ランダムに画像を出す処理

            }
*/


////////////////////////////////////////////////////////////////////////////////////////////////////

            // 識別子によって処理を変えます。
            switch(ret){


            // 画像を出す処理
            case  BTN_LIGHT1 :
                // 対象のLEDを点灯させるために、立てるビットを算出します。
                tmp = ret - BTN_LIGHT1;
                // 対象のLEDが点灯か消灯かを判定します。
                if (led_state & (1 << tmp)){
                    // 点灯していた場合はOFFボタンを表示します。
                    update_button(ret, BTN_OFF);
                    // タッチされたボタンに対応するLEDの対象ビットを落とします。
                    led_state &= ~(1 << tmp);
                    // 落としたビットを反映し、対象のLEDを消灯します。
                    change_led(led_state);
                } else {
                    // 消灯していた場合はONボタンを表示します。
                    update_button(ret, BTN_ON);
                    // タッチされたボタンに対応するLEDの対象ビットを立てます。
                    led_state |= 1 << tmp;
                    // 立てたビットを反映し、対象のLEDを点灯します。
                    change_led(led_state);
                }
                break;


            case  BTN_LIGHT2 :
                // 対象のLEDを点灯させるために、立てるビットを算出します。
                tmp = ret - BTN_LIGHT1;
                // 対象のLEDが点灯か消灯かを判定します。
                if (led_state & (1 << tmp)){
                    // 点灯していた場合はOFFボタンを表示します。
                    update_button(ret, BTN_OFF);
                    // タッチされたボタンに対応するLEDの対象ビットを落とします。
                    led_state &= ~(1 << tmp);
                    // 落としたビットを反映し、対象のLEDを消灯します。
                    change_led(led_state);
                } else {
                    // 消灯していた場合はONボタンを表示します。
                    update_button(ret, BTN_ON);
                    // タッチされたボタンに対応するLEDの対象ビットを立てます。
                    led_state |= 1 << tmp;
                    // 立てたビットを反映し、対象のLEDを点灯します。
                    change_led(led_state);
                }
                break;



            case  BTN_LIGHT3 :
                // 対象のLEDを点灯させるために、立てるビットを算出します。
                tmp = ret - BTN_LIGHT1;
                // 対象のLEDが点灯か消灯かを判定します。
                if (led_state & (1 << tmp)){
                    // 点灯していた場合はOFFボタンを表示します。
                    update_button(ret, BTN_OFF);
                    // タッチされたボタンに対応するLEDの対象ビットを落とします。
                    led_state &= ~(1 << tmp);
                    // 落としたビットを反映し、対象のLEDを消灯します。
                    change_led(led_state);
                } else {
                    // 消灯していた場合はONボタンを表示します。
                    update_button(ret, BTN_ON);
                    // タッチされたボタンに対応するLEDの対象ビットを立てます。
                    led_state |= 1 << tmp;
                    // 立てたビットを反映し、対象のLEDを点灯します。
                    change_led(led_state);
                }
                break;



            // 圧力がなくなるまで、同じ処理をしないように
            // enableに0を設定します。
            enable = 0;
        }
    }


    // タッチスクリーンイベントファイルをクローズします。
    ts_close(ts);
    // フレームバッファのために確保した領域を開放します。
    munmap(pfb, SCREENSIZE);
    // フレームバッファをクローズします。
    close(fd);

    return 0;

//関数の紹介

// ビットマップ形式の画像ファイルを読み込み、
// ボタンのカラーデータを取得する関数。
int load_bmp(void)

// LCDに画像を表示する関数。
void draw_image(int index, int x0, int y0)

// ボタンを表示する関数。
void update_button(int index, int on)

// 座標に対応するボタン識別子を返す関数。
int xy2button(int x, int y)

補足情報(言語/FW/ツール等のバージョンなど)

C言語 Linux

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

以下、実際にどうだかはわかりませんが、参考になると思います。
自販機の当たりプログラム組んだことある俺が仕組み教えてやる

「1000円自販機」ということであれば、当然赤字にならないようにということで、次のようなロジックになるかと思います。
上のリンクにある日数判定も入れるのも手ですよね。

100円の景品:毎回
500円の景品:5回に一度
1000円の景品:10回に一度
10000円の景品:100回に一度

ロジックを決めて、それを実装するだけで、乱数による抽選は不要かと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る