stm32f103與2.4寸TFT可觸液晶屏實現的五子棋AI人機對戰(人工智能博弈樹)

一、移植文件

PS:此工程基於STM32精英板!
將 chess.c 、 chess.h兩個文件添加到過程文件夾下

1.1chess.c

#include "delay.h"	 	 
#include "lcd.h"        
#include "text.h" 
#include "touch.h"	
#include "chess.h"
#include "timer.h"


char param;				//遊戲模式
char player = p1;	//默認黑棋先手

char chess[N][N];	//棋盤地圖
int a[N],b[N];   //記錄每一步棋子的座標位置

int chess_num = 0;		//總棋子數

char p1_time = time;	//黑棋剩餘時間
char p2_time = time;	//白棋剩餘時間

extern u16 POINT_COLOR;	//畫筆顏色


void start1()//開始遊戲
{
	Oninit();	
	draw_checkboard();//畫棋盤	
	//show_param(param);

	while (1)
	{
		chesscomputer();
	}
}



void mymsg(int fun)//遊戲結束彈出選擇窗口
{
	LCD_Fill(Grid_wid,Grid_wid*3,Grid_wid*14,Grid_wid*9,LGRAY);//填充單色  實心矩形
	BACK_COLOR=LGRAY;
	POINT_COLOR=BLACK;
	if(fun == p1)
		Show_Str(Grid_wid*4,Grid_wid*4,200,24,"黑棋獲勝!",24,0);
	else if(fun == p2)
		Show_Str(Grid_wid*4,Grid_wid*4,200,24,"白棋獲勝!",24,0);	
	else if(fun == 3)
		Show_Str(Grid_wid*4,Grid_wid*4,200,24,"平局!",24,0);

	Show_Str(Grid_wid*2,Grid_wid*7,100,16,"重新開始",16,0);	
	Show_Str(Grid_wid*9,Grid_wid*7,100,16,"退出遊戲",16,0);	
	
	POINT_COLOR=WHITE;
	LCD_DrawRectangle(Grid_wid*2-3, Grid_wid*7-3, Grid_wid*6+3, Grid_wid*8+3);  
	LCD_DrawRectangle(Grid_wid*9-3, Grid_wid*7-3, Grid_wid*13+3, Grid_wid*8+3); 
	POINT_COLOR=BLACK;
	BACK_COLOR=BROWN;
}
void Oninit()//初始化參數
{
	int i,j;
	player = p1;	//默認黑棋先手
	for (i = 0; i < N;i++)//棋盤清零
	{
		a[i]= Nochess;
		b[i]= Nochess;
		for (j = 0; j < N; j++)
		{
			chess[i][j] = Nochess;
		}
	}
	chess_num = 0;			//總棋子數清零
	p1_time = time;	//黑棋剩餘時間
	p2_time = time;	//白棋剩餘時間
}

void selete()//選擇遊戲模式
{
	draw_interface();//顯示初始遊戲菜單
	int xtemp,ytemp;
	while (1)
	{		
		tp_dev.scan(0);//掃描
		if (tp_dev.sta&TP_PRES_DOWN)//有按鍵被按下
		{
			delay_ms(10);//必要的延時,否則老認爲有按鍵按下. 
			xtemp = tp_dev.x[0];
			ytemp = tp_dev.y[0];		
			if(xtemp>=112&&xtemp<=208&&ytemp>=114&&ytemp<=146)
			{
				param=player_player;
				LCD_DrawRectangle(112, 114, 208, 146);  
				delay_ms(500);
				return;
			}			
			else if(xtemp>=112&&xtemp<=208&&ytemp>=164&&ytemp<=196)
			{
				param=player_AI;
				LCD_DrawRectangle(112, 164, 208, 196);
				delay_ms(500);
				return;
			}
		}
		else 
			delay_ms(10); 
	}
}

