Move.h && Move.c

本文详细介绍了2048游戏的基本实现原理和技术细节,包括游戏初始化、新方块生成、移动判断及处理等核心功能,并提供了具体的源代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef	MOVE_H
#define	MOVE_H

#define	MOVE_UP		1
#define	MOVE_DOWN	2
#define	MOVE_LEFT	4
#define	MOVE_RIGHT	8

void initField(tHandle* handle);
int newTile(tHandle* handle);
int checkMoveable(tHandle* handle);
int makeMove(tHandle *handle,tUInt8 move);

#endif


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include "Config.h"
#include "Datatypes.h"
#include "Move.h"
#include "Output.h"

void initField(tHandle* handle)
{
	int i;
	int j;
	
	for (i=0;i<TILE_ROWS;i++)
	{
		for (j=0;j<TILE_COLS;j++)
		{
			handle->actField.tile[i][j]=0;
		}
	}
	handle->score=0;
}

int newTile(tHandle* handle)
{
	int i;
	int j;
	tUInt32 r;
	int pos[TILE_MASK+1];
	tField nxtField;
	
	int cnt;
	
	cnt=0;	
	for (i=0; i<TILE_ROWS; i++)
	{
		for (j=0; j<TILE_COLS; j++)
		{
			if ( !handle->actField.tile[i][j]) 
				pos[cnt++] = i * TILE_COLS + j;
		}
	}
	if (cnt)
	{
		memcpy(&nxtField, &(handle->actField), sizeof(tField));
		r=cnt;
		while ( r >= cnt )
		{
			r = rand()&TILE_MASK;
		}
		cnt = pos[r];
		r = rand();
		if (r<0) r = -r;
		if ((r%TILE_4_PROB)==0) r=4;
		else r = 2;
		i = cnt/TILE_ROWS;
		j = cnt%TILE_ROWS;
		nxtField.tile[i][j] = r;
		// TODO: spawnTile(handle,i,j);
		memcpy(&(handle->actField), &nxtField, sizeof(tField));
		return 1;
	}
	else 
	{
		return 0;
	}
}

int checkMoveable(tHandle* handle)
{

	int i,j;
	int retval=0;
	
	for (i=0; i<TILE_ROWS; i++)
	{
		for (j=0; j<TILE_COLS; j++)
		{
			int x, y;
			x = handle->actField.tile[i][j];
			if (x)
			{
				if (j!=0) 
				{
					y = handle->actField.tile[i][j-1];
					if (y==0) retval |= MOVE_LEFT;
					if (x==y) retval |= (MOVE_LEFT|MOVE_RIGHT);
				}
				if (j != TILE_COLS-1) 
				{
					y = handle->actField.tile[i][j+1];
					if (y == 0) retval |= MOVE_RIGHT;
					if (x == y) retval |= (MOVE_LEFT|MOVE_RIGHT);
				}
			}
		}
	}

	for (i=0; i<TILE_COLS; i++)
	{
		for (j=0;j<TILE_ROWS;j++)
		{
			int x,y;
			x=handle->actField.tile[j][i];
			if (x)
			{
				if (j!=0) 
				{
					y=handle->actField.tile[j-1][i];
					if (y==0) retval|=MOVE_UP;
					if (x==y) retval|=(MOVE_UP|MOVE_DOWN);
				}
				if (j!=TILE_ROWS-1) 
				{
					y=handle->actField.tile[j+1][i];
					if (y==0) retval|=MOVE_DOWN;
					if (x==y) retval|=(MOVE_UP|MOVE_DOWN);
				}
			}
		}
	}


	return retval;	
}

