《疯狂Java讲义(第4版)》-----第4章【控制台五子棋】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/82812832

特此说明:本文参考《疯狂Java实战演义》

开发游戏:控制台五子棋
开发工具:记事本

五子棋流程分析

在这里插入图片描述

需求分析

这个游戏比较简单,我们要完成人机下棋,需要棋盘类、棋子类和游戏类。棋盘和棋子都可以看成是游戏的一部分,构成聚合关系。然后根据上面的游戏流程分析。重点还是自上而下地进行结构化设计程序。

  1. 开始游戏
  2. 强行退出或重玩游戏强行退出或重玩游戏
  3. 用户输入落子坐标
  4. 判断落子坐标是否合法
  5. 判断输赢和棋(如有赢方或和棋,判断是否重玩)
  6. 程序输入落子坐标

代码实现

经过约摸8小时左右的奋战。写着调试着,终于大功告成,不知是否还有bug!!笔者参考了原作者思路,并加以改进,完全使用记事本开发。具体代码如下!!
在这里插入图片描述
在这里插入图片描述
Chessman.java


//根据枚举类写法书写,棋子枚举类只需提供黑白棋两个实例即可
public enum Chessman{
	BLACK("●"),WHITE("○");//注意在黑框框命令行下●是灰色,估计是不够黑的缘故吧
	private String chessman;

	private Chessman(String chessman){
		this.chessman = chessman;
	}
	
	public String getChessman(){
		return this.chessman;
	}

	//测试
	/*
	public static void main(String[] args){
		System.out.println(Chessman.BLACK.getChessman());
		System.out.println(Chessman.WHITE.getChessman());
	}
	*/
	
}

Chessboard.java

public class Chessboard{
	//棋盘
	private String[][] chessboard;
	//棋盘长宽
	public static final int CHESSBOARD_SIZE = 15;

	//空参构造函数
	public Chessboard(){} 

	//初始化棋盘,用二维数组表示棋盘,每个数组元素都赋值为┼
	public void initChessboard(){
		this.chessboard = new String[CHESSBOARD_SIZE][CHESSBOARD_SIZE];
		
		//画出棋盘
		for(int i = 0; i< CHESSBOARD_SIZE; i++){
			for(int j = 0; j < CHESSBOARD_SIZE; j++){
				this.chessboard[i][j] = "┼";
			}
		}
		
	}

	
	//打印棋盘	
	public void printChessboard(){
		for(int i = 0; i<CHESSBOARD_SIZE; i++){
			for(int j = 0; j < CHESSBOARD_SIZE; j++){
				System.out.print(this.chessboard[i][j]);
			}
			System.out.println();
		}
	}

	//把棋盘上的位置(posX, posY)放上棋子chessman,单纯从这一点看,
	//棋盘类确实是依赖游戏类的,也就是说,不玩游戏的话,何谈要打印棋盘呢!
	public void setChessboard(int posX, int posY, String chessman){
		this.chessboard[posX][posY] = chessman;
	}
	
	//获得棋盘对象中的棋盘二维数组
	public String[][] getChessboard(){
		return this.chessboard;
	}

	//测试
	/*
	public static void main(String[] args){
		//准备一个棋盘
		Chessboard chessboard = new Chessboard();
		chessboard.initChessboard();
		//打印棋盘
		chessboard.printChessboard();
		//下一个黑子
		chessboard.setChessboard(5,5,"○");
		System.out.println();
		//打印棋盘
		chessboard.printChessboard();
		System.out.println();
		//获得棋盘对象中的棋盘数组并打印
		String[][] chessboard2 = chessboard.getChessboard();
		for(String[] x : chessboard2){
			for(String y : x){
				System.out.print(y);
			}
			System.out.println();
		}
	}
	*/
	
}

Gobang.java

import java.util.Scanner;

public class Gobang{

	//包含棋盘类Chessboard
	private Chessboard chessboard;
	private int posX;//落子横坐标
	private int posY;//落子纵坐标


	//空参构造函数
	public Gobang(){}


	//游戏入口
	public static void main(String[] args){
		Gobang gobang = new Gobang();
		gobang.run();
	}

