继续之前的那个五子棋程序 修复了一些已知的小bug
这里是之前的五子棋程序
修复了一些算法缺陷 本次增加了ai算法
可以人机对战 也可以ai对ai看戏
本次ai算法属于初级算法 稍微用点小套路还是可以干掉他的
以后会更新高级算法
本次还对程序进行了模块化 拆分成了几个文件
下面请看源码关联
游戏入口类
package main.game; /** 游戏入口类 **/ public class gameapp { /** 游戏入口 */ public static void main(string[] args) { gobang game = new gobang(); //player vs ai player p1 = new player("玩家",'彩');//就这么特殊 就用彩棋 热性! player p2 = new aiplayer("机器人",'白'); //player vs player //player p1 = new player("玩家",'黑'); //player p2 = new player("玩家2",'白'); //ai vs ai //player p1 = new aiplayer("玩家",'黑'); //player p2 = new aiplayer("机器人",'白'); game.creategame(p1,p2); game.start(); } }
游戏核心控制类
这里控制游戏核心算法 例如游戏的胜负算法
package main.game; /** * 控制台五子棋游戏 */ public class gobang { private boolean gameover = false; //15*15棋盘 private char[][] table = new char[16][16]; //两个玩家 private player p1,p2; //回合 private int huihe = 0; public player getp1() { return p1; } public player getp2() { return p2; } public void creategame(player p1, player p2){ this.p1=p1; this.p2=p2; } public char[][] gettable() {return table;} /** 展示棋局 **/ private void show(){ int xx =0; system.out.println(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 "); for(char[] cs :table){ system.out.print(" "+xx+(xx>9?"":" ")+" "); for(char c : cs){ if(c==0) system.out.print("·"); system.out.print(c+" "); } system.out.println(); xx++; } } /** 获取下一个走棋的 **/ private player getplayer(){ //p1先走 if (huihe==0) return p1; if (huihe%2!=0) return p2; return p1; } /** 判断是否获胜 **/ private boolean iswin(int x,int y,char c){ /* x 和 y 代表坐标 * xx :x方向需要增加的值 * yy :y方向需要增加的值 * * 例如xx = -1 yy= -1 * 代表需要获取(x-1,y-1)的棋子颜色 * * xx = 1 yy= 1 * 代表需要获取(x+1,y+1)的棋子颜色 * * */ int xx = 0,yy=0; for (int i =1 ;i<9 ;i++ ){ switch (i){ case 1: xx=-1;yy=-1; break; case 2: xx=-1;yy=1; break; case 3: xx=-1;yy=0; break; case 4: xx = 1;yy = -1; break; case 5: xx = 1;yy = 1; break; case 6: xx = 1 ;yy = 0; break; case 7: xx = 0;yy = -1; break; case 8: xx = 0;yy = 1; break; } int n = ishas(x,y,xx,yy,0,c)+ishas(x,y,-xx,-yy,0,c); if(n>=4)return true; } return false; } /** * 检测是否有棋子 * @param x x坐标 * @param y y坐标 * @param xx x方向 * @param yy y方向 * @param size 缓存 * @param c 颜色 * @return 权重 */ private int ishas(int x,int y,int xx,int yy,int size ,char c){ if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)) return size; if(table[x+xx][y+yy] == c){ return ishas(x+xx,y+yy,xx,yy,size+1,c); } return size; } /** 下棋 **/ public boolean put(int x,int y,player p){ if (table[x][y]==character.min_value) { table[x][y] = p.getcolor(); if(iswin(x,y,p.color)){ gameover = true; system.out.println(p.username+"("+p.color+")赢得了胜利"); } return true; } return false; } /** 游戏运行 **/ public void start(){ //本回合下子选手 player p = null; while (!gameover){ //棋盘已满 if(huihe/2+1 == 129)break; if(p==null)p=getplayer(); system.out.println("第"+(huihe/2+1)+"回合,下子方:"+p.getusername()+"("+p.getcolor()+")"); system.out.println("请输入你要下的位置(空格隔开) 例如:10 5"); int ps = p.run(this); //下子错误 if (ps == 0)continue; //游戏结束 用户输入了exit else if( ps == 1)break; show(); p=null; huihe++; } system.out.println("游戏结束"); } }
玩家类
这里是玩家使用控制台下棋算法
package main.game; import java.util.scanner; public /** 玩家类 **/ class player{ string username; char color; scanner scan; public player(string username, char color) { this.username = username; this.color = color; system.out.println(username+"携带"+color+"颜色的棋子加入游戏"); scan = new scanner(system.in); } public string getusername() { return username; } public char getcolor() { return color; } /** 玩家需要获控制台输入的值 **/ public int run(gobang app) { //下棋失败重新开始本回合 string[] strarr ; string in = scan.nextline().trim(); if ("exit".equals(in)) return 1; try { strarr = in.split(" "); if (!app.put(integer.parseint(strarr[0]), integer.parseint(strarr[1]), this)) return 0; }catch (exception e){ return 0; } return -1; } }
ai机器人算法类
这里有ai机器人下棋算法思路
本算发用点套路还是可以很轻松的干掉ai的
本算法属于初级算法 后期会更新高级的
package main.game; import java.util.*; public /** 机器人 **/ class aiplayer extends player { private random r = new random(); private list<piece> pieces = new linkedlist<>(); private char p2 ; private char[][] table; /** 创建ai机器人 **/ public aiplayer(string username, char color) { super(username, color); } @override /** ai机器人的算法 **/ public int run(gobang app){ if (p2 == character.min_value || app.getp1()==this){ this.p2 = app.getp2().color; }else{ this.p2= app.getp1().color; } piece args = up(app); system.out.println("智能下棋("+args.x+","+args.y+")"); try { if (!app.put(args.x, args.y, this)) return 0; }catch (exception e){ return 0; } return -1; } /** 测试用,随缘下棋 **/ private piece test(){ for (int i =0;i<3;i++){ int x = r.nextint(3)+6; int y = r.nextint(3)+6; if(table[x][y] == character.min_value){ return new piece(x,y,0,this.color); } } while (true){ int x = r.nextint(16); int y = r.nextint(16); if(table[x][y] == character.min_value){ return new piece(x,y,0,this.color); } } } /** 智能算法下棋 **/ private piece up(gobang app){ pieces.clear(); table = app.gettable(); for (int x = 0;x <16; x++){ for (int y = 0;y <16; y++){ //判断空余地方获胜几率 if (table[x][y] == character.min_value){ //判断自己权重 sub(x,y,this.color); //判断对手权重 sub(x,y,p2); } } } return get(); } /** 计算权重 **/ private void sub(int x,int y,char c){ char m = this.color; int xx = 0,yy=0; int num = 0 ; for (int i =0 ;i<8 ;i++ ){ switch (i){ case 0: xx = 0;yy = 1; break; case 1: xx=-1;yy=-1; break; case 2: xx=-1;yy=1; break; case 3: xx=-1;yy=0; break; case 4: xx = 1;yy = -1; break; case 5: xx = 1;yy = 1; break; case 6: xx = 1 ;yy = 0; break; case 7: xx = 0;yy = -1; break; } if(c == this.color){ //查自己下子权重 int a = ishas(x, y, xx, yy, 0,this.color,p2)+ishas(x, y, -xx, -yy, 0,this.color,p2); if (a>num)num=a; m = this.color; // num += ishas(x, y, xx, yy, 0,this.color,p2)+ishas(x, y, -xx, -yy, 0,this.color,p2); }else{ //检测对手威胁权重 int a = ishas(x, y, xx, yy, 0,p2,this.color)+ishas(x, y, -xx, -yy, 0,p2,this.color); if (a>num)num=a; m=p2; // num +=ishas(x, y, xx, yy, 0,p2,this.color)+ishas(x, y, -xx, -yy, 0,p2,this.color); } } pieces.add(new piece(x,y,num,m)); } /** 检测周围有没有棋子 **/ private piece get(){ // 挑选权重最大的 pieces.sort(new comparator<piece>() { @override public int compare(piece o1, piece o2) { return o1.info< o2 .info ? 1:(o1.info == o2.info ? 0: -1); } }); //随缘棋子 system.out.println(pieces); if(pieces.size()==0 || pieces.get(0).info == 0)return test(); int max = pieces.get(0).info; piece index = pieces.get(0); for(piece ps : pieces ){ if(ps.info<max){ return index; } index = ps; } return index ; } /** 检测棋子 **/ private int ishas(int x,int y,int xx,int yy,int size ,char c,char c2){ if((x==0&&xx==-1)|| (x==15&&xx==1) || (y==0&&yy==-1) || (y== 15&&yy==1)) return size; if(table[x+xx][y+yy] == c){ return ishas(x+xx,y+yy,xx,yy,size+1,c,c2); }else if(table[x+xx][y+yy] == c2){ return size>3 ? size+2:size-1; } return size; } /**判断危机**/ }
棋子类 这里没啥可用的 就是写ai算法时候调用方便
package main.game; /** ai算法棋子类 **/ public class piece { //坐标 int x; int y; char color; //权重 int info; public piece(int x, int y, int info,char color) { this.x = x; this.y = y; this.info = info; this.color = color; } @override public string tostring() { return "piece"+color+"{" + "x=" + x + ", y=" + y + ", info=" + info + '}'; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 0 黑 白 白 黑 黑 黑 黑 白 白 黑 白 黑 白 黑 白 黑 1 黑 白 黑 黑 白 白 白 黑 黑 白 黑 黑 黑 白 白 白 2 黑 黑 白 白 白 黑 白 白 白 黑 黑 白 黑 白 黑 白 3 白 白 黑 黑 白 黑 白 黑 白 黑 白 白 黑 黑 黑 白 4 黑 黑 白 白 白 黑 黑 白 白 白 白 黑 白 黑 白 黑 5 黑 白 黑 白 黑 黑 白 黑 黑 白 黑 黑 白 黑 白 白 6 黑 白 白 黑 黑 白 白 白 黑 白 黑 黑 白 白 黑 黑 7 白 黑 白 白 黑 白 黑 黑 黑 白 黑 白 黑 白 白 黑 8 黑 白 黑 白 黑 白 黑 黑 黑 黑 白 白 白 黑 黑 黑 9 白 黑 黑 白 白 白 白 黑 白 黑 白 黑 黑 白 白 白 10 白 黑 白 黑 黑 黑 白 白 白 白 黑 白 白 白 黑 黑 11 白 黑 白 黑 黑 黑 黑 白 黑 黑 白 白 白 白 黑 黑 12 黑 白 黑 白 白 白 黑 白 白 白 黑 黑 黑 白 白 黑 13 黑 白 黑 白 黑 白 白 白 白 黑 黑 黑 白 黑 黑 黑 14 黑 黑 黑 黑 白 白 黑 黑 黑 白 白 白 黑 白 白 白 15 白 白 白 黑 黑 黑 白 白 黑 白 黑 白 黑 白 黑 黑 游戏结束
如对本文有疑问, 点击进行留言回复!!
Android 4.0使用Kotlin调用C语言以及汇编语言
Java Class.forName()用法和newInstance()方法原理解析
网友评论