-2

I am trying to make a simple tunnel mining turtle. I tried to display some information on the turtle while mining. For instance, the progress and the fuel consumption.

The process/function of mining the actual tunnel and displaying the information should run simultaneously, but at this point it doesn't really do that.

I try to use the parallel API but it just doesn't work the way I want it to.

Here's the code I have so far:

--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()
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
RubenDefour
  • 31
  • 1
  • 10

5 Answers5

1

As John already said

Parallel requires the use of Yield calls to allow different threads to run.

This is done in nearly any function from the Computercraft APIs. You don't need to call coroutine.yield().

Assuming that your functions MineScreenProcess and FuncTunnel are working fine (I didn't checked their code), you are calling parallel.waitForAll(...) at the end or your script to start the execution. That's all fine and also needed. But your arguments are wrong.

parallel.waitForAll(...) want's a "pointer" to the functions you want to run. You are not passing the pointer of the function as an argument. You are passing the result of your function.

You could try changing:

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

to:

parallel.waitForAll(MineScreenProcess, FuncTunnel)
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Mischa
  • 1,303
  • 12
  • 24
  • Actually, I'd recommend `parallel.waitForAny(...)` since `FuncTunnel` does return, unlike `MineScreenProcess` which is basically an infinite loop for calling `SetMineScreen`. – bit2shift Jul 21 '18 at 11:55
1

Not to do with processes running simultaneously but with your first function 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

I would change it to

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

Also with the FuncHeight function the lines

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

If they answer with 0 then they do not mean infinite they mean no height, which you still can't have, so change the error to the user, the same goes for FuncWidth

-1

Parallel requires the use of Yield calls to allow different threads to run. Review the documentation and add Yield calls to allow other threads to run. The most common way to do this is to add them once per loop. If your tunnel func yields once per loop then the screen process can run. The screen process will have to yield each time to allow the tunnel func to resume.

john elemans
  • 2,578
  • 2
  • 15
  • 26
  • What exactly is a yield call? is that the Coroutine.yiel() command? Doesn't the turtle stop mining when i do that? Do i have to Yield every time i mine a block (every time i mine a block i add 1 to an estimation of how many blocks i mined so far, this is necessary to get the progress.) – RubenDefour Nov 14 '15 at 09:33
  • Yes, try coroutine.yield(). And yes, yield() stops one thread to allow another to run. It's not true multi-processor parallelism. You have to decide on where to put yields() to get the results you are looking for. – john elemans Nov 14 '15 at 17:26
  • Oh, I should add; the yield() in the print routine will allow the mine thread to resume. – john elemans Nov 14 '15 at 17:40
  • Inform yourself about the [API](http://www.computercraft.info/wiki/Parallel_(API)) before coming to hasty conclusions. – bit2shift Jul 21 '18 at 12:10
-1

You can't have true parallelism in ComputerCraft. Coroutines allow for some pseudo-parallelism, but that is as far as you get.

Creator
  • 151
  • 1
  • 9
-1

Try this:

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

Basically when one returns it will run them again so it can constantly run both simultaneously.

  • Yea, no, that's not how it works. Please read the [documentation](http://www.computercraft.info/wiki/Parallel.waitForAny) before coming up with an answer. – bit2shift Jul 21 '18 at 12:04