游戏功能:
1. 自定义棋盘大小(1-n)
2. 两个玩家自由输入落子位置,系统自动判定输赢
参考文章:https://www.programcreek.com/2014/05/leetcode-tic-tac-toe-java/, LeetCode – Tic-Tac-Toe (Java)
运行结果示例:
欢迎来到井字棋游戏(Tic-Tac-Toe)
玩家1请输入要落子的行号(1-3):2
玩家1请输入要落子的列号(1-3):2
玩家1在【2,2】处落子 - - - - O - - - -
玩家2请输入要落子的行号(1-3):1
玩家2请输入要落子的列号(1-3):1
玩家2在【1,1】处落子 X - - - O - - - -
玩家1请输入要落子的行号(1-3):2
玩家1请输入要落子的列号(1-3):2 该位置已有落子,请重新输入行列号!
玩家1请输入要落子的行号(1-3):1
玩家1请输入要落子的列号(1-3):2
玩家1在【1,2】处落子 X O - - O - - - -
玩家2请输入要落子的行号(1-3):2
玩家2请输入要落子的列号(1-3):1
玩家2在【2,1】处落子 X O - X O - - - -
玩家1请输入要落子的行号(1-3):3
玩家1请输入要落子的列号(1-3):3
玩家1在【3,3】处落子 X O - X O - - - O
玩家2请输入要落子的行号(1-3):1
玩家2请输入要落子的列号(1-3):3
玩家2在【1,3】处落子 X O X X O - - - O
玩家1请输入要落子的行号(1-3):1
玩家1请输入要落子的列号(1-3):3 该位置已有落子,请重新输入行列号!
玩家1请输入要落子的行号(1-3):2
玩家1请输入要落子的列号(1-3):2 该位置已有落子,请重新输入行列号!
玩家1请输入要落子的行号(1-3):3
玩家1请输入要落子的列号(1-3):2
玩家1在【3,2】处落子 X O X X O - - O O 玩家1赢了,游戏结束! |
代码:
1.实体类
//JHTP Exercise 8.17: Tic-Tac-Toe
//by pandenghuang@163.com
/**
* 8.17 (Tic-Tac-Toe) Create a class TicTacToe that will enable you to write a
* program to play Tic-Tac-Toe. The class contains a private 3-by-3
* two-dimensional array. Use an enum type to represent the value in each cell
* of the array. The enum’s constants should be named X, O and EMPTY (for a
* position that does not contain an X or an O). The constructor should
* initialize the board elements to EMPTY. Allow two human players. Wherever the
* first player moves, place an X in the specified square, and place an O
* wherever the second player moves. Each move must be to an empty square. After
* each move, determine whether the game has been won and whether it’s a draw.
* If you feel ambitious, modify your program so that the computer makes the
* moves for one of the players. Also, allow the player to specify whether he or
* she wants to go first or second. If you feel exceptionally ambitious, develop
* a program that will play three-dimensional Tic-Tac-Toe on a 4-by-4-by-4 board
* [Note: This is an extremely challenging project!].
*
* @author Pandenghuang@163.com
* 说明:本实体类基于https://www.programcreek.com/2014/05/leetcode-tic-tac-toe-java/中的solution 1修改而成
*/
public class TicTacToe {
int[][] matrix;
enum ticTacToeMark {X,O,EMPTY};
/** Initialize your data structure here. */
public TicTacToe(int n) {
matrix = new int[n][n];
}
/**
* 打印井字棋棋盘
*/
public void displayBoard() {
for (int row=0; row<matrix.length;row++) {
for (int col=0; col<matrix.length;col++) {
if (matrix[row][col]==1)
System.out.printf("%s\t", ticTacToeMark.O);
else if (matrix[row][col]==2)
System.out.printf("%s\t", ticTacToeMark.X);
else
System.out.printf("-\t");
}
System.out.println();
}
}
/** Player {player} makes a move at ({row}, {col}).
@param row The row of the board.
@param col The column of the board.
@param player The player, can be either 1 or 2.
@return The current winning condition, can be either:
0: No one wins.
1: Player 1 wins.
2: Player 2 wins. */
public int move(int row, int col, int player) {
matrix[row][col]=player;
//check row
boolean win=true;
for(int i=0; i<matrix.length; i++){
if(matrix[row][i]!=player){
win=false;
break;
}
}
if(win) return player;
//check column
win=true;
for(int i=0; i<matrix.length; i++){
if(matrix[i][col]!=player){
win=false;
break;
}
}
if(win) return player;
//check back diagonal
win=true;
for(int i=0; i<matrix.length; i++){
if(matrix[i][i]!=player){
win=false;
break;
}
}
if(win) return player;
//check forward diagonal
win=true;
for(int i=0; i<matrix.length; i++){
if(matrix[i][matrix.length-i-1]!=player){
win=false;
break;
}
}
if(win) return player;
return 0;
}
}
2.测试类
import java.util.Scanner;
//JHTP Exercise 8.17: Tic-Tac-Toe
//by pandenghuang@163.com
/**
* 8.17 (Tic-Tac-Toe) Create a class TicTacToe that will enable you to write a
* program to play Tic-Tac-Toe. The class contains a private 3-by-3
* two-dimensional array. Use an enum type to represent the value in each cell
* of the array. The enum’s constants should be named X, O and EMPTY (for a
* position that does not contain an X or an O). The constructor should
* initialize the board elements to EMPTY. Allow two human players. Wherever the
* first player moves, place an X in the specified square, and place an O
* wherever the second player moves. Each move must be to an empty square. After
* each move, determine whether the game has been won and whether it’s a draw.
* If you feel ambitious, modify your program so that the computer makes the
* moves for one of the players. Also, allow the player to specify whether he or
* she wants to go first or second. If you feel exceptionally ambitious, develop
* a program that will play three-dimensional Tic-Tac-Toe on a 4-by-4-by-4 board
* [Note: This is an extremely challenging project!].
*
* @author Pandenghuang@163.com
*
*/
public class TicTacToeTest {
final static int SIZE = 2; //棋盘大小(n*n)
public static void main (String[] args) {
TicTacToe ttt= new TicTacToe(SIZE);
Scanner input = new Scanner(System.in);
int row = 1; //棋盘行号(最小为1,最大为棋盘行数)
int col = 1; //棋盘列号(最小为1,最大为棋盘列数)
int player = 1; //玩家号(1或2)
int status = 0; //游戏状态(0:胜负未分,1:玩家1赢了 2:玩家2赢了)
int count =0; //游戏进行步数计数器
boolean retry = false;
System.out.printf("欢迎来到井字棋游戏(Tic-Tac-Toe)%n");
do {
do {
if (!retry)
player = count%2+1; //玩家1,2交替落子,重新输入(retry)时不交换player
//玩家输入落子的行列号
retry = false; //重新输入时,retry重置
do {
System.out.printf("%n玩家%d请输入要落子的行号(1-%d):",player,SIZE);
row = input.nextInt();
}while (row >SIZE || row<1); //直到输入有效范围内的列号时,结束循环
do {
System.out.printf("%n玩家%d请输入要落子的列号(1-%d):",player,SIZE);
col = input.nextInt();
}while (col >SIZE || col<1); //直到输入有效范围内的列号时,结束循环
//判断输入的位置是空的
if (ttt.matrix[row-1][col-1]==0)
ttt.matrix[row-1][col-1]=1; //落子后,棋盘对应的位置置1
else {
System.out.println("该位置已有落子,请重新输入行列号!");
retry = true; //重新输入
}
}while (ttt.matrix[row-1][col-1]==0 || retry); //直到输入有效行列号时,结束循环
//判断游戏结果
System.out.printf("%n玩家%d在【%d,%d】处落子%n", player,row, col);
status = ttt.move(row-1, col-1, player);
++count;
ttt.displayBoard();
if (status!=0)
System.out.printf("玩家%d赢了,游戏结束!%n",status);
} while (status ==0); //游戏持续进行,直到分出胜负
input.close();
}
}