🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

2回答

5491閲覧

ヒット&ブロー 重複した数をユーザーが入力した場合 ヒット&ブローで重複しない4桁の乱数を答えとし、ユーザーが重複した数を入力したら1ヒット0ブローとなるようにしたいのですがやり方がわかりません。

hm1216

総合スコア6

C

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

0グッド

0クリップ

投稿2019/12/13 06:27

例;答え3875
入力3333
この場合は1ヒット0ブロー。

私が書いたコードだと一度ヒットと判定された数字もブローと判定されてしまいます。
一度ヒット判定した答えの文字を-1など絶対に使わない数字に代入すればいいと思ったのですが...。
ご教示ください。

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

void MakeNumber(int answer[4]);
void input(char* strinput, int* turn);
void hantei(int* hitcount, int* blowcount, char* strinput, int answer[4]);
void outputresult(int turn, int i, char str[10][5], int hitkeep[10], int blowkeep[10]);
int main()
{
printf("数字当てゲーム\n"
"4桁の数を当ててください。\n"
"同じ数は1度しか使用されません。\n");

int answer[4]; //答えを格納するための変数 char strinput[10][5]; //入力値[i]番目を記憶しておくための配列 int turn = 0; //ターン格納変数 int hitcount = 0; int blowcount = 0; int i; int hitkeep[10]; int blowkeep[10]; MakeNumber(answer); for (i = 0; i < 10; i++) { input(strinput[i], &turn);//入力したstrの[i]番目を渡したい(strはstrinputに入っている) hantei(&hitcount, &blowcount, strinput[i], answer); hitkeep[i] = hitcount; blowkeep[i] = blowcount; if (hitcount == 4) { printf("正解。\n"); break; } outputresult(turn, i, strinput, hitkeep, blowkeep); if (turn == 10) { printf("ターン残数0、ゲームオーバー。答えは%d%d%d%dです。\n",answer[0],answer[1],answer[2],answer[3]); } }

}