int makeMove(tHandle *handle,tUInt8 move)
{
	signed int i,j,k;
	int moved;

	moved=0;	
	
	i=checkMoveable(handle);
	if (i&move)
	{
		switch (move)
		{
			case MOVE_UP:
				// 
				for (i=0; i<TILE_COLS; i++)
				{
					int newpos[TILE_ROWS];
					int newTiles[TILE_ROWS];
					int combined[TILE_ROWS];
					
					for (j=0; j<TILE_ROWS; j++) 
					{
						combined[j]=0;
						newTiles[j]=handle->actField.tile[j][i];
						newpos[j]=j;
					}
					for (j=0;j<TILE_ROWS;j++)
					{
						int found;
						combined[j]=0;
						if (newTiles[j])
						{
							found=-1;
							for (k=j-1;k>=0 && found==-1;k--)
							{
								if (newTiles[k]==0) newpos[j]=k;
								else found=k;
							}

							found=-1;
							for (k=j+1;k<TILE_ROWS && found==-1;k++)
							{
								if (newTiles[k])
								{
									found=k;
									if (newTiles[j]==newTiles[k])
									{
										handle->score+=newTiles[j];
										newpos[k]=newpos[j];
										newTiles[j]*=2;
										newTiles[k]=0;
										combined[j]=1;
										moved=1;
									}
								}
							}

							if (newpos[j]!=j)
							{
								transition(handle,handle->actField.tile[j][i], j,newpos[j], i,i);
								combined[newpos[j]]=combined[j];
								newTiles[newpos[j]]=newTiles[j];
								newTiles[j]=0;
								combined[j]=0;
								moved=1;
							}			
						}
					}
					// TODO: transition

					for (j=0;j<TILE_ROWS;j++)
					{
						handle->actField.tile[j][i]=newTiles[j];
					}
				}
				break;

			case MOVE_DOWN:
				// 
				for (i=0;i<TILE_COLS;i++)
				{
					int newpos[TILE_ROWS];
					int newTiles[TILE_ROWS];
					int combined[TILE_ROWS];
					
					for (j=TILE_ROWS-1;j>=0;j--)
					{
						combined[j]=0;
						newTiles[j]=handle->actField.tile[j][i];
						newpos[j]=j;
					}
					for (j=TILE_ROWS-1;j>=0;j--)
					{
						int found;
						combined[j]=0;
						newpos[j]=j;
						if (newTiles[j])
						{
							found=-1;
							for (k=j+1;k<TILE_ROWS && found==-1;k++)
							{
								if (newTiles[k]==0) newpos[j]=k;
								else found=k;
							}
							found=-1;
							for (k=j-1;k>=0 && found==-1;k--)
							{
								if (newTiles[k])
								{
									found=k;
									if (newTiles[j]==newTiles[k])
									{
										handle->score+=newTiles[j];
										newpos[k]=newpos[j];
										newTiles[j]*=2;
										newTiles[k]=0;
										combined[j]=1;
										moved=1;
									}
								}
							}

							if (newpos[j]!=j)
							{
								transition(handle,handle->actField.tile[j][i], j,newpos[j], i,i);
								combined[newpos[j]]=combined[j];
								newTiles[newpos[j]]=newTiles[j];
								newTiles[j]=0;
								combined[j]=0;
								moved=1;
							}			
						}
					}
					// TODO: transition

					for (j=0;j<TILE_ROWS;j++)
					{
						handle->actField.tile[j][i]=newTiles[j];
					}
				}
				break;

			case MOVE_LEFT:
				// 
				for (i=0;i<TILE_ROWS;i++)
				{
					int newpos[TILE_COLS];
					int newTiles[TILE_COLS];
					int combined[TILE_COLS];
					
					for (j=0;j<TILE_COLS;j++) 
					{
						combined[j]=0;
						newTiles[j]=handle->actField.tile[i][j];
						newpos[j]=j;
					}
					for (j=0;j<TILE_COLS;j++)
					{
						int found;
						combined[j]=0;
						newpos[j]=j;
						if (newTiles[j])
						{
							found=-1;
							for (k=j-1;k>=0 && found==-1;k--)
							{
								if (newTiles[k]==0) newpos[j]=k;
								else found=k;
							}

							found=-1;
							for (k=j+1;k<TILE_COLS && found==-1;k++)
							{
								if (newTiles[k])
								{
									found=k;
									if (newTiles[j]==newTiles[k])
									{
										handle->score+=newTiles[j];
										newpos[k]=newpos[j];
										newTiles[j]*=2;
										newTiles[k]=0;
										combined[j]=1;
										moved=1;
									}
								}
							}

							if (newpos[j]!=j)
							{
								transition(handle,handle->actField.tile[i][j], i,i, j,newpos[j]);
								combined[newpos[j]]=combined[j];
								newTiles[newpos[j]]=newTiles[j];
								newTiles[j]=0;
								combined[j]=0;
								moved=1;
							}			
						}
					}
					// TODO: transition

					for (j=0;j<TILE_COLS;j++)
					{
						handle->actField.tile[i][j]=newTiles[j];
					}
				}
				break;

			case MOVE_RIGHT:
				// 
				for (i=0;i<TILE_ROWS;i++)
				{
					int newpos[TILE_COLS];
					int newTiles[TILE_COLS];
					int combined[TILE_COLS];
					
					for (j=TILE_COLS-1;j>=0;j--)
					{
						combined[j]=0;
						newTiles[j]=handle->actField.tile[i][j];
						newpos[j]=j;
					}
					for (j=TILE_COLS-1;j>=0;j--)
					{
						int found;
						combined[j]=0;
						newpos[j]=j;
						if (newTiles[j])
						{
							found=-1;
							for (k=j+1;k<TILE_COLS && found==-1;k++)
							{
								if (newTiles[k]==0) newpos[j]=k;
								else found=k;
							}

							found=-1;
							for (k=j-1;k>=0 && found==-1;k--)
							{
								if (newTiles[k])
								{
									found=k;
									if (newTiles[j]==newTiles[k])
									{
										handle->score+=newTiles[j];
										newpos[k]=newpos[j];
										newTiles[j]*=2;
										newTiles[k]=0;
										combined[j]=1;
										moved=1;
									}
								}
							}

							if (newpos[j]!=j)
							{
								transition(handle,handle->actField.tile[i][j], i,i, j,newpos[j]);
								combined[newpos[j]]=combined[j];
								newTiles[newpos[j]]=newTiles[j];
								newTiles[j]=0;
								combined[j]=0;
								moved=1;
							}			
						}
					}
					// TODO: transition

					for (j=0;j<TILE_COLS;j++)
					{
						handle->actField.tile[i][j]=newTiles[j];
					}
				}
				break;
			}
		if (moved)
		{
			for (i=0;i<TILE_ROWS;i++)
			{
				for (j=0;j<TILE_COLS;j++)
				{
					if (moved<handle->actField.tile[i][j]) moved=handle->actField.tile[i][j];
				}
			}
		}
		if (handle->score>handle->best) handle->best=handle->score;
		return moved;
	} else {
		return 0;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值