对于小游戏2048代码具体讲解

1.如何做到打印外面的方框。

void Game_printf()
{
	int i,k,j;
	printf("SCORE = %d\n", score);
	for (i=0;i<high;i++)        //从第一行开始打印,由上往下。
	{
		for (k=0;k<4;k++)       //画出每一行的格子分割线。
		{
			printf(" ");
			for(j=0;j<4;j++)
			{
				printf("-");
			}
		}
		printf("\n");
		for (k=0;k<4;k++)
		{
			printf("|");
			if (array[i][k]!=0)   //如果这个不为0则将这个数打出来
			{
				printf("%4d", array[i][k]);
			}
			else                //如果这个数是0的话,则打印空格。
			{
				for (j=0; j<4;j++)
				{
					printf(" ");
				}
			}

		}
		printf("|\n");
		if (i==high-1)      //当i位于最后一行的时候,不需要用分割线来进行分割。
		{
			for (k=0; k<4; k++)
			{
				printf(" ");
				for (j=0; j<4; j++)
				{
					printf("-");        //打出最下面的底线。
				}
			}
			printf("\n");
		}
	}
	printf("使用上下左右或者wasd来进行游戏操作\n");        //提示本游戏的键位设置,应该如何玩这个游戏。
}

对于打印方框来说,用好其他的符号,便可以很好的打印这个边框。

每一个空格占四个格子,在进行输出的时候,如果是零,为了美观,我们将这个用四个空格来进行代替。如果是其他的数字,那么就用%4d来输出,那样,数字就会正好的在中间。

void Game_ranf()     //生成一个随机数。
{
    int x,y,t;
    do{
        x=rand()%4;
        y=rand()%4;
    }while(array[x][y]);        //只有在等于0的空格上随机出现。
    t=rand()%10;
    if(t==4)                    //设置概率,当t随机出来为4的时候,赋值给array[x][y]
        array[x][y]=4;
    else                        //否则就是将2赋值给数组空白地方
        array[x][y]=2;
}

2.当知道如何打印格子之后,我们就要开始我们的第一步,根据2048的游戏规则,我么在最开始的时候,我们需要先生成两个随机数,那么我们应该如何来生成着两个随机数呢。

我们可以采用rand(),函数来进行我们的随机数输出,因为是随机生成2或者4,并且我们的2生成的概率要大于四。我们先定义一个xy,来进行位置的输出,如果x和y的数组不是零,那么重新进行随机数的赋值。当然我们还需要注意一个,我们的随机数很多,但是我们的随机数应该被四除取余数。

int Game_win()
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(array[i][j]==2048)
                return 1;
            if(array[i][j]==0)
                return 0;
        }
    }
    return -1;
}

我们还需要写一个来判断输赢的函数,进行暴力搜索,如果有2048,那么就返回1,则代表游戏已经赢了,如果是0,那么返回为0,表示游戏继续,当搜索完成之后,任然没有找到2048或者0,那么我们的游戏就输了。返回-1;

void move_left()
{
    int i,j,k;
	for(i=0;i<4;i++)			//从第一行开始,然后一个一个的来进行左移;
	{
		 k=0;							//用k来当最左边的那个列元素。
		for(j=1;j<4;j++)			//从这一行的第二个开始来进行判断。
		{
			if(array[i][j]!=0)			//判断这个地方的元素是不是等于零,如果等于零,直接下一个。
			{
				if(array[i][k]==0)		//如果第一个等于零,把第一个的元素往右边移动。
				{
					array[i][k]=array[i][j];
					array[i][j]=0;			//移动之后,原本的那个元素变成了零。
				}
				else					//如果不等于零,那么分为两种情况,一种是两个元素相等,一个是不相等。
					if(array[i][k]==array[i][j])			//如果两个元素相等,那么相加,然后到最左边,之后k++;
				{
					array[i][k]=2*array[i][k];
					score+=array[i][k];
					array[i][j]=0;					//原本的那个元素变为了零。
					k++;
				}
				else						//如果两个元素不相同,那么就是碰撞。
				{
					k++;					//首先先加跳到下一个
					array[i][k]=array[i][j];		//将下一个值赋给k。
					if (j!=k)					//如果j不等于k的值,那么就是直接将j的那个元素变为0;
					{
						array[i][j]=0;
					}
				}
			}
		}
	}
}

现在到了我们整个程序最复杂的地方了,我们拿往左边移动来进行举例说明,既然是往左边移动,那么我们就从左边开始我们的循环,设置三个变量,首先用k来当最左边的那个数,在将j赋值1从第二个开始我们的计算查找,如果等于零,那么往后继续走,但是k的值不变,如果碰见不等于的值,那么将k与j的元素互换,相当于j转移到了最左边的地方。如果两个元素相同,将右边的那个置零,左边的元素乘2,那样子,我们等到了合成的式子,如果不是一样的,把右边的放在左边元素的下一位。

	void Game_jixu()
	{
		//为了判断在键盘上按下的哪个键
		int ch2 = 0;
		while (1)
		{
				ch2 = _getch();
				if (ch2 == 72||ch2=='w')
				{
					move_up();
					break;
				}
				if (ch2 == 80||ch2=='s')
				{
					move_down();
					break;
				}
				if (ch2 == 75||ch2=='a')
				{
					move_left();
					break;
				}
				if (ch2 == 77||ch2=='d')
				{
					move_right();
					break;
				}
			}

	}

这一段代码游戏继续的代码,从键盘中获取按键,最好使用<conio.h>文件里面的getch()来进行判断,因为整个是获取后直接执行,更加适合我们这个游戏的设定。

int Game()
{
    int t;
    srand((unsigned int)time(NULL));
    suijishu();
    suijishu();
    dayin();
    Game_jixu();
    while(1)
    {
        t=shuying();
        if(t==1)
        {
            printf("恭喜你,赢得了比赛!\n");
            return;
        }
        if(t==-1)
        {
            printf("很遗憾,你已经没有可移动的方块,你输了\n");
            return;
        }
        else
        {
            Game_jixu();
            system("cls");
            suijishu();
            dayin();
        }
    }
}

剩下的就是游戏的本体了,没有很多需要讲解的,不过我们最好加一个<windows.h>文件下的system("cls");来进行每一次执行之后的清屏,使得玩起来更加舒适。

