步骤 4 - 随机化网格

在此步骤中,您将学习如何在 Lua 脚本中定义自己的函数。首先定义辅助函数,然后使用这些函数来随机化网格中棋子的初始位置。

要随机化网格:

  1. 定义一个返回整数数组的函数。

    在 Lua 中,您可以使用 function 关键字声明函数。

    在 grid:removeAllChildren() 之前将函数添加到脚本中。

    备注

    此函数从索引 1 开始数组。这在 Lua 中是惯例,但不是必需的。请记住,Kanzi Engine 函数,例如 getChild,从索引 0 开始。

    -- Declare a function that returns a list of integers from 1 to length.
    local function createArray(length)
        -- Initialize a variable that contains an empty array.
        local array = {}
        -- Fill the array with integers.
        for i = 1,length do
            array[i] = i
        end
        return array
    end
    
  2. 定义一个函数来随机化给定的整数数组,并将其添加到 createArray 函数之后。

    您可以使用内置的 Lua Math 库。

    -- Declare a function that randomizes the array argument with Fisher-Yates shuffle.
    local function shuffleArray(array)
        -- Loop backward from array length to 2.
        for i = #array, 2, -1 do
            -- Use the Lua Math library to create a random integer.
            local j = math.random(i) -- j is in range [1,i]
            -- Swap the array items at index i and j.
            array[i], array[j] = array[j], array[i]
        end
    end
    
  3. 并非所有拼图配置都是可解的15拼图。定义一个函数来检查给定的排列是否表示一个可解的拼图。如果拼图不可解,该函数将修改排列。在 shuffleArray 函数之后添加该函数。

    -- Declare a function that modifies the given permutation to make it a solvable puzzle.
    local function makeSolvable(permutation)
        local n = #permutation
        -- Count the number of inversions in the permutation.
        local inversions = 0
        for i = 1,n do
            for j = i+1,n do
                if permutation[i] > permutation[j] then
                    inversions = inversions + 1
                end
            end
        end
        -- If the puzzle is not solvable, swap two adjacent pieces to fix it.
        if inversions % 2 == 1 then
            permutation[1], permutation[2] = permutation[2], permutation[1]
        end
    end
    
  4. 要获得随机化网格,请使用网格创建中的辅助函数。

    ...
    
    -- Remove all grid items that were created in the project or by the earlier
    -- executions of the script.
    grid:removeAllChildren()
    
    -- Create a random permutation.
    local permutation = createArray(PieceCount)
    shuffleArray(permutation)
    -- Ensure that the permutation is a solvable puzzle.
    makeSolvable(permutation)
    
    ...
    
  5. 修改填充网格的脚本部分,以便应用置换。

    ...
    
    -- Create the grid children.
    for i = 1,PieceCount do
        -- Create a grid item.
        local piece = piecePrefab:instantiate("piece_" .. i)
    
        -- Assign the number to the piece.
        piece:setProperty(PieceIndexProperty, i)
    
        -- Set the grid coordinates of the new node.
        local p = permutation[i]
        -- Use integer division to get the row index and modulo to get the column index.
        local row = (p-1) // ColumnCount
        local column = (p-1) % ColumnCount
    
    ...
    

当您保存脚本并在 Preview 中点击 重新启动 (Restart) 时,脚本会以随机顺序填充网格中的15个部分。

../../_images/step4-result.png