ビンゴ【初心者です】

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: ビンゴ【初心者です】

Re: ビンゴ【初心者です】

#10

by rriimm5 » 7年前

なるほどわかりました。ありがとうございます。

Re: ビンゴ【初心者です】

#9

by かずま » 7年前

rriimm5 さんが書きました:
7年前
if (scanf("%d", &num) != 1) return 1;
の部分がよくわからないのですが教えていただけませんか?
2つの意味があります。
・ビンゴにならなくても終了させるため
・間違って数字以外を入力したときの暴走を防ぐため

bingo が出て終了するのが正常だとしたら、
途中で終了するのは正常じゃないということで
return 1; にしましたが、return 0; でも構いません。
rriimm5 さんが書きました:
7年前
scanf("%d", &num);
ではだめなのでしょうか?
試しに数字以外の文字を入力してみてください。

Re: ビンゴ【初心者です】

#8

by rriimm5 » 7年前

もしかして、scanf文で文字を打ち込んだときに終了させるようにするためでしょうか?
return 1で異常終了させるということだと思うのですがあっていますか?

Re: ビンゴ【初心者です】

#7

by rriimm5 » 7年前

ありがとうございます
ループを抜ける方法に無駄があったみたいですね。
あと、
if (scanf("%d", &num) != 1) return 1;
の部分がよくわからないのですが教えていただけませんか?
scanf("%d", &num);
ではだめなのでしょうか?

Re: ビンゴ【初心者です】

#6

by かずま » 7年前

穴をあけた時、ビンゴにならなくても、二重ループを抜けて
次の num の入力に行ったほうがよいでしょう。

そこで、i = N; break; を追加することで、内側の j のループを
抜けた後、外側の i のループも終了するようにしました。

コード:

#include <stdio.h>   // scanf, printf, putchar, puts
#include <stdlib.h>  // srand, rand
#include <time.h>    // time

#define N 5  // N は 3, 5, 7, 9

int main(void)
{
    int i, j, k = 0, num = 100, x[N][N], c[100];

    for (i = 0; i < 100; i++) c[i] = i; // ビンゴ表作成
    srand(time(NULL));
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++)
            c[x[i][j] = rand() % num] = c[--num];

    x[N/2][N/2] = -1;

    while (k != N) {    // ビンゴ実行
        for (i = 0; i < N; i++, putchar('\n'))    // ビンゴ表出力
            for (j = 0; j < N; j++) printf("%3d", x[i][j]);

        printf("num = "); // 入力
        if (scanf("%d", &num) != 1) return 1;

        for (i = 0; i < N && k != N; i++)  // ビンゴ検出
            for (j = 0; j < N; j++) 
                if (x[i][j] == num)  {
                    x[i][j] = -1;      // 穴開け
                    for (k = 0; k < N && x[k][j] == -1; k++) ;
                    if (k == N) break;     // 縦ビンゴ
                    for (k = 0; k < N && x[i][k] == -1; k++) ;
                    if (k == N) break;     // 横ビンゴ
                    if (i == j) {
                        for (k = 0; k < N && x[k][k] == -1; k++) ;
                        if (k == N) break; // 斜め右下ビンゴ
                    }
                    else if (i + j == N - 1) {
                        for (k = 0; k < N && x[k][N - 1 - k] == -1; k++) ;
                        if (k == N) break; // 斜め右上ビンゴ
                    }
                    i = N;
                    break;
                }
    }
    puts("bingo");
    return 0;
}

Re: ビンゴ【初心者です】

#5

by かずま » 7年前

かずま さんが書きました:
7年前
x[N/1][N/2] = -1 にしましょう。
x[N/2][N/2] = -1; の間違いです。

Re: ビンゴ【初心者です】

#4

by かずま » 7年前

N を 3, 7, 9 などに変更するなら、
x[2][2] = -1; はまずいでしょう。
x[N/1][N/2] = -1 にしましょう。

N は 11 以上にはできませんね。
入れる数が 99までですから。

Re: ビンゴ【初心者です】

#3

by かずま » 7年前

rriimm5 さんが書きました:
7年前
ビンゴを作ってみたのですが、もっと改良の余地があれば教えてください。
・乱数発生で、既に出た数を生成することがあり、
 やり直しをするのは好ましくない。
・穴あけしない時にビンゴのチェックは不要。
・入れ子になってない限り、for文で異なるループ変数を使う必要はない。
・ビンゴのチェックで、-1 でないものが出てきたときにループを
 抜ければ、ループ変数が bingo5 の代わりになる。

次のコードを参考にプログラムを書き直してみてください。

コード:

#include <stdio.h>   // scanf, printf, puts, putchar
#include <stdlib.h>  // srand, rand
#include <time.h>    // time

#define N 5

