本文主要是介绍关于计算机博弈大赛,爱恩斯坦棋Java面向过程实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、爱恩斯坦棋规则
-
棋盘为5×5的方格形棋盘,方格为棋位,左上角为红方出发区;右下角为蓝方出发区 (如图1);
-
红蓝方各有6枚棋子,分别标有数字1~6。开局时双方棋子在出发区的棋位可以随意摆放;
-
双方轮流掷骰子,然后 移动与骰子显示数字相 对应的棋子。如果相对 应的棋子已从棋盘上移 出,便可走动大于或者 小于此数字,并与此数 字最接近的棋子;(如 图2,红棋掷4,4已被吃, 可移动1或5);
-
红方棋子走动方向为向右、 向下、向右下,每次走动一 格;蓝方棋子走动方向为向 左、向上、向左上,每次走 动一格;
-
如果在棋子走动的目标棋位 上有棋子,则要将该棋子从 棋盘上移出(吃掉)。有时 吃掉本方棋子也是一种策略, 因为可以增加其它棋子走动 的机会与灵活性;
-
率先到达对方出发区角点或将对方棋子全部吃掉一方获胜;(右上局面,掷到蓝4,蓝6可吃红1,吃光对手获胜。右下局面,掷到蓝4,蓝5可向上走,率先到达对角获胜);
-
对弈结果只有胜负,没有和棋;
-
每盘每方用时4分钟,超时判负;每轮双方对阵
最多7盘,轮流先手(甲方一四五盘先手,乙方二
三六七盘先手) ,两盘中间不休息,先胜4盘为
胜方。
二、棋盘与我方布局
这里只是面向没有思路的同学提供一些小小的思路,接到写这个棋的时候啥也不能写,去搞人家整个代码改也看不懂的同学提供一些帮助;这样不仅能让你自己能敲起代码(动起来),而且对自己也是提高逻辑上的一个帮助。网上的算法提供的也是一种下棋的思路,只有自己敲起代码来,才能运用的上别人提供的什么极大极小,UTC,什么的算法。
好了,废话不多说,下棋总应该有棋盘吧,开始写棋盘了!
这里看上去与上面的面板有些不一样,但是也有异曲同工之妙,道理都差不多。然后,我们来看看怎么实现。
1、我们可以将棋盘代买写在一个方法里面,就叫drawTable;但是拥有棋盘之前,我们需要初始化棋盘,直接附初始化代码5*5
public static String[][] table=new String[5][5];//定义一5*5的棋盘//初始化棋盘public static void initTable(){for(int i = 0; i < table.length; ++i)for(int j = 0; j < table[i].length; ++j)table[i][j] = " ";}
2.画棋盘,附上代码
//画棋盘public void drawTable() {System.out.print(" ");for(int i=0;i<table.length;i++)//坐标表示{System.out.printf(" %d ",i);}System.out.printf("\n");for(int i=0;i<table.length;i++){//棋盘的高度System.out.println(" _ _ _ _ _ _ _ _ _ _ ");System.out.print(i);for(int j=0;j<table.length;j++) {//单词高度,每格里追综数据给数组System.out.printf("|_%s_|",table[i][j]);}System.out.printf("\n");System.out.printf("\n"); }}
3.这里前面已经完成棋盘的绘制,已经棋盘的初始化;记得这些代码可以封装在一个模块里,调用时就很方便。
4.接下来是我方棋子的布局,分为上方和下方,敌方棋子的布局,就不用管,因为是对方人布的局,只需要将他输入就行。
//右下棋子布局public void writeRightPieces() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String str=chessBoard.sc.nextLine();String[] arr=str.split("\\s+");for(int i=1;i<=3;i++)//控制行数{int c=4;//数组的列下标for(int j=1;j<=i;j++){table[i+1][c]=arr[c1];c--;//数组的列下标c1++;//用来控制输入的棋子} }this.drawTable(); }//左上棋子开始布局public void writeLeftPieces() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String str=chessBoard.sc.nextLine();String[] arr=str.split("\\s+");int b=2;//初始化列标限制for(int i=0;i<3;i++)//控制行标{ for(int j=0;j<=b;j++)//控制列标{table[i][j]=arr[c2];c2++;}b--;//列表限制-1}this.drawTable();}
5.好了,这里就完成了我方,左上方,和右下方的棋子布局;敌方的棋子布局就很简单,你在左上,那敌方自然在右下,调用右上的方法就可以实现;你在右下,敌方自然在左上调用左上方法即可。
整体代码如下:
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;public class chessBoard {public static final Scanner sc=new Scanner(System.in,"UTF-8");
}class thisChessBoard{private static int c1=0; //用来控制输入的棋子private static int c2=0; //用来控制输入的棋子public static String[][] table=new String[5][5];//定义一5*5的棋盘//初始化棋盘public static void initTable(){for(int i = 0; i < table.length; ++i)for(int j = 0; j < table[i].length; ++j)table[i][j] = " ";}//画棋盘public void drawTable() {System.out.print(" ");for(int i=0;i<table.length;i++)//坐标表示{System.out.printf(" %d ",i);}System.out.printf("\n");for(int i=0;i<table.length;i++){//棋盘的高度System.out.println(" _ _ _ _ _ _ _ _ _ _ ");System.out.print(i);for(int j=0;j<table.length;j++) {//单词高度,每格里追综数据给数组System.out.printf("|_%s_|",table[i][j]);}System.out.printf("\n");System.out.printf("\n"); }}//右下棋子布局public void writeRightPieces() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String str=chessBoard.sc.nextLine();String[] arr=str.split("\\s+");for(int i=1;i<=3;i++)//控制行数{int c=4;//数组的列下标for(int j=1;j<=i;j++){table[i+1][c]=arr[c1];c--;//数组的列下标c1++;//用来控制输入的棋子} }this.drawTable(); }//左上棋子开始布局public void writeLeftPieces() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String str=chessBoard.sc.nextLine();String[] arr=str.split("\\s+");int b=2;//初始化列标限制for(int i=0;i<3;i++)//控制行标{ for(int j=0;j<=b;j++)//控制列标{table[i][j]=arr[c2];c2++;}b--;//列表限制-1}this.drawTable();}
}
三、棋子移动
1.前面我们已经实现了棋盘的绘画,棋子的布局,接下来我们就来实现,棋子该怎么移动;而这里是可以写很多算法的,比如极大极小啊,蒙特卡罗,utc什么的。当你投掷了骰子数,获得该骰子数对应的棋子的坐标,我们便可以移动了;这里我写的算法就很简单,只要能到达对方大本营便可以赢。
2.rust算法,所有棋子一股脑往他大本营冲当遇到边缘时就左右拐。代码如下
import ewn.seat;import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;import ewn.chessBoard;
import ewn.seat;
/** 走棋规则*/
public class move { seat s=new seat();//坐标位置类实例化thisChessBoard tcb=new thisChessBoard();//棋盘布局类实例化//我方在右下走棋规则void ourRightMove() {if(s.seatrow!=0)//行坐标不为0{if(s.seatcol!=0)//列坐标不为0{tcb.table[s.seatrow-1][s.seatcol-1]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow-1][s.seatcol-1]+"移动到%d,%d\n",s.seatrow-1,s.seatcol-1);System.out.print("\n");}else//列坐标为0{tcb.table[s.seatrow-1][s.seatcol]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow-1][s.seatcol]+"移动到%d,%d\n",s.seatrow-1,s.seatcol);System.out.print("\n");}}else//行坐标为0{tcb.table[s.seatrow][s.seatcol-1]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow][s.seatcol-1]+"移动到%d,%d\n",s.seatrow,s.seatcol-1);System.out.print("\n");}tcb.drawTable();//画出棋盘}//我方在左上走棋规则void ourLeftMove() {if(s.seatrow!=4)//行坐标不为0{if(s.seatcol!=4)//列坐标不为0{tcb.table[s.seatrow+1][s.seatcol+1]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow+1][s.seatcol+1]+"移动到%d,%d\n",s.seatrow+1,s.seatcol+1);System.out.print("\n");}else//列坐标为0{tcb.table[s.seatrow+1][s.seatcol]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow+1][s.seatcol]+"移动到%d,%d\n",s.seatrow+1,s.seatcol);System.out.print("\n");}}else//行坐标为0{tcb.table[s.seatrow][s.seatcol+1]=tcb.table[s.seatrow][s.seatcol];tcb.table[s.seatrow][s.seatcol]=" ";System.out.println("我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.printf("====>我方棋子:"+tcb.table[s.seatrow][s.seatcol+1]+"移动到%d,%d\n",s.seatrow,s.seatcol+1);System.out.print("\n");}tcb.drawTable();//画出棋盘}//敌方走棋void otherMove() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");Scanner sc=new Scanner(System.in,"UTF-8");System.out.println("请输入敌方移动后棋子的坐标(x y坐标)");System.out.println("= =>(空格分隔):");String str=sc.nextLine();String[] s1=str.split("\\s+");int row=Integer.parseInt(s1[0]);//获得敌方移动后棋子的行号int col=Integer.parseInt(s1[1]);//获得敌方移动后棋子的列号System.out.println("请输入敌方棋子的棋子号(1=A,2=B,3=C,4=D,5=E,6=F):");System.out.println("=>(敌方移动的棋子号!(1-6)):");int num=sc.nextInt();s.otherSeat(num);//调用坐标方法,获得敌方移动前棋子的行号列号tcb.table[row][col]=tcb.table[s.seatrow][s.seatcol];//将敌方棋子移动到目标位置tcb.table[s.seatrow][s.seatcol]=" ";//将敌方棋子移动前的位置赋值为空,完成棋子移动tcb.drawTable();//画出棋盘}
}
3.这上面给敌方走棋的规则,输入就行了,没什么算法。
四、获取棋子坐标
1.这一步是很重要的,因为你棋子的走动都需要获得坐标,你在场棋子的坐标,敌方在场的棋子的坐标,判断大本营门口是否有对方棋子,有就吃等等,都需要在这里面实现,我这里有我的一些小算法,当棋子被吃的时候,继续投资这个数的时候获取位置的算法。
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Random;
import java.util.Scanner;import ewn.chessBoard;
import ewn.strategy;/*** * @author kuqi**/
/** 写获得骰子数,得到相应骰子坐标* */
public class seat {static final Scanner sc=new Scanner(System.in,"UTF-8");public static int seatrow;public static int seatcol;thisChessBoard tcb=new thisChessBoard();strategy stra=new strategy();/** 我方先走,产生随机骰子,获得骰子对应的棋子坐标* */void ourSeat() throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String dict = null ;//骰子数用来遍历棋盘上棋子的位置
// Random rand = new Random();
// int num= rand.nextInt(6)+1; int num;System.out.print("\n");System.out.print("\n");System.out.println("请输入我方骰子数:");num=sc.nextInt();int flag2=0;//标记,用来查找棋盘上棋子标记,如果找到为1,否则为0,也是循环标记,如果找到flag2=1退出循环,flag2=0do{int count=0;switch(num){case 1:dict="a";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num++;}break;case 2:dict="b";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num=this.select(num);}break;case 3:dict="c";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num=this.select(num);break;}break;case 4:dict="d";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num=this.select(num);break;}break; case 5:dict="e";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num=this.select(num);break;}break;case 6:dict="f";//如果找打棋子for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;flag2=1;break;}}}//如果没有找到if(flag2==0){num--;}break;}}while(flag2==0);}//找相邻位置int select(int num) {int choose=0;int flag=0;int num1=0;int num2=0;String dict;do {if(choose==0)//找大于当前数的{num1=num+1;switch(num1){case 1:dict="a";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;case 2:dict="b";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;case 3:dict="c";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;case 4:dict="d";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;case 5:dict="e";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;case 6:dict="f";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num1;}else {choose=1;}}}break;default:choose=1;break;}}else {//找当前数小于的num2=num--;switch(num2){case 1:dict="a";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;case 2:dict="b";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;case 3:dict="c";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;case 4:dict="d";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;case 5:dict="e";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;case 6:dict="f";for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){flag=1;return num2;}else {choose=0;}}}break;default:choose=1;break;}}}while(flag==0);return 0;}//获得敌方棋子坐标int otherSeat(int num) throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");String dict = null ;//骰子数用来遍历棋盘上棋子的位置switch(num) {case 1:dict="A";break;case 2:dict="B";break;case 3:dict="C";break;case 4:dict="D";break;case 5:dict="E";break;case 6:dict="F";break;default:break;}for(int i=0;i<5;i++) {for(int j=0;j<5;j++){if(tcb.table[i][j].compareTo(dict)==0){seatrow=i;seatcol=j;break;}}}return 0;}
}
2.这里面有三个功能,一个是扫描棋盘棋子获得坐标,一个是当棋子被吃掉时,又投掷该棋子获取与他临近棋子的坐标;最后一个是获得敌方棋子坐标。
五、胜利规则
1.这里就很简单,上面的规则说过,只要到达敌方对角格就算赢,或者吃完敌方就算赢,直接附上代码
/*** * @author kuqi**/
/** 胜利规则* */
public class strategy { thisChessBoard tcb=new thisChessBoard();int win(int flag) throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");Pattern p1=Pattern.compile("^([a-f]){1}");Pattern p2=Pattern.compile("^([A-F]){1}");if(main.sign==1)//我方在右下角{for(int i=1;i<=6;i++)//我方到达对角{Boolean b1=p1.matcher(tcb.table[0][0]).matches();if(b1) {System.out.println("恭喜你, 我方取得胜利!!!");return flag=1;}}for(int i=1;i<6;i++)//敌方到达对角{Boolean b2=p2.matcher(tcb.table[4][4]).matches();if(b2) {System.out.println("很遗憾, 敌方取得胜利……");return flag=1;}}}else//我放在左上角{for(int i=1;i<6;i++)//我方到达对角{Boolean b1=p1.matcher(tcb.table[4][4]).matches();if(b1) {System.out.println("恭喜你, 我方取得胜利!!!");return flag=1;}}for(int i=1;i<=6;i++)//敌方到达对角{Boolean b2=p2.matcher(tcb.table[0][0]).matches();if(b2) {System.out.println("很遗憾, 敌方取得胜利……");return flag=1;}}}int count=0;//我方棋子存在int count1=0;//敌方棋子存在//我方被吃完for(int i=0;i<5;i++){for(int j=0;j<5;j++){Boolean b1=p1.matcher(tcb.table[i][j]).matches();//匹配我方棋子if(b1){count=1;break; }}}if(count==0) {System.out.println("很遗憾, 敌方取得胜利……");return flag=1;}for(int i=0;i<5;i++){for(int j=0;j<5;j++){Boolean b2=p2.matcher(tcb.table[i][j]).matches();//匹配我方棋子if(b2){count1=1;break; }}}if(count1==0) {System.out.println("恭喜你, 我方取得胜利!!!");return flag=1;}return 0;}
}
六、最后是实现人机交互的接口main
1.首先是判断我方在左上,还是右下,调用两个布局,敌方的,和我方的;然后是判断谁先手,给个轮换手标识,再给可以标识做一个循环,每次循环判断时候胜利,不胜利时换敌方下,具体如下:
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;import ewn.chessBoard;
import ewn.move;
import ewn.seat;
import ewn.strategy;/*** * @author kuqi**/
public class main {public static int sign;public static void main(String[] args) throws UnsupportedEncodingException {PrintStream ps=new PrintStream(System.out,true,"UTF-8");Scanner sc=new Scanner(System.in,"UTF-8");thisChessBoard tcb=new thisChessBoard();//棋盘实例化seat s=new seat(); //骰子位置实例化move m=new move(); //移动实例化strategy stra=new strategy();//胜利类实例化//开始下棋System.out.println("请输入我方在左上还是右下(0表示在左上,1表示在右下)");sign=sc.nextInt();if(sign==1) {tcb.initTable();//棋盘初始化tcb.drawTable();//画出棋盘System.out.println("请输入我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.println("= = = = = =>(空格分隔):");tcb.writeRightPieces();//开始我方在右下布局棋子System.out.println("我方棋子布局已完成啦~");System.out.println("到您对手开始布局棋子!");System.out.println("-----------------------------");System.out.print("\n");System.out.println("请输入对手布局的棋子(A=1,B=2,C=3,D=4,E=5,F=6):");System.out.println("= = = = = =>(空格分隔):");tcb.writeLeftPieces();//开始敌方在左上布局棋子System.out.println("敌方棋子布局已经完成了。");System.out.print("\n");System.out.println("-----------------------------");System.out.println("请输入我方先走还是敌方(0表示敌方,1表示我方):");int choose=sc.nextInt();int flag=0;do {if(choose==1){s.ourSeat();//我方获得骰子随机数m.ourRightMove();//我方走棋flag=stra.win(flag);//判断获胜 choose=0;}else {m.otherMove();//敌方走棋flag=stra.win(flag);//判断获胜choose=1;}}while(flag==0);}else{tcb.initTable();//棋盘初始化tcb.drawTable();//画出棋盘System.out.println("请输入我方棋子(a=1,b=2,c=3,d=4,e=5,f=6)");System.out.println("= = = = = =>(空格分隔):");tcb.writeLeftPieces();//我方在左上布局System.out.println("我方棋子布局已完成啦~");System.out.println("到您对手开始布局棋子!");System.out.println("-----------------------------");System.out.print("\n");System.out.println("请输入对手布局的棋子(A=1,B=2,C=3,D=4,E=5,F=6)");System.out.println("= = = = = =>(空格分隔):");tcb.writeRightPieces();//敌方在右下布局System.out.println("敌方棋子布局已经完成了。");System.out.print("\n");System.out.println("-----------------------------");System.out.println("请输入我方先走还是敌方(0表示敌方,1表示我方):");int choose=sc.nextInt();int flag=0;do {if(choose==1){s.ourSeat();//我方获得骰子随机数m.ourLeftMove();//我方走棋flag=stra.win(flag);//判断获胜 choose=0;}else {m.otherMove();//敌方走棋flag=stra.win(flag);//判断获胜choose=1;}}while(flag==0);System.out.println("输入任何字符,退出程序");sc.next();}}
}
结尾
好了,这里就完成所有的实现,以上就是提供一个简单的思路帮助,具体还需要各位小伙伴们亲自去实现,替换一些移动算法,就可以将你所思考,所浏览的算法写上。上面共有五个类chessBoard是棋盘类,move棋子移动类,seat棋盘上棋子类,strategy胜利规则类,组合mian函数类。
这篇关于关于计算机博弈大赛,爱恩斯坦棋Java面向过程实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!