编写程序,实现简单的三子棋游戏。在三子棋中,双方在33的棋盘中轮流下棋,一方用表示,另一方用O表示。如果一方的3个棋子占据了同一行,同一列或者对角线,则该方获胜。如果棋盘已被棋子占满,但没有一方获胜则出现平局。在程序中,一方为用户,用户在界面上输入每次下棋的位置;另一方下棋的位置为随机自动生成。示例输出如图所示。
import java.util.Random;
import javax.swing.*;
class CheckerBoard{
/**
* BOUNDARY 棋盘边界 避免魔法值
* board 棋盘二维数组
* count 棋盘上棋子个数
* route 下棋序列
* firstPlayer 先手 true为玩家 false为机器人
*/
static final Integer BOUNDARY = 3;
char[][] board;
int count;
int[] route;
boolean firstPlayer;
/**
* 默认构造方法
*/
public CheckerBoard() {
count = 0;
int num = 1;
route = new int[10];
board = new char[5][5];
for(int i = 1; i <= BOUNDARY; i++){
for(int j = 1; j <= BOUNDARY; j++){
board[i][j] = (char) ('0' + num++);
}
}
}
/**
* 每个玩家下棋时对棋盘进行更新
* @param local 下棋的位置
* @param c 棋子的类型
*/
public void update(int local, char c) {
int i = (local + 3 - 1) / 3;
int j = (local - 1) % 3 + 1;
board[i][j] = c;
count++;
route[count] = local;
}
/**
* 悔棋方法
* @return 返回是否悔棋成功
*/
public boolean goBack(){
if(count <= 1){
return false;
}
count = Math.max(count - 2, 0);
for(int k = 1; k <= 2; k++){
int local = route[count + k];
int i = (local + 3 - 1) / 3;
int j = (local - 1) % 3 + 1;
board[i][j] = (char) (local + '0');
}
return true;
}
/**
* 检查当前位置是否已经有棋子
* @param local 落子的位置
* @return 有棋子返回true 反之返回false
*/
public boolean check(int local) {
int i = (local + 3 - 1) / 3;
int j = (local - 1) % 3 + 1;
return board[i][j] == '*' || board[i][j] == 'o';
}
/**
* 输出棋盘
* @return 棋盘字符串
*/
public String output() {
StringBuilder str = new StringBuilder("-----------------------\n\n");
for(int i = 1; i <= BOUNDARY; i++) {
str.append(" | ").append(board[i][1]).append(" | ").append(board[i][2]).append(" | ").append(board[i][3]).append(" |\n\n");
}
str.append("------------------------\n");
return str.toString();
}
/**
* 判断当前落子位置是否越界
* @param local 当前落子位置
* @return 越界返回true 反之返回false
*/
public boolean isExceed(int local) {
return local < 1 || local > 9 ;
}
/**
* 判断是否有玩家赢得游戏
* @return 有玩家获胜返true 反之返回 false
*/
public boolean isWin() {
//判断行列
for(int i = 1; i <= BOUNDARY; i++) {
if(board[i][1] == board[i][3] && board[i][2] == board[i][1]) {
return true;
}
if(board[1][i] == board[3][i] && board[2][i] == board[1][i]) {
return true;
}
}
//判断对角线
if(board[1][1] == board[3][3] && board[1][1] == board[2][2]) {
return true;
}
return board[1][3] == board[3][1] && board[1][3] == board[2][2];
}
/**
* 随机选出先手的玩家
* @return true表示用户先手 false表示机器人先手
*/
public boolean firstPlayer() {
String str;
Random random = new Random();
boolean flag = random.nextBoolean();
firstPlayer = flag;
str = flag ? "你" : "机器人";
JOptionPane.showMessageDialog(null, str + "先下!");
return flag;
}
}
public class GoBang {
/**
* b 棋盘全局变量
*/
static CheckerBoard b = new CheckerBoard();
/**
* 机器人下棋方法
*/
public static void robotPut () {
Random rand = new Random();
int local = rand.nextInt(9) + 1;
while(b.check(local)) {
local = rand.nextInt(9) + 1;
}
b.update(local, 'o');
}
/**
* 用户下棋方法
*/
public static void userPut() {
UIManager.put("OptionPane.cancelButtonText", "撤销");
String s = JOptionPane.showInputDialog(b.output() + "请输入位置:");
while("".equals(s) || s == null || b.isExceed(Integer.parseInt(s)) || b.check(Integer.parseInt(s))) {
if(s == null){
if(b.goBack()){
JOptionPane.showMessageDialog(null, "撤销成功!");
}else{
JOptionPane.showMessageDialog(null, "撤销失败!");
}
userPut();
return;
}
JOptionPane.showMessageDialog(null, "输入有误, 请重新输入!");
s = JOptionPane.showInputDialog(b.output() + "请输入位置:");
}
b.update(Integer.parseInt(s), '*');
}
public static void main(String[] args) {
boolean curPlayer = b.firstPlayer();
if(curPlayer) {
userPut();
} else {
robotPut();
}
curPlayer = !curPlayer;
while(!b.isWin()) {
//判断是否平局
if(b.count == 9) {
JOptionPane.showMessageDialog(null,b.output() + "平局!");
System.exit(0);
}
if(curPlayer) {
userPut();
} else {
robotPut();
}
curPlayer = !curPlayer;
}
String str = curPlayer ? "机器人" : "你";
JOptionPane.showMessageDialog(null, b.output() + str + "胜利啦!");
System.exit(0);
}
}