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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

2659閲覧

ビンゴの数を決まった範囲で更新したい

n6n9Qsmt8gLjwKw

総合スコア29

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2015/12/30 07:44

こんにちは
現在、C言語でビンゴを作っています。
ランダムな数でマスを埋められることに成功したのですが、縦列を決まった数字の範囲で表示させたい場合、どうやって表示させるか案が浮かばず困っています。

例えば、一番左端の縦列を1~20の数字の範囲で表示させ、一番左端から2番目の縦列を21~40で表示させたいです。

下記コードの中で最後の出力させる箇所でうまくできないか配列の数字を変えてみたのですが同じ数が表示されるばかりで詰まってしまいました。

できるだけ現在のコードをいじらずに解決したいのですが、いい案がないか知恵をお貸しいただきたいです。

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

#define BINGO_HEIGHT 5//縦5マス
#define BINGO_WEIGHT 5//横5マス
#define MAX_NUM 75//ビンゴの最大ナンバー数

int main(void)
{
int bingo[BINGO_HEIGHT][BINGO_WEIGHT];//ビンゴカード
int number[MAX_NUM];//ビンゴナンバー
int i;

for (i = 0; i < MAX_NUM; ++i) {//数値が被らないように乱数系列を変更 number[i] = i + 1; srand((unsigned)time(NULL));/* 乱数系列の変更 */ } for (i = MAX_NUM-1; i; --i) {//ビンゴナンバーに乱数を入れる int j = number[i]; int k = rand() % (i + 1);//乱数生成 number[i] = number[k]; number[k] = j;//0~74番目のアドレスをランダムな数値で更新 } for (i = 0; i <BINGO_HEIGHT; ++i) {//ビンゴカードのマスを生成した数値で埋める int j; for (j = 0; j <BINGO_WEIGHT; ++j) { printf("%2d ", bingo[i][j] = number[i*5+j]);//出力 } putchar('\n'); } return 0;

}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

できるだけ現在のコードをいじらずに解決したいのですが、いい案がないか知恵をお貸しいただきたいです。

既にシャッフルされた1-75があるので、そこから条件を満たすものを順序通りに取り出せばよいと思います。

例えば、 第1行を1-15、第2行を16-30、第3行を31-45、第4行を45-60、第5行を61-75の範囲で埋める合なら、

C

1for (j = 0; j <BINGO_WEIGHT; ++j) { 2 printf("%2d ", bingo[i][j] = number[i*5+j]);//出力 3}

を下記のように修正すればできると思います。

C

1for (j = 0; j <BINGO_WEIGHT; ++j) { 2 int k; 3 for (k=0; k < MAX_NUM; ++k) { 4 if ((i*15 < number[k]) && (number[k] <= (i+1)*15)) 5 break; 6 } 7 printf("%2d ", bingo[i][j] = number[k]);//出力 8 number[k]=0; 9}

【追記】
あれ? ここにもう少しコメントしていたのですが、別のウィンドウで編集してました。orz

全体的にozwkさんの指摘を参考にされた方がよいと思います。
私の解は「あまり変更しない」の条件での無理矢理な解です。あまり変なことはせず、きちんと全体を理解した上で素直なプログラムにした方がメンテナンス性が良いです。

それから、ここを参考にしてMarkdown記法に従って記入されると良いです。行頭の#は「見出し」指定なので#自身は表示されません。

投稿2015/12/30 09:56

編集2015/12/30 10:20
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n6n9Qsmt8gLjwKw

2015/12/30 12:29

Chironianさん回答ありがとうございます。 問題自体は回答にある通り出力時にif文で判定させることで解決しました。 しかし、自分でもなぜこうなるのか理解しきれていない部分があるため改めてコードを見直しメンテナンス性を上げてみようと思います。 すみません、teratailを使うことが初めてだったため記入時のルールに沿っていませんでした。お手数をおかけして申し訳ありませんでした。
guest

0

本題以前に言うべきことがあるので幾つか。

//数値が被らないように乱数系列を変更

無意味です。forループで何度も呼ぶ意味がありません。

//ビンゴナンバーに乱数を入れる

やっていることとコメントの内容が違っています。
ということは処理内容を理解できていないのでは?

BINGO_WEIGHT

Widthでは?


本題ですが、
120をランダムに並べた数列の先頭5個を左側1列、
21
40をランダムに並べた数列の先頭5個を左側2列、...
としていけばいいのでは。

投稿2015/12/30 08:05

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

n6n9Qsmt8gLjwKw

2015/12/30 12:24

ozwkkさん、回答ありがとうございます。 ・//数値が被らないように乱数系列を変更 ご指摘どおり乱数系列の変更はループする必要がなかったため乱数生成の処理時のループ文に移して簡略化しました。 ・//ビンゴナンバーに乱数を入れる すみません、処理内容を正しく理解せずにコメントを書いていました。 ・BINGO_WEIGHT ご指摘通り横の名前の付け方が違いました。 出力時にif文で数値を判定して左側一列に並べるように変えることで問題は解決しましたが、全体のコードが自分でもわかりにくくなってしまったため処理をもう一度見直して、きちんと理解したうえでコードを修正しようと思います。
ozwk

2015/12/30 13:06

> 乱数生成の処理時のループ文に移して簡略化しました。 いや一回だけ呼べばいいんですよ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問