Computer Craft のメモ
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
ただいまコメントを受けつけておりません。
dofile("lib_neko_0.1.1"); local ary = { 1, 2 }; nekoPosi(1, ary);
dofile("lib_neko_0.1.1"); local ary = { 1, 2, 3, 4 }; nekoNega(1, ary);
dofile("lib_turtle_0.2.3"); local function digBack() local rslt; turtle.turnLeft(); turtle.turnLeft(); rslt = myDig(); turtle.turnRight(); turtle.turnRight(); return rslt; end local function dir(name_, fromDir_, compareFunc_, detectFunc_, forwardFunc_, digFunc_, backFunc_, backDigFunc_) return { name = name_, fromDir = fromDir_, compareFunc = compareFunc_, detectFunc = detectFunc_, forwardFunc = forwardFunc_, digFunc = digFunc_, backFunc = backFunc_, backDigFunc = backDigFunc_, }; end local dirInfo = { }; dirInfo[0] = dir("top", 2, turtle.compareUp, turtle.detectUp, myUp, myDigUp, myDown, myDigDown); dirInfo[1] = dir("front", 4, turtle.compare, turtle.detect, myForward, myDig, myBack, digBack); dirInfo[2] = dir("bottom", 0, turtle.compareDown, turtle.detectDown, myDown, myDigDown, myUp, myDigUp); dirInfo[3] = dir("left", 4, turtle.compare, turtle.detect, myForward, myDig, myBack, digBack); dirInfo[4] = dir("back", 4, turtle.compare, turtle.detect, myForward, myDig, myBack, digBack); dirInfo[5] = dir("right", 4, turtle.compare, turtle.detect, myForward, myDig, myBack, digBack); local stack = { }; local function doCompare(posiFlg, compareFunc, detectFunc, slotAry) for i, slot in ipairs(slotAry) do turtle.select(slot); if compareFunc() then return posiFlg; end end if posiFlg then return false; else return detectFunc(); end end local function doNekosogi(posiFlg, dirCode, slotAry) local dcDI = dirInfo[dirCode]; if not doCompare(posiFlg, dcDI.compareFunc, dcDI.detectFunc, slotAry) then return; end if false == dcDI.digFunc() then return; end dcDI.forwardFunc(); table.insert(stack, { toDir = dirCode, progress = 0 }); local current = stack[table.maxn(stack)]; while true do if 6 <= current.progress then turtle.turnLeft(); if not dirInfo[current.toDir].backDigFunc() then error("Since the return path was shut by unbreakable block, turtle cannot move."); end dirInfo[current.toDir].backFunc(); table.remove(stack); current = stack[table.maxn(stack)]; if nil == current then break; end else if 3 <= current.progress then turtle.turnLeft(); end local curStaIdx = table.maxn(stack); if current.progress ~= dirInfo[current.toDir].fromDir then local cpDI = dirInfo[current.progress]; if doCompare(posiFlg, cpDI.compareFunc, cpDI.detectFunc, slotAry) then if cpDI.digFunc() then cpDI.forwardFunc(); table.insert(stack, { toDir = current.progress, progress = 0 }); current = stack[table.maxn(stack)]; end end end stack[curStaIdx].progress = stack[curStaIdx].progress + 1; end end end -- dirCode : 0(top), 1(front), 2(bottom) function nekoPosi(dirCode, slotAry) doNekosogi(true, dirCode, slotAry); end -- dirCode : 0(top), 1(front), 2(bottom) function nekoNega(dirCode, slotAry) doNekosogi(false, dirCode, slotAry); end
dofile("lib_log"); userEventHandler = nil; local function myPlace(para1) if para1 == 0 then return turtle.placeUp(); elseif para1 == 1 then return turtle.place(); elseif para1 == 2 then return turtle.placeDown(); end end local function myThrow(para1, para2) if para1 == 0 then return turtle.dropUp(para2); elseif para1 == 1 then return turtle.drop(para2); elseif para1 == 2 then return turtle.dropDown(para2); end end local function myExcavate(para1) if para1 == 0 then if turtle.detectUp() then for i = 1, 40 do turtle.digUp(); sleep(0.5); if not turtle.detectUp() then return true; end end return false; else return true; end elseif para1 == 1 then if turtle.detect() then for i = 0, 9 do turtle.dig(); sleep(0); if false == turtle.detect() then return true; end end for i = 0, 9 do turtle.dig(); sleep(0.5); if false == turtle.detect() then return true; end end return false; else return true; end elseif para1 == 2 then if turtle.detectDown() then return turtle.digDown(); else return true; end end end function myDigUp() return myExcavate(0); end function myDig() return myExcavate(1); end function myDigDown() return myExcavate(2); end local function myZzz(para1) sleep(para1 / 1000); end local function myOutput(para1, para2) local dir = { [0] = "top", [1] = "front", [2] = "bottom", [3] = "left", [4] = "back", [5] = "right" }; if para2 == 1 then rs.setOutput(dir[para1], true); else rs.setOutput(dir[para1], false); end end local function mySuck(para1) if para1 == 0 then return turtle.suckUp(); elseif para1 == 1 then return turtle.suck(); elseif para1 == 2 then return turtle.suckDown(); end end local function myAttack(para1) if para1 == 0 then return turtle.attackUp(); elseif para1 == 1 then return turtle.attack(); elseif para1 == 2 then return turtle.attackDown(); end end function refuelPrompt(moveFunc) local firstTime = true; while true do local rslt, msg; if nil ~= moveFunc then rslt, msg = moveFunc(); else if firstTime then firstTime = false; rslt = false; msg = "Out of fuel"; else return true; end end if not rslt and msg == "Out of fuel" then print("Out of fuel. please select [r]efuel or [q]uit."); print("(r/q)"); local ch = read(); if "q" == ch then print("Are you sure you want to stop the script?"); print("(y/n)"); ch = read(); if "q" == ch then error("out of fuel."); end elseif "r" == ch then local selSlot = 1; while true do print("Please type current selected slot number."); ch = read(); local num = tonumber(ch); if nil ~= num and 1 <= num and num <= 16 then selSlot = num; break; else print("Wrong input. Please retry."); end end while true do print("please set fuel item and type slot number."); print("When you finish refueling, Please type q."); print("FuelLevel = " .. turtle.getFuelLevel()); ch = read(); local num = tonumber(ch); if nil ~= num and 1 <= num and num <= 16 then turtle.select(num); local fRslt, fMsg = turtle.refuel(); if not fRslt then print(fMsg); end elseif "q" == ch then turtle.select(selSlot); break; else print("Wrong input. Please retry."); end end end else return rslt, msg; end end end local function myMove(dirName, moveFunc, detectFunc, attackFunc) local rslt, msg; while true do --rslt, msg = moveFunc(); rslt, msg = refuelPrompt(moveFunc); if rslt then return true; else if moveFunc == turtle.back then turtle.turnRight(); turtle.turnRight(); end if detectFunc() then if moveFunc == turtle.back then turtle.turnLeft(); turtle.turnLeft(); end return false; else for i = 0, 9 do attackFunc(); attackFunc(); attackFunc(); if moveFunc == turtle.back then if true == turtle.forward() then turtle.turnLeft(); turtle.turnLeft(); return true; end else --if true == moveFunc() then if true == refuelPrompt(moveFunc) then return true; end end end if moveFunc == turtle.back then turtle.turnLeft(); turtle.turnLeft(); end while true do print("move [" .. dirName .. "] failed. retry? (y/n)"); local input = read(); if "y" == input then break; elseif "n" == input then error("program stopped by user request."); else print("wrong input. type y or n."); end end end end end end function myForward() return myMove("forward", turtle.forward, turtle.detect, turtle.attack); end function myBack() return myMove("back", turtle.back, turtle.detect, turtle.attack); end function myUp() return myMove("up", turtle.up, turtle.detectUp, turtle.attackUp); end function myDown() return myMove("down", turtle.down, turtle.detectDown, turtle.attackDown); end local function myUserEvent(para1) if nil ~= userEventHandler then userEventHandler(para1); end end local cmdInfo = { f = { paraCnt = 0, func = myForward; }, -- [f]orward b = { paraCnt = 0, func = myBack; }, -- [b]ack l = { paraCnt = 0, func = turtle.turnLeft; }, -- turn [l]eft r = { paraCnt = 0, func = turtle.turnRight; }, -- turn [r]ight u = { paraCnt = 0, func = myUp; }, -- [u]p d = { paraCnt = 0, func = myDown; }, -- [d]own s = { paraCnt = 1, func = turtle.select; }, -- [s]elect p = { paraCnt = 1, func = myPlace; }, -- [p]lace t = { paraCnt = 2, func = myThrow; }, -- [t]hrow = drop e = { paraCnt = 1, func = myExcavate; }, -- [e]xcavate = dig z = { paraCnt = 1, func = myZzz; }, -- [z]zz = sleep o = { paraCnt = 2, func = myOutput; }, -- set [o]utput (redstone) k = { paraCnt = 1, func = mySuck; }, -- suc[k] a = { paraCnt = 1, func = myAttack; }, -- [a]ttack v = { paraCnt = 1, func = myUserEvent; }, -- user e[v]ent }; local function getParam(command, idx) local buff = ""; local ch = ""; for i = idx, command:len() do ch = command:sub(i, i); if ch == "," then if buff == "" then return nil, i + 1; else return tonumber(buff), i + 1; end elseif nil ~= string.find("0123456789", ch, 1, true) then buff = buff .. ch; else if buff ~= "" then return tonumber(buff), i; end end end if buff == "" then return nil, command:len() + 1; else return tonumber(buff), command:len() + 1; end end local function get1Cmd(command, idx) local cmd = string.sub(command, idx, idx); local para1, para2, nextIdx, paraCnt; if nil ~= cmdInfo[cmd] then paraCnt = cmdInfo[cmd].paraCnt; else error("unknown command [" .. cmd .. "]"); end if -1 == paraCnt then return nil, nil, nil, idx + 1; elseif paraCnt == 0 then return cmd, nil, nil, idx + 1; elseif paraCnt == 1 then para1, nextIdx = getParam(command, idx + 1); return cmd, para1, nil, nextIdx; elseif paraCnt == 2 then para1, nextIdx = getParam(command, idx + 1); para2, nextIdx = getParam(command, nextIdx); return cmd, para1, para2, nextIdx; end end local function checkLoop(command) local kBgn = {""}; local loopInfo = {}; local ch, repeatCnt, nextIdx, kBgnIdx; for i = 1, command:len() do ch = command:sub(i, i); if "(" == ch then table.insert(kBgn, i); elseif ")" == ch then repeatCnt, nextIdx = getParam(command, i + 1); loopInfo[i] = { beginIdx = table.remove(kBgn), endIdx = i, nextIdx = nextIdx, repeatCnt = repeatCnt, currentCnt = 0 }; i = nextIdx; end end return loopInfo; end function doCommand(command) command = command .. " "; local loopInfo = checkLoop(command); local cmd, para1, para2, nextIdx, ch; local i = 1; while true do ch = command:sub(i, i); if ")" == ch then loopInfo[i].currentCnt = loopInfo[i].currentCnt + 1; if loopInfo[i].repeatCnt <= loopInfo[i].currentCnt then loopInfo[i].currentCnt = 0; i = loopInfo[i].nextIdx; else i = loopInfo[i].beginIdx; end elseif " " == ch then i = i + 1; elseif "\n" == ch then i = i + 1; elseif "(" == ch then i = i + 1; else cmd, para1, para2, nextIdx = get1Cmd(command, i); i = nextIdx; if cmd ~= nil then cmdInfo[cmd].func(para1, para2); end end if command:len() <= i then break; end end end