【问题标题】:generating TTT game tree in lua在 lua 中生成 TTT 游戏树
【发布时间】:2013-12-13 08:49:53
【问题描述】:

我正在尝试在 lua 中编写井字游戏,并计划使用极小极大算法来决定非人类动作。第一步涉及从单个输入状态生成所有可能的板状态树。我试图递归地做到这一点,但似乎无法弄清楚如何。 (我认为)我在概念上理解这应该如何完成,但是在 lua 中实现它时遇到了麻烦。

我正在尝试按以下方式构建我的树。每个节点都是一个包含两个字段的列表。

{ config = {}, children = {} }

Config 是一个整数列表 (0,1,2),代表空、X 和 O,并定义 TTT 板状态。 Children 是一个列表节点,它是所有可能的棋盘状态,距离当前节点一移动。

这是我目前必须构建游戏树的函数

function tree_builder(board, player)
    supertemp = {}

    for i in ipairs(board.config) do

        --iterate through the current board state. 
        --for each empty location create a new node 
        --representing a possible board state

        if board.config[i] == 0 then
            temp = {config = {}, children = {}}

            for j in ipairs(board.config) do
                temp.config[j] = board.config[j]
            end

        temp.config[i] = player
        temp.children = tree_builder(temp, opposite(player))
        supertemp[i] = temp
        end

    end
    return supertemp
end

函数调用方式如下:

start_board = {config = {1,0,0,0}, children = {} }
start_board.children = tree_builder(start_board, 1)

当我注释掉函数的递归元素(“temp.children = builder(temp, reverse(player))”行)并且只生成第一级子级时。输出是正确的。当通过概念上相同的代码调用时(我使用的是love2D,因此格式不同):

for i in pairs(start_board.children) do
    print (start_board.children[i].config)

三个孩子是:

1,1,0,0
1,0,1,0
1,0,0,1

但是,一旦我添加了递归元素,以下是相同的三个子元素的输出

1,1,2,1
1,1,2,1
1,1,2,1

我一直在网上寻求帮助,我发现的大部分内容本质上是概念性的,或者涉及不同语言的实现。我相信我错误地实现了递归元素,但无法理解原因。

【问题讨论】:

  • 我没有仔细查看您的代码,但您似乎使用了全局变量 supertemptemp。请改用局部变量。

标签: algorithm recursion tree lua


【解决方案1】:

不明白opposite(player)temp.children = tree_builder(temp, opposite(player)) 中的含义。

请注意,递归需要结束条件。

这是我在你的结构下的解决方案:

local COL = 3
local ROW = 3   

local function printBoard( b )
    local output = ""
    local i = 1
    for _,v in ipairs(b.config) do
        output = output .. v .. ( (i % COL == 0) and '\n' or ',' )
        i = i + 1
    end
    print( output )
end 

local function shallowCopy( t )
  local t2 = {}
  for k,v in pairs(t) do
    t2[k] = v
  end
  return t2
end 

local MAX_STEP = COL * ROW  

local ING = 0
local P1 = 1
local P2 = 2
local TIE = 3   

local STATUS = { [P1] = "P1 Win", [P2] = "P2 Win", [TIE] = "Tied" } 

local start_board = { config = {P1,0,0,0,0,0,0,0,0}, children = {} }    

local function checkIfOver( board, step )
    local config = board.config
    local over = false
    --check rows
    for i=0,ROW-1 do
        over = true
        for j=1,COL do
            if 0 == config[i*COL+1] or config[i*COL+j] ~= config[i*COL+1] then
                over = false
            end
        end
        if over then
            return config[i*COL+1]
        end
    end
    --check cols
    for i=1,COL do
        over = true
        for j=0,ROW-1 do
            if 0 == config[i] or config[i] ~= config[i+COL*j] then
                over = false
            end
        end
        if over then
            return config[i]
        end
    end
    --check diagonals
    if config[1] ~= 0 and config[1] == config[5] and config[5] == config[9] then
        return config[1]
    end
    if config[3] ~=0 and config[3] == config[5] and config[5] == config[7] then
        return config[3]
    end
    if step >= MAX_STEP then    
        return TIE
    else
        return ING
    end
end 

local function treeBuilder( board, step )
    --check the game is over
    local over = checkIfOver( board, step )
    if  over ~= ING then
        printBoard( board )
        print( STATUS[over], '\n---------\n' )
        return
    end
    local child
    local childCfg
    for i,v in ipairs(board.config) do
        if 0 == v then
            child = { config = {}, children = {} }
            childCfg = shallowCopy( board.config )
            childCfg[i] = (step % 2 == 0) and P1 or P2 
            child.config = childCfg
            table.insert( board.children, child )
            treeBuilder( child, step + 1 )
        end
    end
end 

treeBuilder( start_board, 1 )

【讨论】:

  • 哇。非常感谢这个例子。相反(玩家)是一个函数,如果玩家为 2,则返回 1,如果玩家为 1,则返回 2。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 2020-12-01
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多