⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clean.c

📁 Run Pac-man Game Based on 8086/8088 FPGA IP Core
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/* create a new, empty board */
BOARD *board_new()
{
	int x, y;
	BOARD *nb;
	nb = &myboard;
	nb->status = PLAYING;
	nb->score = 0;
	nb->food_count = 0;
	nb->round = 0;
	op(0, 0,&(nb->player_pos));
	for(x = 0; x < GHOSTCOUNT; x++)
		op(0, 0,&(nb->ghost_pos[x]));
	for(y = 0; y < HEIGHT; y++)
		for(x = 0; x < WIDTH; x++)
		{	
			nb->board_data[x][y].wall  = 0;
			nb->board_data[x][y].food  = 0;
		}
	return nb;
}

/* display a board using curses */
void board_display_curses(BOARD *b)
{
	int i, x, y;
	//uart_puts("inside board_display_curses!\n");
	for(y = 0; y < HEIGHT; y++)
	{
		for(x = 0; x < WIDTH; x++)
		{
			if((b->player_pos.x == x) && (b->player_pos.y == y))
			{
				writef(x,y,MANID);
				continue;
			}
			for(i = 0; i < GHOSTCOUNT; i++)
				if((b->ghost_pos[i].x == x) && (b->ghost_pos[i].y == y))
				{
					writef(x,y,MONSTERID);
					break;
				}
			if(i != GHOSTCOUNT)
				continue;
			if(b->board_data[x][y].wall)
			{
				writef(x,y,WALLID);
				continue;
			}
			if(b->board_data[x][y].food)
			{
				writef(x,y,FOODID);
				continue;
			}
			writef(x,y,SPACEID);
		}/*end of x*/
	}/*end of y*/
	/*last three line is for score and food count */
	for(i=0;i<(b->score*WIDTH/(foodall+1));i++)
		writef(i,HEIGHT-3,SCOREID);
	for(i=0;i<(b->food_count*WIDTH/(foodall+1));i++)
		writef(i,HEIGHT-2,FOODID);
	for(i=0;i<b->round;i++)
		writef(i,HEIGHT-1,MANID);
	//uart_puts("board_display_curses done!\n");
}

/* this makes it possible to semi-graphically draw a board layout with a text editor, as seen above */
void board_init_from_strings(BOARD *b, char *data[])
{
	int x, y;
	b->food_count = 0;
	for(y = 0; y < HEIGHT; y++)
		for(x = 0; x < WIDTH; x++)
			switch (data[y][x])
			{
				case '#':
					b->board_data[x][y].wall = 1;
					b->board_data[x][y].food = 0;
					break;
				case '.':
					b->board_data[x][y].wall = 0;
					b->board_data[x][y].food = 1;
					b->food_count++;
					op(x,y,&(b->player_pos));
					break;
				default:
					b->board_data[x][y].wall = 0;
					b->board_data[x][y].food = 0;
					break;
			}
	/* the player automatically gets the food it starts on */
	b->board_data[b->player_pos.x][b->player_pos.y].food = 0;
	b->food_count--;
	b->score++;
 	/* the ghosts always start in the middle */
	for(x = 0; x < GHOSTCOUNT; x++)
		op((WIDTH/2) - (GHOSTCOUNT/2) + x, 7, &(b->ghost_pos[x]));
	foodall=b->food_count;
	b->status = PLAYING;
	//uart_puts("board_init_from_strings done!\n");
}

/****************************************************************/
/* Ghost control system */
/****************************************************************/

/* A ghost's "memory" */
typedef struct {
	int has_momentum;
	int distance;
	ORDPAIR momentum_dir;
	ORDPAIR last_pos;
} GHOST;

/* global structure to contain all ghosts's memories */
GHOST ghost_record[GHOSTCOUNT];

/* initialization of the ghost memories */
void ghost_initrecs()
{
	int i;
	for(i = 0; i < GHOSTCOUNT; i++)
	{
		ghost_record[i].has_momentum = 0;
		op(-1, -1, &(ghost_record[i].last_pos));
	}
	//uart_puts("ghost_initrecs...done!\n");
}

