游戏规则

在井字游戏中,两个玩家使用各自的标志(一方用 X 则另一方就用O),轮流填写3x3的网格中的某个空格。当一个玩家在网格的水平方向、垂直方向或者对角线方向上出现了三个相同的 X 或三个相同的 o时,游戏结束,该玩家获胜。平局(没有贏家)是指当网格中所有的空格都被填满时没有任何一方的玩家获胜的情况。创建一个玩井字游戏的程序。

实现思路

  1. 使用String数组显示棋盘, 然后根据用户输入的下标, 进行字符串的更改, 然后再显示给用户.
  2. X方落子和另一方落子
  3. 判断结束

显示棋盘

基本思路就是用字符串实现, 先定义一个二维数组, 将可以落子的地方做为可变数据替换, 然后显示给用户. 每一次落子都要调用.所以封装成为一个方法. 因为String数组是引用型, 可以直接修改, 所以, 将棋盘字符串数组写在主函数中, 作为实参.

字符串数组—棋盘 初始化为空白字符串数组

1
2
// Initialize the chess board
String[][] strings = new String[][] { { " ", " ", " " }, { " ", " ", " " }, { " ", " ", " " } };

将显示棋盘的功能封装成一个方法, 每次更改值之后, 然后显示.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Display the chess board
*
* @param array A String array for chess board
*/
public static void showPage(String[][] array) {
System.out.println("-------------");
System.out.println("| " + array[0][0] + " | " + array[0][1] + " | " + array[0][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[1][0] + " | " + array[1][1] + " | " + array[1][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[2][0] + " | " + array[2][1] + " | " + array[2][2] + " |");
System.out.println("-------------");
}

落子

  1. 落子的时候要进行两步

    1. 要判断原来的位置是否有子
      要判断原来的位置是否有子, 只需要检测是否为Space就好了, 因为初始化是space. 判断结束后, 如果出错, 提醒用户再次来过, 所以设置一个while循环.
    2. 并且要判断是否出界, 因为棋盘的区域有限.
      使用最简单的限定if实现就好.

    代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
while (true) {// X player round
System.out.println("Enter a row (0, 1, 2) for player X: ");
int x1 = scanner.nextInt();
if (x1 > strings.length || x1 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

System.out.println("Enter a column (0, 1, 2) for player X: ");
int y1 = scanner.nextInt();
if (y1 > strings.length || y1 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

// If it is right
if (strings[x1][y1] == " ") {
strings[x1][y1] = "X";
break;
} else {
System.out.println("There was a piece, change another position");
continue;
}
}

判断结束

判断结束这一点做的不是很好, 后续能想到好的方法再去修改. 我这边就只想到了五种可以结束的标志

  1. 纵行连成三个
  2. 横行连成三个
  3. 左斜连成三个
  4. 右斜连城三个
  5. 棋盘满了.

同样为了方便我们把这个功能做成一个方法, 因为每一次落子之后都要进行判断是否要继续.
代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Decide if the game is over and print result
*
* @param strings The chess board decided
* @return The result for the game, and print the result
*/
public static boolean isGameOver(String[][] strings) {
// Row same
for (int i = 0; i < strings.length; i++) {
if (strings[i][0].equals(strings[i][1]) && strings[i][1].equals(strings[i][2]) && strings[i][0] != " ") {
System.out.println(strings[i][0] + " player won");
return true;
}
}
// Column same
for (int i = 0; i < strings[0].length; i++) {
if (strings[0][i].equals(strings[1][i]) && strings[1][i].equals(strings[2][i]) && strings[0][i] != " ") {
System.out.println(strings[0][i] + " player won");
return true;
}
}

// / same the left angle.
if (strings[0][0].equals(strings[1][1]) && strings[1][1].equals(strings[2][2]) && strings[2][2] != " ") {
System.out.println(strings[0][0] + " player won");
return true;
}
// \ same the right angle
if (strings[0][2].equals(strings[1][1]) && strings[1][1].equals(strings[2][0]) && strings[1][1] != " ") {
System.out.println(strings[1][1] + " player won");
return true;
}

// Full
for (int i = 0; i < strings.length; i++) {
for (int j = 0; j < strings[i].length; j++) {
if (strings[i][j] == " ")
return false;
}
}

// Draw
System.out.println("There is no space, Draw");
return true;
}

总结

1
2
3
4
5
6
7
8
9
10
11
做这个题目, 他只是一个简单的题目, 也没有用什么高大上的技术, 
只是简简单单的二维数组实现.
简单的程序中也有各种逻辑, 什么东西不是由简单的事情决定的呢
有人说, 把所有简单的事情做好, 就不是一个简单的人.
看似简单, 又有多少人能做到呢?

再来说一下这个代码, 其实有的地方确实实现的不好
1. 判断斜边上连成三个的做的不好, 这个只适用于三子棋, 如果要写五子棋, 八子棋等等就要重写很多代码
这一点程序写的太好.
2. 主函数过于繁琐, 比如 X round 和 O round 完全可以封装成一个方法
3. 有些地方很臃肿.

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import java.util.Scanner;

public class Test8_9 {
public static void main(String[] args) {
// Initialize the chess board
String[][] strings = new String[][] { { " ", " ", " " }, { " ", " ", " " }, { " ", " ", " " } };

// Create a Scanner, get users' input
Scanner scanner = new Scanner(System.in);

// Game running
while (true) {
while (true) {// X player round
System.out.println("Enter a row (0, 1, 2) for player X: ");
int x1 = scanner.nextInt();
if (x1 > 2 || x1 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

System.out.println("Enter a column (0, 1, 2) for player X: ");
int y1 = scanner.nextInt();
if (y1 > 2 || y1 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

// If it is right
if (strings[x1][y1] == " ") {
strings[x1][y1] = "X";
break;
} else {
System.out.println("There was a piece, change another position");
continue;
}
}
showPage(strings);

// Verify if game over
if (isGameOver(strings)) {
break;
}

while (true) {// O player round
System.out.println("Enter a row (0, 1, 2) for player O: ");
int x2 = scanner.nextInt();
if (x2 > 2 || x2 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

System.out.println("Enter a column (0, 1, 2) for player O: ");
int y2 = scanner.nextInt();
if (y2 > 2 || y2 < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

// If it is right
if (strings[x2][y2] == " ") {
strings[x2][y2] = "O";
break;
} else {
System.out.println("There was a piece, change another position");
continue;
}
}
showPage(strings);

// Verify if game over
if (isGameOver(strings)) {
break;
}
}
scanner.close();
}

/**
* Display the chess board
*
* @param array A String array for chess board
*/
public static void showPage(String[][] array) {
System.out.println("-------------");
System.out.println("| " + array[0][0] + " | " + array[0][1] + " | " + array[0][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[1][0] + " | " + array[1][1] + " | " + array[1][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[2][0] + " | " + array[2][1] + " | " + array[2][2] + " |");
System.out.println("-------------");
}

/**
* Decide if the game is over and print result
*
* @param strings The chess board decided
* @return The result for the game, and print the result
*/
public static boolean isGameOver(String[][] strings) {
// Row same
for (int i = 0; i < strings.length; i++) {
if (strings[i][0].equals(strings[i][1]) && strings[i][1].equals(strings[i][2]) && strings[i][0] != " ") {
System.out.println(strings[i][0] + " player won");
return true;
}
}
// Column same
for (int i = 0; i < strings[0].length; i++) {
if (strings[0][i].equals(strings[1][i]) && strings[1][i].equals(strings[2][i]) && strings[0][i] != " ") {
System.out.println(strings[0][i] + " player won");
return true;
}
}

// / same the left angle.
if (strings[0][0].equals(strings[1][1]) && strings[1][1].equals(strings[2][2]) && strings[2][2] != " ") {
System.out.println(strings[0][0] + " player won");
return true;
}
// \ same The right angle
if (strings[0][2].equals(strings[1][1]) && strings[1][1].equals(strings[2][0]) && strings[1][1] != " ") {
System.out.println(strings[1][1] + " player won");
return true;
}

// Full
for (int i = 0; i < strings.length; i++) {
for (int j = 0; j < strings[i].length; j++) {
if (strings[i][j] == " ")
return false;
}
}

// Draw
System.out.println("There is no space, Draw");
return true;
}
}

总结后修改的代码

我在写这篇博客写完总结的时候, 突然发现自己的程序可以改一改, 然后就做了以下修改, 但是还是没有将斜着的判断写出来.
先睡觉了, 后边补上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import java.util.Scanner;

public class Test {
public static void main(String[] args) {
// Initialize the chess board
String[][] strings = new String[][] { { " ", " ", " " }, { " ", " ", " " }, { " ", " ", " " } };

// Create a Scanner, get users' input
Scanner scanner = new Scanner(System.in);

// Game running
while (true) {
round(strings, "X");
showPage(strings);

// Verify if game over
if (isGameOver(strings)) {
break;
}

round(strings, "O");
showPage(strings);

// Verify if game over
if (isGameOver(strings)) {
break;
}
}
scanner.close();
}

/**
* Display the chess board
*
* @param array A String array for chess board
*/
public static void showPage(String[][] array) {
System.out.println("-------------");
System.out.println("| " + array[0][0] + " | " + array[0][1] + " | " + array[0][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[1][0] + " | " + array[1][1] + " | " + array[1][2] + " |");
System.out.println("-------------");
System.out.println("| " + array[2][0] + " | " + array[2][1] + " | " + array[2][2] + " |");
System.out.println("-------------");
}

/**
* Decide if the game is over and print result
*
* @param strings The chess board decided
* @return The result for the game, and print the result
*/
public static boolean isGameOver(String[][] strings) {
// Row same
for (int i = 0; i < strings.length; i++) {
if (strings[i][0].equals(strings[i][1]) && strings[i][1].equals(strings[i][2]) && strings[i][0] != " ") {
System.out.println(strings[i][0] + " player won");
return true;
}
}
// Column same
for (int i = 0; i < strings[0].length; i++) {
if (strings[0][i].equals(strings[1][i]) && strings[1][i].equals(strings[2][i]) && strings[0][i] != " ") {
System.out.println(strings[0][i] + " player won");
return true;
}
}

// / same the left angle.
if (strings[0][0].equals(strings[1][1]) && strings[1][1].equals(strings[2][2]) && strings[2][2] != " ") {
System.out.println(strings[0][0] + " player won");
return true;
}
// \ same The right angle
if (strings[0][2].equals(strings[1][1]) && strings[1][1].equals(strings[2][0]) && strings[1][1] != " ") {
System.out.println(strings[1][1] + " player won");
return true;
}

// Full
for (int i = 0; i < strings.length; i++) {
for (int j = 0; j < strings[i].length; j++) {
if (strings[i][j] == " ")
return false;
}
}

// Draw
System.out.println("There is no space, Draw");
return true;
}

/**
* A Round
* @return
*/
public static void round(String[][] strings, String user) {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Enter a row (0, 1, 2) for player "+ user + ": ");
int x= scanner.nextInt();
if (x > strings.length || x < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

System.out.println("Enter a column (0, 1, 2) for player "+ user + ": ");
int y = scanner.nextInt();
if (y > strings.length || y < 0) {
System.out.println("Input Error, please input the number between 0-2 (0 and 2 inclusive) ");
continue;
}

// If it is right
if (strings[x][y] == " ") {
strings[x][y] = user;
break;
} else {
System.out.println("There was a piece, change another position");
continue;
}
}
// scanner.close();
}
}

修改时发现的问题

在方法中不能使用scanner.close()
这个scanner.close() 相当于把System.in这个流给关掉了, 再次使用的时候就无法使用了, 但是在main方法的最后可以使用一下.