欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言实现N阶的2048小游戏

程序员文章站 2024-03-19 16:51:04
...

内存是一条铺满板砖的街道。不存在二维结构。生活中处处有二维结构。为了让计算机解决更多的问题。将物理上的内存中的一维数组划分为逻辑上的二维数组。请参考《C和指针》。p[i] = *(p+i),那么p[-i] = *(p-i);前者是指针向后滑动i个元素。后者是向前滑动i个元素。则p[i][j] = *(*(p+i)+j) ;本次用到了p[i][-j] = *(*(p+i)-j);表示的意思是指针数组中的第i号元素所指的数组取其从首地址开始向前滑动j个元素。指针不一定指的就是每个元素的首地址,也可指向当前数组中的一个元素,然后通过滑动读写其他元素。这样就解决2048只有4阶的局限性。指针数组中的每个元素指向一维数组中的某个部分,然后通过滑动从而改变一维数组的元素,主函数所给的数组大小由宏定义决定,通过更改宏的值达到更改N阶游戏的目的。如下所示C语言实现N阶的2048小游戏

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<malloc.h>
#define LEN 5      //宏定义    表示N阶
 void random_number (int *p, int n)//返回一个在0到n之间的随机数
 {
  int x;
  srand((unsigned)time(NULL));//随机函数
  x = rand()%n;        //产生0~n之间的随机数
  if (x == 0)              
  {
   x = 4;
  }
  else
  {
   x = 2;
  }             // 随机出现4和2;出现4的概率n分之一。其他概率为出现2的概率.
  while (1)
  {
   srand((unsigned)time(NULL));
  int a = rand()%(n*n) ;     //产生一个0~n*n之间的下标
  if (p[a] == 0)                  //如果该数组元素为0,将4或者2赋值给该元素
  {
   p[a] = x;
   break;
  }
 }
 }
 bool Left (int *p,int n)//左操作函数
 {
  int *arr = (int *)malloc(n*n*sizeof(int));//定义同样长度的数组保存当前数组的元素。
  for (int i=0; i<n*n; i++)
  {
   arr[i] = p[i];
  }
   int **pp = (int **)malloc(n*sizeof(int));//定义二维指针,后边即可当做指针数组使用
   for (int i=0; i<n; i++)
   {
    pp[i] = (p+n*i);//指向
   }
  for (int i=0; i<n; i++)//遍历数组  使得等值的数相加
  {
   for (int j=0; j<n-1; j++)
   {
    for (int k=j+1; k<n; k++)
    {
     if (pp[i][k] == 0)
     {
      continue;
     }
     if (pp[i][j] != pp[i][k])
     {
      break;
     }
      pp[i][j] += pp[i][k];
      pp[i][k] = 0;
      break;
    }
    
   }
  }
  for (int i=0; i<n; i++)//遍历数组,让不为0 的数移位
  {
   for (int j=0; j<n-1; j++)
   {
    if ((pp[i])[j] == 0)
    {
      for (int k = j+1; k<n; k++)
      {
       if ((pp[i])[k] != 0)
       {
        int temp;
        temp = (pp[i])[k];
        (pp[i])[k] = (pp[i])[j];
        (pp[i])[j] = temp;
        break;
       }
      }
    }
   }
  }
  free(pp);//释放申请的内存
  for (int i=0; i<n*n;)//判断玩家的操作是否有效,判断是否出现新的随机数
  {
   if (arr[i] == p[i])
   {
    i++;
    continue;
   }
   return true;
  }
  return false;
 }
 bool Right(int *p,int n)
 {
  int *arr = (int *)malloc(n*n*sizeof(int ));
  for (int i=0; i<n*n; i++)
  {
   arr[i] = p[i];
  }
  int **pp = (int **)malloc(n*sizeof(int));
   for (int i=0; i<n; i++)
   {
    pp[i] = (p+n*i+n);
   }
   for (int i=0; i<n; i++)//遍历数组  使得等值的数相加
  {
   for (int j=1; j<n+1; j++)
   {
    for (int k=j+1; k<n+1; k++ )
    {
     if ((pp[i])[-k] == 0)
     {
      continue;
     }
     if (pp[i][-k] != pp[i][-j])
     {
      break;
     }
     pp[i][-j] += pp[i][-k];
     pp[i][-k] = 0;
     break;
    }
 
   }
  }
  for (int i=0; i<n; i++)//遍历数组,让不为0的数移位
  {
   for (int j=1; j<n+1; j++)
   {
   if (pp[i][-j] == 0)
   {
      for (int k=j+1; k<n+1; k++)
      {
       if ((pp[i])[-k] != 0)
       {
        int temp;
        temp = (pp[i])[-k];
        (pp[i])[-k] = (pp[i])[-j];
        (pp[i])[-j] = temp;
        break;
       }
      }
   }
   }
  }
  free(pp);
  for (int i=0; i<n*n;)
  {
   if (arr[i] == p[i])
   {
    i++;
    continue;
   }
   return true;
  }
  return false;
 }
 bool Up(int *p,int n)
 {
  int *arr = (int *)malloc(n*n*sizeof(int ));
  for (int i=0; i<n*n; i++)
  {
   arr[i] = p[i];
  }
  int **pp = (int **)malloc(n*sizeof(int));
  for (int i=0; i<n; i++)
  {
   pp[i] = p+i;
  }
  for (int i=0; i<n; i++)
  {
   for (int j=0; j<n*(n-1); j+=n)
   {
    for (int k=j+n; k<n*n; k+=n)
    {
     if (pp[i][k] == 0)
     {
      continue;
     }
     if (pp[i][k] != pp[i][j])
     {
      break;
     }
     pp[i][j] += pp[i][k];
     pp[i][k] = 0;
     break;
    }
   }
  }
  for (int i=0; i<n; i++)
  {
   for (int j=0; j<n*(n-1); j+=n)
   {
    if ((pp[i])[j] == 0)
    {
      for (int k=j+n; k<n*n; k+=n)
      {
       if ((pp[i])[k] != 0)
       {
        int temp;
        temp = (pp[i])[k];
        (pp[i])[k] = (pp[i])[j];
        (pp[i])[j] = temp;
        break;
       }
      }
    }
   }
  }
  free(pp);
  for (int i=0; i<n*n;)
  {
   if (arr[i] == p[i])
   {
    i++;
    continue;
   }
   return true;
  }
  return false;
 }
 bool Down(int *p,int n)
 {
  int *arr = (int *)malloc(n*n*sizeof(int ));
  for (int i=0; i<n*n; i++)
  {
   arr[i] = p[i];
  }
  int **pp = (int **)malloc(n*sizeof(int));
  p = p+n*n;
  for (int i=n-1; i>-1; i--)
  {
   pp[i] = p-(n-i);
  }
  for (int i=n-1; i>-1; i--)
  {
   for (int j=0; j<n*(n-1); j+=n)
   {
    for (int k=j+n; k<n*n; k+=n )
    {
     if (pp[i][-k] == 0)
     {
      continue;
     }
     if (pp[i][-j] != pp[i][-k])
     {
      break;
     }
     pp[i][-j] += pp[i][-k];
     pp[i][-k] = 0;
     break;
    }
   }
  }
  for (int i=n-1; i>-1; i--)
  {
   for (int j=0; j<n*(n-1); j+=n)
   {
    if ((pp[i])[-j] == 0)
    {
      for (int k=j+n; k<n*n; k+=n)
      {
       if ((pp[i])[-k] != 0)
       {
        int temp;
        temp = (pp[i])[-k];
        (pp[i])[-k] = (pp[i])[-j];
        pp[i][-j] = temp;
        break;
       }
      }
    }
   }
  }
  free(pp);
  for (int i=0; i<n*n;)
  {
   if (arr[i] == p[i])
   {
    i++;
    continue;
   }
   return true;
  }
  return false;
 }
 bool Game_over(int *p, int n)
 {
  for (int i=0; i<n*n; i++)
  {
   if (p[i] == 0 || p[i] == 2048)
   {
    return false;
   }
  }   
  int **pp = (int **)malloc(n*sizeof(int));
  for (int i=0; i<n; i++)
  {
   pp[i] = (p+n*i);
  }
  for (int i=0; i<n; i++)
  {
   for (int j=0; j<n-1; j++)
   {
    for (int k=j+1; k<n;k++)
    {
     if (pp[i][j] != pp[i][k])
     {
      break;
     }
      free(pp);
      return false;
    }
   }
   }
  for (int i=0; i<n; i++)
  {
   pp[i] = p+i;
   }
  for (int i=0; i<n; i++)
  {
   for (int j=0; j<n*(n-1); j+=n )
   {
    for (int k=j+n; j<n*n; j++)
    {
     if (pp[i][j] != pp[i][k])
     {
      break;
     }
     free(pp);
     return false;
    }
   }
  }
 return true;
 }
  