	//运行游戏
	public void run(){
		//游戏开始提示
		System.out.println("**********游戏开始**********");
		System.out.println("exit----->强行退出**********");
		System.out.println("**********游戏开始**********");
		System.out.println();
		

		//准备棋盘
		this.chessboard = new Chessboard();
		this.chessboard.initChessboard();
		this.chessboard.printChessboard();
		
		System.out.println("请按照x,y格式输入棋子坐标");
		Scanner scan = new Scanner(System.in);

		while(scan.hasNextLine()){
				

			//存储用户输入的字符串到input
			String input = scan.nextLine();
			//如果输入exit,强制退出游戏
			if(input.equals("exit")){
				System.out.println("您已经退出游戏");
				break;
			}
			//输入不合法,重新输入
			if(!isLegal(input)){
				continue;
			}
			
			//输入合法,相应位置放上黑棋
			if(!isFull()){
				this.chessboard.setChessboard(this.posX,this.posY, Chessman.BLACK.getChessman());
					
			}else{
				
				//棋盘已经占满棋子,和棋
				System.out.println("和棋了!是否再玩一盘?输入y重玩,输入其他退出游戏");
				String isReplay = scan.nextLine();
				//如果重玩,输入的是y
				if(isReplay.equals("y")){
					chessboard.initChessboard();
					chessboard.printChessboard();
					continue;
				}else{
					//如果输入的是非y,结束游戏
					break;
				}
			}
			
			
			//判断用户是否赢了
			if(isWin(posX, posY, Chessman.BLACK.getChessman())){
				this.chessboard.printChessboard();
				System.out.println("恭喜您赢了!是否再玩一盘?输入y重玩,输入其他退出游戏");
				String isReplay = scan.nextLine();
				//如果重玩,输入的是y
				if(isReplay.equals("y")){
					chessboard.initChessboard();
					chessboard.printChessboard();
					continue;
				}else{
					//如果输入的是非y,结束游戏
					break;
				}
			}else{
				
				//用户没有赢,机器就继续下棋,随机找一个空着的位置落子
				int posMachineX = (int)(Math.random()*(this.chessboard.CHESSBOARD_SIZE-1));
				int posMachineY = (int)(Math.random()*(this.chessboard.CHESSBOARD_SIZE-1));
				//得到棋盘数组
				String[][] chessboardArr = this.chessboard.getChessboard();
				while(chessboardArr[posMachineX][posMachineY]!="┼"){
					posMachineX = (int)(Math.random()*(this.chessboard.CHESSBOARD_SIZE-1));
					posMachineY = (int)(Math.random()*(this.chessboard.CHESSBOARD_SIZE-1));
					
				}
				
				//如果棋盘还没有满的话
				if(!isFull()){
					this.chessboard.setChessboard(posMachineX ,posMachineY , Chessman.WHITE.getChessman());
					
				}else{
				
					//棋盘已经占满棋子,和棋
					System.out.println("和棋了!是否再玩一盘?输入y重玩,输入其他退出游戏");
					String isReplay = scan.nextLine();
					//如果重玩,输入的是y
					if(isReplay.equals("y")){
						chessboard.initChessboard();
						chessboard.printChessboard();
						continue;
					}else{
						//如果输入的是非y,结束游戏
						break;
					}
				}
				

				//判断机器是否赢了
				if(isWin(posX, posY, Chessman.WHITE.getChessman())){
					this.chessboard.printChessboard();
					System.out.println("您输了!是否再玩一盘?(y/n)");
					String isReplay = scan.nextLine();
					if(isReplay.equals("y")){
						chessboard.initChessboard();
						chessboard.printChessboard();
						continue;
					}else{
						//输入的是非y,退出游戏
						break;	
					}
				}
			}
			this.chessboard.printChessboard();
			System.out.println("请按照x,y格式输入棋子坐标");
			
		}		
	}

