五子棋工程心得-----艺果yiguo

五子棋工程心得

1.工程框架

1.1分级管理

  • 对于一个工程的编辑来说为了更好的管理所有的应用,main函数中只包括几个工程管理外不要加其他的函数,这样有利于你的层级管理如下:
int main(int argc,char const *argv[])
{loop://项目初始化project_init();//项目运行project_run();//项目资源回收project_uninit();goto loop;return 0;
}
  • 对于不同功能的函数进行分类为初始化、运行、资源回收三个工程函数,让它们分别管理工程里的初始化、运行,资源回收的相应函数。例如:
void project_init()
{//初始化lcdlcd_init();//初始化touchtouch_init();//棋盘棋子置空pieces_init();
}

1.2在工程管理头文件中定义、管理全局变量

这样的作法一般用于多文件全局变量,不建议用于单文件的全局变量,单文件建议用(static修饰)。

/*多文件全局变量!以及跨文件宏定义!
*/
#ifndef _PROJECT_H_
#define _PROJECT_H_#define quit_game 0xff
#define undraw 0xfe
#define Empty_pieces 0x00
#define NonEmpty_pieces 0x01
#define black 0
#define white 1
#define colorless 0xfd
#define Covered 1
#define unCovered 0
​
​
typedef struct coordinate{int x;int y;int Function_flag;
}Coordinate;
typedef struct piecesdata{char pieces[16][16];char black_white[16][16];char game_progress[16][16];char pieces_color;char blackcount;char whitecount;
}Piecesdata;
​
Coordinate location;
Piecesdata ps;
#endif
/*单文件全局变量静态化
*/
static char fd_lcd;

2.算法简析