bool Win (int *p, int n)
 {
  for (int i=0; i<n*n; i++)
  {
   if (p[i] == 2048)
   {
    return true;
   }
  }
  return false;
 }
 void Show(int *p, int n)
 {
  for (int i=0; i<n; i++)
  {
   for (int j=0; j<n; j++)
   {
    printf("%4d  ",p[i*n+j]);
   }
   printf("\n");
   printf("\n");
  }
 }
 int main()
 {
  int arr[LEN*LEN] = {};    //定义一个n*n的一维数组,初始化为全0。并当做二维数组使用。
  char key;
  random_number (arr, LEN);//调用随机函数给数组赋值
  random_number (arr, LEN);
  Show(arr,LEN);//输出数组
  while (1)//从键盘获取上下左右操作键值。调用相应的函数
  {
   while (key = getch())
  {
   key = getch();
    switch(key)
    {
    case 72: if (Up(arr,LEN)) 
        random_number (arr, LEN);//如果操作有效,产生新的随机值。
     break;
    case 80: if (Down(arr,LEN)) 
        random_number (arr, LEN);
     break;
    case 75: if (Left(arr,LEN)) 
        random_number (arr, LEN);
     break;
    case 77: if (Right(arr,LEN)) 
        random_number (arr, LEN);
    default :break;
    }
    break;
  }
   system("CLS");//清屏
   Show(arr,LEN);//再次输出数组
   if (Game_over(arr,LEN))//判断输了
   {
    printf("game over,you lose\n");
    break;
   }
   if (Win(arr,LEN))
   {
    printf("game over,you win\n");//判断获胜
    break;
   }
  }
  return 0;
 }