void start()//開始遊戲
{
	int x1, y1;
	Oninit();	
	draw_checkboard();//畫棋盤	
	show_param(param);
	show_time();

	while (1)
	{
		TIM_Cmd(TIM3, ENABLE);  //使能TIMx
		tp_dev.scan(0);//掃描
		if (tp_dev.sta&TP_PRES_DOWN)//有按鍵被按下
		{
			delay_ms(10);//必要的延時,否則老認爲有按鍵按下 
			//按下悔棋按鈕 改變外框顏色
			if(tp_dev.x[0]>=Grid_wid*(N + 1)-2&&tp_dev.x[0]<=Grid_wid*(N + 3)+2&&tp_dev.y[0]>=Grid_wid*(N/2 + 1)&&tp_dev.y[0]<=Grid_wid*(N/2 + 2)+6)
			{
				LCD_DrawRectangle(Grid_wid*(N + 1)-2, Grid_wid*(N/2 + 1), Grid_wid*(N + 3)+2, Grid_wid*(N/2 + 2)+6);
				retract_chess();//悔棋
				delay_ms(500);
				POINT_COLOR=WHITE;
				LCD_DrawRectangle(Grid_wid*(N + 1)-2, Grid_wid*(N/2 + 1), Grid_wid*(N + 3)+2, Grid_wid*(N/2 + 2)+6);
				POINT_COLOR=BLACK;
			}	
						
			x1 = mod_xy(tp_dev.x[0]);
			y1 = mod_xy(tp_dev.y[0]);			
			if (param == player_player)
			{
					TIM_Cmd(TIM3, DISABLE);  //關閉使能TIMx外設
					delay_ms(100);
					Chess_piece(x1, y1);
			}
			else if (param == player_AI)
			{
					if (Chess_piece(x1, y1))
					{
						TIM_Cmd(TIM3, DISABLE);  //關閉使能TIMx外設
						delay_ms(500);
						chesscomputer();
					}	
			}		
		}
		
		if(p1_time == 0||p2_time == 0)//到時間了則對方獲勝
		{
				p1_time=time;
				p2_time=time;
				Restart(1,p1+p2-player);
		}
	}
}

void Restart(int par,int player)//重新開始遊戲
{
	if (par == 1)
		mymsg(player);			
	else
		mymsg(3);		

	int xtemp,ytemp;
	while (1)
	{		
		p1_time = time;	//黑棋剩餘時間
		p2_time = time;	//白棋剩餘時間
		tp_dev.scan(0);//掃描
		if (tp_dev.sta&TP_PRES_DOWN)//有按鍵被按下
		{
			delay_ms(10);//必要的延時,否則老認爲有按鍵按下. 
			xtemp = tp_dev.x[0];
			ytemp = tp_dev.y[0];		

			if(xtemp>=Grid_wid*2-3&&xtemp<=Grid_wid*6+3&&ytemp>=Grid_wid*7-3&&ytemp<=Grid_wid*8+3)
			{
				LCD_DrawRectangle(Grid_wid*2-3, Grid_wid*7-3, Grid_wid*6+3, Grid_wid*8+3); 
				delay_ms(300); 				
				start();
			}			
			else if(xtemp>=Grid_wid*9-3&&xtemp<=Grid_wid*13+3&&ytemp>=Grid_wid*7-3&&ytemp<=Grid_wid*8+3)
			{
				LCD_DrawRectangle(Grid_wid*9-3, Grid_wid*7-3, Grid_wid*13+3, Grid_wid*8+3); 
				delay_ms(300); 			
				//軟件復位
				__disable_fault_irq();
				NVIC_SystemReset();
			}
		}
		else 
			delay_ms(10); 
	}
}


