#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
void start();
void qingchu();
void restart();
void chexiao();
void random();
void print();
void up(int tp[]);
void down(int tp[]);
void left(int tp[]);
void right(int tp[]);
void which_key();
void magic(int c);
void judge();
int cube[16] = { 0 };
int main(void)
{
srand((unsigned)time(0));
which_key();
system("pause");
return 0;
}
void which_key()// 接受用戶輸入的字符執行對應的功能。
{
start ();
do
{
int haha = _getch();
switch(haha)
{
case '1': qingchu(); break; // 清除數組中的2。
case '2': restart(); break;
case '3': chexiao(); break; //此功能正在開發中。
case 'w':
case 'a':
case 's':
case 'd': magic(haha); break;
case 'q': exit(1);
}
}while (1);
}
void start() //開始遊戲,產生兩個隨機的2或4。
{
random();
random();
print();
}
void restart() // 這個應該是最簡單的了,只需要把數組賦值爲0,然後調用start函數即可。
{
int i;
for (i = 0; i < 16; cube[i] = 0,i++);
start();
}
void chexiao() //此功能正在開發中。
{
;
}
void qingchu()
{
int i, j = 0;
for (i = 0; i < 16; i++)
if (cube[i] == 2) cube[i] = 0;
for (i = 0; i < 16; i++)
if (cube[i] == 0) j = j + 1;
if (j == 16) start(); // 如果矩陣中只有2,那麼執行清除後相當於重新開始遊戲。
else print(); // 如果執行了轉換那麼就輸出轉換後的矩陣。
}
void random() //在空白的地方隨機產生2或者4;
{
int temp[16] = { 0 }, i, j = 0; //思路是創建一個臨時的數組保存那些數值爲0的元素的下標,
for (i = 0; i < 16; i++) //然後用隨機函數讀取其中的一個下標,隨機賦值爲2或4。(2的概率爲0.1。)
if (cube[i] == 0) temp[j++] = i;
if (j == 0) judge();
else
{
i = rand() % j;
if (rand() % 100 >= 10) cube[temp[i]]= 2;
else cube[temp[i]] = 4;
}
}
void print() //打印操作後的二維數組;
{
int i;
system("cls");
puts("|* - * - * - * - * - * 2 0 4 8 * - * - * - * - * - *|");
puts("|\t 清除(1) 重新開始(2) 撤銷(3)\t |");
puts("|* - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *|");
puts("遊戲操作說明:\n \x01 上下左右移動對應鍵盤上的W、S、A、D。\n \
\x01 退出請按 Q 鍵。\n \x01 請把輸入法轉換到英文狀態再進行遊戲!\n");
printf("-----------------------------");
for (i = 0; i < 16; i++)
{
if (i == 0) printf("\n|");
if (i % 4 == 0 && i != 0) printf("\n-----------------------------\n|");
if (cube[i] == 0) printf(" %-4c |", ' ');
else printf(" %-4d |", cube[i]);
}
printf("\n-----------------------------\n");
}
void up(int tp[])
{
int a[4][4], i, j, k = 0, temp[4] = { 0 };
int copy[16];
for (i = 0; i < 16; copy[i] = tp[i], i++); //以上兩行代碼是用來判斷執行up操作後是否添加隨機數。
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
a[i][j] = tp[k++]; //將一維數組轉換換成二維數組。
for (j = 0; j < 4; j++)
{
k = 0;
for (i = 0; i < 4; i++)
if (a[i][j] != 0) temp[k++] = a[i][j]; //把一列中不爲0的元素按順序賦值到臨時數組中。
for (k = 0; k < 3; k++)
{
if (temp[k] == 0) break;
if (temp[k] == temp[k + 1])
{
if (k == 0) { temp[0] += temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 1) { temp[1] += temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 2) { temp[2] += temp[3]; temp[3] = 0; }
}
} //此for循環把臨時數組中的員元素相加並移動0至數組尾部。
k = 0;
for (i = 0; i < 4; a[i][j] = temp[k++], i++); //把臨時數組中的元素賦值到原來的一列中。
for (k = 0; k < 4; temp[k] = 0, k++); //把臨時數組重新賦值爲0。
}
k = 0;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tp[k++] = a[i][j] ; //把二維數組轉換成原來的一維數組。
for (i = 0; i < 16; i++)
{
if (copy[i] != tp[i]) break;
}
if (i != 16) random(); //判斷是否添加隨機數。判斷的依據是如果執行up操作後數組沒有變化的話就不添加隨機數,否則添加隨機數。
}
void down(int tp[])
{
int a[4][4], i, j, k = 0, temp[4] = { 0 };
int copy[16];
for (i = 0; i < 16; copy[i] = tp[i], i++);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
a[i][j] = tp[k++];
for (j = 0; j < 4; j++)
{
k = 0;
for (i = 3; i >=0 ; i--)
if (a[i][j] != 0) temp[k++] = a[i][j];
for (k = 0; k < 3; k++)
{
if (temp[k] == 0) break;
if (temp[k] == temp[k + 1])
{
if (k == 0) { temp[0] += temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 1) { temp[1] += temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 2) { temp[2] += temp[3]; temp[3] = 0; }
}
}
k = 0;
for (i = 3; i >=0 ; a[i][j] = temp[k++], i--);
for (k = 0; k < 4; temp[k] = 0, k++);
}
k = 0;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tp[k++] = a[i][j];
for (i = 0; i < 16; i++)
{
if (copy[i] != tp[i]) break;
}
if (i != 16) random();
}
void left(int tp[])
{
int a[4][4], i, j, k = 0, temp[4] = { 0 };
int copy[16];
for (i = 0; i < 16; copy[i] = tp[i], i++);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
a[i][j] = tp[k++];
for (i = 0; i < 4; i++)
{
k = 0;
for (j = 0; j <4; j++)
if (a[i][j] != 0) temp[k++] = a[i][j];
for (k = 0; k < 3; k++)
{
if (temp[k] == 0) break;
if (temp[k] == temp[k + 1])
{
if (k == 0) { temp[0] += temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 1) { temp[1] += temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 2) { temp[2] += temp[3]; temp[3] = 0; }
}
}
k = 0;
for (j = 0; j < 4; a[i][j] = temp[k++], j++);
for (k = 0; k < 4; temp[k] = 0, k++);
}
k = 0;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tp[k++] = a[i][j];
for (i = 0; i < 16; i++)
{
if (copy[i] != tp[i]) break;
}
if (i != 16) random();
}
void right(int tp[])
{
int a[4][4], i, j, k = 0, temp[4] = { 0 };
int copy[16];
for (i = 0; i < 16; copy[i] = tp[i], i++);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
a[i][j] = tp[k++];
for (i = 0; i < 4; i++)
{
k = 0;
for (j = 3; j >= 0; j--)
if (a[i][j] != 0) temp[k++] = a[i][j];
for (k = 0; k < 3; k++)
{
if (temp[k] == 0) break;
if (temp[k] == temp[k + 1])
{
if (k == 0) { temp[0] += temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 1) { temp[1] += temp[2]; temp[2] = temp[3]; temp[3] = 0; }
if (k == 2) { temp[2] += temp[3]; temp[3] = 0; }
}
}
k = 0;
for (j = 3; j >= 0; a[i][j] = temp[k++], j--);
for (k = 0; k < 4; temp[k] = 0, k++);
}
k = 0;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tp[k++] = a[i][j];
for (i = 0; i < 16; i++)
{
if (copy[i] != tp[i]) break;
}
if (i != 16) random();
}
void magic(int c)
{
if (c == 119) up(cube);
if (c == 115) down(cube);
if (c == 97) left(cube);
if (c == 100) right(cube); //根據輸入的字符判斷執行的操作。
print();
int i, j = 0;
for (i = 0; i < 16; i++)
{
if (cube[i] == 2048)
{
printf("恭喜你,你的智商已達到2048!!擊敗全球99.99%%的用戶!\n\t請按任意鍵繼續。。。");
getchar();
} // 判斷數組中的元素是否有2048,如果有則打印相關內容。
if (cube[i] != 0) j++;
}
if(j == 16) judge(); //如果數組中的元素都不爲零的話,就判斷是否可以繼續遊戲。
}
void judge()
{
int i, j = 0;
for (i = 0; i < 16; i++)
{
if (cube[i] == cube[i + 1] && i != 3 && i != 7 && i != 11) j = 1; // 相鄰的元素相等且不爲3,7,11時,可以進行。
if (cube[i] == cube[i + 4] && i < 12) j = 1; // 下標相差爲4的元素相等,且最大最大下標小於16時,可以進行遊戲。
}
if (j == 0) printf("別費力氣了,已經 GAME OVER 了!!\n\t請按有效鍵重新開始或退出!");
}