日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2048小游戏(变态版哦)

發(fā)布時間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2048小游戏(变态版哦) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

近日,由于博主同學(xué)暑假有個作業(yè)是寫個2048小游戲,我一聽挺好玩的。。然后就開始了。。

首先,2048在移動過程中的規(guī)則其實也沒有特別難,但是感覺也不是一句話就能說完的。(不過玩的多……感覺總是有的)

廢話不多說,其實博主同學(xué)提供了pdf描述了2048的算法。

各位筒子入坑前請先過幾眼這個規(guī)則,以及其算法(當然我覺得算法第二點有點問題,后述)

那么在游戲的編寫前,可以先對細枝末節(jié)做一些準備。
1.出現(xiàn)數(shù)字2/4的概率

int getRand() {int i = rand() % 10;if (i < 1)return 4;elsereturn 2; }

2.移動后新數(shù)字產(chǎn)生的位置(當然也是隨機數(shù)了)

int getRandAddr()//返回一個0-15的數(shù) {return rand() % 16; }bool isSafeAddr(int addr)//由上一個函數(shù)產(chǎn)生的位置不一定安全,判斷一下 {if (a[addr / 4][addr % 4] == 0)//當這個位置是0,也就是空才安全return true;return false;//都沒安全當然不安全拉 }

3.判斷2048游戲是否結(jié)束(就是你game over拉)