/* get a ghost's action - this function *must* return only legal moves */
void ghost_action(BOARD *b, char gn, ORDPAIR *dir) 
{
	ORDPAIR willpos;
	//uart_puts("ghost_action1!\n");
	if(op_eq(&(b->player_pos), &(b->ghost_pos[gn])))
		op(0,0,dir);
		//uart_puts("ghost_action2!\n");
	/*uart_puts("player position=");
	uart_putv(b->player_pos.x);
	uart_putv(b->player_pos.y);
	uart_puts("ghost position=");
	uart_putv(b->ghost_pos[gn].x);
	uart_putv(b->ghost_pos[gn].y);*/
	/* first look along the x corridor */
	if(b->player_pos.x == b->ghost_pos[gn].x)
	{
		int y, dy;
		//uart_puts("ghost_action2.1!\n");
		dy = (b->player_pos.y < b->ghost_pos[gn].y) ? -1 : 1;
		for(y = b->ghost_pos[gn].y + dy; y != b->player_pos.y; y += dy)
			if (b->board_data[b->player_pos.x][y].wall) 
				//uart_puts("ghost_action2.2!\n");
				break;
		if(y == b->player_pos.y)
		{
			//uart_puts("ghost_action2.3!\n");
			ghost_record[gn].has_momentum = 1;
			ghost_record[gn].distance = abs(b->ghost_pos[gn].y - b->player_pos.y);
			op(0, dy,&(ghost_record[gn].momentum_dir));
		}
		//uart_puts("ghost_action3!\n");
	}
	/* next look along the y corridor */
	if(b->player_pos.y == b->ghost_pos[gn].y)
	{
		int x, dx;
		//uart_puts("ghost_action3.1!\n");
		dx = (b->player_pos.x < b->ghost_pos[gn].x) ? -1 : 1;
		for(x = b->ghost_pos[gn].x + dx; x != b->player_pos.x; x += dx)
			if(b->board_data[x][b->player_pos.y].wall)
				//uart_puts("ghost_action3.2!\n");
				break;
		if(x == b->player_pos.x)
		{
			//uart_puts("ghost_action3.3!\n");
			ghost_record[gn].has_momentum = 1;
			ghost_record[gn].distance = abs(b->ghost_pos[gn].x - b->player_pos.x);
			op(dx, 0,&(ghost_record[gn].momentum_dir) );
		}
	}
	//uart_puts("ghost_action4\n");
	/* check to see if the ghost saw the player recently */
	if(ghost_record[gn].has_momentum) 
	{
		//uart_puts("ghost_action4.1!\n");
		op_sum(&(b->ghost_pos[gn]), &(ghost_record[gn].momentum_dir), dir);
		if(!b->board_data[dir->x][dir->y].wall)
		{
			//uart_puts("ghost_action4.2!\n");
			ghost_record[gn].distance--;
			if(ghost_record[gn].distance == 0)
				ghost_record[gn].has_momentum = 0;
				//uart_puts("ghost_action4.3!\n");
			ghost_record[gn].last_pos = b->ghost_pos[gn];
			op(ghost_record[gn].momentum_dir.x,ghost_record[gn].momentum_dir.y,dir);
		}
		ghost_record[gn].has_momentum = 0;
	}
	//uart_puts("ghost_action5\n");
	/* no momentum, do random walk, no stepping backwards */
	do{
			//uart_puts("ghost_action do loop\n");
			op_from_dir(get_rand(5),dir);
			op_sum(&(b->ghost_pos[gn]),dir,&willpos);
			//uart_puts("ghost_action do end \n");
		}
	while(b->board_data[willpos.x][willpos.y].wall ||op_eq(&willpos,&(ghost_record[gn].last_pos)));
	//uart_puts("ghost_action6\n");
	ghost_record[gn].last_pos = b->ghost_pos[gn];
	//uart_puts("ghost_action7\n");
}

