系統隨機產生四個不同的有序的數字 (從小到大排列),等待用戶輸入猜測的結果, 用A來表示數字正確且位置正確的個數 ,用B來表示數字正確但位置不正確的個數,給八次機會,猜中則遊戲成功,機會用完則遊戲失敗
分析:1.需要一個數組存放生成的隨機數,保證數據不重複且按從小到大排列
2.需要另外一個數組存放用戶的猜測結果
3.需要一個變量記錄已經猜了多少次
4.將兩個數組進行比較,統計A和B的個數並告知用戶,方便其繼續猜
5.當用戶全部猜中或機會用完時,遊戲結束,退出
我第一次得到題目時編寫的代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
//提示遊戲規則
printf("****************************************************\n");
printf("*********************遊戲規則***********************\n");
printf("系統將隨機生成四個不同的有序數字(按從小到大排列)\n");
printf("請輸入您猜測的四個數字\n");
printf("用A表示數字正確且位置正確的個數\n");
printf("用B表示數字正確但位置不正確的個數\n");
printf("一共有八次機會\n");
printf("****************************************************\n");
//產生不同的隨機數
srand(time(NULL));
int number[4];
number[0] = rand() %9+1;
number[1] = rand() %9+1;
number[2] = rand() %9+1;
number[3] = rand() %9+1;
while (number[1] == number[0]) {
number[1] = rand() %9+1;
}
while (number[2] == number[1] || number[2] == number [0]) {
number[2] = rand() %9+1;
}
while (number[3] == number[2] || number[3] == number [1] || number[3] ==number[0]) {
number[3] = rand() %9+1;
}
//這一句是爲了檢查數據是否重複,真正編譯時應該刪掉
printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
//將隨機數按從小到大排列
for(int i = 0; i < 4; i++){
for(int j = 0; j < i; j++)
{
if(number[i] < number[j]){
number[i] = number[i] + number[j];
number[j] = number[i] - number[j];
number[i] = number[i] - number[j];
}
}
}
//這一句是爲了檢查數據是否正確排列,真正編譯時應該刪掉
printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
//輸入數據並判斷
int guess[4];
int count = 8;
do{
int countA = 0;
int countB = 0;
//提示用戶輸入數據
printf("請輸入四個1~9的數字(每輸一個按一次回車):\n");
for (int i = 0; i < 4; i++) {
scanf("%d",&guess[i]);
while (guess[i] < 1 || 9 < guess[i]) {
printf("輸入數據有誤,請重新輸入\n");
scanf("%d",&guess[i]);
}
}
printf("%4d %4d %4d %4d\n",guess[0],guess[1],guess[2],guess[3]);
//判斷數字、位置是否相同並計數
for ( i = 0; i < 4; i++) {
if (guess[i] == number[i]) {
countA++;
continue;
}
for (int j = 0; j < 4; j++) {
if (i == j) {
continue;
} else if (guess[i] == number[j]){
countB++;
}
}
}
printf("一共有 %dA,%dB\n",countA,countB);
//判斷遊戲是否應該結束
if (countA == 4) {
printf("恭喜您!遊戲成功\n");
getchar();
getchar();
exit(EXIT_SUCCESS);
}
count--;
printf("還有%d次機會\n",count);
printf("*******************************************\n");
}while (count > 0);
printf("次數用完,遊戲失敗\n");
printf("正確數字爲:%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
getchar();
getchar();
return 0 ;
}
這個代碼是存在很多不足的,我在經過這兩天學習之後,主要進行了四個修改。
1.產生不同的隨機數部分
這是整個代碼最傻的部分,我第一次編寫時考慮使用for循環比較下標來保證數據不重複,但一直沒辦法實現,所以用了一個很傻的方法來使它不重複,實際上是不可取的。後來發現可以通過與一個臨時變量比較來實現,代碼如下:
//產生不同的隨機數
srand(time(NULL));
int number[4];
for (int i = 0; i < 4; i++) {
//定義一個temp存放隨機數
int temp = rand() %9+1;
//判斷是否爲第一個數
if (i == 0) {
//是第一個數,直接存放
number[i] = temp;
} else {
//不是,將temp與先前的數進行比較
for (int j = 0; j < i; j++) {
if (number[j] == temp ) {
//相同,退出循環,重新生成temp
i--;
break;
} else{
//不同,直接存放
number[i] = temp;
}
}
}
}
printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
用這個方法就不會顯得那麼傻,而且可以借鑑到其他地方
2.判斷數字、位置是否相同並計數部分
這一部分乍一看沒問題,其實可以更加簡化,也更方便理解,代碼如下:
//判斷數字、位置是否相同並計數
for (i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
//判斷數字是否相同
if (guess[i] == number[j]){
//數字相同,判斷位置是否相同
if (i == j) {
//位置相同,A+1
countA++;
} else{
//位置不同,B+1
countB++;
}
}
}
}
printf("一共有 %dA,%dB\n",countA,countB);
3.將隨機數按從小到大排列部分
這個部分主要是在兩個數據交換位置時,通過兩個數據相互加減的方法來交換雖然不需要引入第三個變量,但是增加了運算,使效率變低,也顯得不夠簡單,因此最後改爲引入第三個變量進行交換。
4.對countA、countB的定義部分
將 int countA和int countB放進了do...while循環中,造成了重複定義,這實際上是不夠嚴謹的,於是將這兩個變量的定義提到外部,並在循環的最後將其清零。
修改後的所有代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
//提示遊戲規則
printf("****************************************************\n");
printf("*********************遊戲規則***********************\n");
printf("系統將隨機生成四個不同的有序數字(按從小到大排列)\n");
printf("請輸入您猜測的四個數字\n");
printf("用A表示數字正確且位置正確的個數\n");
printf("用B表示數字正確但位置不正確的個數\n");
printf("一共有八次機會\n");
printf("****************************************************\n");
//產生不同的隨機數
srand(time(NULL));
int number[4];
for (int i = 0; i < 4; i++) {
//定義一個temp存放隨機數
int temp = rand() %9+1;
//判斷是否爲第一個數
if (i == 0) {
//是第一個數,直接存放
number[i] = temp;
} else {
//不是,將temp與先前的數進行比較
for (int j = 0; j < i; j++) {
if (number[j] == temp ) {
//相同,退出循環,重新生成temp
i--;
break;
} else{
//不同,直接存放
number[i] = temp;
}
}
}
}
//這一句是爲了檢查數據是否重複,真正編譯時應該刪掉
printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
//將隨機數按從小到大排列
for( i = 0; i < 4; i++){
for(int j = 0; j < i; j++)
{
if(number[i] < number[j]){
//使用第三方變量更方便,也更有效率
int temp = 0;
temp = number[i];
number[i] = number[j];
number[j] = temp;
}
}
}
//這一句是爲了檢查是否正確排序,真正編譯時應該刪掉
printf("%4d %4d %4d %4d\n",number[0],number[1],number[2],number[3]);
//輸入數據並判斷
int guess[4];
int count = 8;
int countA = 0;
int countB = 0;
do{
/*
int countA = 0;
int countB = 0; 定義只定義一次,所以應該在外部定義
*/
//提示用戶輸入數據
printf("請輸入四個1~9的數字:\n");
for (int i = 0; i < 4; i++) {
scanf("%d",&guess[i]);
//判斷數據是否在1-9區間內
while (guess[i] < 1 || 9 < guess[i]) {
printf("輸入數據有誤,請重新輸入\n");
scanf("%d",&guess[i]);
}
}
printf("%4d %4d %4d %4d\n",guess[0],guess[1],guess[2],guess[3]);
//判斷數字、位置是否相同並計數
for (i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
//判斷數字是否相同
if (guess[i] == number[j]){
//數字相同,判斷位置是否相同
if (i == j) {
//位置相同,A+1
countA++;
} else{
//位置不同,B+1
countB++;
}
}
}
}
printf("一共有 %dA,%dB\n",countA,countB);
//判斷是否全部猜中
//全部猜中,遊戲結束
if (countA == 4) {
printf("恭喜您!遊戲成功\n");
getchar();
getchar();
exit(EXIT_SUCCESS);
}
//沒猜中,次數-1,A、B清零
count--;
countA = 0;
countB = 0;
printf("還有%d次機會\n",count);
}while (count > 0);
//機會用完,遊戲結束
printf("次數用完,遊戲失敗。\n");
getchar();
getchar();
return 0 ;
}
其實這個程序還有不完善的地方,比如說沒有考慮用戶輸入相同數字時的處理等,但題目所需要的功能已經實現,玩一玩還是挺有意思的