疯狂java讲义课后习题答案.pdf(李刚)

所需积分/C币:37 2014-08-04 00:18:15 16.45MB PDF
收藏 收藏 13
举报

java 方面 编程思想想的课后的习题,是李刚老师的经典 不是我爸是李刚的李刚java 方面 编程思想想的课后的习题,是李刚老师的经典 不是我爸是李刚的李刚
第1章控制台五子棋 1.22“电脑”下棋 玩家输入了坐标,系统判断玩家没有游戏胜利后,就应该轮到“电脑”下棋,在本章的开头中我们 已经讲到,本章可以实现一个简单的电脑来进行游戏,只需要随便的产生棋盘坐标,就可以让“电脑” 在相应的坐标中下棋。如果电脑随机宀生的坐标中已经存在棋子,那么我们可以重新随机产生坐标,直 到产生的坐标上没有存在棋子为止。当“电脑”下完棋后,就可以使用同样的判断方式(判断是否五子 相连)来判断“电脑”所下的棋子是杏已经使得游戏胜利,如果游戏胜利,冋样地去提小玩家,电脑已 经胜利了。 在本章我们并不需要实现强大的人工智能“电脑”,只需要简单的随机产生坐标即可。 1.3创建游戏的各个对象 这里设计三个类来完成游戏的功能,棋盘类( Chessboard),游戏类( Gobang Game)与棋子类 ( Chessman)(枚举类),类的关系如图12所示,从图中可以看出, Chessboard依赖于 Gobang Game, gobang Game的改变,会影响到 Chessboard状态的改变,而 Chessman与 Gobang Game是一个聚合 关系。下面一一介绍。 Chessman Gob anggame WIN COUNT BLACK Chessman ant WhITE: Chessman sX 0 Y t 0 getchessman o: String chessboard Chessboard isvalid o boolean 0..1 start o void isReplay (: boolean computerDo ( int[] isWon O boolean t main Chessboard board String[][] BOARD SIZE int 22 initBoard o printBoard ( setBoard o getBoard o String[[] 图1.2五子棋类图 第1章控制台五子棋 1.3.1 Chessboard类 要进行五子棋游戏,必须有有一个棋盘,而这个类主要控制棋盘的初始化,输岀与及增加新的棋子 这个类包含以下方法 口 void initBoard(O,这个方法用于初始化棋盘,开始新的游戏时,应该调用此方法,初始化出一 个新的空棋盘 口 void printBoard(),此方法用于在控制台输出棋盘,各方每一完一颗棋子后,由于棋盘上棋子的 状态有改变,所以必须调用此方法重新输入棋盘 void setboard( int posX, int posY, String chessman),posX与posY是新下棋子的X与y坐 标, chessman是新下棋子的类型(黑子与自子),每下完一颗棋子后,通过调用此方法把棋 子设置到棋盘上。 口 Stringed getBoard(),返回棋盘,返同类型是保存棋盘的二维数组。 当我们需要初始化棋盘的时候,可以直接啁用 Chessboard的 inboard方法,我们需要考虑该方 法需要实现的功能:初始化棋盘。由于我们将棋盘看作是·个二维数组,因此 inboard就需要帮我们 去创建一个二维数组,创建二维数组可以使用以下代码。 代码清单: codelgobang srclorg\crazyitigobang Chessboard java ObjectId array =new Object[size]size for(int i=0; i< array length; i++)t for(int j=0; j< array[]. length; j++)i array= new object(; 以上代码创建一个固定大小(一维与二维大小)的二维数组,再通过嵌套循环为数组中的每一个元 素进行赋值。在游戏中如果我们进行了下棋的操作,可以直接改变这个数组的某一个元素值。在创建 Chessboard类时,我们就需要发挥面向对象的思维,在我们的稈序中,所有看到的或者想的事物,我 们郴可以将其抽象成只体的某个对象,并赋予一定的属性与行为。在改计对象的过程中,如果有某些事 物拿捏不准,不知如何设计属性或者行为,可以将其设计成接口或者抽象类。 Chessboard中提供了一个 printBoard的方法用于打印棋盘,在本章中,我们就需要将棋盘数组打 印到控制台中,因此该方法可以简单的调用 System. out. print去打印相关的字符串。需要注意的是,由 于 printBoard方法是没有参数的,因此我们需要为 Chessboard提供个二维数组变量,当调用 printBoard法的时候,将对象内的维数组打印,我们可以将 Chessboard看作一个有状态的Java 对象,有状态的Java对象可以理解成一个Java对象保存一些与该对象相关的状态属性,如果该对象没 有保存与该对象相关的状态属性,那么我们可以将这个对象看成一个无状态的Java对象 当外部调用 Chessboard的 seaBoard方法时,就可以将某个值设置到 Chessboard中的二维数组里 告诉 Chessboard玩家或者“电脑”在某个位置下了怎样的棋子 132 Chessman类 Chessman类是一个枚举类,此类是构造器私有的,不能直接创建,里面有 BLACK与WHTE两 个静态属性,代表黑子与白子枚举类,两个表态属性都是 Chessman类型的,要获取棋子,则通过这两 个属性调用以下的方法获取棋子: 口 String getChessmano,返回 String类型的棋子实例,“●”或者“○” 如果我们需要得到棋了的宇符串(“●”或者“○”),可以使用以下的代码。 代码清单: codelgobangsrclorgicrazyitigobang\Chessman. java Chessman. BLACK. getChessman(: 第1章控制台五子棋 1.3.3 Gobang Game类 Gobang Game类是进行游戏的类, Chessboard依赖于此类,此类搾制游戏的开始,重玩与结束, 并影响 Chessboard类。主要包含以下构造器与方法: 口 Gobang Gameo,默认无参数构造器。 口 Gobang Game( Chessboard chessboard),有参数构造器,以个 Chessboard实例去初始化 这个类。 口 boolean isvalid( String inputStr),此方法验证控制台的输入字符串是否合法,如果合法,返回 true,如果不合法,则返回 false,此方法抛出 Exception异常。 口 void start(),开始游戏。此方法抛出 Exception异常。 boolean is Replay( String chessman),是否重新廾始游戏,如果是,返回true,否则返回 false, 参数 chessman代表黑子或白子。 intl computerD(),计算机随机下棋,由计算机自动设置棋盘,并返回包含新下棋了位置ⅹ与 y坐标的i切数组类型。 口 boolean is Won( int pos x, int posY, String ico),判断输贏,参数p。sX与pOsY代表新下棋子 的ⅹ与y坐标,ico代表新下的棋子类型,如果赢了,返回true,香则返叫 false。 Gobang Game是我们工了棋游戏的主体类,游戏里面所有的处理都在该类中实现。 Gobang Game 屮的 is Valid方法用于验证控制台的输入,玩家主要在控制台输入下棋的坐标,下棋的坐标的字符申形 式为:Xy,我们需要对字符串进行处理得到ⅹ和y的值,如果玩家输入的字符串不符合系统要求,则 Jis Valid 方法返回 false,只有当该方法返回true的时侯,才会去修改 Chessboard的二维数组。 Gobang Game中提供了一个 start方法,用于游戏的开始,我们需要考虑游戏开始的行为,例如需 要初始化棋盘(调用 Chessboard的ini方法),需要开始从控制台读取玩家的输入信息、打印棋盘,验 证控制台输入的信息等,这些功能我们将在下血的章节中加以措述。 当轮到“电脑”下棋的吋候,我们需要随机生成电脑的下棋坐标, Gobang Game中的 computerD 方法用于随机产生坐标。 判断一局游戏是杳胜利,可以调用 Gobang Game的 isWon方法,该方法判断游戏是胜利,是五 了棋中最主要的方法,五了棋是否可以相连的所有逻辑,都会在该方法中实现。 is Won方法会在每次下 棋后(玩家下棋或者“电脑”下棋)调用。 到此,游戏中的三个对象已经设计完成,这三个对象中已绎定义好了各种方法,并在前面章节中详 细描述了各个方法的作用,在下面章节中我们将开始对这三个对象所定义的方法进行实现。当然,如果 需要做到更好的程序解耦,我们可以使用·些设计模式,例如将游戏规则写成·个具体的算法,可以使 用策略模式,如果需要产生岀不同的棋子(将搾制台换成其他界面),可以编写棋子工厂等。但是本章 主要目的是展现一个最简单的五子棋,因此本章中并个涉及任何只体的设计模式。 1.4棋盘类实现 在此类中,主要是用个Srng类型的二维数组 board去保棋盘, board代表棋盘的某个 位置(代表ⅹ坐标,j代表y坐标),如果此位置没有棋子,默认值为“十”,如果有棋子, board[]的 值为“●”或者“○”。用一个不可改变的常量 BOARD SIZE来表示棋盘的大小,所以保存这个棋盘 的是一个 BOARD S| ZE BOARD S|zE的二维数组。图1.3描述了为什么需要使用一个二维数组来代 表一个棋盘,如果把棋盘的一列当做一个数组,那么N列的棋盘就是一个二维数组,用数组能很好的存 储与表现这个棋盘。 第1章控制台五子棋 board[o] board[1] board[N] 图13棋盘与数组的关系 1.4.1初始化棋盘 在1.3节介绍过,此类主要是实现棋盘初始始化、输出、与史新,在这节便用代似一步一步地实现 各个功能。首先我们需要初始化棋盘的实现,看以下代码片段。 代码清单: codelgobanglsrclorg\crazyitlgobang\ Chessboard」java public void init Board i ∥初始化棋盘数组 board= new String[BOARD SIZEjBOARD SIZE]: ∥把每个元素赋值为“十”,用于控制台输出棋盘 for( int i=0; i< BOARD_SIZE; i++)i for( intj=0; j<BOARD SIZE; j++ board[[]="t 上面代码中, BOARD_SzE是代表棋盘的大小,用一个 String叩类型的二维数组来代表棋盘,创 建此数组后,通过迭代为为个数组元素的值赋为“十”来初始化棋盘。创建了棋盘数组后,如果需要定 位到棋盘的某个位置,只需要得到棋盘数组的一维值与二维值即可,例如处理玩家下棋动作的时候,可 以将数组中具体的某个“十”替换成具体的棋子字符串。 14.2输出棋盘 输出棋盘,只需要 Chessboard的 board属性(二维数组)的每一个值,打印到控制台中。如果可 以做到更好的扩展性,我们可以在二维数组中存放棋了对象,而不是简单的字符串,那么存放在二维数 组中的每一个棋子对象,都可以实现某个棋子接口或者继承棋子的抽象类,这样可以更好的做到游戏的 扩展性。当然,我们在本章为了简单起见,只在该二维数组中存放需要打印的字符串,打印时只需要得 到具体的某个二维数组的元素,将其打印即可。 代码清单: codelgobangIsrclorgicrazyitigobang Chessboard java public void printBoardo t ∥打印每个数组元素 for( int i=0; i< BOARD_SIZE; i++)t 第1章控制台五子棋 for( int j=0; j< BOARD_SIZE: j++)t 打印后不换行 System.out print( board[0) ∥每打印完一行数组元素就换行一次 System. out. print( in") 棋盘的输出与棋盘的初始化相类似,都是要遍历保存棋盘的数组,只不过是每遍历到一个元素都要 输岀来,注意到这里的输出方法用的是 System. out. print()前不是常用的 System. out println(),这里因为 System. out. printIng)方汯是输出后自动换行的,如果使用此方法,便达不到我们需要的效果,棋盘的输 出效果如图1.4。 图1.4控制台五子棋的棋盘 打印出来的效果,就好像在控制台中出现了个棋盘。 14.3获取棋盘 在 Chessboard中提供了一个 getBoard的方法,用于返回本对象的棋盘二维数组,该方法一股在 游戏类 Gobang Game中调用,游戏类得到棋盘的二维数组,可以用于判断棋盘中的某一个位置是否有 棋子或者计算游戏是杏胜利 getB。ard方法只需要将本对象中的 board(二维数组)返回即可,代码如下。 代码清单: code\gobang srclorgicrazyitigobang\Chessboard. java 返回棋盘 @ return返回棋盘 public Stringed getBoardo i return this board 到此,棋盘类的几个方法都已经实现,该类的主要功能是创建棋盘、打印棋盘等,实现的过程中涉 及了一些Java语言的基本操作,例如嵌套循环、创建二维数组等。在下面的小节中,我们将去实现游 戏的核心部分。 第1章控制台五子棋 1.5棋子枚举类实现 在某些情况下,一个类的属性是有限而且固定的(在某些情况下),例如本章中的棋子类,它只有 两个对象,票棋和白棋。这种实例有限而且固定的类,在Java里面称为枚举类,枚举类的关健字用enun 而不是cass,此类中有两个枚举属性 BLACK和WHTE,代表黑子与白子,代码实现如下 代码清单: codelgobang srclorgicrazyitl! gobang chessman」java public enum Chessman i BLACK( O),WHITE(O) private String chessman; 私有构造器 private Chessman(String chessman) this chessman chessman @ return黑棋或者白棋 public String getChessman(( return this chessman: 在上血的代码中,可以看到,枚举类是用enum关键字代替了cass关键字,看到此枚举类的构造 器的权限修饰符是 private,也是表明此类是不可以通过外部创建的,只能在此类的内部创建,这是为了 保证此对象只有黑子与白子两种类型。黑体代码是列出枚举值,实际上就是调用私用构造器创建此对象, 等同以下代码 public static final Chessman BLACK new Chessman("0) public static final Chessman WHITE= new Chessman(O") 由于 BLACK与WHTE两个属性是静态的,所以要获取黑了或者白子,可以通过以下代码来获得: Chessman. BLACK. getChessman (; Chessman. WHITE. getchessman( 在控制台屮,我们可以使用这种方式来确定棋子的字符串,如果我们需要在 sWing或者其他界面中 展示一个棋子,可能需要为具体的某个棋子保存相应的棋子图片,在本章中,由于棋子只是普通的两个 字符串,因此可以直接写成枚举对象即可。 如果你希望你的程能有更好的扩展性,笔者建议可以棖据情况建立棋子接凵,并提供白棋与黑棋的 实现类,我们在棋盘二维数组中存放的只是某个接口,而不是具体的类,这样,提高了程序的可扩展性, 在本小节的开头提到:在某些情况下,一个类中的属性有限并且是固定的。但是在我们开发的实际情况 中(特别是做企业应用),随着业务的不断变化,类的不可变几乎是不可能的。举个例了,如果需要将 本章中的五子棋迁移到 swing界面中,那么该棋子枚举类就不得不更改了。 虽然本章是为了做一个较为简单的五子棋,但更多的想向大家展现面向对象的思维。 1.6游戏类实现 木章中的游戏类是 Gogang Game,在该类中,主要控制游戏的廾始,重新廾始与结束,验让玩家 输入的合法性,判断游戏的输与赢,调用棋盘类来初始化棋盘,打印棋盘,使用棋子类去设置棋盘等 此类中有四个属性,两个int类型的posX与poxY,用来存储玩家现在输入的ⅹ与y坐标(x和y坐标 第1章控制台五子棋 是指玩家输入的数字对应棋盘数组中的一维值与二维值),一个默认值为5的int类型常量W| N COUNT 游戏胜利需要连接的棋子达到的连子数目,由」是五子棋,因此只需要5个棋子相连,游戏就胜利。还 有一个 Chessboard类型的变量 chessboard,用来表示棋盘,游戏中就只用到一个棋盘,该对象可以使 用初始化棋盘、打印棋盘、获得棋盘(数组)等方法 1.6.1使用 BufferedReader获取键盘输入 Buffered Reader是Java|O流中的一个字符包装流,它必须建立在字符流的基础之上。该对象可以 从输入流中读取文本,但标准输入: System. in是字节流,所以程序需要使用转换流 InputStream Reader 将其包装成字符流。所以程序中用于狄取键盘的输入采用以下代码创建 ∥获取键盘的输入 BufferedReader br= new BufferedReader(new InputStreamReader(System. in)); String inputstr= null; / br. read line:每当键盘输入一行内容按回车键,则输入的内容被b读取到 while( (inputStr br read()= null t *处理键盘输入 Bufferedreader中有个 headLine方法,此方法总是读取下行的输入字符串,如果没有下行 则返回nu。当得到玩家输入的字符后,我们可以进这些字符进行验证,验证完后,如果字符串符合系 统要求,可以在验证处使用 continue跳出本次循环。 如果需要读取输入,我们就需要为这些输入作岀不冋的判断,例如,玩家输入了y(继续游戏),那 么我们就需要判断玩家输入了y后程序所需要执行哪些操作,因此,这样会为whie循环体中增加许多 的近语句,这些i语句会影响程序的可读性,如果需要将这些近语句去掉,我们可以将每个i中的代码 抽取出来,作为只体的一个处理类。这样做不仅减少whie循环体中的代竹,而且可以使得程序史加清 断,程序的耦合度更低, While循环体中只负责读取玩家输入的字符串,而具体的处理则不必由该方法 来执行。由于本章中的代码与动作相对较少,因此)不涉及如何实现以上所说的处理模式,更深入的可 以查看“仿QQ游戏大厅”一章。 1.6.2验证玩家输入字符串的合法性 根据引言中提到的输入约定,玩家在控制台输入的字符串必须是以(x-y)的方式输入,还需要验证输 入的字符串是否能转换为数字,是否超越棋盘的边界(小于等于1,大于等于棋盘数组的长度),并且需 要判断该位置是否已经存在棋子,具体判断流程如图1.5所示。 输入 <是否做字 是否出范E 是否三经有棋于 图15验讦流稈 首先,X与y必须是一个数字,由以下代码验证 代码清单: code\gobang srclorgicrazyitigobang\Gobang Game」java ·10· 第1章控制台五子棋 将用户输入的字符串以逗号()作为分隔,分隔成两个字符串 String[ pos StrArr inputStr split(","); posX Integer parseInt( pos Str Arr[0])-1 posY=Integer parseInt( posStrArr[1])-1 1 catch(Number FormatException e chessboard. printBoard(o System。 out println("请以(数字,数字)的格式输入:" return false 当我们调用 Integer; parselnt方法将宁符串转换成一个 Integer类型的时候,如果需要转换的字符串 不能转换成某个数字,该方法将会抛出 NumberFormatEXception异常,我们可以使用 catch将该异 常捕获,提示玩家需要重新输入棋子坐标。除了判断玩家输入的字符串是否符合我们游戏所要求的格式 外,还需要判断玩家输入的坐标范闱,即该范围不可小于1并不可人于棋盘数组的最人值,例如棋盘是 10乘10,但玩家输入了11,那么将会抛出 ArraylndexOutofBoundsException异常,因此,x与y的 范围只能是大于1与小于N(棋盘的大小),如果超这个范围,则需要提示玩家重新输入,由以下代 码验证。 民码清单: codelgobanglsrclorg\crazyitigobang\ Gobang Game java ∥检查输入数值是否在范围之内 if( posx <0 posX >=Chessboard BOARD_ SIZE II posY<0 lI posY > Chessboard BOARD_SIZE ) i chessboard. printBoard( System. out. println("与Y坐标只能大于等于1与小于等于 + Chessboard BOARD SZE+",请重新输入:") return false 验证了输入坐标的合法性后,还需要验证玩家输入的坐标中是否已经存在棋了,我们通过 Chessboard对象中的 getBoard方法可以得到棋盘的维数组,根据玩家输入的坐标得到数组中的元 素,再判断元素是否已经是一个棋子(“●”或者“○”),如果该坐标中已经有棋子(元素值为“十”), 则提示玩家重新输入,由以下代码验证。 代码清单: codelgobang srclorg\crazyitigobang Gobang Game」java ∥检查输入的位置是否已经有棋子 String[n board chessboard getBoardo if( board[pos X][posY]!="+")C chessboard. printBoard( System. out. println("此位置已经有棋子,请重新输入:") return false 以上代码中,如果 board[不等于“十”(“十”是棋盘每个位置的默认值),则证明此位置有棋了 需要提示玩家重新输入。这里需要注意的是,如果没有前一个判断(判断输入的坐标是否超过棋盘范围), 那么通过棋盘数组获取某个元素时,就会抛出 ArrayIndexOutOfBoundsException异常。 1.6.3判断输贏 判断游戏输赢,需要在玩家输入了坐标并通过了合法性验证后(输入的坐标),再执行输赢的验证, 同样地,如果是“电脑”随杋生成的坐标,我们同样的需要进行输赢验证,因此,我们已经将判断输赢 的行为,独立成一个 isWon方法(详细请看133中的 Gobang Game类) 判断输赢在本章的程序中稍微复杂,有两种方法来判断输赢:

...展开详情
试读 127P 疯狂java讲义课后习题答案.pdf(李刚)
立即下载 低至0.43元/次 身份认证VIP会员低至7折
    抢沙发
    一个资源只可评论一次,评论内容不能少于5个字
    • 签到新秀

      累计签到获取,不积跬步,无以至千里,继续坚持!
    • 分享达人

      成功上传6个资源即可获取
    关注 私信 TA的资源
    上传资源赚积分,得勋章
    最新推荐
    疯狂java讲义课后习题答案.pdf(李刚) 37积分/C币 立即下载
    1/127
    疯狂java讲义课后习题答案.pdf(李刚)第1页
    疯狂java讲义课后习题答案.pdf(李刚)第2页
    疯狂java讲义课后习题答案.pdf(李刚)第3页
    疯狂java讲义课后习题答案.pdf(李刚)第4页
    疯狂java讲义课后习题答案.pdf(李刚)第5页
    疯狂java讲义课后习题答案.pdf(李刚)第6页
    疯狂java讲义课后习题答案.pdf(李刚)第7页
    疯狂java讲义课后习题答案.pdf(李刚)第8页
    疯狂java讲义课后习题答案.pdf(李刚)第9页
    疯狂java讲义课后习题答案.pdf(李刚)第10页
    疯狂java讲义课后习题答案.pdf(李刚)第11页
    疯狂java讲义课后习题答案.pdf(李刚)第12页
    疯狂java讲义课后习题答案.pdf(李刚)第13页
    疯狂java讲义课后习题答案.pdf(李刚)第14页
    疯狂java讲义课后习题答案.pdf(李刚)第15页
    疯狂java讲义课后习题答案.pdf(李刚)第16页
    疯狂java讲义课后习题答案.pdf(李刚)第17页
    疯狂java讲义课后习题答案.pdf(李刚)第18页
    疯狂java讲义课后习题答案.pdf(李刚)第19页
    疯狂java讲义课后习题答案.pdf(李刚)第20页

    试读已结束,剩余107页未读...

    37积分/C币 立即下载 >