void draw_checkboard()//繪製棋盤
{
	BACK_COLOR=BROWN;
	LCD_Clear(BROWN);//設置背景色
	int i;
	for (i = 0; i < N;i++)//畫地圖
	{
		lcd_draw_bline(m_wid + i*Grid_wid, m_wid, m_wid + i*Grid_wid, m_wid + Grid_wid * (N - 1),1,BLACK);
		lcd_draw_bline(m_wid, m_wid + i*Grid_wid, m_wid + Grid_wid * (N - 1), m_wid + i*Grid_wid,1,BLACK);
	}
	//3 3    3 11   7 7    11 3    11 11  五個點的位置
	gui_fill_circle(m_wid+3*Grid_wid, m_wid+3*Grid_wid, 3, BLACK);
	gui_fill_circle(m_wid+3*Grid_wid, m_wid+11*Grid_wid, 3, BLACK);
	gui_fill_circle(m_wid+7*Grid_wid, m_wid+7*Grid_wid, 3, BLACK);
	gui_fill_circle(m_wid+11*Grid_wid, m_wid+3*Grid_wid, 3, BLACK);
	gui_fill_circle(m_wid+11*Grid_wid, m_wid+11*Grid_wid, 3, BLACK);
}



void draw_interface()//繪製初始遊戲選擇界面
{
	BACK_COLOR=LIGHTGREEN;
  LCD_Clear(LIGHTGREEN);
	
	int x1=72;
	POINT_COLOR=YELLOW;
	Show_Str(x1,48,200,24,"五",24,0);
	POINT_COLOR=WHITE;
	Show_Str(x1+24*3,48,200,24,"子",24,0);
	POINT_COLOR=BROWN;
  Show_Str(x1+24*6,48,200,24,"棋",24,0);
	POINT_COLOR=WHITE;
  LCD_DrawRectangle(112, 114, 208, 146);
  LCD_DrawRectangle(112, 164, 208, 196);
	POINT_COLOR=BLACK;
	Show_Str(128,122,200,16,"人人對戰",16,0);	
	Show_Str(128,172,200,16,"人機對戰",16,0);
	BACK_COLOR=BROWN;
}


void remove_chess(int x1,int y1)//擦除棋子
{
	gui_fill_circle(m_wid+x1*Grid_wid, 	m_wid+y1*Grid_wid, Chess_R, BROWN);
	lcd_draw_bline(m_wid+x1*Grid_wid-Chess_R, m_wid+y1*Grid_wid,m_wid+x1*Grid_wid+Chess_R, m_wid+y1*Grid_wid,1,BLACK);
	lcd_draw_bline(m_wid+x1*Grid_wid, m_wid+y1*Grid_wid-Chess_R,m_wid+x1*Grid_wid, m_wid+y1*Grid_wid+Chess_R,1,BLACK);

	if(x1==0)		
		lcd_draw_bline(m_wid, m_wid+y1*Grid_wid,m_wid+Chess_R, m_wid+y1*Grid_wid,1,BLACK);
	if(y1==0)
		lcd_draw_bline(m_wid+x1*Grid_wid, m_wid,m_wid+x1*Grid_wid, m_wid+Chess_R,1,BLACK);
	if(x1==N-1)
		lcd_draw_bline(m_wid+x1*Grid_wid+2, m_wid+y1*Grid_wid,m_wid+x1*Grid_wid+Chess_R, m_wid+y1*Grid_wid,1,BACK_COLOR);	
	if(y1==N-1)
		lcd_draw_bline(m_wid+x1*Grid_wid, m_wid+y1*Grid_wid+1,m_wid+x1*Grid_wid, m_wid+y1*Grid_wid+Chess_R,1,BACK_COLOR);


	//如果是五個特殊點	 五個點的位置:3 3    3 11   7 7    11 3    11 11  
	if(
			(x1==3&&y1==3) 	||
			(x1==3&&y1==11) ||
			(x1==7&&y1==7) 	||
			(x1==11&&y1==3) ||
			(x1==11&&y1==11) 
		)
	{
		gui_fill_circle(m_wid+x1*Grid_wid, m_wid+y1*Grid_wid, 3, BLACK);
	}
}




void retract_chess()//悔棋
{ 
	if(chess_num>=2)
	{
		int x1,y1;
		
		x1 = a[chess_num-1];
		y1 = b[chess_num-1];
		chess[x1][y1] = Nochess;
		remove_chess(x1,y1);
		chess_num--;
		
		x1 = a[chess_num-1];
		y1 = b[chess_num-1];
		chess[x1][y1] = Nochess;
		remove_chess(x1,y1);
		chess_num--;
		
		p1_time = time;	//黑棋剩餘時間
		p2_time = time;	//白棋剩餘時間
		
	}
}


