2048 小游戏

来源:互联网 发布:java map实现内存缓存 编辑:程序博客网 时间:2024/06/10 08:19

一个简易的2048小游戏     算是学习C语言的一次小练手,马马虎虎把


/***********************************

2048 游戏
游戏规则:
1.开始时在方块内随即产生两个数字  2    (需要随机数)
2.通过w a s d 控制游戏   (移动数字)
3.所有的数字都会随按键方向靠拢
4.在靠拢的过程中,如果相邻的数字一样的,相加
5.当整个界面中产生一个2048 游戏胜利 (胜利判定条件)
6.当整个界面中没有空格(0)的时候,游戏失败(失败判定条件)


************************************/
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define SIZE  4




int score=0;                        //我看别人都用了,不用觉得很low
int map[SIZE][SIZE]={0};


char getch(void)                     
{
char n=0;
system("stty -icanon");
system("stty -echo");
n=getchar();
system("stty icanon");
system("stty echo");
return n;
}




void pauses()                       //清屏暂定输入功能
{
while(getchar()!='\n');
getchar();
}
void printf_MAP();                        //数组print 
void put_new(char dir);                   //数组中随即出现2
void game();                              //相当于游戏开始
void Add(char dir);                       //每次移动符合条件的两个区域会加起来
                                          //具体函数装成了下面四个函数
void moveup();                            //向上移动,并且数组自动计算
void movedown();      //下同
void moveleft();
void moveright();
int check();                              //胜利或者失败条件判断




void main(void)
{
int a=0;
srand(time(NULL));
printf("\t\t+----------------------+\n");
printf("\t\t|   welcome to 2014    |\n");
printf("\t\t|   任意key开始 q退出  |\n");
printf("\t\t|   name:钱   PQ1709   |\n");
printf("\t\t+----------------------+\n");
pauses();

system("clear");
put_new('0');        //开始
game();

}




void printf_MAP()
{
//可以使用for循环构图,但是代码不是很直观。
printf("\t\t+-------------------------------+\n");
printf("\t\t| %4d  | %4d  | %4d  | %4d  |\n",map[0][0],map[0][1],map[0][2],map[0][3]);
printf("\t\t|-------------------------------+\n");
printf("\t\t| %4d  | %4d  | %4d  | %4d  |\n",map[1][0],map[1][1],map[1][2],map[1][3]);
printf("\t\t+-------------------------------+\n");
printf("\t\t| %4d  | %4d  | %4d  | %4d  |\n",map[2][0],map[2][1],map[2][2],map[2][3]);
printf("\t\t+-------------------------------+\n");
printf("\t\t| %4d  | %4d  | %4d  | %4d  |\n",map[3][0],map[3][1],map[3][2],map[3][3]);
printf("\t\t|-------------------------------+\n");
printf("\t\t   your score: %d\n",score);
}


void Add(char dir)                            //wasd操作
{
int i=0;int j=0;int k=0;
switch(dir){
case 'w':
moveup();
break;
case 's':
movedown();
break;
case 'a':
moveleft();
break;
case 'd':
moveright();
break;
}
}


void game()
{
char c='\0';
c=getch();
//scanf("%c",&c);
//while(getchar()!='\n');
while(c!='q'){
system("clear");
Add(c);                                        //计算移动后的数组
if(check()==1){
printf("\t\t恭喜您赢了!\n");
printf_MAP();
printf("感谢汪易方老师和陈老师的帮助和教导\n");
break;
}else if(!check()){
printf("\t\t恭喜您输了\n");
printf_MAP();
printf("感谢汪易方老师和陈老师的帮助和教导\n");
break;
}
put_new(c);                                    //计算之后在随即家一个数字2
printf_MAP();                                  
c=getch();
//while(getchar()!='\n');                        //讨厌的缓存
}
}
void put_new(char dir)
{
int i=0;
int row =0, col =0;
row=rand()%4;                        //随即生成行列
col=rand()%4;                     
switch(dir){
case '0':map[row][col]=2;break;    //开局随即产生2
case 'w':
if(map[3][col]==0){                //w:   (如果第三行随即处!=0) 在第三行随即产生一个2,如果等于0,则循环在一个不等于0的地方产生2
map[3][col]=2;
}else {
for(i=0;i<4;i++){
if(map[3][i]==0){
map[3][i]=2;
break;
}
}
}
break;
case 's':
if(map[0][col]==0){                
map[0][col]=2;
}else {
for(i=0;i<4;i++){
if(map[0][i]==0){
map[0][i]=2;
break;
}
}
}
break;
case 'a':
if(map[row][3]==0){                
map[row][3]=2;
}else {
for(i=0;i<4;i++){
if(map[row][3]==0){
map[row][3]=2;
break;
}
}
}
break;
case 'd':
if(map[row][0]==0){                
map[row][0]=2;
}else {
for(i=0;i<4;i++){
if(map[row][0]==0){
map[row][0]=2;
break;
}
}
}
break;
default :break;


}
}




