②はsleep(0)の間隔ではうまくいかないので、sleep(0.5)の間隔でdig()する処理も追加した。
②
砂
砂
砂
亀石
石 石
石 石
石石石
※という対策を入れたがまだテストしてない。⇒
うまく出来ていない。時々停まってる。
「採掘を繰り返す」わけですが、岩盤を採掘しようとして失敗している場合もありうるので、適当なところで切り上げる。
岩盤が正面にあるような場所で正確に作業しようとすること自体に無理があるので、適当。
下を掘る場合
下に掘る場合は特に問題はないと思うので、1回だけ掘る。
[移動時]
ブロックにぶつかって移動できない場合は、エラーとはしない。
MOBに引っかかって、移動しようとした方向に移動できない場合は、移動が成功するまで同じ方向への移動を繰り返す。mobを排除する為に、攻撃(turtle.attack())も行う。とはいえ、所定の回数繰り返しても解決しない場合は、プレイヤーに継続するかあきらめるか決めてもらうようにする。
※書くだけ書いたがまだテストしてない。
[他①]
「ミニ言語」にturtle.suck()とturtle.attack()を追加。
k = suc[k]
a = [a]ttack
[他②]
「ミニ言語」に[v]という命令を追加。
ミニ言語で書いたスクリプトの途中で、Luaで書いた処理を呼び出すための仕組み。
v = user e[v]ent
「lib_turtle_x.x.x」を利用するプログラムに”イベントハンドラ”的な関数を書き、
「lib_turtle_x.x.x」の「userEventHandler」という変数にその関数の”ポインタ”を指定しておけば、vが処理されるタイミングで、その「”イベントハンドラ”」が呼ばれるという仕組み。
以下ソース
lib_turtle_0.2.1
dofile("lib_log");
userEventHandler = nil;
local function myPlace(para1)
if para1 == 0 then
turtle.placeUp();
elseif para1 == 1 then
turtle.place();
elseif para1 == 2 then
turtle.placeDown();
end
end
local function myThrow(para1, para2)
if para1 == 0 then
turtle.dropUp(para2);
elseif para1 == 1 then
turtle.drop(para2);
elseif para1 == 2 then
turtle.dropDown(para2);
end
end
local function myExcavate(para1)
if para1 == 0 then
if turtle.detectUp() then
repeat
turtle.digUp();
sleep(0.5);
until not turtle.detectUp()
end
elseif para1 == 1 then
if turtle.detect() then
for i = 0, 9 do
turtle.dig();
sleep(0);
if false == turtle.detect() then
return;
end
end
for i = 0, 9 do
turtle.dig();
sleep(0.5);
if false == turtle.detect() then
return;
end
end
end
elseif para1 == 2 then
turtle.digDown();
end
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
turtle.suckUp();
elseif para1 == 1 then
turtle.suck();
elseif para1 == 2 then
turtle.suckDown();
end
end
local function myAttack(para1)
if para1 == 0 then
turtle.attackUp();
elseif para1 == 1 then
turtle.attack();
elseif para1 == 2 then
turtle.attackDown();
end
end
local function myMove(dirName, moveFunc, detectFunc, attackFunc)
local rslt, msg;
while true do
rslt, msg = moveFunc();
if rslt then
return;
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;
else
for i = 0, 9 do
attackFunc();
attackFunc();
attackFunc();
if moveFunc == turtle.back then
if true == turtle.forward() then
turtle.turnLeft();
turtle.turnLeft();
return;
end
else
if true == moveFunc() then
return;
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
local function myForward()
myMove("forward", turtle.forward, turtle.detect, turtle.attack);
end
local function myBack()
myMove("back", turtle.back, turtle.detect, turtle.attack);
end
local function myUp()
myMove("up", turtle.up, turtle.detectUp, turtle.attackUp);
end
local function myDown()
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);
--log("getParam i = " .. i .. " / ch =[" .. ch .. "]");
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;
--log(idx .. " / " .. cmd);
if nil ~= cmdInfo[cmd] then
paraCnt = cmdInfo[cmd].paraCnt;
else
--log("unknown command [" .. cmd .. "]");
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 };
--log("loopInfo[" .. i .. "]");
--log(" beginIdx = " .. loopInfo[i].beginIdx);
--log(" endIdx = " .. loopInfo[i].endIdx);
--log(" nextIdx = " .. loopInfo[i].nextIdx);
--log(" repeatCnt = " .. loopInfo[i].repeatCnt);
--log(" currentCnt = " .. loopInfo[i].currentCnt);
i = nextIdx;
end
end
return loopInfo;
end
function doCommand(command)
command = command .. " ";
local loopInfo = checkLoop(command);
--for i, dat in pairs(loopInfo) do
--log("check loopInfo")
--log(" i = " .. i);
--log(" " .. dat.beginIdx .. " / " .. dat.endIdx .. " / " .. dat.repeatCnt);
--end
local cmd, para1, para2, nextIdx, ch;
local i = 1;
while true do
ch = command:sub(i, i);
--log("doCommand idx = " .. i .. " [" .. ch .. "]");
if ")" == ch then
--log("i = " .. i);
--log( loopInfo[i].beginIdx .. " / " .. loopInfo[i].endIdx .. " / "
-- .. loopInfo[i].nextIdx .. " / " .. loopInfo[i].repeatCnt);
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);
--log(" nextIdx = " .. nextIdx);
i = nextIdx;
if cmd ~= nil then
cmdInfo[cmd].func(para1, para2);
end
end
if command:len() <= i then
break;
end
end
end
kyoten
dofile("lib_turtle_0.2.1");
torchCnt = 0;
levelCnt = 0;
local function myUserEvent(para1)
if 0 == para1 then
torchCnt = 1;
elseif 1 == para1 then
torchCnt = torchCnt + 1;
if torchCnt == 2 or torchCnt == 7 or torchCnt == 9 or torchCnt == 14 then
doCommand("le1le1 rr ");
end
elseif 2 == para1 then
if torchCnt == 2 or torchCnt == 7 or torchCnt == 9 or torchCnt == 14 then
doCommand("s4 p0 s1 ");
end
elseif 3 == para1 then
doCommand("s2 t2,64 s3 t2,64 s5 t2,64 s6 t2,64 s7 t2,64 s8 t2,64 s9 t2,64"
.. "s10t2,64 s11t2,64 s12t2,64 s13t2,64 s14t2,64 s15t2,64 s16t2,64 ");
elseif 4 == para1 then
if 0 < levelCnt then
doCommand(string.rep("e2d e2d ", levelCnt));
end
elseif 5 == para1 then
doCommand(string.rep("e0u e0u ", levelCnt) .. " r s1p1 e0u p1p0 e2dl ");
elseif 6 == para1 then
if levelCnt == 0 then
doCommand("p2 ");
end
elseif 7 == para1 then
levelCnt = levelCnt + 1;
end
end
userEventHandler = myUserEvent;
print("slot1 : cobblestone x 64");
print("slot2 : ladder x 64");
print("slot3 : ladder x 16");
print("slot4 : torch x 64");
print("slot5 : chest x 2");
-- print("required fuel level : "); -- TODO
print("hit any key when ready.");
read();
doCommand("e2d (s1(p1l)4 s2e2d p0)64 (s1(p1l)4 s3 e2d p0)16 (e0u)6 s1p2 ");
doCommand("s1 (e1f)2 rp2p1e0up1p0ld ");
doCommand("e2d e2s1p2(p1l)4 u s5p2 le1fe2de2dus1p2(p1l)4us5p2lle1fl v3 ");
doCommand("("
.. " s1(v0 (e1f r v6 p1 e0u p1p0 v1 d v2 l)14 v6 p1 u p1p0 d l)4 rre1ll v4 v3 v5 "
.. " l e1fr s1 ("
.. " (e1fv6 e0up0d)13 e1fle1fl "
.. " (e1fv6 e0up0d)13 e1fre1fr "
.. " )6"
.. " (e1fv6 e0up0d)13 "
.. " ll (e1f)13 l (e1f)13 l v4 v3 v7 v5 "
.. " "
.. ")2 ");