首先拖了一周才来更新Lab2实在有点不好意思。
Lab2训练的主要是ADT的设计,这里就简单介绍一下我对于ChessAndGo的设计思路:
首先在报告中有给出几个类:Action,Board,Piece,Player,Position,Game。先讲一下一个基本问题:如何判断一个棋手拥有棋盘上的某个子?如何判断棋盘上坐标是否有子?第一个问题:如何判断一个棋手拥有棋盘上某个子,我第一次想了两种思路,1是在piece类里面加一个player,用于表示属性,但是仔细想一下这个就会出错误,用现实的逻辑上去讲,棋就在那里,与它属于谁是无关的,也就是说小明拥有棋子A,小天拥有棋子A,棋子A并不会因为拥有者而发生变化,它就是棋子A。(当然这样做也是可行的,可能是我想法太绕了)。由此衍生出来了第二个思路:棋手应该知道自己拥有哪个棋子,这个思路是显而易见的,非常符合我们的第一思路。那么我就在棋手类里面设立一个position的容器,容器里面放置了所有棋盘上属于A的坐标,这样以来就解决了问题,当旗手落子到(2,1)坐标上时,(2,1)就应该添加到棋手的坐标容器里,当(2,1)上的棋子因为移动,被吃,被移除等操作不再属于A时,将坐标从A的坐标容器中移除即可。这样一来实际上就形成了一个映射关系:棋手的坐标->棋盘上具体位置->位置上的棋子,由此就实现了一一对应,对于后续开发也就比较简单了。棋盘上是否有子这个问题,我选择构造了一个全新的棋子empty,这个棋子用于代表“空”这个属性。解决了上面特别是第一个问题,整个ADT的构造也就解决了,下面介绍各种类的设计:
Action类,Action表示棋手拥有的动作,包括落子,吃子,移子,查询子,移除子等几个操作。这些操作上并没有太难的地方,都是一个思路:传递的参数包括:棋手,棋盘,子(落子需要),坐标(可能有多个)。 Action类的问题在于,如何让玩家能够调用这些动作。这里也有两个思路:1.玩家内置一个Action类调用动作。2.Action类的动作均为static静态动作。 我认为第一种会有一个问题:所有玩家可以调用的动作都是一样的,如果每个玩家都内置一个Action类的话,浪费资源。所以我选择了第二种思路。如果有其他思路欢迎评论。
Board类:Board类需要映射到现实的棋盘,那么就将棋盘直接看作一个数组即可(报告感觉有点提示,例如坐标上面就会引导向这方面想)Board初始化时应该给予一个较大的空间,我选用的是50x50的棋盘,然后有一个size数字,用于控制棋盘的显示大小(围棋棋盘和象棋棋盘显然不同大小,就需要从这里显示) 初始化时应该将棋盘上的每个点都放置一个空的棋子。
Game类及其子类:Game类作为设计的ChessGame和GoGame的父类,主要是整合一些资源,包括两位玩家,棋盘,棋子等。这里将国际象棋的所有棋子和围棋的黑白棋与空棋子都放入到了Game类中,任何游戏都可以随意调用里面的棋子。 关于ChessGame这里提一下,创建ChessGame时要注意将棋子分发给各位玩家(也就是分发坐标),并不能只将棋子放在棋盘上,这样是构成不了映射关系的。 子类还需要读取控制台输入的命令行,这里比较简单就不再赘述了。
综上来看,Lab2的p3要求设计的棋类游戏总体而言不算太难。但是要理清思路,寻找本质问题。在这里问题是映射关系,如何将棋手拥有的棋子映射到棋盘上是最需要解决的问题。
Lab3开发一周的感想:
完成了航班,高铁两个Entry,稍微能够感受到复用的作用了,如果我需要添加一个共性的操作,那么在底部添加显然比在各个子类中添加要容易一些。这给我们维护项目带来了较大的便利。
这里想讲一些GUI的一些设计小贴士,因为自己从来没有设计过类似的,所以基本上是从头开始。这次就航班而言的表格显然有两部分:始发航班,到达航班。那么需要设计两个Jtable,这里我推荐自定义布局,也就是空布局,因为想要添加的元素并不多,只是起到一个显示的作用,所以不需要太过美化,下面是现目前的效果图,之后应该还会优化:
个人觉得还是有些单调,但是只是作为学习了解用,之后的开发还需要更加详细的去了解使用。