关于2048的问题

C语言 码拜 6年前 (2015-05-11) 360次浏览 0个评论
 

①运行的时候会突然某一行都变成16或者32,这个是怎么回事
②之前在随机出现数字的函数里面加了一个srand(),导致运行的时候总是会卡,去掉之后就不卡了,这是为什么

附上代码,有些长

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
int num[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
int score=0;//记录合成分数

//产生随机数
int randnum(int x)
{
	int a;
	//srand((unsigned)time(NULL));
	a=rand()%x;
	return a;
}

//判断游戏是否结束,结束返回0,否则返回1
int gamefail()
{
	int i,j,l=0;       
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(num[i][j]!=0)
				l++;   //l记录非空白格的个数 
		}
	}
	//判断
	if(l!=16)
	{
		return 1;
	}else{
		l=0;   //l记录是否有相邻的数字相同 
		//从上往下
		for(j=0;j<4;j++)
		{
			for(i=1;i<3;i++)
			{
				if((num[i][j]==num[i+1][j])||(num[i][j]==num[i-1][j]))
				{
					l++;
					break;
				}
			}
			if((num[i][j]==num[i+1][j])||(num[i][j]==num[i-1][j]))
				break;
		}
		if(l!=0)
			return 1;
		else
		{
			l=0;
			for(i=0;i<4;i++)
			{
				for(j=1;j<3;j++)
				{
					if((num[i][j]==num[i][j+1])||(num[i][j]==num[i][j-1]))
					{
						l++;
						break;
					}
				}
				if((num[i][j]==num[i][j+1])||(num[i][j]==num[i][j-1]))
					break;
			}
			if(l!=0)
				return 1;
			else
				return 0;
		}
	}
}

//初始化
void start()
{
	int x1,y1;//初始随机坐标
	int r;//随机数
	int i,j;
	x1=randnum(4);
	y1=randnum(4);
	r=randnum(10);
	if(r==9)
	{
		num[x1][y1]=4;
	}else{
		num[x1][y1]=2;
	}
	i=randnum(4);
	j=randnum(4);
	while(num[i][j]!=0)
	{
		i=randnum(4);
		j=randnum(4);
	}
	r=randnum(10);
	if(r==9)
	{
		num[i][j]=4;
	}else{
		num[i][j]=2;
	}
}

void randr()
{
	int i,j,r;
	i=randnum(4);
	j=randnum(4);
	while(num[i][j]!=0)
	{
		i=randnum(4);
		j=randnum(4);
	}
	r=randnum(10);
	if(r==9)
		num[i][j]=4;
	else
		num[i][j]=2;
}

void moveup()
{
	int i,j,k;
	int temp[4]={0,0,0,0};       //间接转换
	//将原来的数组中的非零数相邻放置
	for(j=0;j<4;j++)
	{
		for(i=0;i<4;i++)
		{
			for(k=0;k<3;k++)
			{
				if(num[k][j]==0)
				{
					num[k][j]=num[k+1][j];
					num[k+1][j]=0;
				}
			}
		}
	}
	//将数组的列转入中间变量并移动、相加
	for(j=0;j<4;j++)
	{
		k=0;
		for(i=0;i<4;i++)
		{
			if(i==3)
			{
				temp[k++]=num[i][j];
				num[i][j]=0;
			}else{
				if(num[i][j]!=num[i+1][j]&&num[i][j]!=0)
				{
					temp[k++]=num[i][j];
					num[i][j]=0;
				}else if(num[i][j]==num[i+1][j])
				{
					temp[k++]=num[i][j]+num[i+1][j];
					score+=temp[k-1];//计算得分
					num[i][j]=num[i+1][j]=0;
				}
			}
		}
		for(i=0;i<4;i++)
			num[i][j]=temp[i];
	}
}

void moveleft()
{
	int i,j,k;
	int temp[4]={0,0,0,0};
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			for(k=0;k<3;k++)
			{
				if(num[i][k]==0)
				{
					num[i][k]=num[i][k+1];
					num[i][k+1]=0;
				}
			}
		}
	}
	for(i=0;i<4;i++)
	{
		k=0;
		for(j=0;j<4;j++)
		{
			if(j==3)
			{
				if(num[i][j]!=0)
				{
					temp[k++]=num[i][j];
					num[i][j]=0;
				}
			}else{
				if(num[i][j]!=num[i][j+1]&&num[i][j]!=0)
				{
					temp[k++]=num[i][j];
					num[i][j]=0;
				}else if(num[i][j]==num[i][j+1])
				{
					temp[k++]=num[i][j]+num[i][j+1];
					score+=temp[k-1];
					num[i][j]=num[i][j+1]=0;
				}
			}
		}
		for(j=0;j<4;j++)
		{
			num[i][j]=temp[j];
		}
	}
}

