- 游戏规则:双人游戏。谁先完成五个棋子的连线(横向/纵向/斜向),谁胜利。
- 代码介绍:一共有五个类,分别是:Chessboard(棋盘类)、Piece(棋子类)、Rule(规则类)、Location(坐标类)、Game(执行类)
界面展示(控制台输入输出)
源代码
Chessboard(棋盘类)
package com.crb.wuziqi;
public class Chessboard {
public static final int ROW_COUNT = 15; // 行数
public static final int COLUMN_COUNT = 15; // 列数
// 存放棋子的二维数组
private Piece[][] pieceArr = new Piece[ROW_COUNT][COLUMN_COUNT];
/**
* 初始化棋盘
*/
public void initChessboard(){
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COLUMN_COUNT; j++) {
Piece piece = null;
if (i == 0){
if(j == 0){
piece = new Piece(i,j,'┌'); // 左上角
}else if(j == COLUMN_COUNT - 1){
piece = new Piece(i,j,'┐'); // 右上角
}else{
piece = new Piece(i,j,'┬');
}
} else if (i == ROW_COUNT - 1){
if (j == 0){
piece = new Piece(i,j,'└'); // 左下角
}else if(j == COLUMN_COUNT - 1){
piece = new Piece(i,j,'┘'); // 右下角
}else{
piece = new Piece(i,j,'┴');
}
} else {
if (j == 0){
piece = new Piece(i,j,'├');
}else if(j == COLUMN_COUNT - 1){
piece = new Piece(i,j,'┤');
}else{
piece = new Piece(i,j,'┼');
}
}
pieceArr[i][j] = piece;
}
}
}
/**
* 打印棋盘
*/
public void printChessboard(){
char[] number = {'1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
for (int j = 0; j < COLUMN_COUNT; j++) {
System.out.print(" " + number[j]); // 打印列号
}
System.out.println();
for (int i = 0; i < ROW_COUNT; i++) {
System.out.print(number[i]); // 打印行号
for (int j = 0; j < COLUMN_COUNT; j++) {
System.out.print(pieceArr[i][j].getSymbol());
if (j != pieceArr[i].length - 1)
System.out.print("─");
}
System.out.println();
}
}
/**
* 落子方法
* @param piece 要下的棋子
*/
public void putDownPiece(Piece piece){
int row = piece.getRow(); // 获得棋子的行坐标
int column = piece.getColumn(); // 获得棋子的纵坐标
pieceArr[row][column] = piece; // 放到棋盘
}
/**
* 判断棋盘上指定位置是否可以落子
* @param location 指定位置
* @return 如果能落子,返回true,如果不能,返回false
*/
public boolean canPutDown(Location location){
// 如果棋盘上此处已经有黑子 ● 或者白子 o ,返回 false,否则返回 true
// 获取行号和列号
int row = location.getRow();
int column = location.getColumn();
Piece piece = pieceArr[row][column];
if (piece.getSymbol() == '●' || piece.getSymbol() == 'o'){
return false;
}else {
return true;
}
}
/**
* 根据行坐标和列坐标获取棋子对象
* @param row 行坐标
* @param column 列坐标
* @return 返回指定棋子对象
*/
public Piece getPiece(int row,int column){
return pieceArr[row][column];
}
}
Piece(棋子类)
package com.crb.wuziqi;
public class Piece {
private int row; // 棋子的行坐标,从0开始,最大是14
private int column; // 棋子的列坐标,从0开始,最大是14
private char symbol; // 棋子的符号 黑子 ● 白子 o
public Piece() {
}
public Piece(int row, int column, char symbol) {
this.setRow(row);
this.setColumn(column);
this.symbol = symbol;
}
public int getRow() {
return row;
}
public void setRow(int row) {
if (row < 0){
row = 0;
}else if (row > 14){
row = 14;
}
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
if (column < 0){
column = 0;
}else if (column > 14){
column = 14;
}
this.column = column;
}
public char getSymbol() {
return symbol;
}
public void setSymbol(char symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return "symbol(" + row + "," + column + ')';
}
}
Rule(规则类)
package com.crb.wuziqi;
import java.util.Scanner;
public class Rule {
// 创建一个Scanner对象,用于接收用户输入内容
private static Scanner scanner = new Scanner(System.in);
/**
* 获取落子位置
* @return 返回当前落子位置
*/
public static Location getLocation(){
// 提取用户输入的全部内容
String input = scanner.nextLine();
// 只要输入的内容长度不是3 或者 输入的行号,列号不符合要求就让用户重新输入
while(input.length() != 3 ||
isRightCharacter(input.charAt(0)) == false ||
input.charAt(1) != ',' ||
isRightCharacter(input.charAt(2)) == false){
System.out.print("位置输入有误,请重新输入: ");
input = scanner.nextLine();
}
//System.out.println(input);
// 获取用户输入的行号
char rowChar = input.charAt(0);
// 获取用户输入的列号
char columnChar = input.charAt(2);
// 用户输入的行号或列号是从1开始的,我们数组的下标是从0开始的
// 行号或列号中有A,B,C,D,E,F 我们数组里只有数字 A应该是下标9,B应该是下标10,C应该是下标11
int row = indexForChar(rowChar);
int column = indexForChar(columnChar);
Location location = new Location(row,column);
return location;
}
/**
* 判断给定的字符是否正确
* @param c 给定的字符
* @return 如果正确,返回 true,不正确则返回 false
*/
private static boolean isRightCharacter(char c){
if (c >= '1' && c <= '9'|| c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'){
return true;
}
return false;
}
/**
* 把字符转换成数组下标
* @param c 需要转换成下标的字符 c的取值范围是 字符 1-9, a-f, A-F
* @return 返回字符对应的下标
*/
private static int indexForChar(char c){
// 假设 c的值是'5'
int index = -1;
if (c >= '1' && c <= '9'){
index = c - '1'; // 假设 c 的值是‘5’ 53 - 49 = 4;
}else if (c >= 'a' && c <= 'f'){
index = c - 'a' + 9; // 假设 c 的值是‘d’ 100 - 97 + 9 = 12;
}else if (c >= 'A' && c <= 'F'){
index = c - 'A' + 9; // 假设 c 的值是‘D’ 68 - 65 + 9 = 12;
}
return index;
}
/**
* 判断指定位置是否可以落子
* @param location 指定位置
* @return 如果能落子,返回 true,如果不能落子,返回 false
*/
public static boolean canPutDown(Chessboard chessboard,Location location){
// 如果棋盘上此处已经有黑子 ● 或者白子 o ,返回 false,否则返回 true
return chessboard.canPutDown(location);
}
/**
* 判断输赢
* @param chessboard 当前棋盘
* @param piece 当前最新下的棋子
* @return 返回黑子获胜还是白子获胜
*/
public static boolean isWin(Chessboard chessboard, Piece piece){
// (一)判断横向是否达到5个或者更多同色子
int row = piece.getRow(); // 获取棋子行号
int column = piece.getColumn(); // 获取棋子列号
char symbol = piece.getSymbol(); // 获取棋子颜色
int count = 1; // 让count初始值是1,因为当前棋子就算一个
// 计算当前棋子的左侧有几个同色棋子
int i = row;
int j = column - 1;
while(j >= 0){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
j --; // 继续向左找棋子
}else{
// 如果不是同色,直接break
break;
}
}
// 计算当前棋子的右侧有几个同色的棋子
i = row;
j = column + 1;
while (j <= Chessboard.COLUMN_COUNT - 1){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
j ++; // 继续向左找棋子
}else{
// 如果不是同色,直接break
break;
}
}
if (count >= 5){
return true;
}
// (二)判断纵向是否达到 5 个或者更多同色子
count = 1; // count需要重置为1
// 计算当前棋子的上方有几个同色棋子
i = row - 1;
j = column;
while (i >= 0){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i --; // 继续向上找棋子
}else{
// 如果不是同色,直接break
break;
}
}
// 计算当前棋子的下侧有几个同色的棋子
i = row + 1;
j = column;
while (i <= Chessboard.COLUMN_COUNT - 1){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i ++; // 继续向下找棋子
}else{
// 如果不是同色,直接break
break;
}
}
if (count >= 5){
return true;
}
//(三)判断斜着(左下右上)是否达到 5 个或者更多同色子
count = 1; // count需要重置为1
// 计算当前棋子的左下方有几个同色棋子
i = row + 1;
j = column - 1;
while (i <= Chessboard.ROW_COUNT - 1 && j >= 0){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i ++; // 向下移动位置
j --; // 向左移动位置
}else{
// 如果不是同色,直接break
break;
}
}
// 计算当前棋子的右上方有几个同色的棋子
i = row - 1;
j = column + 1;
while (i >= 0 && j <= Chessboard.COLUMN_COUNT - 1){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i --; // 向上移动位置
j ++; // 向右移动位置
}else{
// 如果不是同色,直接break
break;
}
}
if (count >= 5){
return true;
}
//(四)判断斜着(左上右下)是否达到 5 个或者更多同色子
count = 1; // count需要重置为1
// 计算当前棋子的左上方有几个同色棋子
i = row - 1;
j = column - 1;
while (i >= 0 && j >= 0){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i --; // 向上移动位置
j --; // 向左移动位置
}else{
// 如果不是同色,直接break
break;
}
}
// 计算当前棋子的右下方有几个同色的棋子
i = row + 1;
j = column + 1;
while (i <= Chessboard.ROW_COUNT - 1 && j <= Chessboard.COLUMN_COUNT - 1){
Piece piece1 = chessboard.getPiece(i,j);
char symbol1 = piece1.getSymbol();
if (symbol1 == symbol){
// 如果同色,让 count++
count ++;
i ++; // 向上移动位置
j ++; // 向右移动位置
}else{
// 如果不是同色,直接break
break;
}
}
if (count >= 5){
return true;
}
return false;
}
}
Location(坐标类)
package com.crb.wuziqi;
public class Location {
private int row;
private int column;
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public Location(int row, int column) {
this.row = row;
this.column = column;
}
public Location() {
}
@Override
public String toString() {
return "Location{" +
"row=" + row +
", column=" + column +
'}';
}
}
Game(执行类)
package com.crb.wuziqi;
public class Game {
public static void main(String[] args) {
// 游戏开始之前,先创建棋盘
Chessboard chessboard = new Chessboard();
// 初始化棋盘
chessboard.initChessboard();
// 绘制棋盘(空棋盘)
chessboard.printChessboard();
// 开始游戏
startGame(chessboard);
}
private static void startGame(Chessboard chessboard) {
while(true){
// (一)黑子下棋
// 提示黑子下棋
System.out.print("黑子下棋,请输入落子位置(例如:6,A):");
// 获取黑子落子的位置
Location location = Rule.getLocation();
// 判断是否能在此处落子
// 只要不能落子,就一直获取新的位置
while (Rule.canPutDown(chessboard, location) == false){
System.out.print("此处已有棋子,请输入新的位置(例如:6,A):");
location = Rule.getLocation();
}
// 落子
Piece piece = new Piece(location.getRow(), location.getColumn(),'●');
chessboard.putDownPiece(piece);
// 绘制棋盘
chessboard.printChessboard();
// 判断输赢
if (Rule.isWin(chessboard,piece)){
System.out.println("游戏结束!黑子获胜!");
break;
}
// (二)白子下棋
// 提示白子下棋
System.out.print("白子下棋,请输入落子位置(例如:6,A):");
// 获取白子落子的位置
Location location1 = Rule.getLocation();
// 判断是否能在此处落子
// 只要不能落子,就一直获取新的位置
while (Rule.canPutDown(chessboard, location1) == false){
System.out.print("此处已有棋子,请输入新的位置(例如:6,A):");
location1 = Rule.getLocation();
}
// 落子
Piece piece1 = new Piece(location1.getRow(), location1.getColumn(),'o');
chessboard.putDownPiece(piece1);
// 绘制棋盘
chessboard.printChessboard();
// 判断输赢
if (Rule.isWin(chessboard,piece1)){
System.out.println("游戏结束!白子获胜!");
break;
}
}
}
}
写在最后的话
最近开始实训啦,这就是最近做的一个小项目!老师说这个项目“麻雀虽小五脏俱全”,学完java基础和面向对象的基本知识之后,这个就可以当做一个练手的项目啦。有问题的话 评论或私聊都可以哈,看到了一定会回复的!!!加油加油!!!