面向对象设计问题

5
我将使用Java(或其他面向对象的语言)开发一个井字棋游戏。现在我脑海中已经有了一般设计的图像。
界面: 玩家,然后我将能够根据我想要的对手实现几个基于Player类的玩家类,例如随机玩家、智能玩家等。
类: Board类,带有一个二维整数数组,0表示空位,1表示我,-1表示对手。评估函数也将在此处,根据当前棋盘布局和轮到谁来返回下一个最佳移动。
裁判类,它将创建Board实例和两个玩家实例,然后开始游戏。
这是我的面向对象设计的大致想法。请问有人能给我任何批评吗?我发现这非常有益。非常感谢。
5个回答

8
当我思考对象结构时,我认为我的方法可以做以下两件事之一:
1)向“对象”询问问题
2)命令“对象”去执行某些操作
也就是说,向“棋盘”询问下一步最佳走法对我来说没有意义。棋盘应该只保存值并告诉你它的状态。
我可能会有一个专门确定给定“智能体”下一步最佳走法的对象。我们称之为“move_brain”。然后你可以说:“嘿,move_brain,在这个棋盘和这个智力水平下,下一步最佳走法是什么?”
现在你所概述的棋盘类具有许多职责:保存状态,允许用户移动,并考虑如何下一步移动。这太多责任了。
最后,我想说的是:鉴于这个程序不是非常庞大,几乎任何解决方案都可以。祝好运!

干杯,Greelmo。 思考这些问题的方式真的很棒。 我可能把太多东西放在一个对象中了。 - Kevin
不用担心。看看这本书,里面有一些非常棒的设计思路。 http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882 - Dexter

5

我会定义3个接口:

  • 游戏接口
  • 玩家接口
  • 棋盘接口

以下是每个类的简要概述:

游戏:

  • 玩家(只能容纳2个玩家)
  • 棋盘(可以是其他类或仅为2D矩阵)
  • 开始();
  • 下一个回合();
  • 重新开始();
  • 游戏是否结束();

玩家:

  • onTurn()(这是告诉你轮到你出牌的事件)
  • play(int x, int y);
  • onWin()(这个事件告诉你赢了)
  • onLose()(你输了)
  • onTie();(你平局了)

您可以按以下方式运行代码:

IPlayer meAsAPlayer = new UserPlayer(); //you'd have to implement this
                                        //as an "empty" class that would let the user
                                        //specify the actions
IPlayer AIPlayer = new AIPlayer(); //one AI class you'd have implemented
Game game = new Game(meAsAPlayer, AIPlayer);
game.start(); //this would run one game to the end
game.start(); //this would be the second game already

决定哪些游戏操作是正确的,哪些是错误的将由Game类来决定。如果玩家尝试进行错误的操作,它将阻止并再次调用该玩家的OnTurn()事件。

或者,您可以定义一个抽象类APlayer,而不是定义IPlayer接口,该抽象类只允许您进行正确的移动操作。


1
我认为使用“对手”和“我”来表示玩家的移动并不太准确。应该是“X”和“O”或第一和第二玩家。除此之外,你已经有了一个开端。输入处理在哪里进行?裁判还是棋盘上的方格或其他地方?另外,如何跟踪超过一局游戏的统计信息?
这只是一些想法。

我决定使用Referee类来处理用户输入(两个整数表示他们想要的下一步)。我决定再创建另一个类,名为Move类。你提到的最后一点是指多人游戏情况,对吗? - Kevin
是的 - 也看看 @Greelmo 的回答。他花了更多时间来思考,他的答案很有条理。 - Michael Dorgan

1
通常的想法是尽可能使对象自包含和单一化,这将让您更快更紧密地设计事物。
此外,不要害怕将最小的部分建模为自己的类实体。如果您可以从高级别直接对所有内容进行建模,则交互会简单得多。

这是否意味着让每个可能的对象都作为其自身的类? - Kevin

1

首先,您需要使用一些符号值,例如枚举或常量来表示棋盘上插槽的状态。


谢谢,使用枚举来表示棋盘上的棋子? - Kevin
其实,既然你这么说了,最好还是为棋子创建一个类,并将它们的实例放在棋盘上。例如,你可以创建一个名为 Piece 的类,并给它一个属性 Team,并将其设置为代表棋子所属的团队。棋盘只需要是一个 Piece 的二维数组即可。 - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接