游戲規(guī)則
玩家先輸入四個數(shù)字争便,與系統(tǒng)產(chǎn)生的四個1-9之間的不重復的且從小到大排序隨機數(shù)進行比較级零,如果錯誤,根據(jù)顯示的結果再次進行猜測始花,直至正確妄讯。
游戲原理
1.產(chǎn)生四個1-9之間的不重復的隨機數(shù)孩锡。
2.將其從小到大排序酷宵。
3.與玩家輸入的數(shù)字進行比較。
4.如果有n個數(shù)字正確且位置正確的數(shù)躬窜,則輸出nA浇垦,如果有m個數(shù)字正確,位置不正確的數(shù)荣挨,則輸出mB男韧。
若玩家第一次猜錯,則可以根據(jù)nAmB這個結果進行合理分析并再次猜測默垄。
實現(xiàn)
先寫好頭文件
/#include <stdio.h>
/#include <stdlib.h>
/#include <time.h>
生成隨機數(shù)
步驟
1生成數(shù)組
2產(chǎn)生隨機數(shù)的同時去比較是否重復
3如果重復就重新再產(chǎn)生一個隨機數(shù)
4如果不重復就保存
5每次i的值正好可以用來判斷已經(jīng)有幾個了
首先定義一個數(shù)組并初始化此虑,再生成隨機數(shù)
注:有關生成隨機數(shù)的內(nèi)容在‘C語言基礎練習-隨機數(shù)’里面詳細介紹過,這里便不再復述口锭。
代碼如下
int array[4] = {};
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一個 直接保存
array[i] = temp;
}else{
//判斷前面是否已經(jīng)存在了
int j = 0;
for(; j <i; j++){
//比較j對應的值和temp是否相同
if(array[j] == temp){
//重復了
// printf("重復了:%d\n",temp);
break;
}
}
//判斷是怎么出來的
if (j == i){
//將i前面的比較一遍都沒發(fā)現(xiàn)重復的
//保存temp值
array[i] = temp;
}else{
//重復了
//重新回到當前這一次
i--;
}
}
}
- 雖然說隨機數(shù)在前面的筆記中有介紹過朦前,但是這里有一個新的要求,就是四個數(shù)中不能有相同的數(shù)字鹃操。
- 所以在保存生成的這個數(shù)之前韭寸,要先判斷這個數(shù)與之前的數(shù)是否相同,若相同荆隘,就不能保存恩伺,然后重新生成再進行判斷,直至生成的數(shù)與前面的不同椰拒,再保存到數(shù)組中晶渠。
- 由代碼可知,首先判斷這個數(shù)是否是第一個生成的數(shù)燃观,因為第一個生成的數(shù)前面沒有數(shù)字褒脯。所以直接保存即可。
- 從第二個數(shù)字起仪壮,就要進行是否相同的判斷憨颠。
這里假設已經(jīng)生成了第四個數(shù)字,現(xiàn)在要將其與前三個數(shù)進行對比。定義一個整型j爽彤,且j = 0养盗,此時i = 3,要將第四個數(shù)從第一個數(shù)開始進行判斷,就用一個for循環(huán)适篙,進行次數(shù)控制并連續(xù)判斷往核,只要進行了i -1次判斷且判斷數(shù)字都不相同,生成的這個數(shù)即可保存到數(shù)組嚷节,如若順序判斷中一旦相同聂儒,即停止判斷,退出當前for循環(huán)硫痰。 - 當退出當前for循環(huán)后衩婚,若數(shù)字有相同的,會再次進行最外層的for循環(huán)中的i++從而效斑,而此時i=3非春,再次生成一個隨機數(shù)后,i就等于4了缓屠,就不會再生成隨機數(shù)奇昙,所以我們在內(nèi)層for循環(huán)執(zhí)行完或break出來之后,若要再次生成隨機數(shù)就要進行一下i - -敌完。
if (j == i){
array[i] = temp;
}else{
i--;
}
將數(shù)組排序
排序的方法有很多储耐,在這里我們使用冒泡排序將數(shù)組按從小到大排好序
(由于在上一篇筆記中介紹過冒泡排序,這里就直接放上代碼)
代碼如下
int i,j,t; //從小到大排序 滨溉;冒泡排序
for(i = 0;i < 3;i++){ //控制遍歷次數(shù) 有N個數(shù)什湘,遍歷N-1次;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
由于這個游戲是讓玩家猜數(shù)业踏,所以并不需要輸出生成的數(shù)組禽炬,但是在邊寫代碼的時候,可以輸出這個數(shù)組以便檢查是否存在bug勤家。
輸出的代碼如下
//輸出
for (int i = 0; i< 4; i++){
printf("%d ", array[i]);
}
printf("\n");
用戶輸入腹尖,游戲“開始”
用戶輸入
int input[4],shu;
printf("請輸入四個數(shù)字\n");
for(int a = 0;a < 4;a++){ //用另外一個數(shù)組儲存輸入的數(shù)字
scanf("%d",&shu);
input[a] = shu;
}
這里需要注意的是,要用另一個數(shù)組來儲存用戶輸入的數(shù)字伐脖。即代碼中的input热幔。
計算n、m
即在nAmB中的n讼庇、m绎巨。并判斷是否全對,若不對蠕啄,則告知玩家nAmB场勤,并再次進行猜測戈锻,直至猜對。
由上述可得和媳,整個輸入及計算過程要放在while(1)的循環(huán)里格遭。
計算過程有兩種方法。
方法一
分別計算A,B的值
代碼如下
首先計算A的值
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出數(shù)字和位置都正確的個數(shù)
if(input[a] == array[i]){
num++;
}
a++;
}
再計算數(shù)字正確的個數(shù)
a = 0;
while(a < 4){ //算出數(shù)字正確的個數(shù)
for(i = 0;i < 4;i++){
if(input[a] == array[i]){
space1++;
}
}
a++;
}
在計算B之前留瞳,應將a重新變?yōu)?拒迅,因為在計算A的值之后,a 變成了3她倘。
計算B的值
space2 = space1 - num;//算出數(shù)字正確璧微,位置不正確的個數(shù) ,即B的值
printf("%dA%dB\n",num,space2);
if(num == 4){
printf("猜測正確硬梁!");
break;
}
用一個if語句前硫,使猜對后跳出while循環(huán)。
方法二
A,B一起計算.
代碼如下
while(1){
//提示輸入
printf("請輸入猜測的數(shù)字:");
for (int i = 0; i < 4; i++) {
scanf("%d", &input[i]);
}
//
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (org[i] == input[j]) {
//數(shù)字存在 判斷位置
if (i == j){
aCount++;
}else{
bCount++;
}
}
}
}
//提示用戶結果
printf("%dA%dB\n", aCount, bCount);
//判斷是否正確
if( aCount == 4){
printf("全對!!!!\n");
break;
}else{
aCount = 0;
bCount = 0;
}
}
- 玩家輸入后靶溜,首先判斷是否有相同的數(shù)字存在开瞭。
- 若存在懒震,則判斷位置罩息。
- 若判斷位置正確,就意味著這個數(shù)位置个扰,數(shù)字都正確瓷炮,則aCount++。
- 若判斷位置不正確递宅,就意味著這個數(shù)位置不正確但數(shù)字正確娘香,就bCount++。
- 最后如果aCount != 4办龄。玩家再次進行猜測烘绽,而此時aCount, bCount都要進行清零才能重新正常地進行下一次猜測。
由上述可得俐填,方法二相當于是方法一的優(yōu)化版安接,因為方法二的計算過程更加直觀,簡潔英融。
將方法一改為函數(shù)版
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int array[4] = {};
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一個 直接保存
array[i] = temp;
}else{
//判斷前面是否已經(jīng)存在了
int j = 0;
for(; j <i; j++){
//比較j對應的值和temp是否相同
if(array[j] == temp){
//重復了
// printf("重復了:%d\n",temp);
break;
}
}
//判斷是怎么出來的
if (j == i){
//將i前面的比較一遍都沒發(fā)現(xiàn)重復的
//保存temp值
array[i] = temp;
}else{
//重復了
//重新回到當前這一次
i--;
}
}
}
int i,j,t; //從小到大排序 盏檐;冒泡排序
for(i = 0;i < 3;i++){ //控制遍歷次數(shù) 有N個數(shù),遍歷N-1次驶悟;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
while(1){
int input[4],shu;
printf("請輸入四個數(shù)字\n");
for(int a = 0;a < 4;a++){ //用另外一個數(shù)組儲存輸入的數(shù)字
scanf("%d",&shu);
input[a] = shu;
}
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出數(shù)字和位置都正確的個數(shù)
if(input[a] == array[i]){
num++;
}
a++;
}
a = 0;
while(a < 4){ //算出數(shù)字正確的個數(shù)
for(i = 0;i < 4;i++){
if(input[a] == array[i]){
space1++;
}
}
a++;
}
space2 = space1 - num;//算出數(shù)字正確胡野,位置不正確的個數(shù)
printf("%dA%dB\n",num,space2);
if(num == 4){
printf("猜測正確!");
break;
}
}
return 0;
}
函數(shù)版
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void randomNumber(int array[4]);// 生成隨機數(shù)
void bubbleSort(int array[4]);//排序
int game(int array[4]);//進行游戲
int main(){
int array[4] = {};
randomNumber(array);
bubbleSort(array);//()中的array是指針痕鳍,指向array這個數(shù)組的首地址硫豆,這樣做可以直接訪問地址,修改數(shù)據(jù)
while(1){
game(array);
if(game(array) == 4){
printf("猜測正確!");
break;
}
}
return 0;
}
void randomNumber(int array[4]){
srand(time(NULL));
for (int i = 0; i < 4; i++){
int temp = rand() % 9 + 1;
if (i == 0){//第一個 直接保存
array[i] = temp;
}else{
//判斷前面是否已經(jīng)存在了
int j = 0;
for(; j <i; j++){
//比較j對應的值和temp是否相同
if(array[j] == temp){
//重復了
// printf("重復了:%d\n",temp);
break;
}
}
//判斷是怎么出來的
if (j == i){
//將i前面的比較一遍都沒發(fā)現(xiàn)重復的
//保存temp值
array[i] = temp;
}else{
//重復了
//重新回到當前這一次
i--;
}
}
}
}
void bubbleSort(int array[4]){
int i,j,t; //從小到大排序 熊响;冒泡排序
for(i = 0;i < 3;i++){ //控制遍歷次數(shù) 有N個數(shù)恭应,遍歷N-1次;
for(j =0;j < 4 -i -1;j++){
if(array[j] > array[j + 1]){
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
}
}
int game(int array[4]){
int input[4],shu;
printf("請輸入四個數(shù)字\n");
for(int a = 0;a < 4;a++){ //用另外一個數(shù)組儲存輸入的數(shù)字
scanf("%d",&shu);
input[a] = shu;
}
int num = 0,space1 = 0,a = 0,space2;
for(int i = 0;i < 4;i++){ //算出數(shù)字和位置都正確的個數(shù)
if(input[a] == array[i]){
num++;
}
a++;
}
a = 0;
while(a < 4){ //算出數(shù)字正確的個數(shù)
for(int m = 0;m < 4;m++){
if(input[a] == array[m]){
space1++;
}
}
a++;
}
space2 = space1 - num;//算出數(shù)字正確耘眨,位置不正確的個數(shù)
printf("%dA%dB\n",num,space2);
return(num);
}
//若要輸出原來的四個數(shù)字昼榛,則在array和while之間加入以下代碼
/* for (int i = 0; i< 4; i++){
printf("%d ", array[i]);
}
printf("\n");
*/
- 如果使用DEV C++,srand(time(NULL));中可以自動轉換剔难,若用Visual studio,則需進行強制轉換胆屿。srand((unsigned int)time(NULL));
- 在Visual studio中,輸入需要使用vs封裝的scanf偶宫。scanf_s("%d",&shu);
作者有話說
- 到此非迹,這個demo就做完啦!
- 通過這個demo纯趋,對各種循環(huán)語句運用更加熟練了
- 并且意識到要用自定義函數(shù)來單獨進行某個功能的重要性
- 還有......熟能生巧憎兽!