void show_param(int n)//顯示遊戲模式
{
	POINT_COLOR=WHITE;
	if(n==player_AI)
	{
		Show_Str(Grid_wid*N,Grid_wid*(N/2 - 2),			 200,16,"人機對戰",16,0);		
	}
	else if(n==player_player)
	{
		Show_Str(Grid_wid*N,Grid_wid*(N/2 - 2),			 200,16,"人人對戰",16,0);		
	}
	POINT_COLOR=BLACK;
	Show_Str(Grid_wid*(N + 1),Grid_wid*(N/2 + 1)+3,			 200,16,"悔棋",16,0);		
	POINT_COLOR=WHITE;
  LCD_DrawRectangle(Grid_wid*(N + 1)-2, Grid_wid*(N/2 + 1), Grid_wid*(N + 3)+2, Grid_wid*(N/2 + 2)+6);
	POINT_COLOR=BLACK;
}

void show_time(void)//顯示剩餘時間
{
	gui_fill_circle(Grid_wid*N+Chess_R, 	Grid_wid*2+Chess_R, Chess_R, BLACK);
	Show_Str			 (Grid_wid*(N+1),				Grid_wid*2,					200,16,		"剩餘:",16,0);		
	LCD_ShowNum		 (Grid_wid*(N+3)+m_wid,	Grid_wid*2,					p1_time-1,2,16);//顯示一個數字
	Show_Str			 (Grid_wid*(N+5)-m_wid,	Grid_wid*2,					200,16,		"s",16,0);		
	
	gui_fill_circle(Grid_wid*N+Chess_R, 	Grid_wid*12+Chess_R, Chess_R, WHITE);
	Show_Str			 (Grid_wid*(N+1),				Grid_wid*12,				200,16,		"剩餘:",16,0);	
	LCD_ShowNum		 (Grid_wid*(N+3)+m_wid,	Grid_wid*12,				p2_time-1,2,16);//顯示一個數字	
	Show_Str			 (Grid_wid*(N+5)-m_wid,	Grid_wid*12,				200,16,		"s",16,0);
}


int mod_xy(int xy)//座標修正
{
	int res = (int)((double)(xy-m_wid) / Grid_wid + 0.5);
	if (res < N && res >= 0)
	{
		return res;
	}
	else
	{
		return -1;
	}
}



int judge(int x, int y)//判斷此位置是否可以落子
{
	return chess[x][y] ? 0 : 1;
}


int judge_win(int x, int y)//判斷遊戲輸贏
{
	int i, j, k;
	const int step[4][2] = { { 1, 0 }, { 0, 1 }, { 1, 1 }, { 1, -1 } };
	for (i = 0; i < 4; ++i)
	{
		const int d[2] = { -1, 1 };
		int count = 1;
		for (j = 0; j < 2; ++j)
		for (k = 1; k <= 4; ++k)
		{
			int row = x + k*d[j] * step[i][0];
			int col = y + k*d[j] * step[i][1];
			if (row >= 1 && row <= N &&
				col >= 1 && col <= N &&
				chess[x][y] == chess[row][col])
				count += 1;
			else
				break;
		}
		if (count >= 5)
			return 1;
	}
	if (chess_num == N*N)
	{
		delay_ms(1000);
		Restart(2,player);		
	}

	return 0;
}



