ビンゴーゲーム
去年の講義の課題でビンゴーゲームを作ったのですが、よくこんなものが書けたなと感心してしまいました。今の自分に同じようなものを作れと言われると、書ける自信がありません。
アルゴリズム自体というよりも、プレイヤーがプレイしやすいようにUIとかを色々考えているのがほんとに素晴らしいと思うし、昔の自分を褒めてあげたい。
ただ、今の自分が与えられるアドバイスとしては、入力を整数型(int)じゃなくて、文字列型(char)にした方が、入力エラーに対応できるんじゃないかとおもいますねぇ。
/* ビンゴゲーム */ #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 5 #define M 100 /* ビンゴのカードをを作る */ /* 111は閉じている、100は開いている */ void card(int s[][N], int n[][N]) { for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { s[i][j] = 111; n[i][j] = 0; } } s[N/2][N/2] = 100; n[N/2][N/2] = 1; } /* カードの状態を出力する */ /* 見やすくするため111はX、100はOにする */ void out(int s[][N]) { for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if(s[i][j] == 111) printf(" X "); else if(s[i][j] == 100) printf(" O "); else printf("%3d ", s[i][j]); } printf("\n"); } printf("\n\n\n"); } int main(void) { int i, j, k, a[N][N], s[N][N], n[N][N], x[M], y[M], c, L, A, fa, fb, fc, fd, z; /* ゲームのイントロ */ printf("\n-----> BINGO GAME <-----\n\n"); printf("何回挑戦する?(5 ~ 100): "); scanf("%d", &L); printf("\n\n[0 ~ 99 の数を入力してね]\n\n"); card(s, n); out(s); //カードを出力 /* 数字の被り防止のため、0~99を配列に入れ真理値を1にする */ for(i = 0; i < M; i++) { x[i] = 1; y[i] = 1; } /* 乱数でカードに数字を振り分ける */ /* 被る数があればやり直す */ srand(time(NULL)); for(i = 0; i < N; i++) { j =0; while(j < N) { k = rand() % M; if(x[k] == 1) { a[i][j] = k; x[k] = 0; } else continue; j++; } } a[N/2][N/2] = 100; //カードの中心は入力値の範囲外で常に真 //out(a); //デバッグ用、onにすると予めに答えがわかる /* 入力値がカードの値に一致するかどうか、ビンゴの判定、カウント */ c = L; while(c > 0) { //挑戦回数のカウント printf("あと %d 回\n\n", c); printf("A = "); scanf("%d", &A); if(A < 0 || A > 99) { //入力値の範囲を制限 printf("(0 ~ 99) の数を入力しろ\n\n\n"); continue; } if(y[A] == 1) { //入力値が被らなかった場合 y[A] = 0; int flag = 0; for(i = 0; i < N; i++) for(j =0; j < N; j++) { if(A == a[i][j]) { //数値の一致を判定 printf("GREAT!!\n\n"); s[i][j] = a[i][j]; n[i][j] = 1; out(s); //out(n); flag = 1; break; } if(flag) break; if(i == N - 1 && j == N - 1) printf("はずれ!\n\n\n"); } } else if(y[A] == 0) { //入力値が被った場合 printf("数字が被ってるよ!もう一度!\n\n\n"); continue; } for(i = 0; i < N; i++) { //縦、横、斜めでのビンゴの判定 fa = 1; fb = 1; fc = 1; fd = 1; for(j = 0; j < N; j++) { if(n[i][j] != 1) fa = 0; if(n[j][i] != 1) fb = 0; if(n[j][j] != 1) fc = 0; if(n[N - (j + 1)][j] != 1) fd = 0; } if(fa || fb || fc || fd) { printf("BINGO!!!\tYOU WIN !!!\n\n"); break; } } if(fa || fb || fc || fd) break; c--; } if(c == 0) { //挑戦回数が0になったらアウト printf("残り %d 回\n\nYOU LOSE !!!\n\n", c); } /* カードの答え合わせが可能 */ while(1) { printf("答え合わせをしますか?\n(YES = 1 ; NO = 0):"); scanf("%d", &z); printf("\n"); if(z == 1) { printf("--->答え合わせ<---\n\n"); out(a); break; } else if(z == 0) break; else printf("\nちょと何いってるかわからない\n\n\n"); } return 0; } /* 説明 変数 ・i, j, k, c, L, A, fa, fb, fc, fd, z; a[N][N], s[N][N], n[N][N], x[M], y[M],:int型 for文の引数i, j, k, カウントc, 挑戦回数L, 入力値A, ビンゴ判定fa, fb, fc, fd, 答え合わせz, カードの値a[][], s[][], 真理値n[][], 全数値x[][], y[][], 処理内容 ・12〜22行:ビンゴのカードをを作る ・26〜39行:カードの状態を出力する ・66〜74行:乱数でカードに数字を振り分ける ・79〜109行:入力値がカードの値への一致を判定 ・111〜129行:縦、横、斜めでのビンゴの判定 ・132〜143行:カードの答え合わせ */
ターミナルで実行
/* 実行結果(中略あり) -----> BINGO GAME <----- 何回挑戦する?(5 ~ 100): 40 [0 ~ 99 の数を入力してね] X X X X X X X X X X X X O X X X X X X X X X X X X あと 40 回 A = 10 はずれ! あと 39 回 A = 11 GREAT!! X X X X X X X X X X X X O X X X 11 X X X X X X X X あと 38 回 A = 11 数字が被ってるよ!もう一度! あと 38 回 A = 111 (0 ~ 99) の数を入力しろ あと 38 回 A = 19 はずれ! あと 37 回 A = 30 はずれ! 〜〜〜〜〜〜〜〜〜〜(中略) あと 1 回 A = 79 GREAT!! 9 X 2 X 79 X X 94 78 X X X O X X X 11 X X X 83 87 80 X X BINGO!!! YOU WIN !!! 答え合わせをしますか? (YES = 1 ; NO = 0):1 --->答え合わせ<--- 9 34 2 23 79 54 15 94 78 62 77 0 O 18 43 32 11 96 40 22 83 87 80 25 1 */