void moveup()                            
{
int i=0;int j=0;int k=0;                            //循环四次每次一列
for(j=0;j<4;j++){
int n=4;
while(n--){                                     //循环四次
for(i=0;i<3;i++){                           //循环三次,最后一行没意义
if(map[i][j]==0){                       //找到行中的0
for(k=i;k<3;k++){                   //0下面的数字向上移动
map[k][j]=map[k+1][j];          //下面的数字变成0
map[k+1][j]=0;
}
}
}
}
for(i=0;i<3;i++){                                //相邻的两个数字如果相等
if(map[i][j]==map[i+1][j]){                  //上面的数字翻北
map[i][j]*=2;                            //下面的数字变成0
score+=10;
for(k=i+1;k<3;k++){
map[k][j]=map[k+1][j];
map[k+1][j]=0;
}
}
}
}

}


void movedown()
{
int i=0;int j=0;int k=0;
for(j=0;j<4;j++){
int n=4;
while(n--){
for(i=3;i>0;i--){
if(map[i][j]==0){
for(k=i;k>0;k--){
map[k][j]=map[k-1][j];
map[k-1][j]=0;
}
}
}
}
for(i=3;i>0;i--){
if(map[i][j]==map[i-1][j]){
map[i][j]*=2;
score+=10;
for(k=i-1;k>0;k--){
map[k][j]=map[k-1][j];
map[k-1][j]=0;
}
}
}
}
}
void moveleft()
{
int i=0;int j=0;int k=0;
for(i=0;i<4;i++){
int n=4;
while(n--){
for(j=0;j<3;j++){
if(map[i][j]==0){
for(k=j;k<3;k++){
map[i][k]=map[i][k+1];
map[i][k+1]=0;
}
}
}
}
for(j=0;j<3;j++){
if(map[i][j]==map[i][j+1]){
map[i][j]*=2;
score+=10;
for(k=j+1;k<3;k++){
map[i][k]=map[i][k+1];
map[i][k+1]=0;
}
}
}
}
}
void moveright()
{
int i=0;int j=0;int k=0;
for(i=0;i<4;i++){
int n=4;
while(n--){
for(j=3;j>0;j--){
if(map[i][j]==0){
for(k=j;k>0;k--){
map[i][k]=map[i][k-1];
map[i][k-1]=0;
}
}
}
}
for(j=3;j>0;j--){
if(map[i][j]==map[i][j-1]){
map[i][j]*=2;
score+=10;
for(k=j-1;k>0;k--){
map[i][k]=map[i][k-1];
map[i][k-1]=0;
}
}
}
}
}


int check()
{
int i=0;int j=0;
for(i=0;i<4;i++){                                   //2048太多了,我改成128,游戏可以胜利;
for(j=0;j<4;j++){
if(map[i][j]==2048){
return 1;
}
}
}
for(i=0;i<4;i++){
for(j=1;j<4;j++){
if(map[i][j]==map[i][j-1]){
return 2;
}
}
}
for(j=0;j<4;j++){
for(i=0;i<4;i++){
if(map[i-1][j]==map[i][j]){
return 2;
}
}
}

for(i=0;i<4;i++){                               
for(j=0;j<4;j++){
if(map[i][j]==0){
return 2;
}
}
}     
return 0  ;                         //代表没有数字相等了并且没有0,不可以移动了,return gg

}