8

我将编写一个国际象棋服务器和一个或多个国际象棋客户端,我想以独立于编程语言的方式描述国际象棋规则(例如,基于游戏状态的允许移动,游戏完成时的规则)。这有点棘手,因为一些国际象棋规则(例如 King Castling、en passent、基于 3 个或更多重复移动的平局)不仅基于棋盘布局,而且基于移动的历史。

我希望格式为:

  • 文本的
  • 人类可读
  • 基于标准(例如 YAML、XML)
  • 易于用多种语言解析

但我愿意牺牲其中任何一个来换取合适的解决方案。

我的主要问题是:如何构建如此复杂的算法,以从数据格式对如此复杂的状态进行操作?

后续问题是:您能否提供一个以类似方式解决的类似问题的示例,可以作为起点?

编辑:为了响应清晰的请求——考虑我将有一个用 Python 编写的服务器,一个用 C# 编写的客户端和另一个用 Java 编写的客户端。我想避免在每个地方指定规则(例如允许的棋子移动、检查情况等)。我更愿意以独立于语言的方式指定这些规则一次。

4

9 回答 9

4

让我们想想。我们正在描述具有状态和行为的对象(位置和片段)。我们需要注意当前状态和从当前状态更改的一组不断变化的允许状态更改。

这就是编程。您不想要一些“元语言”,然后可以用常规编程语言进行解析。只需使用编程语言。

从普通语言中的普通类定义开始。让一切正常工作。那么,这些类定义就是国际象棋的定义。

除了极少数例外,所有编程语言都是

  • 文本
  • 人类可读
  • 合理标准化
  • 由它们各自的编译器或解释器轻松解析。

只需选择一种语言,您就完成了。由于处理细微差别需要一段时间,因此使用 Python 或 Ruby 之类的动态语言可能比使用 Java 或 C# 之类的静态语言更快乐。

如果你想要便携性。选择一种可移植的语言。如果您希望将语言嵌入到“更大”的应用程序中,那么请为您的“更大”应用程序选择语言。


由于最初的需求不完整,次要的小问题是如何让代码与多个客户端一起运行。

  1. 没有多种语言的客户。选一个。例如,Java 并坚持使用它。

  2. 如果您必须拥有多种语言的客户端,那么您需要一种可以嵌入到所有三种语言运行时环境中的语言。你有两个选择。

    • 嵌入解释器。例如,Python、Tcl 和 JavaScript 是轻量级解释器,您可以从 C 或 C# 程序中调用它们。这种方法适用于浏览器,它可以为您工作。Java,通过 JNI 也可以利用这一点。您可以使用一些 BPEL 规则引擎进行尝试。

    • 将解释器生成为单​​独的子进程。在您的应用程序和生成的解释器之间打开命名管道或套接字或其他东西。您的 Java 和 C# 客户端可以与 Python 子进程通信。您的 Python 服务器可以简单地使用此代码。

于 2008-10-11T16:48:28.680 回答
2

到目前为止,我从回复中收集到的信息:

对于棋盘数据表示:

请参阅有关 [棋盘表示]( http://en.wikipedia.org/wiki/Board_representation_(chess))的 Wikipedia 文章。

对于国际象棋移动数据表示:

请参阅有关Portable Game NotationAlgebraic Chess Notation的 Wikipedia 文章

对于国际象棋规则表示:

这必须使用编程语言来完成。如果一个人想减少在规则将以一种以上的语言实现的情况下编写的代码量,那么有几个选项

  1. 使用目标语言存在可嵌入解释器的语言(例如 Lua、Python)。
  2. 使用通用语言可以编译成的虚拟机(例如,用于 C# 的 IronPython,用于 Java 的 JPython)。
  3. 为目标语言可以与之通信的规则使用后台守护程序或子进程。
  4. 用每种目标语言重新实现规则算法。

尽管我希望有一种声明式语法可以被多种语言解释以强制执行国际象棋规则,但我的研究使我没有找到可能的候选者。我怀疑基于约束的编程可能是一种可能的途径,因为存在许多语言的求解器,但我不确定它们是否能真正满足这一要求。感谢大家的关注,也许将来会出现答案。

于 2008-10-13T22:22:23.233 回答
2

编辑:删除了过于冗长的答案。

简短的回答是,用 Python 编写规则。使用 Iron Python 将其连接到 C# 客户端,使用 Jython 连接到 Java 客户端。

于 2008-10-11T16:57:04.453 回答
2

这是回答后续问题:-)

我可以指出,最流行的国际象棋服务器之一在这里记录了它的协议(警告、FTP 链接,并且不支持被动 FTP),但只是为了向它编写接口,而不是出于任何其他目的。您可以开始为此服务器编写客户端作为学习经验。

相关的一件事是,好的国际象棋服务器提供的功能不仅仅是移动中继。

也就是说,有一个更基本的协议用于连接国际象棋引擎,记录在这里

哦,顺便说一句:维基百科的董事会代表

正如许多人已经指出的那样,董事会代表之外的任何事情都属于该计划本身。

于 2008-10-11T17:00:56.987 回答
2

已经有一种广泛使用的特定于国际象棋的格式,称为Portable Game Notation。还有智能游戏格式,它适用于许多不同的游戏。

于 2008-10-11T17:09:30.310 回答
2

我建议用 Prolog 来描述规则。

于 2008-10-11T17:14:31.173 回答
0

要表示棋盘的当前状态(包括转换可能性等),您可以使用 Forsyth-Edwards Notation,它会给您一个简短的 ascii 表示。例如:

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

将是开放的董事会位置。

然后,为了表示从某个位置开始的特定移动,您可以使用数字移动符号(如在对应国际象棋中使用的那样),它为您提供了棋盘上移动的简短(4-5 位)表示。

至于代表规则 - 我很想了解自己。目前,我的国际象棋引擎的规则只是用 Python 编写的,可能不像我想要的那样具有声明性。

于 2008-10-19T21:53:34.927 回答
0

我同意 ΤZΩΤZΙΟΥ 留下的评论,即。只需让服务器进行验证并让客户端提交潜在的移动即可。如果这不是您想要的设计方式,那么只需按照 S. Lott 和其他人的建议用 Python 编写规则。

真的不应该那么难。您可以将规则分为三大类:
- 依赖于棋盘状态的规则(易位、过路、平局、过牌、将死、通过过牌、是否轮到该玩家等)
- 规则适用于所有棋子(不能与您自己颜色的另一棋子占据相同的方格,移动到带有对手棋子的方格==捕获,不能移出棋盘)
-适用于每个单独棋子的规则。(棋子不能向后移动,城堡不能对角移动,等等)

每个规则都可以实现为一个函数,然后对于每个半步,通过查看它是否通过所有验证来确定其有效性。

对于提交的每个潜在移动,您只需按以下顺序检查规则:

  1. 拟议的举措可能有效吗?(这件作品的正确“形状”)
  2. 它符合董事会的限制吗?(这块被挡住了,它会从边缘移开吗)
  3. 此举是否违反国家要求?(这次行动后我是否受到检查?我是否通过检查?这是否合法?)

如果所有这些都正常,那么服务器应该接受这个移动是合法的……</p>

于 2008-11-18T03:48:18.067 回答
0

Drools 具有现代人类可读的规则实现——https: //www.jboss.org/drools/。他们有一种方式,用户可以在 Excel 中输入他们的规则。与其他工具相比,更多用户可以理解 Excel 中的内容。

于 2008-10-11T18:31:16.570 回答