int Chess_piece(int x1, int y1)//落子
{
	if(x1 == -1||y1 == -1)
	{
		return 0;
	}
	if (judge(x1, y1))
	{
		if (player == p1)
			gui_fill_circle(m_wid+x1*Grid_wid, 	m_wid+y1*Grid_wid, Chess_R, BLACK);
		else
			gui_fill_circle(m_wid+x1*Grid_wid, 	m_wid+y1*Grid_wid, Chess_R, WHITE);
		chess[x1][y1] = player;
		//按順序存儲每一個棋子的座標位置
		a[chess_num] = x1;
		b[chess_num] = y1;		
		chess_num++;
		if (judge_win(x1, y1))
		{
			delay_ms(1000);
			Restart(1,player); 
		}
		changeplayer();
		p1_time=time;
		LCD_ShowNum			 (Grid_wid*(N+3)+m_wid,Grid_wid*2,				p1_time-1,2,16);  						//顯示一個數字
		p2_time=time;
		LCD_ShowNum			 (Grid_wid*(N+3)+m_wid,Grid_wid*12,				p2_time-1,2,16);  						//顯示一個數字
		return 1;
	}
	return 0;
}


void changeplayer()//玩家交換
{
	player = p1 + p2 - player;
}


int scorejudge(int row,int col)//評分系統使用的判斷是否可以落子函數
{
	if ((row >= 0 && row < N) && (col >= 0 && col < N))
	{
		return 1;
	} 
	else
	{
		return 0;
	}
}



