特此说明:本文参考《疯狂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{//包含棋盘类Chessboardprivate 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()){//存储用户输入的字符串到inputString 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();//如果重玩,输入的是yif(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();//如果重玩,输入的是yif(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();//如果重玩,输入的是yif(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){//五个棋子拼接成一字符串subStringString 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;}}

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

  1. java下载pdf6_疯狂java讲义第6版 电子版(pdf格式)

    疯狂java讲义第6版pdf是李刚打造的经典java编程图书的最新版,为了帮助更多的读者能真正掌握Java编程,感受到Java语言的魅力,领会到Java编程的快乐,作者根据多年来的Java授课经验,精 ...

  2. 李刚疯狂java讲义第3_【Java】-NO.16.EBook.4.Java.1.009-【疯狂Java讲义第3版 李刚】- 泛型...

    1.0.0 Summary Tittle:[Java]-NO.16.EBook.4.Java.1.009-[疯狂Java讲义第3版 李刚]- 泛型 Style:EBook Series:Java Si ...

  3. 学习《疯狂Java讲义第4版》PDF+代码+课件+面试题分析

    学习java选择了<疯狂java讲义>最新的第四版,用了两个多月时间看完,一边阅读,一边敲代码.对Java有了不少新的认识.书中实例清晰明了,讲解也是娓娓道来.Java可以编写图形桌面系统 ...

  4. 《疯狂Java讲义》学习笔记 第六章 面向对象(下)

    <疯狂Java讲义>学习笔记 第六章 面向对象(下) 6.1包装类 基本数据类型 包装类 byte Byte short Short int Integer long Long char ...

  5. 《疯狂Java讲义》学习笔记 第六章 面向对象(下续)

    这里## 6.6 Java 9改进的接口 6.6.1 接口的概念 6.6.2 Java 9中接口的定义 6.6.3接口的继承 ==以下代码中纯在自己的很多错误== 6.6.4使用接口 6.6.5接口和 ...

  6. 刚从阿里、头条面试回来,疯狂java讲义第五版百度网盘

    Netty实战 无论是想要学习Spring 5 .Spark.Cassandra等这样的系统,还是通过学习Netty来构建自己的基于Java的高性能网络框架,或者是更加具体的高性能Web或者游戏服务器 ...

  7. 携程Java面试题,疯狂java讲义第三版

    开头 我们面试的时候 ,经常会被问这种到问题:Spring中bean的循环依赖怎么解决? Spring中bean的加载过程? spring相关的问题一直是大厂面试常问到的一个问题,也是一直困扰这我们, ...

  8. 开源新作!疯狂java讲义第四版

    一.内存与线程 1.内存结构 内存是计算机的重要部件之一,它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平.JVM的内存结构规定Java程序 ...

  9. 疯狂java讲义第五版电子书,一文说清!

    什么是 Arthas? Arthas 是一款开源在线诊断工具,采用命令行交互模式,支持 web 端在线诊断,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断.这是一款开源一年多 G ...

  10. 【社区图书馆】疯狂 Java 讲义:但凡种种,不一而足

    虽说酒香不怕巷子深,但是千里之外并不一定能闻到,有人看到这可能会感觉这不免有些杠的味道,其实我想表达的是好酒也需要宣传,比如今天我所要讲的这本书<疯狂Java讲义>. 这不是[赠书活动], ...

最新文章

  1. 开源图形库 FreeImage
  2. qt 最小化到托盘linux,Qt窗口最小化到托盘,托盘菜单控制
  3. abap 中modify 的使用
  4. 列举python中常用的数据类型_Python基础知识 变量和简单数据类型
  5. 一文读懂机器学习库graphLab
  6. 深入理解JavaScript中的闭包
  7. PostgreSQL数据库的安装与配置
  8. Java面向对象编程,绘制思维导图(全面详细整理)
  9. 现在的小程序,商家凭什么入驻你!
  10. WIFI驱动详细设计说明书
  11. java如何将mp4写入光盘_MP4文件刻录成DVD
  12. CSDN 社区年终总结|回顾 2021
  13. 内核手动释放内存方法
  14. css hack方法,css hack方式有哪些
  15. Qt “Could not create directory“ 问题的一种解决方法
  16. flex弹性盒子flex-grow 和flex的区别
  17. 浙大计算机学院多厉害,一张图,就能告诉你浙大到底有多牛!
  18. 我国地理信息系统产业发展前景
  19. asp获取电脑物理地址_编写Metasploit模块获取Xshell和Xftp明文密码
  20. 【Android项目实战 | 从零开始写app(十二)】实现app首页智慧服务热门推荐热门主题、新闻

热门文章

  1. DTU的功能以及性能
  2. oracle查看主备库延迟时间,【分享】Oracle 主备库容灾维护常用的九个SQL
  3. Script Insertion -客户端脚本植入攻击
  4. HUB75E 点阵屏的使用
  5. 数据结构与算法分析C++语言描述(第四版)图论学习记录
  6. 景联文科技:深度了解语音识别之发音词典及语音数据采集标注
  7. lms算法的verilog实现_LMS verilog实现的LMS的算法,另外有tb文件可以测试 代码正确 VHDL-FPGA- 252万源代码下载- www.pudn.com...
  8. 《逆袭大学——传给IT学子正能量》CSDN连载目录
  9. 微信加入群聊的测试设计点
  10. Android 开源UI框架汇总