語言 隨機數不變_用c語言做最簡易的2048小遊戲
技術標籤:語言 隨機數不變
1.最基本的要求
掌握if-else語句,迴圈,二維陣列,函式。
2.瞭解2048的遊戲規則
規則如下:
每次可以選擇上下左右其中一個方向去滑動,每滑動一次,所有的數字方塊都會往滑動的方向靠攏,系統也會在空白的地方隨機出現一個數字方塊,2或4,相同數字的方塊在靠攏時相加。玩家要想辦法在這小小的16格範圍中湊出“2048”這個數字方塊。
3.找到遊戲的核心
很顯然遊戲的核心是控制移動:
怎樣移動就要根據遊戲規則來提煉條件,我們可以發現其實上下左右只要想出一個方向,其他三個方向也是信手拈來。搞定了移動就還剩下幾個比較重要的:隨機數的產生、剩餘空值(這裡指的是0)的統計、是否遊戲結束的判斷以及用二維陣列來實現方塊。
(隨機數的產生、清屏、暫停這些基礎c語言課程中不會學到,本菜雞做的時候也是上了度娘又上知乎才學到的。接下來我也會單獨強調的。)
最簡易的2048如下圖所示:
1.4x4棋盤
用二維陣列即可,如接下來你將會看到我用qq[4][4]來代表棋盤。
2.移動
以向上移動為例:
void up(){ int i,j,k; for (i = 0; i < 4; i++) { k = 0; for(j = 1; j < 4;j++) //同一列中qq[j][i]在qq[k][i]下面 { if(qq[j][i] > 0) //判斷qq[k][i]下面是否為零0數 { if (qq[j][i] == qq[k][i]) //判斷兩個數是否相同,相同就要合起來 { score += qq[k][i] *= 2; //分數累加,相同的加起來,使用*2也是一樣的 qq[j][i] = 0; //合起來後原來下面這項qq[j][i]給了qq[k][i]所以本身要變為0 } else if (qq[k][i] == 0) //判斷上面的這項是否為0 { qq[k][i] = qq[j][i]; //是 就直接換值 qq[j][i] = 0; } else //上面項與下面不等於0的項不相等同時上面項不等於零時 { qq[k+1][i] = qq[j][i]; //將下面項移到上面項的後一項 k++; if (k != j) //如果qq[j][i]本來就是qq[k][i]的後一項就相當於不移動值不變,就不執行令qq[j][i]等於0的指令 { qq[j][i] = 0; //qq[j][i]不是qq[k][i]後一項就移到它後一項同時原來的位置上的數變為0 } } } } }}
要將移動的條件理清楚,一個一個條件慢慢來,搞清楚是並列還是包含關係。
以 一列 為例
第一個判斷條件可以表示成如下圖所示:
第二、三個判斷條件可以表示成如下圖所示:
接下來的可以仿照這個上面兩張圖自己想一想,最好自己畫個圖理解其中的邏輯關係。
3.重新開始遊戲及隨機數的基本格式
void restart(){ system("cls"); //清屏 printf(" ****2048****\n"); printf("由8上 2下 4左 6右控制,5重新開始,1退出遊戲\n"); //提示訊息 score = 0; //重置分數 int n = rand() % 16; //在0-15中隨機取出一個數 int i,j; for (i = 0; i < 4; i++) //行數 { for (j = 0; j < 4; j++) //列數 { if (n-- == 0) //隨機令一個二維陣列中的等於2 { qq[i][j]=2; } else //除了一個等於2其他都等於0 { qq[i][j]=0; } printf("%5d",qq[i][j]); //5寬度輸出 } printf("\n\n"); //兩換行更美觀 }}
產生隨機數需要包含的標頭檔案:
#include#include
C 庫函式 void srand(unsigned int seed) 播種由函式 rand 使用的隨機數發生器。它初始化隨機種子,會提供一個種子,這個種子會對應一個隨機數,如果使用相同的種子後面的 rand() 函式會出現一樣的隨機數。
srand((unsigned)time(0));//設定隨機數種子(隨機數型別)
number=rand();
一個都不能少
例如:i=rand()%N意思是在0到(N-1)之間隨機取一個數
4.統計空值的個數(作為產生隨機數的範圍及判斷是否遊戲結束)
int zero_number() //記錄所剩0的個數{ int n,i,j; n = 0; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (qq[i][j] == 0) { n++; //統計0的個數 } } }
5.產生隨機數
srand((int)time(0)); int i,j; int n = rand() % zero_number(); //產生一個0 到(剩幾個零-1)的隨機數 for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if(qq[i][j] == 2048) //判斷是否勝利 { m = 2; } if (qq[i][j] == 0&& n-- == 0) //隨機給一個位置上是0的賦值2或者4 { if (rand() % 3) //取個0-2的隨機數,取到1,2都是賦2 , 0 是賦4,賦值2或者4的比例是2:1 { qq[i][j] = 2; } else { qq[i][j] = 4; } } printf("%5d",qq[i][j]); } printf("\n\n"); }
6.判斷遊戲是否結束
int gameover() //判斷陣列中沒0的時候相鄰項是否相等{ int n,i,j; n = 1; //n作為判斷條件 for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (qq[i][j] == qq[i][j+1]|| qq[j][i] == qq[j+1][i]) //判斷陣列中相鄰項是否相等 { n = 0; } } } return n;}
if (zero_number() == 0&& gameover()) //同時滿足陣列沒有一個0且相鄰的數不相等 { system("cls"); printf("遊戲失敗\n"); system("pause"); break; //遊戲失敗的出口 }
7.遊戲的主體控制部分begin函式、main函式和標頭檔案
void begin() { for(;;) //無條件進入for迴圈 { system("cls"); printf(" ****2048****\n"); printf("由8上 2下 4左 6右控制,5重新開始,1退出遊戲\n"); srand(time(0)); int i,j; int n = rand() % zero_number(); //產生一個0 到(剩幾個零-1)的隨機數 for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if(qq[i][j] == 2048) //判斷是否勝利 { m = 2; } if (qq[i][j] == 0&& n-- == 0) //隨機給一個位置上是0的賦值2或者4 { if (rand() % 3) //取個0-2的隨機數,取到1,2都是賦2 , 0 是賦4,賦值2或者4的比例是2:1 { qq[i][j] = 2; } else { qq[i][j] = 4; } } printf("%5d",qq[i][j]); } printf("\n\n"); } int in = getch(); //獲得控制鍵輸入 switch (in) //控制上下左右,重新開始和退出遊戲 { case '8' : up(); break; case '2' : down(); break; case '4' : left(); break; case '6' : right(); break; case '5' : restart(); break; case '1' : m = 1; break; default : ; } if (m == 1) //對了應1控制鍵退出遊戲的出口 { break; } if (m == 2) //遊戲勝利的出口 { system("cls"); printf("遊戲勝利\n"); system("pause"); break; } if (zero_number() == 0&& gameover()) //同時滿足陣列沒有一個0且相鄰的數不相等 { system("cls"); printf("遊戲失敗\n"); system("pause"); break; //遊戲失敗的出口 } }}
void main(){ restart(); begin(); system("pause"); system("cls"); printf("得分為:%d\n歡迎下次在玩!!!",score); system("pause");}
#include #include #include //要用到隨機數 #include //要用到清屏#include //要用到暫停void begin(); //遊戲開始時的主要控制中心void restart(); //重新開始int gameover(); //判斷是否失敗int zero_number(); //二維陣列中零的個數void up(); //向上移void down(); //向下移void left(); //向左移void right(); //向右移int qq[4][4]; //4*4的位置int score; //統計分數int m = 0; //m用來作判斷條件
本人也是一個剛接觸(零基礎)c語言的菜雞,對於這個遊戲其實實際用時差不多用八個小時左右。本菜雞是肝網課(迴圈、一維陣列、函式、二維陣列用1.5倍速)肝了一個晚自習(兩個小時左右),構思了一個晚自習並且查詢完了要用到的沒學過的東西(隨機數一類的東西),敲程式碼敲了一個上午(四個小時左右其中出現了很多初學者經常犯的錯誤可能是因為一直看網課實際操作不行)不斷的調整和簡化,雖然用的時間有點多,但是收穫很多,增加了興趣、鞏固了知識以及開拓了思維。
對於剛接觸c語言的老鐵們有興趣才有動力,而每一次打完程式碼編譯執行沒有絲毫問題我相信都會有一種成就覺,千萬不要抗拒打程式碼。
祝各位程式碼越打越舒暢越打越六!!!
加油
最後附上程式碼:
#include #include #include //要用到隨機數 #include //要用到清屏#include //要用到暫停void begin(); //遊戲開始時的主要控制中心void restart(); //重新開始int gameover(); //判斷是否失敗int zero_number(); //二維陣列中零的個數void up(); //向上移void down(); //向下移void left(); //向左移void right(); //向右移int qq[4][4]; //4*4的位置int score; //統計分數int m = 0; //m用來作判斷條件void main(){ restart(); begin(); system("pause"); system("cls"); printf("得分為:%d\n歡迎下次在玩!!!",score); system("pause");}void restart(){ system("cls"); //清屏 printf(" ****2048****\n"); printf("由8上 2下 4左 6右控制,5重新開始,1退出遊戲\n"); //提示訊息 score = 0; //重置分數 int n = rand() % 16; //在0-15中隨機取出一個數 int i,j; for (i = 0; i < 4; i++) //行數 { for (j = 0; j < 4; j++) //列數 { if (n-- == 0) //隨機令一個二維陣列中的等於2 { qq[i][j]=2; } else //除了一個等於2其他都等於0 { qq[i][j]=0; } printf("%5d",qq[i][j]); //5寬度輸出 } printf("\n\n"); //兩換行更美觀 }}void begin() { for(;;) //無條件進入for迴圈 { system("cls"); printf(" ****2048****\n"); printf("由8上 2下 4左 6右控制,5重新開始,1退出遊戲\n"); srand(time(0)); int i,j; int n = rand() % zero_number(); //產生一個0 到(剩幾個零-1)的隨機數 for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if(qq[i][j] == 2048) //判斷是否勝利 { m = 2; } if (qq[i][j] == 0&& n-- == 0) //隨機給一個位置上是0的賦值2或者4 { if (rand() % 3) //取個0-2的隨機數,取到1,2都是賦2 , 0 是賦4,賦值2或者4的比例是2:1 { qq[i][j] = 2; } else { qq[i][j] = 4; } } printf("%5d",qq[i][j]); } printf("\n\n"); } int in = getch(); //獲得控制鍵輸入 switch (in) //控制上下左右,重新開始和退出遊戲 { case '8' : up(); break; case '2' : down(); break; case '4' : left(); break; case '6' : right(); break; case '5' : restart(); break; case '1' : m = 1; break; default : ; } if (m == 1) //對了應1控制鍵退出遊戲的出口 { break; } if (m == 2) //遊戲勝利的出口 { system("cls"); printf("遊戲勝利\n"); system("pause"); break; } if (zero_number() == 0&& gameover()) //同時滿足陣列沒有一個0且相鄰的數不相等 { system("cls"); printf("遊戲失敗\n"); system("pause"); break; //遊戲失敗的出口 } }}int zero_number() //記錄所剩0的個數{ int n,i,j; n = 0; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (qq[i][j] == 0) { n++; //統計0的個數 } } } return n;}int gameover() //判斷陣列中沒0的時候相鄰項是否相等{ int n,i,j; n = 1; //n作為判斷條件 for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (qq[i][j] == qq[i][j+1]|| qq[j][i] == qq[j+1][i]) //判斷陣列中相鄰項是否相等 { n = 0; } } } return n;}void up(){ int i,j,k; for (i = 0; i < 4; i++) { k = 0; for(j = 1; j < 4;j++) //同一列中qq[j][i]在qq[k][i]下面 { if(qq[j][i] > 0) //判斷qq[k][i]下面是否為零0數 { if (qq[j][i] == qq[k][i]) //判斷兩個數是否相同,相同就要合起來 { score += qq[k][i] *= 2; //分數累加,相同的加起來,使用*2也是一樣的 qq[j][i] = 0; //合起來後原來下面這項qq[j][i]給了qq[k][i]所以本身要變為0 } else if (qq[k][i] == 0) //判斷上面的這項是否為0 { qq[k][i] = qq[j][i]; //是 就直接換值 qq[j][i] = 0; } else //上面項與下面不等於0的項不相等同時上面項不等於零時 { qq[k+1][i] = qq[j][i]; //將下面項移到上面項的後一項 k++; if (k != j) //如果qq[j][i]本來就是qq[k][i]的後一項就相當於不移動值不變,就不執行令qq[j][i]等於0的指令 { qq[j][i] = 0; //qq[j][i]不是qq[k][i]後一項就移到它後一項同時原來的位置上的數變為0 } } } } }}void down(){ int i,j,k; for (i = 0 ; i < 4 ; i++) { k = 3; for (j = 2; j >= 0; j--) { if (qq[j][i] > 0) { if(qq[k][i] == qq[j][i]) { score += qq[k][i] *= 2; qq[j][i] = 0; } else if (qq[k][i] == 0) { qq[k][i] = qq[j][i]; qq[j][i] = 0; } else { qq[k-1][i] = qq[j][i]; k--; if (k != j) { qq[j][i] = 0; } } } } }}void left(){ int i,j,k; for (i = 0; i < 4; i++) { k = 0; for (j = 1; j < 4; j++) { if (qq[i][j] > 0) { if(qq[i][k] == qq[i][j]) { score += qq[i][k] *= 2; qq[i][j] = 0; } else if (qq[i][k] == 0) { qq[i][k] = qq[i][j]; qq[i][j] = 0; } else { qq[i][k+1] = qq[i][j]; k++; if (k != j) { qq[i][j] = 0; } } } } }}void right(){ int i,j,k; for (i = 0; i < 4; i++) { k = 3; for (j = 2; j >= 0; j--) { if (qq[i][j] > 0) { if(qq[i][k] == qq[i][j]) { score += qq[i][k] *= 2; qq[i][j] = 0; } else if (qq[i][k] == 0) { qq[i][k] = qq[i][j]; qq[i][j] = 0; } else { qq[i][k-1] = qq[i][j]; k--; if (k != j) { qq[i][j] = 0; } } } } }}
☆ END ☆