描述国际象棋规则的推荐数据格式

发布于 2024-07-06 17:18:22 字数 546 浏览 16 评论 0原文

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

我更喜欢的格式是:

  • 文本
  • 的人类可读的
  • 基于标准(例如 YAML、XML)
  • ,可以轻松地用多种语言进行解析

,但我愿意为了合适的解决方案而牺牲其中任何一个。

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

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

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

I'm going to be writing a chess server and one or more clients for chess and I want to describe the rules of chess (e.g. allowable moves based on game state, rules for when a game is complete) in a programming language independant way. This is a bit tricky since some of the chess rules (e.g. King Castling, en passent, draws based on 3 or more repeated moves) are based not only on the board layout but also on the history of moves.

I would prefer the format to be:

  • textual
  • human readable
  • based on a standard (e.g. YAML, XML)
  • easily parsable in a variety of languages

But I am willing to sacrifice any of these for a suitable solution.

My main question is: How can I build algorithms of such a complexity that operate on such complex state from a data format?

A followup queston is: Can you provide an example of a similar problem solved in a similar manner that can act as a starting point?

Edit: In response to a request for clarity -- consider that I will have a server written in Python, one client written in C# and another client written in Java. I would like to avoid specifying the rules (e.g. for allowable piece movement, circumstances for check, etc.) in each place. I would prefer to specify these rules once in a language independant manner.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

橘香 2024-07-13 17:18:22

让我们想想。 我们用状态和行为来描述对象(位置和片段)。 我们需要记录当前状态以及一组不断变化的允许状态更改。

这就是编程。 您不需要某种可以用常规编程语言解析的“元语言”。 只需使用一种编程语言即可。

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

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

  • 文本
  • 人类可读的、
  • 合理标准化的、
  • 易于由各自的编译器或解释器解析的。

只需选择一种语言,就完成了。 由于需要一段时间才能弄清楚其中的细微差别,因此您可能会更喜欢 Python 或 Ruby 这样的动态语言,而不是 Java 或 C# 这样的静态语言。

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


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

  1. 没有多种语言的客户端。 选一个。 例如,Java,并坚持下去。

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

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

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

Let's think. We're describing objects (locations and pieces) with states and behaviors. We need to note a current state and an ever-changing set of allowed state changes from a current state.

This is programming. You don't want some "meta-language" that you can then parse in a regular programming language. Just use a programming language.

Start with ordinary class definitions in an ordinary language. Get it all to work. Then, those class definitions are the definition of chess.

With only miniscule exceptions, all programming languages are

  • Textual
  • Human readable
  • Reasonably standardized
  • Easily parsed by their respective compilers or interpreters.

Just pick a language, and you're done. Since it will take a while to work out the nuances, you'll probably be happier with a dynamic language like Python or Ruby than with a static language like Java or C#.

If you want portability. Pick a portable language. If you want the language embedded in a "larger" application, then, pick the language for your "larger" application.


Since the original requirements were incomplete, a secondary minor issue is how to have code that runs in conjunction with multiple clients.

  1. Don't have clients in multiple languages. Pick one. Java, for example, and stick with it.

  2. If you must have clients in multiple languages, then you need a language you can embed in all three language run-time environments. You have two choices.

    • Embed an interpreter. For example Python, Tcl and JavaScript are lightweight interpreters that you can call from C or C# programs. This approach works for browsers, it can work for you. Java, via JNI can make use of this, also. There are BPEL rules engines that you can try this with.

    • Spawn an interpreter as a separate subprocess. Open a named pipe or socket or something between your app and your spawned interpreter. Your Java and C# clients can talk with a Python subprocess. Your Python server can simply use this code.

始终不够爱げ你 2024-07-13 17:18:22

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

There's already a widely used format specific to chess called Portable Game Notation. There's also Smart Game Format, which is adaptable to many different games.

爺獨霸怡葒院 2024-07-13 17:18:22

我建议使用 Prolog 来描述规则。

I would suggest Prolog for describing the rules.

山色无中 2024-07-13 17:18:22

这是回答后续问题:-)

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

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

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

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

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

This is answering the followup question :-)

I can point out that one of the most popular chess servers around documents its protocol here (Warning, FTP link, and does not support passive FTP), but only to write interfaces to it, not for any other purpose. You could start writing a client for this server as a learning experience.

