2048小游戏的C语言实现(待完善)

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<string.h>
#include<conio.h> //为了读取方向键
#include<time.h> //为了生成随机数
#define N 4

int Map[4][4];
//这是为了显示该游戏棋盘


/*主要是由八个函数完成基本功能,第一个ShowMap,主要是显示游戏的期盼格子
第二个isGameOver判断游戏是否结束,棋盘全部占满,且上下左右没有可以合并的值,则游戏失败;反之出现2048则游戏成功
第三个随机数字函数,主要是借用随机种子函数来为合并之后空出来的位置随机生成一个数字
第四个上移函数,主要是针对同列非同行的相同数字,合并之后需要补位
第五个下移函数,主要是针对同列非同行的相同数字,合并之后需要补位,下移到底
第六个左移函数,主要是针对同行非同列的相同数字,合并之后需要补位,左移到底
第七个右移函数,主要是针对同行非同列的相同数字,合并之后需要补位,右移到底
第八个函数,是通过ascll码值从键盘读取上下左右键
*/

void ShowMap()
{
	printf("\t欢迎来到2048\n");
    printf("\t游戏界面如下:\n");
    for( int i = 0; i < N; i++)
    {
        for( int j = 0; j < N; j++)
        {
            printf("%6d", Map[i][j] );
        }
        printf("\n");
        printf("\n");
    }
}

int isGameOver()       //判断是否游戏结束
{
	int flag = 1;
	int i, j;
	for (i = 0; i < 4; i++)
	for (j = 0; j < 4; j++)
	if (!Map[i][j])
	{
		flag = 0;
	}
	//如果没有空位但是有相邻相同的数也可以继续
	if (flag == 1)
	{
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				if (i != 0 && Map[i][j] == Map[i - 1][j])
					flag = 0;
				if (i != 3 && Map[i][j] == Map[i + 1][j])
					flag = 0;
				if (j != 0 && Map[i][j] == Map[i][j - 1])
					flag = 0;
				if (j != 3 && Map[i][j] == Map[i][j + 1])
					flag = 0;
			}
		}
	}
	if (flag == 1)
	{
		printf("游戏结束");
	}
	return flag;
}

void RandNum()
{
	//判断游戏是否结束了
    isGameOver();
	srand(time(NULL));
    //判断坐标一个随机的位置
    int i = rand() % 4;
    int j = rand() % 4;
	int data = 2;
	if (rand() % 5 == 0)
	{
		data = 4;
	}
    while(Map[i][j] != 0) //当该下标已经有值
    {
        //产生随机的数字
		j++;
		if(j == 4)
		{
			i = (i+1) % 4;
			j = 0;
		}
    }
	Map[i][j] = data;
}

int MoveUp()
{
    int tmp = 0; //记录是否发生移动
	for( int j = 0; j < N; j++)
    {
		//移动
		for( int i = 1; i < N; i++)
        {
            //同列非同行 上移
            if (Map[i][j] && !Map[i-1][j])
            {
                Map[i-1][j] = Map[i][j];
				Map[i][j] = 0;
				//上移到底
				if( i > 1)
				{
					i -= 2;
					tmp = 1; 
				}
            }
        }
		//合并数字
		for( int i = 1; i < N; i++)
		{
			if(Map[i][j] == Map[i-1][j])
			{
				Map[i-1][j] = 2 * Map[i][j]; 
				Map[i][j] = 0;
				tmp = 1;
			}
		}
		//移动之后又需要补空位
		for( int i = 1; i < N; i++)
		{
			//同列非同行 上移
            if (Map[i][j] && !Map[i-1][j])
            {
                Map[i-1][j] = Map[i][j];
				Map[i][j] = 0;
				//上移到底
				if( i > 1)
				{
					i -= 2;
					tmp = 1; 
				}
            }
		}
   }
	return tmp;
}

int MoveDown()
{
	int tmp = 0;
	for( int j = 0; j < N; j++)
    {
		//移动
		for( int i = 2; i >= 0; i--)
        {
            //同列非同行 下移
            if (Map[i][j] && !Map[i+1][j])
            {
                Map[i+1][j] = Map[i][j];
				Map[i][j] = 0;
				//上移到底
				if( i < 2)
				{
					i += 2;
					tmp = 1; 
				}
            }
        }
		//合并数字
		for( int i = 2; i >= 0; i--)
		{
			if(Map[i][j] == Map[i+1][j])
			{
				Map[i+1][j] = 2 * Map[i][j]; 
				Map[i][j] = 0;
				tmp = 1;
			}
		}
		//移动之后又需要补空位
		for( int i = 2; i >= 0; i--)
		{
			//同列非同行 下移
            if (Map[i][j] && !Map[i+1][j])
            {
                Map[i+1][j] = Map[i][j];
				Map[i][j] = 0;
				//上移到底
				if( i < 2)
				{
					i += 2;
					tmp = 1; 
				}
            }
		}
   }
	return tmp;
}

int MoveLeft()
{
	int tmp = 0;
	for( int i = 0; i < N; i++)
	{
		//同行 左移
		for( int j = 1; j < N; j++)
		{
			if(Map[i][j] && !Map[i][j-1] )
			{
				Map[i][j-1] = Map[i][j];
				Map[i][j] = 0;
				if(j > 1)
				{
					j -= 2;
					tmp = 1;
				}
			}
		}
		//合并数字
		for( int j = 1; j < N; j++)
		{
			if(Map[i][j] == Map[i][j-1])
			{
				Map[i][j-1] = 2 * Map[i][j];
				Map[i][j] = 0;
				tmp = 1;
			}
		}
		//合并数字以后再次移动
		for( int j = 0; j < N; j++)
		{
			if(Map[i][j] && !Map[i][j-1] )
			{
				Map[i][j-1] = Map[i][j];
				Map[i][j] = 0;
				if(j > 1)
				{
					j -= 2;
					tmp = 1;
				}
			}
		}
	}
	return tmp;
}

int MoveRight()
{
	int tmp = 0;
	for( int i = 0; i < N; i++)
	{
		//同行 右移
		for( int j = 2; j >= 0; j--)
		{
			if(Map[i][j] && !Map[i][j+1] )
			{
				Map[i][j+1] = Map[i][j];
				Map[i][j] = 0;
				if(j < 2)
			    {
				   j += 2;
				   tmp = 1;
			    }
			}
		}
		//合并数字
		for( int j = 2; j >= 0; j--)
		{
			if(Map[i][j] == Map[i][j+1])
			{
				Map[i][j+1] = 2 * Map[i][j];
				Map[i][j] = 0;
				tmp = 1;
			}
		}
		//合并数字以后再次移动
		for( int j = 2; j >= 0; j--)
		{
			if(Map[i][j] && !Map[i][j+1] )
			{
				Map[i][j+1] = Map[i][j];
				Map[i][j] = 0;
			    if(j < 2)
			    {
				   j += 2;
				   tmp = 1;
			    }
			}
		}
	}
	return tmp;
}

void keyboard()
{
	int ch = getch();
    switch (ch)
	{
		case 72://向上
			if (MoveUp())
			{
				RandNum();
				system("cls");
				ShowMap();
			}
			break;
		case 75:
			if (MoveLeft())
			{
				RandNum();
				system("cls");
				ShowMap();
			}
			break;
		case 77:	
			if (MoveRight())
			{
				RandNum();
				system("cls");
				ShowMap();
			}
			break;
		case 80:	// down
			if (MoveDown())
			{
				RandNum();
				system("cls");
				ShowMap();
			}
			break;
		default:
			break;
		}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值