2.1网格定点算法简析

  • 对于一个触摸屏上的网格点查询附近的点的采用最小距离有两种;坐标做差取最小,i = (x-15)/30;x =
    (i30+15-x)>(i30+45-x)?(i30+45):(i30+15);y坐标也相同的处理。功能当你想点击周围四个点被覆盖的点,由于电容屏的精确度较低,我们需要提高用户的体验感
    做的处理,采用欧拉公式法:x = (pow2((30-minx),miny) ?(x-30):(pow2(minx, (30-miny))
    /*网格定点算法location.x,location.y为全局变量网格的开始坐标为(175,15)结束坐标为(625,465)
*/
#define pow2(x,y) ((x)*(x)+(y)*(y))void location_change_grid()
{int x,y;x = location.x;y = location.y;if(abs(y-400)>240||abs(x-240) > 240){location.Function_flag = undraw;}else{int i,j;i = (x-15)/30;x = (i*30+15-x)>(i*30+45-x)?(i*30+45):(i*30+15);j = (y-175)/30;y = (j*30+175-y)>(j*30+205-y)?(j*30+205):(j*30+175);/*功能当你想点击周围四个点被覆盖的点,由于电容屏的精确度较低,我们需要提高用户的体验感 做的处理*/if(ps.pieces[(x-15)/30][(y-175)/30] != Empty_pieces){int minx,miny;  if(x < location.x && y < location.y) //在相对位置的第一象限{minx = abs(location.x - x);miny = abs(location.y - y);x = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(x+30):(pow2(minx, (30-miny))<pow2((30-minx), (30-miny))?(x):(x+30)));y = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(pow2((30-minx), miny)<pow2((30-minx), (30-miny))?(y):(y+30)):(y+30));}else if(x > location.x && y < location.y) //在相对位置的第二象限{minx = abs(location.x - x);miny = abs(location.y - y);x = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(x-30):(pow2(minx, (30-miny))<pow2((30-minx), (30-miny))?(x):(x-30)));y = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(pow2((30-minx), miny)<pow2((30-minx), (30-miny))?(y):(y+30)):(y+30));}else if(x > location.x && y > location.y)//在相对位置的第三象限{minx = abs(location.x - x);miny = abs(location.y - y);x = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(x-30):(pow2(minx, (30-miny))<pow2((30-minx), (30-miny))?(x):(x-30)));y = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(pow2((30-minx), miny)<pow2((30-minx), (30-miny))?(y):(y-30)):(y-30));}else if(x < location.x && y > location.y)//在相对位置的第四象限{minx = abs(location.x - x);miny = abs(location.y - y);x = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(x+30):(pow2(minx, (30-miny))<pow2((30-minx), (30-miny))?(x):(x+30)));y = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(pow2((30-minx), miny)<pow2((30-minx), (30-miny))?(y):(y-30)):(y-30));}else //其他{location.Function_flag = undraw;}}}location.x = x;location.y = y;
}
minx = abs(location.x - x);
miny = abs(location.y - y);
//三点与获取点之间的次进点,前项x为最近点
//采用最小距离公式——欧拉公式
x = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(x-30):(pow2(minx, (30-miny))<pow2((30-minx), (30-miny))?(x):(x-30)));
//同上
y = (pow2((30-minx),miny)<pow2(minx, (30-miny))?(pow2((30-minx), miny)<pow2((30-minx), (30-miny))?(y):(y-30)):(y-30));

2.2判定游戏是否结束

  • 对于五子棋的游戏结束有以有连成五子或以上的子就结束,可能出现的情况是左斜对角,右斜对角,横,竖。分别用函数实现如下的int
    passTop_right(int i,int j,int n,int m) 参数:当前位置为i,j;原位置n,m。
/*将棋盘的信息存储在typedef struct piecesdata{char pieces[16][16];//是否下有棋子char black_white[16][16];//是黑子还是白子或无子char game_progress[16][16];//是否以及判定过这一个点char pieces_color;//当前下子的颜色char blackcount;//黑子数char whitecount;//白字数}Piecesdata;中
*/
#define max(x,y) ((x)>(y)?(x):(y))static char win;int passTop_right(int i,int j,int n,int m)int pass_right(int i,int j,int n,int m)int passBottom_right(int i,int j,int n,int m)int pass_Bottom(int i,int j,int n,int m)int pass(int i, int j, int n, int m);
​
int game_over()
{   for(int i = 0;i < 16;i++){for(int j = 0;j < 16;j++){ps.game_progress[i][j] = 0;}}int count;for(int j = 0;j < 16;j++){for(int i = 0;i < 16;i++){count = 0;if(ps.game_progress[i][j] == unCovered){count = pass(i, j, i, j);}if(count >= 5){if(ps.black_white[i][j] == black)win = black;elsewin = white;location.Function_flag = -1;break;}}}   
}
//判断当前位置左上角是否有五子,返回左上方向上的棋子数
int passTop_right(int i,int j,int n,int m)
{if(ps.black_white[i][j] == colorless||ps.black_white[i][j]!=ps.black_white[n][m]||i < 0||j < 0||i >= 16||j >= 16){return 0;}return passTop_right(i-1, j+1, n, m)+1;
}
//判断当前位置左角是否有五子,返回左方向上的棋子数
int pass_right(int i,int j,int n,int m)
{if(ps.black_white[i][j] == colorless||ps.black_white[i][j]!=ps.black_white[n][m]||i < 0||j < 0||i >= 16||j >= 16){return 0;}return pass_right(i, j+1, n, m)+1;
}
//判断当前位置左下角是否有五子,返回左下方向上的棋子数
int passBottom_right(int i,int j,int n,int m)
{if(ps.black_white[i][j] == colorless||ps.black_white[i][j]!=ps.black_white[n][m]||i < 0||j < 0||i >= 16||j >= 16){return 0;}return passBottom_right(i+1, j+1, n, m)+1;
}
//判断当前位置下角是否有五子,返回下方向上的棋子数
int pass_Bottom(int i,int j,int n,int m)
{if(ps.black_white[i][j] == colorless||ps.black_white[i][j]!=ps.black_white[n][m]||i < 0||j < 0||i >= 16||j >= 16){return 0;}return pass_Bottom(i+1, j, n, m)+1;
}
//返回所有路径上的最多的个数。
int pass(int i, int j, int n, int m)
{int Top_right,right,Bottom_right,Bottom;Top_right = passTop_right(i, j, n, m);right = pass_right(i, j, n, m);Bottom_right = passBottom_right(i, j, n, m);
​Bottom = pass_Bottom(i, j, n, m);return (max(Top_right,max(right,max(Bottom,Bottom_right))));
}
2020/7/17 10:27 finish 艺果yiguo

https://pan.baidu.com/s/1300HNo43HgPZwtXF-wt1Qw
提取码:yigu


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部