Computercraft Lua多个进程同时运行

时间:2015-11-13 09:13:13

标签: lua minecraft computercraft

我正在尝试制作一个简单的隧道采掘龟。我试图在挖掘时显示关于乌龟的一些信息。例如,进度和燃料消耗。

挖掘实际隧道和显示信息的过程/功能应该同时运行,但此时它并没有真正做到这一点。

我尝试使用并行API,但它并没有像我想要的那样工作。

这是我到目前为止的代码:

--Starting Conditions--
HeightQuestion = true
WidthQuestion = true
LengthQuestion = true
BlocksToMine =0
EstBlocksDone =0
BlocksDone =0
BlocksToDo =0
screen = 0


function FuncFuel()
    if turtle.getFuelLevel() < 10 then
        turtle.refuel()
        print("fuel level: " .. turtle.getFuelLevel() ..  "/".. turtle.getFuelLimit())
    else
        print("fuel level: " .. turtle.getFuelLevel().. "/".. turtle.getFuelLimit())
    end 
end

function FuncHeight()
    while (HeightQuestion == true) do -- Height Question
        print("Height of tunnel?")
        IniHeight = tonumber(read())
        if IniHeight == nil then
            print( "Please answer with a number." )
        elseif IniHeight >= 2 then
            HeightQuestion = false
        elseif IniHeight == 1 then
            print( "The tunnel Height must be larger than one." )
        elseif IniHeight == 0 then
            print( "The tunnel Height can't be infinite." )
        else
            print( "The tunnel Height must be positive." )
        end
    end
    Height=IniHeight
 end

function FuncWidth()
    while (WidthQuestion == true) do -- Width Question
        print("Width of tunnel?")
        IniWidth = tonumber(read())
        if IniWidth == nil then
            print( "Please answer with a number." )
        elseif IniWidth > 0 then
            WidthQuestion = false
        elseif IniWidth == 0 then
            print( "The tunnel Width can't be infinite." )
        else
            print( "The tunnel Width must be positive." )
        end 
    end
    Width=IniWidth
end

function FuncLength()
    while (LengthQuestion == true) do -- Length Question
        print("Length of tunnel?")
        IniLength = tonumber(read())
        if IniLength == nil then
            print( "Please answer with a number." )
        elseif IniLength > 0 then
            LengthQuestion = false
        elseif IniLength == 0 then
            LengthQuestion = false
            InfiniteLength = true
            TorchesQuestion = false
            TorchSpacingQuestion = false
        else
            print( "The tunnel Length must be positive." )
        end
    end
    Length=IniLength
end

function FuncDig()
    while turtle.detect()==true do
        turtle.dig()
        BlocksDone = BlocksDone+1
        sleep(0.5)
    end
end

function FuncDigUp()
    while turtle.detectUp()==true do
        turtle.digUp()
        BlocksDone = BlocksDone+1
        sleep(0.5)
    end
end

function FuncDigDown()
    while turtle.detectDown()==true do
        turtle.digDown()
        BlocksDone = BlocksDone+1
        sleep(0.5)
    end
end

function FuncRight()
    turtle.turnRight()
    FuncDig()
    turtle.forward()
    turtle.turnLeft()
end

function FuncLeft()
    turtle.turnLeft()
    FuncDig()
    turtle.forward()
    turtle.turnRight()
end

function FuncUp()
    FuncDigUp()
    turtle.up()
end

function FuncDown()
    FuncDigDown()
    turtle.down()
end

function FuncForward()
    FuncDig()
    turtle.forward()
end



function SetMineScreen()
    BlocksToMine = IniHeight*IniWidth*IniLength
    BlocksToDo = BlocksToMine-BlocksDone
    PercentageDone= EstBlocksDone*100/BlocksToMine
    if turtle.getFuelLevel() < 10 then
        turtle.refuel(1)
    end
    term.clear()
    print("    ----------MineBot----------    \n")
    print("    ---------ACTIVATED---------    \n")
    print("    Total Amount To Do: " .. BlocksToMine .. "\n")
    print("    Total Amount Done: " .. BlocksDone ..  "\n")
    print("    Estimated Done: " .. EstBlocksDone ..  "\n")
    print("    Progress : " .. PercentageDone .. "\n")
    print("    Fuel Level: " .. turtle.getFuelLevel() .. "/" .. turtle.getFuelLimit() .. "\n")
    print("    <-- previous      Next-->")