One thing that's relevant is that good chess servers offer many more features than just a move relay.

That said, there is a more basic protocol used to interface to chess engines, documented here.

Oh, and by the way: Board Representation at Wikipedia

Anything beyond board representation belongs to the program itself, as many have already pointed out.

阳光①夏 2024-07-13 17:18:22

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

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

Edit: Overly wordy answer deleted.

The short answer is, write the rules in Python. Use Iron Python to interface that to the C# client, and Jython for the Java client.

笛声青案梦长安 2024-07-13 17:18:22

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

对于棋盘数据表示:

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

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

请参阅有关便携式游戏符号 和 代数国际象棋表示法

对于国际象棋规则表示:

这必须是使用编程语言完成。 如果想要减少用多种语言实现规则的情况下编写的代码量,那么有几种选择:

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

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

What I've gathered from the responses so far:

For chess board data representations:

See the Wikipedia article on [chess board representations](http://en.wikipedia.org/wiki/Board_representation_(chess)).

For chess move data representations:

See the Wikipedia articles on Portable Game Notation and Algebraic Chess Notation

For chess rules representations:

This must be done using a programming language. If one wants to reduce the amount of code written in the case where the rules will be implemented in more than one language then there are a few options

  1. Use a language where an embedable interpreter exists for the target languages (e.g. Lua, Python).
  2. Use a Virtual Machine that the common languages can compile to (e.g. IronPython for C#, JPython for Java).
  3. Use a background daemon or sub-process for the rules with which the target languages can communicate.
  4. Reimplement the rules algorithms in each target language.

Although I would have liked a declarative syntax that could have been interpreted by mutliple languages to enforce the rules of chess my research has lead me to no likely candidate. I have a suspicion that Constraint Based Programming may be a possible route given that solvers exist for many languages but I am not sure they would truly fulfill this requirement. Thanks for all the attention and perhaps in the future an answer will appear.

木緿 2024-07-13 17:18:22

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

Drools has a modern human readable rules implementation -- https://www.jboss.org/drools/.
They have a way users can enter their rules in Excel. A lot more users can understand what is in Excel than in other tools.

旧情别恋 2024-07-13 17:18:22

为了表示棋盘的当前状态(包括易位可能性等),您可以使用
Forsyth-Edwards Notation,这将为您提供简短的 ASCII 表示。 例如:

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

将是开盘位置。

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

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

To represent the current state of a board (including castling possibilities etc) you can use
Forsyth-Edwards Notation, which will give you a short ascii representation. e.g.:

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

Would be the opening board position.

Then to represent a particular move from a position you could use numeric move notation (as used in correspondence chess), which give you a short (4-5 digits) representation of a move on the board.

As to represent the rules - I'd love to know myself. Currently the rules for my chess engine are just written in Python and probably aren't as declarative as I'd like.

榆西 2024-07-13 17:18:22

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

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

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

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

  1. 提议的举措是否可能有效? (这件作品的正确“形状”)
  2. 它符合棋盘的限制吗? (棋子是否被阻挡,它是否会移出边缘)
  3. 该移动是否违反了国家要求? (此移动后我是否处于检查状态?我是否通过检查移动?这是否合法?)

如果所有这些都可以,那么服务器应该接受该移动为合法......

I would agree with the comment left by ΤΖΩΤΖΙΟΥ, viz. just let the server do the validation and let the clients submit a potential move. If that's not the way you want to take the design, then just write the rules in Python as suggested by S. Lott and others.

It really shouldn't be that hard. You can break the rules down into three major categories:
- Rules that rely on the state of the board (castling, en passant, draws, check, checkmate, passing through check, is it even this player's turn, etc.)
- Rules that apply to all pieces (can't occupy the same square as another piece of your own colour, moving to a square w/ opponent's piece == capture, can't move off the board)
- Rules that apply to each individual piece. (pawns can't move backwards, castles can't move diagonally, etc)

Each rule can be implemented as a function, and then for each half-move, validity is determined by seeing if it passes all of the validations.

For each potential move submitted, you would just need to check the rules in the following order:

  1. is the proposed move potentially valid? (the right "shape" for the piece)
  2. does it fit the restraints of the board? (is the piece blocked, would it move off the edge)
  3. does the move violate state requirements? (am I in check after this move? do I move through check? is this en passant capture legal?)

If all of those are ok, then the server should accept the move as legal…

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文