井字游戏的 DFA

DFA for a Tic Tac Toe Game

我想制作一个 C++ 程序,为 Tic Tac Toe 制作 DFA,只接受先手获胜。我有工作代码,它正在生成 DFA。我还有一个计算状态数的函数。我得到 2,203,642 个状态,但我不确定这是对还是错。谁能告诉我应该有多少个州?

我不确定我是否完全理解问题,但我可以根据我的理解回答。

我们需要做的第一件事是模拟 Tic Tac Toe 游戏。没有一种正确或错误的方法可以做到这一点。我提出以下模型:Tic-Tac-Toe 游戏是一个长度为 9 的字符串,由 0、1 和 2 组成。 0s 对应无人认领的位置,1s 对应玩家 1 认领的位置,2s 对应玩家 2 认领的位置。字符串内的位置对应于从左到右,然后从上到下的位置。玩家 1 赢得这场比赛:122010001;输掉这场比赛:100222110;而且这个游戏无效111222111.

所以我们正在寻找一个 DFA 来识别玩家 1 获胜的有效游戏。如果 (a) 至少有一名玩家未获胜,并且 (b) 两名玩家的步数相同或玩家 1 比玩家 2 多一步,则游戏有效。在任何这些情况下,玩家 1 获胜:

  • 111SSSSSS
  • SSS111SSS
  • SSSSSS111
  • 1SS1SS1SS
  • S1SS1SS1S
  • SS1SS1SS1
  • 1SSS1SSS1
  • SS1S1S1SS

这里,S代表任意符号0, 1, 2。因此,这是制作 DFA 的一种方法:

  1. 编写一个 DFA,接受上面列表中 8 个正则表达式所描述的语言的联合。

  2. 从 1 复制 DFA,但玩家 2 获胜而不是玩家 1。现在,通过将状态从接受切换为不接受来否定 DFA,反之亦然。

  3. 通过考虑从步骤 1 和步骤 2 获得的 DFA 的交集来构建笛卡尔乘积机。此 DFA 现在可以识别“玩家 1 获胜而玩家 2 未获胜”。

  4. 现在构造一个新的DFA来识别走法数是否有效。我们将有 100 个状态:玩家 1 有 10 个移动计数,玩家 2 有 10 个移动计数。标记为接受对应于 #1 = #2 或 #1 = #2 + 1 的那些状态(应该有 20 个这样的状态)。

  5. 构造第 3 步和第 4 步中机器的笛卡尔积机器,使用交集来确定接受状态。由此产生的 DFA 准确识别玩家 1 获胜而玩家 2 失败的有效游戏。

注意:在每一步之后,您可以最小化生成的 DFA,以使笛卡尔积机器结构具有更少的状态。此外,您可以最小化步骤 5 中的机器,以获得接受该语言的尽可能小的 DFA。

可能不是很有帮助,但如果您编写一个程序来生成上面概述的 DFA,然后让该程序一路最小化 DFA,您应该会得到正确的答案。