end

function MineScreenProcess()
    while true do
        SetMineScreen()
        sleep(0.5)
    end
end

function FuncTunnel()
    FuncFuel()
    Width = Width - 1
    Height = Height - 1 
    for i=1, Length do
        for i=1,Height do
            FuncUp()    
        end
        for i=1, Height / 2 do
            for i=1,Width do
                FuncDig()
                FuncRight() 
                EstBlocksDone = EstBlocksDone+1
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
            FuncDown()
            for i=1, Width do               
                FuncDig()
                EstBlocksDone = EstBlocksDone+1
                FuncLeft()  
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
            FuncDown()
        end
        if Height % 2 == 0 then
            for i=1,Width do
                FuncDig()
                EstBlocksDone = EstBlocksDone+1
                FuncRight()     
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
            for i=1, Width do               
                FuncDig()
                FuncLeft()  
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
        elseif Height % 2 == 1 then
            for i=1,Width do
                FuncDig()
                EstBlocksDone = EstBlocksDone+1
                FuncRight()     
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
            FuncDown()
            for i=1, Width do               
                FuncDig()
                FuncLeft()  
                EstBlocksDone = EstBlocksDone+1
            end
            FuncDig()
            EstBlocksDone = EstBlocksDone+1
        end
        FuncForward()
    end
    turtle.turnRight()  
    turtle.turnRight()  
    for i=1, Length do
        turtle.forward()
    end
    turtle.turnRight()  
    turtle.turnRight()  
end


FuncHeight()
FuncWidth()
FuncLength()

parallel.waitForAll(MineScreenProcess(), FuncTunnel())
--FuncDig()

5 个答案:

答案 0 :(得分:1)

约翰已经说过了

  

Parallel需要使用Yield调用来允许不同的线程运行。

这几乎可以在Computercraft API的任何功能中完成。您不需要致电coroutine.yield()

假设您的函数MineScreenProcessFuncTunnel工作正常(我没有检查过他们的代码),您最后会调用parallel.waitForAll(...)或脚本启动执行。这一切都很好,也需要。但你的论点是错误的。

parallel.waitForAll(...)想要&#34;指针&#34;到你想要运行的功能。您没有将函数的指针作为参数传递。您正在传递函数的结果。

您可以尝试更改:

parallel.waitForAll(MineScreenProcess(), FuncTunnel())

为:

parallel.waitForAll(MineScreenProcess, FuncTunnel)

答案 1 :(得分:1)

与您的第一个函数FuncFuel

同时运行的进程无关
function FuncFuel()
    if turtle.getFuelLevel() < 10 then
        turtle.refuel()
        print("fuel level: " .. turtle.getFuelLevel() ..  "/".. turtle.getFuelLimit())
    else
        print("fuel level: " .. turtle.getFuelLevel().. "/".. turtle.getFuelLimit())
    end 
end

我会把它改成

function FuncFuel()
    if turtle.getFuelLevel() < 10 then
        turtle.refuel()
    end 
    print("fuel level: " .. turtle.getFuelLevel().. "/".. turtle.getFuelLimit())
end

使用FuncHeight功能行

elseif IniHeight == 0 then
    print( "The tunnel Height can't be infinite." )

如果他们用0回答,那么他们并不意味着infinite他们的意思是没有高度,你仍然不能拥有,所以将错误更改为用户,同样适用于{{1} }}

答案 2 :(得分:0)

试试这个:

while true do
  parallel.waitForAny(MineScreenProcess(), FuncTunnel())
end

基本上当一个人返回时,它会再次运行它们,因此它可以同时运行。

答案 3 :(得分:-1)

Parallel需要使用Yield调用来允许不同的线程运行。查看文档并添加Yield调用以允许其他线程运行。最常见的方法是每个循环添加一次。如果你的隧道函数每个循环产生一次,那么屏幕进程就可以运行了。每次屏幕进程都必须允许隧道功能恢复。

答案 4 :(得分:-1)

你无法在ComputerCraft中拥有真正的并行性。协同程序允许一些伪并行,但这就是你得到的。