/* update the board - b contains board to update, action contains  player's move */
char update_board(BOARD *b, char action)
{
	ORDPAIR newpos,tempos;
	char i, retval;
	retval = 1;
	//uart_puts("!!!!update_board 1\n");
	op_from_dir(action,&newpos);
	op_sum(&(b->player_pos),&newpos,&newpos);
	//uart_puts("!!!!update_board 2\n");
	if(b->board_data[newpos.x][newpos.y].wall)		
		op(b->player_pos.x,b->player_pos.y,&newpos);
		//uart_puts("!!!!update_board 3\n");
	for(i = 0; i < GHOSTCOUNT; i++)
	{
		//uart_puts("!!!!update_board 3.1\n");
		if(op_eq(&newpos,&(b->ghost_pos[i])))
		{
			//uart_puts("!!!!update_board 3.2\n");
			b->status = GAME_OVER;
			retval = 0;
			break;
			}
		//uart_puts("!!!!update_board 3.3\n");
		ghost_action(b,i,&tempos);/*Here is the problem*/
		op_sum(&(b->ghost_pos[i]),&tempos,&(b->ghost_pos[i]));
		if(op_eq(&newpos,&(b->ghost_pos[i])))
		{
			//uart_puts("!!!!update_board 3.4\n");
			b->status = GAME_OVER;
			retval = 0;
			break;
		}
		//uart_puts("!!!!update_board 3.5\n");
	}
	//uart_puts("!!!!update_board 4\n");
	if(b->board_data[newpos.x][newpos.y].food)
	{
		//uart_puts("!!!!update_board 4.1\n");
		b->board_data[newpos.x][newpos.y].food = 0;
		b->score++;
		b->food_count--;
		if (b->food_count == 0)
		{
			//uart_puts("!!!!update_board 4.2\n");
			b->status = ROUND_OVER;
			retval = 0;
		}
	}
	//uart_puts("!!!!update_board 5\n");
	op(newpos.x,newpos.y,&(b->player_pos));
	return retval;
}

char player_action()
{
	char key=getch();
	switch(key)
	{
		case 15 : 
			{stop=1; /*uart_puts("END!\n");*/ return -1;}
		case 1: 
			{ /*uart_puts("UP!\n");*/ return UP;}
		case 2:
			{ /*uart_puts("DOWN!\n");*/ return DOWN;}
		case 4:
			{ /*uart_puts("LEFT!\n");*/ return LEFT;}
		case 8: 
			{ /*uart_puts("RIGHT!\n");*/ return RIGHT;}
		default :
			{ /*uart_puts("STAY!\n");*/ return STAY;}
	}
}

void graphictest()
{
	int i,j;
	/* test herizon line in different color */
	for(i=0;i<VGAWIDTH;i++)
		for(j=0;j<VGAHEIGHT;j++)
			plot(i,j,j%16);
	/*show monster in left up corner, 320x200 256 color mode VGA*/
	for(j=0;j<MAXCURY;j++)
		for(i=0;i<MAXCURX;i++)
			writef(i,j,(j*MAXCURX+i)%GRAPHCHAR_BUTT);
}

void main(int argc, char *argv[])
{
	ORDPAIR initpos;
	BOARD *b;
	stop=0;
	//uart_puts("hello!\n");
	//uart_putv(0x1234);
	op_from_dir(0,&initpos);
	graphictest();
	b = board_new();
	ghost_initrecs();
	b->round=MAXROUND;
	/*outer loop of rounds*/
	do{
	 	board_init_from_strings(b, default_board);
		do{
			board_display_curses(b);
			}
		while(update_board(b, player_action())&&(!stop));
		//uart_puts("*****round.......loop\n");
		b->round--;
		/*uart_puts("b->round=");
		uart_putv(b->round);
		uart_puts("b->status=");
		uart_putv(b->status);
		uart_puts("stop=");
		uart_putv(stop);*/
		}
	while(((b->status != GAME_OVER) || (b->round >= 0))&&(!stop));
	//uart_puts("!!!!!!!!!!!!!!!!out of round loop\n");
	getch();
	//uart_puts("--------------------finish---------------------\n");
	while(1) stop=1;/*deadloop*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -