以下是标准答案源程序:
Chessboard类
package org.crazyit.gobang;
/**
- 棋盘对象
- @author yangenxiong yangenxiong2009@gmail.com
- @author Kelvin Mak kelvin.mak125@gmail.com
- @version 1.0
-
网站: 疯狂Java* -
Copyright (C), 2009-2010, yangenxiong -
This program is protected by copyright laws. */ public class Chessboard { // 定义一个二维数组来充当棋盘 private String[][] board; // 定义棋盘的大小 public static final int BOARD_SIZE = 22;
/**
- 初始化棋盘
- @return void */ public void initBoard() { // 初始化棋盘数组 board = new String[BOARD_SIZE][BOARD_SIZE]; // 把每个元素赋值为“十”,用于控制台输出棋盘 for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { board[i][j] = "十"; } } } public void test() { Object[][] array = new Object[10][10]; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { array[i][j] = new Object(); } } }
/**
- 在控制台输出棋盘的方法 */ public void printBoard() { // 打印每个数组元素 for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { // 打印后不换行 System.out.print(board[i][j]); } // 每打印完一行数组元素就换行一次 System.out.print("\n"); } }
/**
- 给棋盘位置赋值
- @param posX
- X坐标
- @param posY
- Y坐标
- @param chessman
- 棋子 */ public void setBoard(int posX, int posY, String chessman) { this.board[posX][posY] = chessman; }
/**
- 返回棋盘
- @return 返回棋盘 */ public String[][] getBoard() { return this.board; } }
回帖列表回帖(6) | 浏览(8) Scott Smith 2012-04-06 13:14:38 删除 1楼 Chessman类:
package org.crazyit.gobang;
/**
- 棋子枚举类
- @author yangenxiong yangenxiong2009@gmail.com
- @author Kelvin Mak kelvin.mak125@gmail.com
- @version 1.0
-
网站: 疯狂Java* -
Copyright (C), 2009-2010, yangenxiong -
This program is protected by copyright laws. */ public enum Chessman { BLACK("●"), WHITE("○"); //public static final Chessman = new Chessman(""); private String chessman;
/**
- 私有构造器 */ private Chessman(String chessman) { this.chessman = chessman; }
/**
-
@return String 黑棋或者白棋
*/
public String getChessman() {
return this.chessman;
}
}Scott Smith 2012-04-06 13:16:20 删除 2楼 GobangGame类:
package org.crazyit.gobang;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
- 五子棋游戏类
- @author yangenxiong yangenxiong2009@gmail.com
- @author Kelvin Mak kelvin.mak125@gmail.com
- @version 1.0
-
网站: 疯狂Java* -
Copyright (C), 2009-2010, yangenxiong -
This program is protected by copyright laws. */ public class GobangGame { // 定义达到赢条件的棋子数目 private final int WIN_COUNT = 5; // 定义用户输入的X坐标 private int posX = 0; // 定义用户输入的X坐标 private int posY = 0; // 定义棋盘 private Chessboard chessboard;
/**
- 空构造器 */ public GobangGame() { }
/**
- 构造器,初始化棋盘和棋子属性
- @param chessboard
- 棋盘类 */ public GobangGame(Chessboard chessboard) { this.chessboard = chessboard; }
/**
- 检查输入是否合法。
- @param inputStr
- 由控制台输入的字符串。
- @return 字符串合法返回true,反则返回false。 */ public boolean isValid(String inputStr) { // 将用户输入的字符串以逗号(,)作为分隔,分隔成两个字符串 String[] posStrArr = inputStr.split(","); try { posX = Integer.parseInt(posStrArr[0]) - 1; posY = Integer.parseInt(posStrArr[1]) - 1; } catch (NumberFormatException e) { chessboard.printBoard(); System.out.println("请以(数字,数字)的格式输入:"); return false; } // 检查输入数值是否在范围之内 if (posX < 0 || posX >= Chessboard.BOARD_SIZE || posY < 0 || posY >= Chessboard.BOARD_SIZE) { chessboard.printBoard(); System.out.println("X与Y坐标只能大于等于1,与小于等于" + Chessboard.BOARD_SIZE
- ",请重新输入:"); return false; } // 检查输入的位置是否已经有棋子 Scott Smith 2012-04-06 13:16:47 删除 3楼 String[][] board = chessboard.getBoard(); if (board[posX][posY] != "十") { chessboard.printBoard(); System.out.println("此位置已经有棋子,请重新输入:"); return false; } return true; }
/**
- 开始下棋 */ public void start() throw*ception { // true为游戏结束 boolean isOver = false; chessboard.initBoard(); chessboard.printBoard(); // 获取键盘的输入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String inputStr = null; // br.readLine:每当键盘输入一行内容按回车键,则输入的内容被br读取到 while ((inputStr = br.readLine()) != null) { isOver = false; if (!isValid(inputStr)) { // 如果不合法,要求重新输入,再继续 continue; } // 把对应的数组元素赋为"●" String chessman = Chessman.BLACK.getChessman(); chessboard.setBoard(posX, posY, chessman); // 判断用户是否赢了 if (isWon(posX, posY, chessman)) { isOver = true;
} else {
// 计算机随机选择位置坐标
int[] computerPosArr = computerDo();
chessman = Chessman.WHITE.getChessman();
chessboard.setBoard(computerPosArr[0], computerPosArr[1],
chessman);
// 判断计算机是否赢了
if (isWon(computerPosArr[0], computerPosArr[1], chessman)) {
isOver = true;
}
}
// 如果产生胜者,询问用户是否继续游戏
if (isOver) {
// 如果继续,重新初始化棋盘,继续游戏
if (isReplay(chessman)) {
chessboard.initBoard();
chessboard.printBoard();
continue;
}
// 如果不继续,退出程序
break;
}
chessboard.printBoard();
System.out.println("请输入您下棋的坐标,应以x,y的格式输入:");
}
}
/**
- 是否重新开始下棋。
- @param chessman
- "●"为用户,"○"为计算机。
- @return 开始返回true,反则返回false。 */ public boolean isReplay(String chessman) throw*ception { chessboard.printBoard(); String message = chessman.equals(Chessman.BLACK.getChessman()) ? "恭喜您,您赢了," : "很遗憾,您输了,"; System.out.println(message + "再下一局?(y/n)"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Scott Smith 2012-04-06 13:17:17 删除 4楼 if (br.readLine().equals("y")) { // 开始新一局 return true; } return false;
}
/**
- 计算机随机下棋 */ public int[] computerDo() { int posX = (int) (Math.random() * (Chessboard.BOARD_SIZE - 1)); int posY = (int) (Math.random() * (Chessboard.BOARD_SIZE - 1)); String[][] board = chessboard.getBoard(); while (board[posX][posY] != "十") { posX = (int) (Math.random() * (Chessboard.BOARD_SIZE - 1)); posY = (int) (Math.random() * (Chessboard.BOARD_SIZE - 1)); } int[] result = { posX, posY }; return result; }
/**
- 判断输赢
- @param posX
- 棋子的X坐标。
- @param posY
- 棋子的Y坐标
- @param ico
- 棋子类型
- @return 如果有五颗相邻棋子连成一条直接,返回真,否则相反。 */ public boolean isWon(int posX, int posY, String ico) { // 直线起点的X坐标 int startX = 0; // 直线起点Y坐标 int startY = 0; // 直线结束X坐标 int endX = Chessboard.BOARD_SIZE - 1; // 直线结束Y坐标 int endY = endX; // 同条直线上相邻棋子累积数 int sameCount = 0; int temp = 0;
// 计算起点的最小X坐标与Y坐标
temp = posX - WIN_COUNT + 1;
startX = temp < 0 ? 0 : temp;
temp = posY - WIN_COUNT + 1;
startY = temp < 0 ? 0 : temp;
// 计算终点的最大X坐标与Y坐标
temp = posX + WIN_COUNT - 1;
endX = temp > Chessboard.BOARD_SIZE - 1 ? Chessboard.BOARD_SIZE - 1
: temp;
temp = posY + WIN_COUNT - 1;
endY = temp > Chessboard.BOARD_SIZE - 1 ? Chessboard.BOARD_SIZE - 1
: temp;
// 从左到右方向计算相同相邻棋子的数目
String[][] board = chessboard.getBoard();
for (int i = startY; i < endY; i++) {
if (board[posX][i] == ico && board[posX][i + 1] == ico) {
sameCount++;
} else if (sameCount != WIN_COUNT - 1) {
sameCount = 0;
}
}
if (sameCount == 0) {
// 从上到下计算相同相邻棋子的数目
for (int i = startX; i < endX; i++) {
if (board[i][posY] == ico && board[i + 1][posY] == ico) {
sameCount++;
} else if (sameCount != WIN_COUNT - 1) {
sameCount = 0;
Scott Smith 2012-04-06 13:19:50 删除 5楼 }
j++;
}
}
}
return sameCount == WIN_COUNT - 1 ? true : false;
}
public static void main(String[] args) throw*ception {
GobangGame gb = new GobangGame(new Chessboard());
gb.start();
}
}
疑问1:上述第一处红色部分,为什么要保留那个空构造器,虽然书中139页也提示建议为java类保留无参数的默认构造器,可是还是不明白这样做有什么实际的意义!希望知道的朋友明示!!!
疑问2:第二处红色部分,为什么是string值等于ico,难道黑子的某种值等于ico???
Scott Smith 2012-04-06 13:21:10 删除 6楼 该死!红色部分字体不显示了!我直接说把!
第一处红色部分:/**
- 空构造器 */ public GobangGame() { }
第二处红色部分:if (board[i][posY] == ico && board[i + 1][posY] == ico)