int main(void)
{
    int i, j, k = 0, num, x[N][N], c[100];

    for (i = 0; i < 100; i++) c[i] = i; // ビンゴ表作成
    srand(time(NULL));
    num = 100;
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++)
            x[i][j] = rand() % num, c[x[i][j]] = c[--num];
    x[2][2] = -1;

    while (k != N) {    // ビンゴ実行
        for (i = 0; i < N; i++, putchar('\n'))    // ビンゴ表出力
            for (j = 0; j < N; j++) printf("%3d", x[i][j]);

        printf("num = "); // 入力
        if (scanf("%d", &num) != 1) return 1;

        for (i = 0; i < N && k != N; i++)  // ビンゴ検出
            for (j = 0; j < N; j++)
                if (x[i][j] == num) {
                    x[i][j] = -1;      // 穴開け
                    for (k = 0; k < N && x[k][j] == -1; k++) ;
                    if (k == N) break;     // 縦ビンゴ
                    for (k = 0; k < N && x[i][k] == -1; k++) ;
                    if (k == N) break;     // 横ビンゴ
                    if (i == j) {
                        for (k = 0; k < N && x[k][k] == -1; k++) ;
                        if (k == N) break; // 斜め右下ビンゴ
                    }
                    else if (i + j == N - 1) {
                        for (k = 0; k < N && x[k][N - 1 - k] == -1; k++) ;
                        if (k == N) break; // 斜め右上ビンゴ
                    }
                }
    }
    puts("bingo");
    return 0;
}

Re: ビンゴ【初心者です】

#2

by usao » 7年前

・処理を必要な回数だけ行うようにしてみてはどうでしょう.
 例えば,
 穴をあける とか 斜め方向のビンゴ判定 とか
 何度も繰り返す必要はないですよね.
 ビンゴの判定自体,穴が開かなければやる必要ないですし.

・途中で止める方法が無いように見えます.ビンゴになるまで終われません.
 例えば負の値を入力したら中止とか,そういうのがあってもよいのでは.

・あとは初期の表作成の方法の工夫とかですかね.
 現在の方法だと,運が悪いと永久に終わらないかもしれない(!)ですよね.
 所定の手順で必ず完了するような方法にしてみてはどうでしょう.

・動作面ではないですが,変数名が意味不明なのも改善したいところ.

ビンゴ【初心者です】

#1

by rriimm5 » 7年前

ビンゴを作ってみたのですが、もっと改良の余地があれば教えてください。
今はポインタについて学習しています。
初心者なので間違いなどがあったらわかりやすく指摘していただけると幸いです。

0~99までの乱数を使った5×5のビンゴで、穴は-1で表しています。

コード:

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

#define N 5

int main(void)
{
    int a, i, i1, i3, i4, j, j2, j3, j4, num, bingo5, x[N][N], c[100];

    // ビンゴ表作成
    for (i = 0; i < 100; i++) {
        c[i] = 1;
    }
    srand(time(NULL));
    for (i = 0; i < N; i++) {
        for (j = 0; j < N;) {
            a = rand() % 100;
            if (c[a] == 1) {
                x[i][j] = a;
                c[a] = 0;
                j++;
            }
        }
    }
    x[2][2] = -1;

    // ビンゴ実行
    while(1) {
        // ビンゴ表出力
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                printf("%3d", x[i][j]);
            }
            printf("\n");
        }

        // 入力
        printf("num = ");
        scanf("%d", &num);

        // ビンゴ検出
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                // 穴開け
                if (x[i][j] == num) {
                    x[i][j] = -1;
                }

                // 縦ビンゴ
                bingo5 = 0;
                for (i1 = 0; i1 < N; i1++) {
                    if (x[i1][j] == -1) {
                        bingo5 += 1;
                    }
                }
                if (bingo5 == 5) {
                    break;    
                }

                // 横ビンゴ
                bingo5 = 0;
                for (j2 = 0; j2 < N; j2++) {
                    if (x[i][j2] == -1) {
                        bingo5 += 1;
                    }
                }
                if (bingo5 == 5) {
                    break;    
                }

                // 斜め右下ビンゴ
                bingo5 = j3 = 0;
                for (i3 = 0; i3 < N; i3++) {
                    if (x[i3][j3] == -1) {
                        bingo5 += 1;
                    }
                    j3++;
                }
                if (bingo5 == 5) {
                    break;    
                }
                
                // 斜め右上ビンゴ
                bingo5 = j4 = 0;
                for (i4 = 4; i4 >= 0; i4--) {
                    if (x[i4][j4] == -1) {
                        bingo5 += 1;
                    }
                    j4++;
                }
                if (bingo5 == 5) {
                    break;    
                }
            }
            if (bingo5 == 5) {
                break;
            }
        }
        if (bingo5 == 5) {
            printf("bingo\n");
            break;
        }
    }
    
    return 0;
}

ページトップ