OK

  加上了AI,总算是可以玩了。不过目前的AI只会消极防守,玩家和电脑都不能赢的时候AI只会随机下,好在棋盘小,所以这个问题不算太大。

  大概也不会继续完善了吧……都是重复工作,学不了什么新东西。就是练练脑子。

  AI还是让琪琪点醒的,“如果发现要赢了就堵住”,我原来的想法是想办法遍历棋局找出二连的棋子,都想到脑子疼了。明明反过来思考一下,如果往一个地方落子之后有人能赢,那这个地方不就是关键位置么,这样最多九次就能找到答案了。

  留了一个找不出问题所在的小bug,随手用笨方法堵上了。

  另外还是不知道怎么把无限while循环里面的Scanner关掉……虽然只是警告不是错误,但是看着还是很不爽啊……

  jar文件打了个包

 1 package ticTacToeII;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         Game game = new Game();
 6         Player player = new Player();
 7         Computer computer = new Computer();
 8         
 9         while (true) {
10             game.printChessBoard();
11             
12             player.move(game);
13             System.out.println();
14             if (game.checkWin()) {
15                 game.printChessBoard();
16                 System.out.println("你赢了!!!!!!!赢了啊啊啊啊啊啊啊啊啊啊啊啊!!!!");
17                 break;
18             }
19             if (game.isFilled()) {
20                 game.printChessBoard();
21                 System.out.println("平局了。");
22                 break;
23             }
24             
25             System.out.print("电脑落子:");
26             
27             computer.move(game);
28             if (game.checkWin()) {
29                 System.out.println(); // 奇怪的bug,如果电脑赢了会出现打印错误,暂时用这个方法修补。
30                 game.printChessBoard();
31                 System.out.println("电脑赢了!!!!!!!赢了啊啊啊啊啊啊啊啊啊啊啊啊!!!!");
32                 break;
33             }
34             if (game.isFilled()) {
35                 game.printChessBoard();
36                 System.out.println("平局了。");
37                 break;
38             }
39                 
40             System.out.println();
41         }
42     }
43     
44     /** 测试用跟踪方法。*/
45     protected static void trace(String toShow) {
46         System.out.printf("===Traceback:%s===
", toShow);
47     }
48 }
Client类
  1 package ticTacToeII;
  2 
  3 class Game {
  4     private String chessBoard;
  5     private String[][] pieces = new String[3][3];
  6     
  7     /** 初始化棋盘样式和棋子数组。*/
  8     public Game() {
  9         chessBoard = 
 10                 "--------------   
" +
 11                 "| %s | %s | %s | 
" +
 12                 "--------------   
" +
 13                 "| %s | %s | %s | 
" +
 14                 "--------------   
" +
 15                 "| %s | %s | %s | 
" +
 16                 "--------------   
";
 17         
 18         for (String[] s1: pieces) {
 19             for (int i = 0; i < s1.length; i++)
 20                 s1[i] = " ";
 21         }
 22     }
 23     
 24     /** 在棋盘上落子。*/
 25     int changeBoard(int row, int column, String chessMan) {
 26         if (this.pieces[row][column] == " ") {
 27             this.pieces[row][column] = chessMan;
 28             return 1;
 29         }
 30         return -1;
 31     }
 32     
 33     /** 棋子数组降维。*/
 34     private String[] pieceList() {
 35         String[] temp = new String[9];
 36         for (int i = 0, j = 0; i < 3; i++, j += 3)
 37             System.arraycopy(this.pieces[i], 0, temp, j, 3);
 38         return temp;
 39     }
 40     
 41     /** 打印棋盘。*/
 42     void printChessBoard() {
 43         System.out.printf(this.chessBoard, (Object[])this.pieceList());
 44     }
 45     
 46     /** 判断平局。*/
 47     boolean isFilled() {
 48         for (String[] s1: this.pieces) {
 49             for (String s2: s1) {
 50                 if (s2 == " ")
 51                     return false;
 52             }
 53         }
 54         return true;
 55     }
 56     /** 判断胜利。*/
 57     boolean checkWin() {
 58         for (int i = 0; i < 3; i++) {
 59             if ((this.pieces[i][0] == this.pieces[i][1] && 
 60                 this.pieces[i][1] == this.pieces[i][2] && 
 61                 this.pieces[i][1] != " ")
 62                 ||
 63                 (this.pieces[0][i] == this.pieces[1][i] && 
 64                 this.pieces[1][i] == this.pieces[2][i] &&
 65                 this.pieces[1][i] != " "))
 66                 return true;
 67         }
 68         if ((this.pieces[0][0] == this.pieces[1][1] &&
 69             this.pieces[1][1] == this.pieces[2][2] &&
 70             this.pieces[1][1] != " ")
 71             ||
 72             (this.pieces[2][0] == this.pieces[1][1] &&
 73             this.pieces[1][1] == this.pieces[0][2] &&
 74             this.pieces[1][1] != " "))
 75             return true;
 76         
 77         return false;
 78     }
 79     
 80     /** 方法重载,接受一个棋子数组的拷贝,判断此情况下能否胜利。*/
 81     boolean checkWin(String[][] list) {
 82         for (int i = 0; i < 3; i++) {
 83             if ((list[i][0] == list[i][1] && 
 84                 list[i][1] == list[i][2] && 
 85                 list[i][1] != " ")
 86                 ||
 87                 (list[0][i] == list[1][i] && 
 88                 list[1][i] == list[2][i] &&
 89                 list[1][i] != " "))
 90                 return true;
 91         }
 92         if ((list[0][0] == list[1][1] &&
 93             list[1][1] == list[2][2] &&
 94             list[1][1] != " ")
 95             ||
 96             (list[2][0] == list[1][1] &&
 97             list[1][1] == list[0][2] &&
 98             list[1][1] != " "))
 99             return true;
100         
101         return false;
102     }
103     
104     /** 返回一个棋子数组的拷贝。*/
105     String[][] piecesCopy() {
106         String[][] copy = new String[3][3];
107         for (int i = 0; i < 3; i++) {
108             for (int j = 0; j < 3; j++)    {
109                 copy[i][j] = this.pieces[i][j];
110             }
111         }
112         return copy;
113     }
114 }
Game类
 1 package ticTacToeII;
 2 
 3 class Computer {
 4     
 5     /** 电脑落子。*/
 6     void move(Game game) {
 7         int row, column;
 8         
 9         // 如果有关键点就落在那。
10         if (getCriticalPoint(game)[0] != -1) {
11             row = getCriticalPoint(game)[0];
12             column = getCriticalPoint(game)[1];
13             game.changeBoard(row, column, "×");
14             return;
15         }
16         
17         // 否则就随机产生位置。
18         while (true) {
19             row = (int) (Math.random() * 3);
20             column = (int) (Math.random() * 3);
21             if (game.changeBoard(row, column, "×") == -1)
22                 continue;
23             break;
24         }
25     }
26     
27     /** 找出并返回棋盘上的关键点。*/
28     private int[] getCriticalPoint(Game game) {
29         int[] coordinate = {-1, -1};
30         String[][] copy = game.piecesCopy();
31         String[] chessman = {"×", "○"}; // 顺序反了的话即使能赢也会优先堵玩家。
32         String temp;
33         
34         // 拷贝棋盘并遍历,找出落子后能胜利的点,不管是哪一方胜利。
35         for (int i = 0; i < 3; i++) {
36             for (int j = 0; j < 3; j++) {
37                 for (String s: chessman) {
38                     if (copy[i][j] != " ") // 位置占用了就直接跳过不废话。
39                         continue;
40                     temp = copy[i][j];
41                     copy[i][j] = s;
42                     if (game.checkWin(copy)) {
43                         coordinate[0] = i;
44                         coordinate[1] = j;
45                         return coordinate;
46                     }
47                     copy[i][j] = temp;
48                 }
49             }
50         }
51         return coordinate;
52     }
53 }
Computer类
 1 package ticTacToeII;
 2 
 3 class Player {
 4     
 5     /** 玩家落子。*/
 6     @SuppressWarnings("resource")
 7     void move(Game game) {
 8         
 9         while (true) {
10             java.util.Scanner input = new java.util.Scanner(System.in);
11             
12             System.out.print("请输入行数(1-3):");
13             String row = input.next();
14             if (!isValid(row))
15                 continue;
16             System.out.print("请输入列数(1-3):");
17             String column = input.next();
18             if (!isValid(column))
19                 continue;
20             
21             int r = Integer.parseInt(row) - 1;
22             int c = Integer.parseInt(column) - 1;
23             
24             if (game.changeBoard(r, c, "○") == -1) {
25                 System.out.println("这里有子了。
");
26                 continue;
27             }
28             
29             return;
30         }
31     }
32     
33     /** 检查玩家输入。*/
34     private boolean isValid(String userInput) {
35         if (userInput.matches("[123]{1}"))
36             return true;
37         else
38             return false;
39     }
40 }
Player类
原文地址:https://www.cnblogs.com/chihane/p/3450572.html