int chessscore(int x, int y, int worb)//棋盤權值函數
{
	int sumscore = 0;
	char u, d, l, r, lu, ld, ru, rd;//u上 d下 l左 r右 lu左上 ld左下 ru右上 rd右下
	int row, col, count1, count2, count3, count4;   //1橫 2豎 3斜上 4斜下
	count1 = count2 = count3 = count4 = 1;
	l = r = u = d = lu = ld = ru = rd = 0;
	chess[x][y] = worb;      //模擬下棋

	//橫向
	row = x, col = y + 1;
	while (chess[row][col] == worb && scorejudge(row,col))
	{
		count1++;
		col++;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		r++;
		col++;
	}
	row = x, col = y - 1;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count1++;
		col--;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		l++;
		col--;
	}


	//豎向
	row = x + 1, col = y;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count2++;
		row++;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		d++;
		row++;
	}
	row = x - 1, col = y;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count2++;
		row--;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		u++;
		row--;
	}

	//斜上
	row = x - 1, col = y + 1;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count3++;
		col++;
		row--;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		ru++;
		col++;
		row--;
	}
	row = x + 1, col = y - 1;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count3++;
		col--;
		row++;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		ld++;
		col--;
		row++;
	}
	

	//斜下
	row = x + 1, col = y + 1;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count4++;
		col++;
		row++;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		rd++;
		col++;
		row++;
	}
	row = x - 1, col = y - 1;
	while (chess[row][col] == worb && scorejudge(row, col))
	{
		count4++;
		col--;
		row--;
	}
	while (chess[row][col] == 0 && scorejudge(row, col))
	{
		lu++;
		col--;
		row--;
	}

	chess[x][y] = Nochess;

	if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5)//成五
	{
		return sumscore = 5000000;
	}


	if ((count1 == 4 && count2 == 4 && l >= 1 && r >= 1 && u >= 1 && d >= 1) ||
		(count1 == 4 && count3 == 4 && l >= 1 && r >= 1 && ru >= 1 && ld >= 1) ||
		(count1 == 4 && count4 == 4 && l >= 1 && r >= 1 && rd >= 1 && lu >= 1) ||
		(count2 == 4 && count3 == 4 && u >= 1 && d >= 1 && ru >= 1 && ld >= 1) ||
		(count2 == 4 && count4 == 4 && u >= 1 && d >= 1 && lu >= 1 && rd >= 1) ||
		(count3 == 4 && count4 == 4 && ru >= 1 && ld >= 1 && lu >= 1 && rd >= 1))
		//雙活四
	{
		return sumscore = 4000000;
	}


	if ((count1 == 4 && l >= 1 && r >= 1) || (count2 == 4 && u >= 1 && d >= 1) ||
		(count3 == 4 && ru >= 1 && ld >= 1) || (count4 == 4 && lu >= 1 && rd >= 1))
		//活四
	{
		return sumscore = 800000;
	}

	if ((count1 == 4 && ((l == 0 && r >= 1) || (l >= 1 && r == 0))) 
		|| (count2 == 4 && ((u == 0 && d >= 1) || (u >= 1 && d == 0))) 
		||(count3 == 4 && ((ld == 0 && ru >= 1) || (ld >= 1 && ru == 0))) 
		|| (count4 == 4 && ((lu == 0 && rd >= 1) || (lu >= 1 && rd == 0))))
	{
		sumscore = sumscore + 35000; //成四
	}

	if ((count1 == 3 && count2 == 3 && l >= 1 && r >= 1 && u >= 1 && d >= 1) ||
		(count1 == 3 && count3 == 3 && l >= 1 && r >= 1 && ru >= 1 && ld >= 1) ||
		(count1 == 3 && count4 == 3 && l >= 1 && r >= 1 && rd >= 1 && lu >= 1) ||
		(count2 == 3 && count3 == 3 && u >= 1 && d >= 1 && ru >= 1 && ld >= 1) ||
		(count2 == 3 && count4 == 3 && u >= 1 && d >= 1 && lu >= 1 && rd >= 1) ||
		(count3 == 3 && count4 == 3 && ru >= 1 && ld >= 1 && lu >= 1 && rd >= 1)) 
		//雙活三
	{
		return sumscore + 400000;
	}


	if ((count1 == 3 && l >= 1 && r >= 1) || (count2 == 3 && u >= 1 && d >= 1) ||
		(count3 == 3 && ru >= 1 && ld >= 1) || (count4 == 3 && lu >= 1 && rd >= 1))
		//活三
	{
		sumscore = sumscore + 60000;
		return sumscore;
	} 


	if ((count1 == 2 && count2 == 2 && l >= 1 && r >= 1 && u >= 1 && d >= 1) ||
		(count1 == 2 && count3 == 2 && l >= 1 && r >= 1 && ru >= 1 && ld >= 1) ||
		(count1 == 2 && count4 == 2 && l >= 1 && r >= 1 && rd >= 1 && lu >= 1) ||
		(count2 == 2 && count3 == 2 && u >= 1 && d >= 1 && ru >= 1 && ld >= 1) ||
		(count2 == 2 && count4 == 2 && u >= 1 && d >= 1 && lu >= 1 && rd >= 1) ||
		(count3 == 2 && count4 == 2 && ru >= 1 && ld >= 1 && lu >= 1 && rd >= 1))
		//雙活二
	{
		sumscore = sumscore + 20000;
	}

	if ((count1 == 2 && l >= 1 && r >= 1) || (count2 == 2 && u >= 1 && d >= 1) ||
		(count3 == 2 && ru >= 1 && ld >= 1) || (count4 == 2 && lu >= 1 && rd >= 1))
		//單活二
	{
		sumscore = sumscore + 10000;
	}
	if ((count1 == 3 && ((l == 0 && r >= 1) || (l >= 1 && r == 0)))
		|| (count2 == 3 && ((u == 0 && d >= 1) || (u >= 1 && d == 0)))
		|| (count3 == 3 && ((ld == 0 && ru >= 1) || (ld >= 1 && ru == 0)))
		|| (count4 == 3 && ((lu == 0 && rd >= 1) || (lu >= 1 && rd == 0))))
	{
		sumscore = sumscore + 5000; //成三
	}
	return sumscore;

}

void chesscomputer()//機器落子
{
int i, j, cscore, cscorel, pscore, pscorel, row1, col1, row2, col2;
	cscore = pscore = 0; row1 = row2 = col1 = col2 = -1;
	
	//尋找最優落子位置
	if (chess_num <= 1)
	{
		row1 = 7;
		col1 = 7;
		do
		{
			row1++;
			col1++;
		} while (!judge(row1, col1));
		Chess_piece(row1, col1);
	}
	else
	{
		for (i = 0; i < N; i++)
		{
			for (j = 0; j < N; j++)
			{
				if (judge(i, j))
				{
					cscorel = chessscore(i, j, p1);
					if (cscorel > cscore)
					{
						cscore = cscorel;
						row1 = i;
						col1 = j;
					}
					pscorel = chessscore(i, j, p2);
					if (pscorel > pscore)
					{
						pscore = pscorel;
						row2 = i;
						col2 = j;
					}
				}
			}
		}
		if (row1 == -1 && col1 == -1 && row2 == -1 && col2 == -1)//沒找到最優解 平局
		{
				Restart(2,player);
		}
		else
		{
			if (chess_num == 3)
			{
				Chess_piece(row2, col2);
			}
			else
			{
				if (cscore > pscore)
				{
					Chess_piece(row1, col1);							
				}
				else
				{
					Chess_piece(row2, col2);
				}
			}
		}
	}
}