最后把整个代码放在下面,供参考,如果有写的不好的地方,希望各位大佬指出来,共同学习。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
#define high 4
#define wide 4
int score=0;
int array[4][4]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void suijishu()     //生成一个随机数。
{
    int x,y,t;
    do{
        x=rand()%4;
        y=rand()%4;
    }while(array[x][y]);        //只有在等于0的空格上随机出现。
    t=rand()%10;
    if(t==4)                    //设置概率,当t随机出来为4的时候,赋值给array[x][y]
        array[x][y]=4;
    else                        //否则就是将2赋值给数组空白地方
        array[x][y]=2;
}
void dayin()
{
	int i,k,j;
	printf("SCORE = %d\n", score);
	for (i=0;i<high;i++)        //从第一行开始打印,由上往下。
	{
		for (k=0;k<4;k++)       //画出每一行的格子分割线。
		{
			printf(" ");
			for(j=0;j<4;j++)
			{
				printf("-");
			}
		}
		printf("\n");
		for (k=0;k<4;k++)
		{
			printf("|");
			if (array[i][k]!=0)   //如果这个不为0则将这个数打出来
			{
				printf("%4d", array[i][k]);
			}
			else                //如果这个数是0的话,则打印空格。
			{
				for (j=0; j<4;j++)
				{
					printf(" ");
				}
			}

		}
		printf("|\n");
		if (i==high-1)      //当i位于最后一行的时候,不需要用分割线来进行分割。
		{
			for (k=0; k<4; k++)
			{
				printf(" ");
				for (j=0; j<4; j++)
				{
					printf("-");        //打出最下面的底线。
				}
			}
			printf("\n");
		}
	}
	printf("使用上下左右或者wasd来进行游戏操作\n");        //提示本游戏的键位设置,应该如何玩这个游戏。
}
int shuying()
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(array[i][j]==2048)
                return 1;
            if(array[i][j]==0)
                return 0;
        }
    }
    return -1;
}
void move_left()
{
    int i,j,k;
	for(i=0;i<4;i++)			//从第一行开始,然后一个一个的来进行左移;
	{
		 k=0;							//用k来当最左边的那个列元素。
		for(j=1;j<4;j++)			//从这一行的第二个开始来进行判断。
		{
			if(array[i][j]!=0)			//判断这个地方的元素是不是等于零,如果等于零,直接下一个。
			{
				if(array[i][k]==0)		//如果第一个等于零,把第一个的元素往右边移动。
				{
					array[i][k]=array[i][j];
					array[i][j]=0;			//移动之后,原本的那个元素变成了零。
				}
				else					//如果不等于零,那么分为两种情况,一种是两个元素相等,一个是不相等。
					if(array[i][k]==array[i][j])			//如果两个元素相等,那么相加,然后到最左边,之后k++;
				{
					array[i][k]=2*array[i][k];
					score+=array[i][k];
					array[i][j]=0;					//原本的那个元素变为了零。
					k++;
				}
				else						//如果两个元素不相同,那么就是碰撞。
				{
					k++;					//首先先加跳到下一个
					array[i][k]=array[i][j];		//将下一个值赋给k。
					if (j!=k)					//如果j不等于k的值,那么就是直接将j的那个元素变为0;
					{
						array[i][j]=0;
					}
				}
			}
		}
	}
}
void move_right()
{
	int i,j,k;
	for (i=0;i<4;i++)
	{
		 k=3;
		for(j=2;j>=0;j--)
		{
			if(array[i][j]!=0)
			{
				if (array[i][k]==0)
				{
					array[i][k]=array[i][j];
					array[i][j]=0;
				}
				else
					if(array[i][k] == array[i][j])
				{
					array[i][k]*=2;
					score+=array[i][k];
					array[i][j]=0;
					k--;
				}
				else
				{
					k--;
					array[i][k] = array[i][j];
					if (j != k)
					{
						array[i][j] = 0;
					}
				}
			}
		}
	}
}
void move_up()
{
    	int i,j,k;
	for (j = 0; j < 4; j++)
	{
		k=0;
		for (i=1;i<4;i++)
		{
			if(array[i][j]>0)
			{
				if (array[k][j] == array[i][j])
				{
					array[k][j]*=2;
					score+=array[k][j];
					array[i][j]=0;
					k++;
				}
				else
                    if(array[k][j]==0)
				{
					array[k][j]=array[i][j];
					array[i][j]=0;
				}
				else
				{
				    k++;
					array[k][j]=array[i][j];
					if(i!=k)
					{
						array[i][j]=0;
					}
				}
			}
		}
	}
}
void move_down()
{
    int i,j,k;
	for(j=0;j<4;j++)
	{
		k=3;
		for(i=2;i>=0;i--)
		{
			if(array[i][j]>0)
			{
				if(array[k][j]==array[i][j])
				{
					array[k][j]*=2;
					score+=array[k][j];
					array[i][j]=0;
					k--;
				}
				else
                    if(array[k][j]==0)
				{
					array[k][j]=array[i][j];
					array[i][j]=0;
				}
				else
				{
					k--;
					array[k][j]=array[i][j];
					if (i!=k)
					{
						array[i][j]=0;
					}
				}
			}
		}
	}
}
	void Game_jixu()
	{
		//为了判断在键盘上按下的哪个键
		int ch2 = 0;
		while (1)
		{
				ch2 = _getch();
				if (ch2 == 72||ch2=='w')
				{
					move_up();
					break;
				}
				if (ch2 == 80||ch2=='s')
				{
					move_down();
					break;
				}
				if (ch2 == 75||ch2=='a')
				{
					move_left();
					break;
				}
				if (ch2 == 77||ch2=='d')
				{
					move_right();
					break;
				}
			}

	}
int Game()
{
    int t;
    srand((unsigned int)time(NULL));
    suijishu();
    suijishu();
    dayin();
    Game_jixu();
    while(1)
    {
        t=shuying();
        if(t==1)
        {
            printf("恭喜你,赢得了比赛!\n");
            return;
        }
        if(t==-1)
        {
            printf("很遗憾,你已经没有可移动的方块,你输了\n");
            return;
        }
        else
        {
            Game_jixu();
            system("cls");
            suijishu();
            dayin();
        }
    }
}
int main()
{
    Game();
    system("pause");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值