//4桁の乱数作成
void MakeNumber(int answer[4])
{
int i;
int count = 0;
int num;

srand((unsigned)time(NULL)); while (count < 4) { num = rand() % 10; for (i = 0; i < count; i++) { //重複がある場合 if (answer[i] == num) { break; } } //重複が無い場合 if (i >= count) { answer[count++] = num; } }

}

//キーボードから任意の数字を入力
//入力したものが数字じゃなかった場合と4桁じゃなかった場合ターンのカウントはせず、入力をやり直させる
void input(char* strinput, int* turn)
{
char str[10];
int len = 0; //文字の長さを格納
int i;

while (true) { gets_s(str,10); len = strlen(str); if (len != 4) { printf("4桁の数字を入力してください。\n"); continue; } for (i = 0; i < len; i++) { if (str[i] < '0' || str[i] > '9')//iが0または9より小さい場合ループを抜ける { break; } } if (i != 4) { printf("数字を入力してください。\n"); continue; } break; } strinput[0] = str[0]; strinput[1] = str[1]; strinput[2] = str[2]; strinput[3] = str[3]; strinput[4] = str[4]; (*turn)++; //入力ができたらターン数を加算D

}

//入力した数と答えの数を比較する
//Hit,Blowを保管するための関数の宣言、複数の戻り値を返す関数を引数を使って実現する

void hantei(int* hitcount, int* blowcount, char strinput[5], int answer[4])
{
int hit = 0;
int nothit = 0;
int blow = 0;
int i;
int j;
int inputNum[4];

//char型から数値に変換 for (i = 0; i < 4; i++) { inputNum[i] = strinput[i] - '0'; } //ヒット判定 for (i = 0; i < 4; i++) { if (inputNum[i] == answer[i]) { answer[i] = -1; hit++; } else //hit以外はnothit { nothit++; } } *hitcount = hit; //一個ヒットしたらブローとは判定されない。 //hitが0だったらそれはヒットじゃない //ヒットした以外の数値もブロー判定する if(nothit = 4) //nothitが4つだった場合と { for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (i != j && inputNum[i] == answer[j]) { blow++; } } } *blowcount = blow; }

}

//ヒットとブローの数を出力
void outputresult(int turn, int i, char strinput[10][5], int hitkeep[10], int blowkeep[10])
{
for (i = 1; i <= turn; i++)
{
printf("%d回目 入力値:%s,Hit:%d Blow:%d\n", i, strinput[i-1], hitkeep[i-1], blowkeep[i-1]);
}

}

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

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

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

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

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

guest

回答2

0

自己解決

解決しました!

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

void MakeNumber(int answer[4]);
void input(char* strinput, int* turn);
void hantei(int* hitcount, int* blowcount, char* strinput, int answer[4]);
void outputresult(int turn, int i, char str[10][5], int hitkeep[10], int blowkeep[10]);
int main()
{
printf("数字当てゲーム\n"
"4桁の数を当ててください。\n"
"同じ数は1度しか使用されません。\n");

int answer[4]; //答えを格納するための変数 char strinput[10][5]; //入力値[i]番目を記憶しておくための配列 int turn = 0; //ターン格納変数 int hitcount = 0; int blowcount = 0; int i; int hitkeep[10]; int blowkeep[10]; MakeNumber(answer); for (i = 0; i < 10; i++) { input(strinput[i], &turn);//入力したstrの[i]番目を渡したい(strはstrinputに入っている) hantei(&hitcount, &blowcount, strinput[i], answer); hitkeep[i] = hitcount; blowkeep[i] = blowcount; if (hitcount == 4) { printf("正解。\n"); break; } outputresult(turn, i, strinput, hitkeep, blowkeep); if (turn == 10) { printf("ターン残数0、ゲームオーバー。答えは%d%d%d%dです。\n",answer[0],answer[1],answer[2],answer[3]); } }

}

//4桁の乱数作成
void MakeNumber(int answer[4])
{
int i;
int count = 0;
int num;

srand((unsigned)time(NULL)); while (count < 4) { num = rand() % 10; for (i = 0; i < count; i++) { //重複がある場合 if (answer[i] == num) { break; } } //重複が無い場合 if (i >= count) { answer[count++] = num; } }

}

//キーボードから任意の数字を入力
//入力したものが数字じゃなかった場合と4桁じゃなかった場合ターンのカウントはせず、入力をやり直させる
void input(char* strinput, int* turn)
{
char str[10];
int len = 0; //文字の長さを格納
int i;

while (true) { gets_s(str,10); len = strlen(str); if (len != 4) { printf("4桁の数字を入力してください。\n"); continue; } for (i = 0; i < len; i++) { if (str[i] < '0' || str[i] > '9')//iが0または9より小さい場合ループを抜ける { break; } } if (i != 4) { printf("数字を入力してください。\n"); continue; } break; } strinput[0] = str[0]; strinput[1] = str[1]; strinput[2] = str[2]; strinput[3] = str[3]; strinput[4] = str[4]; (*turn)++; //入力ができたらターン数を加算D

}

//入力した数と答えの数を比較する
//Hit,Blowを保管するための関数の宣言、複数の戻り値を返す関数を引数を使って実現する

void hantei(int* hitcount, int* blowcount, char strinput[5], int answer[4])
{
int hit = 0;
int nothit = 0;
int blow = 0;
int i;
int j;
int inputNum[4];
int answercopy[4];

answercopy[0] = answer[0]; answercopy[1] = answer[1]; answercopy[2] = answer[2]; answercopy[3] = answer[3]; //char型から数値に変換 for (i = 0; i < 4; i++) { inputNum[i] = strinput[i] - '0'; } //ヒット判定 for (i = 0; i < 4; i++) { if (inputNum[i] == answercopy[i]) { hit++; answercopy[i] = -1; //hitが加算されたらanswerの[i]番目に使わない数字を代入しておく } } *hitcount = hit; //一個ヒットしたらブローとは判定されない //ヒットした以外の数値もブロー判定する for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (i != j && inputNum[i] == answercopy[j]) { blow++; answercopy[j] = -1; } } } *blowcount = blow;

}

//ヒットとブローの数を出力
void outputresult(int turn, int i, char strinput[10][5], int hitkeep[10], int blowkeep[10])
{
for (i = 1; i <= turn; i++)
{
printf("%d回目 入力値:%s,Hit:%d Blow:%d\n", i, strinput[i-1], hitkeep[i-1], blowkeep[i-1]);
}

}

投稿2019/12/13 07:52

hm1216

総合スコア6

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

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

0

ユーザーが重複した数を入力したら1ヒット0ブローとなるようにしたいのですがやり方がわかりません。

本当にそれでいいのでしょうか。仕様として「重複した入力はヒット・ブローの判定もせずに弾く」ほうが、ゲーム性が高まるかと思います。

投稿2019/12/13 06:36

maisumakun

総合スコア145963

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

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

hm1216

2019/12/13 06:50

>ユーザーが重複した数を入力したら1ヒット0ブローとなるようにしたいのですがやり方がわかりません。 とりあえず今はこれでいかせてください。 そのやり方を知りたいのです。
maisumakun

2019/12/13 06:53

正解が「9876」で「3333」と入力した場合も、「1ヒット0ブロー」でいいのですか?
hm1216

2019/12/13 07:51

解決しました!迅速な対応ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問