void movedown()
{
	int i,j,k;
	int temp[4]={0,0,0,0};
	for(j=0;j<4;j++)
	{
		for(i=3;i>=0;i--)
		{
			for(k=3;k>0;k--)
			{
				if(num[k][j]==0)
				{
					num[k][j]=num[k-1][j];
					num[k-1][j]=0;
				}
			}
		}
	}
	for(j=0;j<4;j++)
	{
		k=3;
		for(i=3;i>=0;i--)
		{
			if(i==0)
			{
				if(num[i][j]!=0)
				{
					temp[k--]=num[i][j];
					num[i][j]=0;
				}
			}else{
				if(num[i][j]!=num[i-1][j]&&num[i][j]!=0)
				{
					temp[k--]=num[i][j];
					num[i][j]=0;
				}else if(num[i][j]==num[i-1][j])
				{
					temp[k--]=num[i][j]+num[i-1][j];
					score+=temp[k+1];
					num[i][j]=num[i-1][j]=0;
				}
			}
		}
		for(i=3;i>=0;i--)
			num[i][j]=temp[i];
	}
}

void moveright()
{
	int i,j,k;
	int temp[4]={0,0,0,0};
	for(i=0;i<4;i++)
	{
		for(j=3;j>=0;j--)
		{
			for(k=3;k>0;k--)
			{
				if(num[i][k]==0)
				{
					num[i][k]=num[i][k-1];
					num[i][k-1]=0;
				}
			}
		}
	}
	for(i=0;i<4;i++)
	{
		k=3;
		for(j=3;j>=0;j--)
		{
			if(j==0)
			{
				if(num[i][j]!=0)
				{
					temp[k--]=num[i][j];
					num[i][j]=0;
				}
			}else{
				if(num[i][j]!=num[i][j-1]&&num[i][j]!=0)
				{
					temp[k--]=num[i][j];
					num[i][j]=0;
				}else if(num[i][j]==num[i][j-1])
				{
					temp[k--]=num[i][j]+num[i][j-1];
					score+=temp[k+1];
					num[i][j]=num[i][j-1]=0;
				}
			}
		}
		for(j=0;j<4;j++)
			num[i][j]=temp[j];
	}
}

//输出
void output()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(j==3)
				printf("%6d\n",num[i][j]);
			else
				printf("%6d",num[i][j]);
		}
	}
	printf("分数:%d\n",score);
}
int max()
{
	int i,j,m=num[0][0];
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			if(num[i][j]>m)
				m=num[i][j];
		}
	}
	return m;
}

void search()
{
	if(max()==2048)
		printf("成功合成2048");
	else if(max()==4096)
		printf("成功合成4096");
	else if(max()==8192)
		printf("成功合成8192");
}

void main()
{
	int i,j,k=0,l=0;
	char c;//接收w,a,s,d
	int move;
	int num1[4][4];
	//初始化
	do
	{
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				num[i][j]=0;
			}
		}
		start();
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				if(num[i][j]!=0)
					l++;
			}
		}
	}while(l!=2);
	output();

	//开始游戏
	while(gamefail())//首先判断游戏是否可以继续进行
	{
		move=0;
		//判断如何移动
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				num1[i][j]=num[i][j];
			}
		}
		c=getch();
		switch(c)
		{
			case ""W"":
			case ""w"":moveup();break;
			case ""A"":
			case ""a"":moveleft();break;
			case ""S"":
			case ""s"":movedown();break;
			case ""D"":
			case ""d"":moveright();break;
			default :printf("请输入正确的按键\n");
		}
		for(i=0;i<4;i++)
		{
			for(j=0;j<4;j++)
			{
				if(num1[i][j]==num[i][j])
					move++;
				else
					break;
			}
			if(num1[i][j]!=num[i][j])
				break;
		}
		if(move!=16)
		{
			//在空白地方产生一个随机数
			randr();
			system("cls");
			//输出
			output();
		}else{
			printf("请移动方块\n");
		}
		search();
	}
	printf("GAME OVER");
	system("pause");
}
40分
Srand这个函数应该只运行一次,他是随机数种子,起初始化作用。你把它放在每一个随机数函数执行之前是多余的,
参考代码段:
https://github.com/707wk/Senior-middle-school/tree/master/2048
引用 1 楼 cao_julians 的回复:

Srand这个函数应该只运行一次,他是随机数种子,起初始化作用。你把它放在每一个随机数函数执行之前是多余的,

原来是这样

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\rand.c

/***
*rand.c - random number generator
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines rand(), srand() - random number generator
*
*******************************************************************************/

#include <cruntime.h>
#include <mtdll.h>
#include <stddef.h>
#include <stdlib.h>

/***
*void srand(seed) - seed the random number generator
*
*Purpose:
*       Seeds the random number generator with the int given.  Adapted from the
*       BASIC random number generator.
*
*Entry:
*       unsigned seed - seed to seed rand # generator with
*
*Exit:
*       None.
*
*Exceptions:
*
*******************************************************************************/

void __cdecl srand (
        unsigned int seed
        )
{
        _getptd()->_holdrand = (unsigned long)seed;
}


/***
*int rand() - returns a random number
*
*Purpose:
*       returns a pseudo-random number 0 through 32767.
*
*Entry:
*       None.
*
*Exit:
*       Returns a pseudo-random number 0 through 32767.
*
*Exceptions:
*
*******************************************************************************/

int __cdecl rand (
        void
        )
{
        _ptiddata ptd = _getptd();

        return( ((ptd->_holdrand = ptd->_holdrand * 214013L
            + 2531011L) >> 16) & 0x7fff );
}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于2048的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!