1.2chess.h

#ifndef __CHESS_H__
#define __CHESS_H__


#define Grid_wid 	16 						//網格寬度
#define m_wid 		(Grid_wid/2)  //修正寬度
#define Chess_R  	(Grid_wid/2)  //棋子半徑

#define p1 				1							//玩家1
#define p2 				2							//玩家2
#define Nochess 	0							//空棋

#define N  				15						//棋盤格數

#define player_player	3					//人人模式
#define player_AI			4					//人機模式

#define time 16									//每方下棋剩餘時間

void start1();										//機器與機器對戰,測試用
void mymsg(int fun);							//遊戲結束彈出選擇窗口
void Oninit(void);								//初始化參數
void selete(void);								//選擇遊戲模式
void start(void);									//開始遊戲
void Restart(int par,int player); //重新開始遊戲
void draw_checkboard(void);				//繪製棋盤
void draw_interface(void);				//繪製初始遊戲選擇界面
void remove_chess(int x1,int y1); //擦除棋子
void retract_chess(void);					//悔棋
void show_param(int n);						//顯示遊戲模式
void show_time(void);							//顯示剩餘時間
int mod_xy(int xy);								//座標修正
int judge(int x, int y);					//判斷此位置是否可以落子
int judge_win(int x, int y);			//判斷遊戲輸贏
int Chess_piece(int x, int y);		//落子
void changeplayer(void);					//玩家交換
int scorejudge(int row,int col);	//評分系統使用的判斷是否可以落子函數
int chessscore(int x, int y, int worb);//棋盤權值函數
void chesscomputer(void);					//機器落子


#endif


二、運行遊戲

2.1 修改main.c添加Restart函數並調用start函數

#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "usart.h" 
#include "led.h" 		 	 
#include "lcd.h"  
#include "key.h"      
#include "malloc.h"
#include "sdio_sdcard.h"  
#include "w25qxx.h"    
#include "ff.h"  
#include "exfuns.h"   
#include "text.h" 
#include "atk_ncr.h"
#include "touch.h"	
#include "chess.h"
#include "timer.h"


int main(void)
{
	delay_init();	    	 //延時函數初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷優先級分組爲組2:2位搶佔優先級,2位響應優先級
	uart_init(115200);	 	//串口初始化爲115200
	LED_Init();		  			//初始化與LED連接的硬件接口
	KEY_Init();					//初始化按鍵
	LCD_Init();			   		//初始化LCD     
	W25QXX_Init();				//初始化W25Q128
	tp_dev.init();				//初始化觸摸屏
	my_mem_init(SRAMIN);		//初始化內部內存池
	exfuns_init();				//爲fatfs相關變量申請內存  
	f_mount(fs[0], "0:", 1); 		//掛載SD卡 
	f_mount(fs[1], "1:", 1); 		//掛載FLASH.
	alientek_ncr_init();		//初始化手寫識別     
	while (font_init()) 			//檢查字庫
	{
		LCD_ShowString(30, 50, 200, 16, 16, "Font Error!");
		delay_ms(200);
		LCD_Fill(30, 50, 240, 66, WHITE);//清除顯示	     
	}
	TIM3_Int_Init(9999,7199);//計時器 1s	
	TP_Init();
	//TP_Adjust();
	//start1();//開始遊戲
	selete();//遊戲模式選擇
	start();//開始遊戲
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章