	//判断输入是否合法
	public boolean isLegal(String input){
		
		//要判断输入的格式是否是x,y格式
		String[] posStrArr = input.split(",");
		
		try{
			this.posX = Integer.parseInt(posStrArr[0]) - 1;
			this.posY = Integer.parseInt(posStrArr[1]) - 1;
		}catch(Exception e){
			//输入的数字格式不正确,导致用逗号劈开的字符串并不是数字
			chessboard.printChessboard();
			System.out.println("请按照x,y的格式(注意范围1-15)输入: ");
			return false;
		}
		
		
		//判断用户输入的坐标是否超过棋盘范围
		if(this.posX < 0 || this.posX >= this.chessboard.CHESSBOARD_SIZE || 
				this.posY < 0 || this.posY >= this.chessboard.CHESSBOARD_SIZE){
			chessboard.printChessboard();
			System.out.println("输入坐标不在棋盘范围(1-15)内,请重新输入: ");
			return false;
		}

		//判断输入的位置上是否已经有棋子
		String[][] chessboard_tmp = this.chessboard.getChessboard();
		if(!chessboard_tmp[this.posX][this.posY].equals("┼")){
			chessboard.printChessboard();
			System.out.println("这个位置上已经有棋子,请重新输入: ");
			return false;
		}
			
		return true;	
	}

	//判断输赢,传入的是当前落下的棋子,可根据颜色判断赢方
	//思路:每行、每列、每斜着的棋子,拼接成串,看是否包含五个黑子或五个白子连着的情况
	public boolean isWin(int posX, int posY, String chessman){
		//五个棋子拼接成一字符串subString
		String subString = "";
		for(int i = 0; i < 5; i++){
			subString += chessman;
		}

		//获得当前对象chessboard的棋盘的二维数组
		String[][] chessboard_tmp = this.chessboard.getChessboard();
		
		//判断每一行和每一列是否有五子相邻的情况
		for(int i = 0; i < this.chessboard.CHESSBOARD_SIZE; i++){
			//临时字符串,用于拼接每一行的串
			String tmp_row = "";
			//临时字符串,用于拼接每一列的串
			String tmp_col = "";
			for(int j = 0; j < this.chessboard.CHESSBOARD_SIZE; j++){
				tmp_row += chessboard_tmp[i][j];
				tmp_col += chessboard_tmp[j][i];
			}
			if(tmp_row.contains(subString) || tmp_col.contains(subString)){
				return true;
			}
		}
		
		//判断起点是第一行的斜着的两个方向串是否有五子相邻的情况
		for(int k = 0; k < this.chessboard.CHESSBOARD_SIZE; k++){
			//临时字符串,拼接起点是第一行的斜着的串
			String tmp_left = "";//斜着左下
			String tmp_right = "";//斜着右下
			//斜着右下
			for(int i = 0, j = k; i < this.chessboard.CHESSBOARD_SIZE && j < this.chessboard.CHESSBOARD_SIZE; i++,j++){
				tmp_left += chessboard_tmp[i][j];
			}
			//斜着左下
			for(int i = 0, j = k; i < this.chessboard.CHESSBOARD_SIZE && j >= 0; i++,j--){
				tmp_right += chessboard_tmp[i][j];
			}
			if(tmp_left.contains(subString) || tmp_right.contains(subString)){
				return true;
			}
		}

		//判断起点是最后一行的斜着的两个方向串是否有五子相邻的情况
		for(int k = 0; k < this.chessboard.CHESSBOARD_SIZE; k++){
			//临时字符串,拼接起点是最后一行的斜着的串
			String tmp_left = "";//斜着左上
			String tmp_right = "";//斜着右上
			//斜着右下
			for(int i = this.chessboard.CHESSBOARD_SIZE - 1, j = k; i >= 0 && j >= 0; i--,j--){
				tmp_left += chessboard_tmp[i][j];
			}
			//斜着左下
			for(int i = this.chessboard.CHESSBOARD_SIZE - 1, j=k; i >= 0 && j < this.chessboard.CHESSBOARD_SIZE; i--,j++){
				tmp_right += chessboard_tmp[i][j];
			}
			if(tmp_left.contains(subString) || tmp_right.contains(subString)){
				return true;
			}
		}
		
		return false;
	}

	//判断棋盘是否已经占满棋子
	public boolean isFull(){
		
		//得到棋盘数组
		String[][] chessboardArr = this.chessboard.getChessboard();
		//判断是否和棋
		for(int i = 0; i < this.chessboard.CHESSBOARD_SIZE; i++){
			for(int j = 0; j < this.chessboard.CHESSBOARD_SIZE; j++){
				if(chessboardArr[i][j].equals("┼")){
					return false;
				}
			}
		}
		return true;
	}


}

猜你喜欢

转载自blog.csdn.net/ccnuacmhdu/article/details/82812832