bool isEnd() {for (int i = 0; i < 4; i++)//第一步,只要有空位,那就還沒輸{for (int j = 0; j < 4; j++){if (a[i][j] == 0)return false;}}//第二步,當你滿了之后,要判斷上下左右相鄰的是否還能合并for (int i = 0; i < 4; i++)//行{for (int j = 0; j < 3; j++){if (a[i][j] == a[i][j + 1])return false;}}for (int i = 0; i < 4; i++)//列{for (int j = 0; j < 3; j++){if (a[j][i] == a[j+1][i])return false;}}return true; }

對了,頂上預(yù)編譯指令和全局變量如下

#include<iostream> #include<string> #include<ctime>//給srand()預(yù)備 #include<conio.h> using namespace std;int a[4][4];//2048的數(shù)組 int b[4][4];//提供給它撤銷功能(不過就提供了一步,感覺要很多步要用棧吧。 //PS:真正的2048哪有這個功能啊) int score=0;//記錄積分 int score_ex = 0;//為撤銷而存在

好了,下面進入正文。
W/A/S/D的移動是2048的核心,我只展示一下W吧,反正其他類似,敲起來累死(方向變來變?nèi)?#xff0c;路癡的我要神經(jīng)衰弱了)

void isW()//0往下靠攏 {for (int i = 0; i < 4; i++)//排0{//感覺這個和冒泡類似,不過只將0往下冒//這兒采用的是大數(shù)往上浮//最上面的一格不考慮if (a[1][i] != 0)//第二行{if (a[0][i] == 0){a[0][i] = a[1][i];a[1][i] = 0;}}if (a[2][i] != 0)//第三行{for (int j = 0; j < 2; j++){if (a[j][i] == 0){a[j][i] = a[2][i];a[2][i] = 0;break;/*這兒要解釋一下為什么找到一個就夠,而且從最上面開找。假設(shè)1{0248},當2浮動后,0就會往下一位,由于我已經(jīng)從第一行開寫,所以不會存在有0存留在上面。假設(shè)2{0024},這個假設(shè)說明了這個for循環(huán)要從0開始的原因,不然2只會和第二個0作交換,形成{0240}。*/}}}if (a[3][i] != 0)//第四行{for (int j = 0; j < 3; j++){if (a[j][i] == 0){a[j][i] = a[3][i];a[3][i] = 0;break;}}}}//排0結(jié)束,下面開始合并并算積分for (int i = 0; i < 4; i++){int flag = 3;//找出列中最后一個非零的for (int j = 3; j >= 0; j--){if (a[j][i] != 0){break;}flag--;}if (flag == 0)//只有第一行非零continue;//也就是只有一個數(shù),根本不能合并,直接跑下一行if (flag == 1){//有兩個數(shù),判斷一下能否合并就好if (a[0][i] == a[1][i]){a[0][i] += a[0][i];//不用*2是為了省時,沒去學(xué)移位,這兒移位最好吧a[1][i] = 0;//合并了就置0score += a[0][i];continue;}continue;}if (flag == 2){if (a[0][i] == a[1][i]){a[0][i] += a[0][i];a[1][i] = a[2][i];//這兒要注意不能立馬置0,而是把下一個數(shù)先移上來a[2][i] = 0;score += a[0][i];continue;}if (a[1][i] == a[2][i]){a[1][i] += a[1][i];a[2][i] = 0;score += a[1][i];continue;}continue;}/*if (flag == 2)//這兒是PDF中的算法,但是我認為它并不符合真正的2048,為了方便大家我再手打一遍算法描述2),每次按方向鍵后,逐行計算移動后的方格值的算法是:先將所有值為0的數(shù)移至行首。然后從行首開始逐一和后一個數(shù)比較,如果相等則合并這2個格子,合并過的方塊不再繼續(xù)合并;那么問題就來了假設(shè)原先是{0888}的轉(zhuǎn)置,那么往上移動時,0往下沉,完成0的移動后應(yīng)該為{8880}的轉(zhuǎn)置,根據(jù)算法描述,0的方向是行首,那么從行首開始合并,結(jié)果應(yīng)該是{81600},細心的小伙伴到這兒應(yīng)該發(fā)現(xiàn)問題大了!這個規(guī)則不讓人玩高分啊!!沒發(fā)現(xiàn)的話,你就用注釋的代碼多玩玩,出了1024就神級了。。。{if (a[1][i] == a[2][i]){a[1][i] += a[1][i];a[2][i] = 0;score += a[1][i];continue;}else{if (a[0][i] == a[1][i]){a[0][i] += a[0][i];a[1][i] = a[2][i];a[2][i] = 0;score += a[0][i];continue;}}continue;}*/if (flag == 3){//這兒的邏輯可能會令人作嘔,因為我是從原來的規(guī)則改過來的if (a[0][i] == a[1][i]){//判斷12兩行是否相同a[0][i] += a[0][i];a[1][i] = a[2][i];a[2][i] = a[3][i];a[3][i] = 0;score += a[0][i];//有必要進一步判斷剩下的兩行能否合并,例{2244},之所以后面不是a[2][i]與a[3][i]是因為上面剛做過移動if (a[1][i] == a[2][i]){a[1][i] += a[1][i];a[2][i] = 0;score += a[1][i];}continue;//移動完就去下一行吧}else{if (a[1][i] == a[2][i]){//當前兩行不同,就判斷23兩行是否相同a[1][i] += a[1][i];a[2][i] = a[3][i];a[3][i] = 0;score += a[1][i];continue;}if (a[2][i] == a[3][i]){//跑到這兒就意味著1223不相同,判斷34是否相同a[2][i] += a[2][i];a[3][i] = 0;score += a[2][i];continue;}continue;}}/*if (flag == 3){if (a[2][i] == a[3][i]){a[2][i] += a[2][i];a[3][i] = 0;score += a[2][i];if (a[0][i] == a[1][i]){a[0][i] += a[0][i];a[1][i] = a[2][i];a[2][i] = 0;score += a[0][i];}continue;}else{if (a[1][i] == a[2][i]){a[1][i] += a[1][i];a[2][i] = a[3][i];a[3][i] = 0;score += a[1][i];continue;}if (a[0][i] == a[1][i]){a[0][i] += a[0][i];a[1][i] = a[2][i];a[2][i] = a[3][i];a[3][1] = 0;score += a[0][i];continue;}continue;}}*/} }

當當當,完成四個移動的函數(shù)還改了好幾遍真是頭昏腦漲啊。

接下來制定游戲規(guī)則部分,不過先初始化一下吧

void init() {cout << "rule:\n\t1.w/s/a/d for direction\n\t2.r to restart \n\t3.u to 返回一步(不能連續(xù)用)\n\t4.e to exit\n";for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){a[i][j] = 0;b[i][j] = 0;}}score = 0;score_ex = 0;srand(time(NULL));//如果隨機數(shù)種子不改一下,每次玩的都一樣……int addr = getRandAddr();a[addr / 4][addr % 4] = getRand();}

