主要的方法调用都放在了main方法里面
细节在代码内有注释
public static void main(String[] args) {
menu();
Scanner s = new Scanner(System.in);
System.out.println("请输入:");
while (s.hasNextLine()) {
String a = s.nextLine();
switch (a) {
case "玩":
int cnt = 2;//用于判断棋盘是否满,因为走的步数为奇数,所以一定有一方多走一步
wanfa();//玩几阶的
int n = s.nextInt();//n代表阶数//
String[][] board = chuShiHua(n);//初始化棋盘,全部设为空格,用board接受
boardprint(board, n, n); //打印棋盘
System.out.println("谁先下:");//谁先下
String who = s.next();
String flag = " ";//判断是否结束
if (n % 2 == 1) {
while (cnt <= ((int) (Math.pow(n, 2)) - 1)) {
Move(board, n, n, who);//这里是人和电脑都走同样的步数
cnt += 2;
flag = isWin(board, 2,who);
if (flag.equals("*")) {
System.out.println("你赢了,电脑输了,游戏结束");
break;
} else if (flag.equals("#")) {
System.out.println("你输了,电脑赢了,游戏结束");
break;
}
/*//谁走最后一步取决于who的是谁
lastStep(board, n, n, who);*/
}
} else {
while (cnt <= ((int) (Math.pow(n, 2)))) {
Move(board, n, n, who);//这里是人和电脑都走同样的步数
cnt += 2;
flag = isWin(board, n,who);
if (flag.equals("*")) {
System.out.println("你赢了,电脑输了");
break;
} else if (flag.equals("#")) {
System.out.println("你输了,电脑赢了");
break;
}
}
}
//判断谁赢
break;
case "不玩":
exit();//退出程序
break;
default:
System.out.println("还玩不玩(玩/不玩)");
break;
}
if (a.equals("不玩")) {
break;
}
}
}
当方格为奇数n时,pow(n,2)为方个数也为奇数,所以万一到最后一步都没有分出胜负,就要有人走这一步,定义函数名为lastStep,board是move当方法调用完只会要是还要走最后一格,就把最后的那个数组定义为board.row,col,who,分别代表数组的行,列,和谁先走第一步的。public static void lastStep(String[][] board, int row, int col, String who) { if (who.equals("我")) { //人下棋,用*表示 String[][] peopleboard = peopleMove(board, row, col);//peopleboard表示人下完之后的棋盘 boardprint(peopleboard, row, col);//重现打印棋盘 } else if (who.equals("电脑")) { String[][] computerboard = computerMove(board, row, col);//computerboard表示电脑下完之后的棋盘 boardprint(computerboard, row, col);//重现打印棋盘 } if(isWin(board,row,who).equals(" ")) System.out.println("游戏结束,平局"); }
下面的是move方法,当who="我"时,代表的是人先走,who=”电脑“时,代表电脑先走,谁先走棋盘打印的先后是不一样的。
public static void Move(String[][] board, int row, int col, String who) { Scanner s = new Scanner(System.in); while (true) { if (who.equals("我")) { //人下棋,用*表示 String[][] peopleboard = peopleMove(board, row, col);//peopleboard表示人下完之后的棋盘 boardprint(peopleboard, row, col);//重现打印棋盘 System.out.println();//分隔开两个棋盘 //电脑下棋,用#表示 String[][] computerboard = computerMove(peopleboard, row, col);//computerboard表示电脑下完之后的棋盘 boardprint(computerboard, row, col);//重现打印棋盘 break; } else if (who.equals("电脑")) { //电脑下棋,用#表示 String[][] computerboard = computerMove(board, row, col);//computerboard表示电脑下完之后的棋盘 boardprint(computerboard, row, col);//重现打印棋盘 System.out.println();//分隔开两个棋盘 //人下棋,用*表示 String[][] peopleboard = peopleMove(computerboard, row, col);//peopleboard表示人下完之后的棋盘 boardprint(peopleboard, row, col);//重现打印棋盘 break; }/*else { System.out.println("请重新输入:"); who=s.next(); }*/ } }
这里是电脑下棋的方法,首先是随机生成[0,row),[0,col),的值,一是防止数组越界,二是可以去访问数值的值,电脑当已经给出了两个随机值x,y,后,首先进行判定是否写入”#“(#代表电脑下的棋子),当判定(peopleborad[x][y].equals("*") || peopleborad[x][y].equals("#")成立事,直接退出内层循环,然后读入下一次随机值,直到(peopleborad[x][y].equals("*") || peopleborad[x][y].equals("#")不满足为止、
public static String[][] computerMove(String[][] peopleborad, int row, int col) { while (true) { int x = new Random().nextInt(row); int y = new Random().nextInt(col); while (true) { if (peopleborad[x][y].equals("*") || peopleborad[x][y].equals("#")) { break; } else { peopleborad[x][y] = "#"; return peopleborad; } } } }
这里是人为手动输入,正常情况先人看到那个地方有棋子,就不会去输那个位置对应的下标了,但是有时候也有键盘滑的时候,万一你输入了已经存在的地方,这里再次写入判定方法,即board[x - 1][y - 1].equals("*") || board[x - 1][y - 1].equals("#"),知道这个不成立,才会进入数组辅助的那一步,人走的记为*。
public static String[][] peopleMove(String[][] board, int row, int col) { Scanner s = new Scanner(System.in); while (true) { System.out.print("请输入位置:"); int x = s.nextInt(); int y = s.nextInt(); if (x > 0 && x <= row && y > 0 && y <= col) { while (true) { if (board[x - 1][y - 1].equals("*") || board[x - 1][y - 1].equals("#")) { System.out.println("位置有重复:"); break; } board[x - 1][y - 1] = "*"; return board; } } else if (x < 1 || x > row || y > col || y < 1) { System.out.println("超过范围"); } }
初始化数组,全部以空格的形式存在
public static String[][] chuShiHua(int n) { String board[][] = new String[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { board[i][j] = " "; } } return board; }
打印棋盘,这个boardprint是要多次被调用的,所以我们要写得比较好,什么叫比较好呢,就是外部只需要把数组,数组大小传进来,我们就能按照想要的排版把他打印出来。
public static void boardprint(String[][] board, int row, int col) { //打印棋盘 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { System.out.print(" " + board[i][j] + " "); if (j < col - 1) { System.out.print("|"); } } System.out.println(); for (int j = 0; j < col; j++) { System.out.print("---"); if (j < col - 1) { System.out.print("|"); } } System.out.println(); //打印分割线 } System.out.println(); }
下面这段程序就比较简单了,就是switch进入游戏前面调用的那几个方法,打印菜单等
public static void wanfa() { System.out.println("玩几阶的:"); } public static void exit() { System.out.println("退出程序"); } public static void menu() { System.out.println("-----------------"); System.out.println("-----------------"); System.out.println("----玩不玩三子棋---"); System.out.println("----“玩“表示玩----"); System.out.println("---“不玩“表示不玩--"); System.out.println("-----------------"); System.out.println("-----------------"); } }
最后一个是我还没写出来的,要是有人知道怎么写判定三子棋是否分出胜负的算法,欢迎在评论区留言,我一定怀着一颗崇拜之心来学习。来看看我的暴力代码吧。来吧~展示~
public static String isWin(String[][] board, int n,String who) { //检索的元素在3个棋子中间是时 String flag = ""; if(who.equals("我")){ for (int i = 0; i < n; i++) { int j = 0; if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == "*") { flag = "*"; return flag; } else if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == "#") { flag = "#"; return flag; } } for (int k = 0; k < 3; k++) { int j = 0; int i=0; if (board[j][k] == board[j + 1][k] && board[j + 1][k] == board[j + 2][k] && board[j = 2][k] == "*") { flag = "*"; return flag; } else if (board[i][k] == board[i + 1][k] && board[i + 1][k] == board[i + 2][k] && board[i = 2][k] == "#") { flag = "#"; return flag; } } int i = 0; if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i + 2][i + 2] == "*") { flag = "*"; return flag; } else if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i + 2][i + 2] == "#") { flag = "#"; return flag; } int j = 2; if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i + 2][j - 2] && board[i + 2][j - 2] == "*") { flag = "*"; return flag; } else if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i + 2][j - 2] && board[i + 2][j - 2] == "#") { flag = "#"; return flag; } } else if(who.equals("电脑")){ for (int i = 0; i < n; i++) { int j = 0; if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == "#") { flag = "#"; return flag; } else if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] == "*") { flag = "*"; return flag; } } for (int k = 0; k < 3; k++) { int j = 0; int i=0; if (board[j][k] == board[j + 1][k] && board[j + 1][k] == board[j + 2][k] && board[j = 2][k] == "#") { flag = "#"; return flag; } else if (board[i][k] == board[i + 1][k] && board[i + 1][k] == board[i + 2][k] && board[i = 2][k] == "*") { flag = "*"; return flag; } } int i = 0; if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i + 2][i + 2] == "#") { flag = "#"; return flag; } else if (board[i][i] == board[i + 1][i + 1] && board[i + 1][i + 1] == board[i + 2][i + 2] && board[i + 2][i + 2] == "*") { flag = "*"; return flag; } int j = 2; if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i + 2][j - 2] && board[i + 2][j - 2] == "#") { flag = "#"; return flag; } else if (board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i + 2][j - 2] && board[i + 2][j - 2] == "*") { flag = "*"; return flag; } } return " "; }
虽然很暴力,但是为了完成实现三子棋,没办法。