2048小程序

#include<stdio.h>
#include<stdlib.h>
#include <conio.h>
#include<assert.h>
#define N  4


void Print(int (*arr)[N],int n)//输出
{
	system("cls");
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			printf("%5d",arr[i][j]);
		}
		printf("\n\n");
	}
	printf("\n\n\n\n");
}


bool IsContinue(int (*arr)[N],int n) //游戏是否可以继续
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]==0)
			{
				return true;
			}
		    if(i>0&&arr[i][j]==arr[i-1][j])
			{		
					return true;		
			}
			 if(i<n-1&&arr[i][j]==arr[i+1][j])
			{
					return true;
			}
			 if(j>0&&arr[i][j]==arr[i][j-1])
			{
     				return true;
			}
			 if(j<n-1&&arr[i][j]==arr[i][j+1])
			 {
					return true;
			 }
		}
	}
	return false;
}


int GetDirectionkey()//获取方向键
{
	int ch1=0;
	int ch2=0;
    if(ch1=getch())
    {      
        ch2=getch();
    }
  return ch2;
}

bool IsAddress(int (*arr)[N],int n)
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]==0)
			{
				return true;
			}
		}
	}
	return false;
}
void  Address(int (*arr)[N],int n)//产生一个随机值(随机位置)
{
	int tmp=rand()%5;//随机值
	int row=rand()%n;//随机位置
	int col=rand()%n;
	int count=0;
	if(tmp!=4)
	{
	   tmp=2;
	}	
	if(arr[row][col]==0)
	{
		arr[row][col]=tmp;
	}
	else 
	{
		count=row*n+col;
		while(arr[row][col]!=0)
		{
			count=(count+1)%(n*n);
			row=count/n;
			col=count%n;
		}
		arr[row][col]=tmp;
	}
}

bool IsMoveUp(int (*arr)[N],int n)//是否可以上移
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]!=0)
			{
				 if(i>0&&arr[i][j]==arr[i-1][j])
				 {
					 return true;
				 }
			    for(int k=i-1;k>=0;k--)
			   {
				   if(arr[k][j]==0)
				   {
					   return true;
				   }
			    }
			}
		}
	}
	return false;
}

bool IsMoveDown(int (*arr)[N],int n)//是否可以下移
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]!=0)
			{
				if(i<n-1&&arr[i][j]==arr[i+1][j])
				{
					return  true;
				}
			    for(int k=i;k<n;k++)
				{
					if(arr[k][j]==0)
					{
						return true;
					}
				}
			}
		}
	}
	return false;
}


bool IsMoveLeft(int (*arr)[N],int n)//是否可以左移
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]!=0)
			{
				if(j>0&&arr[i][j]==arr[i][j-1])
				{
					return true;
				}
				for(int k=j-1;k>=0;k--)
				{
					if(arr[i][k]==0)
					{
						return true;
					}
				}			
			}
		}
	}
	return false;
}

bool IsMoveRight(int (*arr)[N],int n)//是否可以右移
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(arr[i][j]!=0)
			{
				if(j<n-1&&arr[i][j]==arr[i][j+1])
				{
					return true;
				}
				for(int k=j;k<n;k++)
				{
					if(arr[i][k]==0)
					{
						return true;
					}
				}
			}
		}
	}
	return false;
}

void Move(int *arr,int n) //将一维数组元元素移动在一起
{
	for(int i=0;i<n;i++)
	{
		if(arr[i]==0)
		{
			for(int j=i+1;j<n;j++)
			{
				if(arr[j]!=0)
				{
					arr[i]=arr[j];
					arr[j]=0;
					break;
				}
			}
		}
	}
}

void Sum(int *arr,int n)//将一维数组相邻两个相同的数加起来赋给前者,后者置0
{
	for(int i=0;i+1<n;i++)
	{
		if(arr[i]!=0&&arr[i]==arr[i+1])
		{
			arr[i]+=arr[i];
			arr[i+1]=0;
		}
	}
}

void MoveUp(int (*arr)[N],int n)//向上移更新数据
{
	int i;
	int j;
	int *brr=(int *)calloc(n,sizeof(int));
	assert(brr!=NULL);
	for(j=0;j<n;j++)
	{
		for(i=0;i<n;i++)
		{
			brr[i]=arr[i][j];
			arr[i][j]=0;
		}
		 Move(brr,n);
		 Sum(brr,n);
	     Move(brr,n);
		 for(i=0;i<n;i++)
		{
			arr[i][j]=brr[i];
			brr[i]=0;
		}
	}
	free(brr);
}

void MoveDown(int (*arr)[N],int n) //向下移更新数据
{
	int i;
	int j;
	int *brr=(int *)calloc(n,sizeof(int));
	assert(brr!=NULL);
	for(j=0;j<n;j++)
	{
		for(i=n-1;i>=0;i--)
		{
			brr[n-1-i]=arr[i][j];
			arr[i][j]=0;
		}
		Move(brr,n);
		Sum(brr,n);
	    Move(brr,n);
		for(i=0;i<n;i++)
		{
			arr[n-1-i][j]=brr[i];
			brr[i]=0;
		}
	}
	free(brr);
}

void MoveLeft(int (*arr)[N],int n) //向左移更新数据
{
	int i;
	for(i=0;i<n;i++)
	{
		Move(arr[i],n);
		Sum(arr[i],n);
	    Move(arr[i],n);
	}
}

void MoveRight(int (*arr)[N],int n) //向右移更改数据
{
	int i;
	int j;
	int *brr=(int *)calloc(n,sizeof(int));
	assert(brr!=NULL);
	for(i=n-1;i>=0;i--)
	{
		for(j=0;j<n;j++)
		{
			brr[n-1-j]=arr[i][j];
			arr[i][j]=0;
		}
		Move(brr,n);
		Sum(brr,n);
	    Move(brr,n);
		for(j=0;j<n;j++)
		{
			arr[i][n-1-j]=brr[j];
			brr[j]=0;
		}
	}
	free(brr);
}

void Merge(int (*arr)[N],int n)//更改数据
{
    int tmp=GetDirectionkey();//获取方向键
	int flag=0;
	if(tmp==72&&IsMoveUp(arr,n)) //上
	{	
		MoveUp(arr,n);
		flag=1;
	}
	else if(tmp==80&&IsMoveDown(arr,n))//下
	{
		MoveDown(arr,n);	
	    flag=1;
	}
	else if(tmp==75&&IsMoveLeft(arr,n))//左
	{
		MoveLeft(arr,n);		
		flag=1;	
	}
	else if(tmp==77&&IsMoveRight(arr,n)) //右
	{
		MoveRight(arr,n);	  		
		flag=1;
	}
	if(flag==1&&IsAddress(arr,n))
	 {
		 Address(arr,n);
	 }	
}

void  Game(int (*arr)[N],int n)
{
	Address(arr,n);
	Address(arr,n);
	Print(arr,n);
	while(IsContinue(arr,n))
	{
		Merge(arr,n); 
		Print(arr,n);
    }
	system("cls");
	printf("Game Over!\n");
}


int main()
{
	int arr[N][N]={0};
	Game(arr,N);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值