那么開始GAME吧

void game() {string choose;cout << "choose level: 1-normal 2-hard 3-BT:";//選擇難度吧,騷年~while (cin>>choose){if (choose[0] == '1'){init();break;}if (choose[0] == '2'){init2();break;}if (choose[0] == '3'){init3();//哈哈變態(tài)版,添加了四個障礙break;}}while (1){display();if (isEnd())//判斷你是否還能移動{string end;cout << "\t\tGame over !\n";cout << "\t\tYour Score is:" << score << endl;cout << "input 'r' to restart other to exit.";cin >> end;if (end[0] == 'r'){system("cls");game();}else{exit(0);}}//cin >> choose;//原來用這個,每次輸入w/a/s/d都要按下Enterchoose[0] = _getch();//這個按了w就會直接移動了,詳情百度conio.h _getch();if (choose[0] == 'u'){reWrite();//just one step ,就是將備份的數(shù)組寫回進來system("cls");continue;}copyRight();//既然你都不撤回了,我就先將現(xiàn)在的保存一下switch (choose[0]){case 'w':isW(); break;//上下左右case 'a':isA(); break;case 's':isS(); break;case 'd':isD(); break;case 'e':exit(0);case 'r':{system("cls"); game(); break; }//一般人不會一直玩到棧溢出吧。。。default:{system("cls");cout << "Error input,Try angin.\n";continue;}}if (isSame()){//如果相同就不產(chǎn)生新數(shù)字了,算法里面沒描述,玩過都知道~system("cls");//因為每次都會display()還是應(yīng)該清除一下continue;}int addr = getRandAddr();while (!isSafeAddr(addr))//一直找到安全位置為止{addr = getRandAddr();}a[addr / 4][addr % 4] = getRand();//產(chǎn)生新數(shù)了。system("cls");} }

下面這個函數(shù)都是在里面出現(xiàn)過,不是很重要而且沒代碼的

void init2()//這個只是一個障礙,想要4障礙自己寫一下吧 {cout << "rule:\n\t1.w/s/a/d for direction\n\t2.r to restart \n\t3.u to 返回一步(不能連續(xù)用)\n\t4.e to exit\n";for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){a[i][j] = 0;b[i][j] = 0;}}score = 0;score_ex = 0;srand(time(NULL));int addr = getRandAddr();a[addr / 4][addr % 4] = getRand();addr = getRandAddr();while (!isSafeAddr(addr)){addr = getRandAddr();}a[addr / 4][addr % 4] = -1; }void display()//打印一下 {char D = char(127);//障礙物的樣子,我也不知道用啥好for (int i = 0; i < 4; i++){cout << "\t";for (int j = 0; j < 4; j++){if (a[i][j] == 0)//每次都是0眼都花了{cout << ".\t";continue;}if (a[i][j] == -1 || a[i][j] == -2 || a[i][j] == -3 || a[i][j] == -4)//遇到障礙物{cout << D<<"\t";continue;}cout << a[i][j] << "\t";}cout << "\n\n";}cout << "score: " << score << "\n\n";cout << "\t" << "Next:"; }

這兒可能代碼還不全,待會上傳下載的,會在下面補上。
附上一張變態(tài)版的皂片吧(^__^) 嘻嘻……

總結(jié)

以上是生活随笔為你收集整理的2048小游戏(变态版哦)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。