忍者ブログ

cc-memo

Computer Craft のメモ

autoRefuel

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

autoRefuel

タートルの給油、面倒ですよね。


そこで今回ご紹介したいのが、この、


autoRefuel

・複数のタートルに、指定したfuelLevel分の給油を自動で行うプログラム。
・給油作業だけでなく、給油施設の構築も半自動で行ってくれる。
・給油施設が構築済みの場合は、それを壊さずに動作する。
・燃料用チェストへの燃料の投入は手動だが、そのへんはそのうち何とかするということで。
・今回は俺々フレームワークは使わなかった。(まだバグ取り中だし、、、)
・動作させるのに必要なアイテムは、
 チェスト:4、フロッピー:1、ディスクドライブ:1
・フロッピーを使用するが、
 ここに何らかのプログラムを入れておかなければいけないのではなく、
 「autoRefuel」の実行時にフロッピー内に自動的にstartupを作成する。
 フロッピー内に既にstartupが有る場合、いったん別名で退避して、作業終了時には元に戻す。
 (ようなコードを書いたが未テスト(またですか))
・「autoRefuel」の実行はマイニングタートルで行う必要が有る。
・ブランチマイニングのプログラムを試す時に、8機のタートルそれぞれに溶岩バケツ32杯分給油しているのだが、これがまじ面倒くさいので作った。

Tips
・「startupが保存されているフロッピーが入っているディスクドライブ」の隣でタートルが「起動」or「再起動」した時には、フロッピーの中のstartupで動作する。
 ⇒タートル内にstartupが有る場合でも、フロッピーのstartupが優先される。

以下ソース

autoRefuel
local ARMSG__IM_NOT_LABELED          = 1;
local ARMSG__GIVE_ME_FUEL_MORE       = 2;
local ARMSG__REFUELING_WAS_COMPLETED = 3;

local floppySource =
[[
local function setMsg(armsg)
  rs.setAnalogOutput("bottom", armsg);
end

local function freeze()
  while true do
    sleep(60);
  end
end

turtle.turnLeft();
turtle.turnLeft();

if nil == os.getComputerLabel() then
  print("I'm not labeled turtle.");
  setMsg(ARMSG__IM_NOT_LABELED);
  freeze();
end

local lastSlot = -1;
local selSlot;
while true do
  sleep(0);
  if ARG_FUEL_LEVEL <= turtle.getFuelLevel() then
    print("Refueling was completed.");
    setMsg(ARMSG__REFUELING_WAS_COMPLETED);
    freeze();
  end
  
  print("Give me fuel more.");
  setMsg(ARMSG__GIVE_ME_FUEL_MORE);

  selSlot = 1;
  if -1 ~= lastSlot and 1 <= turtle.getItemCount(lastSlot) then 
    selSlot = lastSlot;
  else
    for i = 1, 16 do
      if 1 <= turtle.getItemCount(i) then
        selSlot = i;
        break;
      end
    end
  end

  local itemCnt = turtle.getItemCount(selSlot);
  if 1 <= itemCnt then
    turtle.select(selSlot);
    local beforeLv = turtle.getFuelLevel();
    local rslt     = turtle.refuel(1);
    local afterLv  = turtle.getFuelLevel();
    local unitFLv  = afterLv - beforeLv;

    print("[status] : ARG_LV  = " .. ARG_FUEL_LEVEL);
    print("           afterLv = " .. afterLv);

    if not rslt then
      print("This is not fuel.");
      turtle.drop();
    else
      if 1 == turtle.getItemCount(selSlot) and 1 == itemCnt then
        -- Probably empty bucket.
        turtle.drop();
      else
        itemCnt = turtle.getItemCount(selSlot)
        if afterLv + unitFlv * itemCnt < ARG_FUEL_LEVEL then
          turtle.refuel(itemCnt);
        else
          local useCnt = (ARG_FUEL_LEVEL - afterLv) / unitFlv + 1;
          turtle.refuel(useCnt);
        end
      end
    end
  end
end
]];

local SLOT_CHEST  = 1;
local SLOT_FLOPPY = 2;
local SLOT_DRIVE  = 3;

print("slot1 : chest       x 2");
print("slot2 : floppy disk x 1");
print("slot3 : disk drive  x 1");
print("left  side : chest for fuels");
print("right side : chest for turtles");

local fuelLV;
while true do
  print("Input fuel level to start the script."); 
  term.write("fuel level >");
  local input = read();
  fuelLV = tonumber(input);
  if nil == fuelLV then
    print("Wrong input. Please retry.");
  else
    break;
  end
end

turtle.digUp();
turtle.up();

turtle.turnRight();
turtle.select(SLOT_CHEST);

turtle.place();
turtle.turnLeft();
turtle.turnLeft();
turtle.place();

turtle.turnRight();
turtle.select(SLOT_DRIVE);
turtle.placeUp();
turtle.select(SLOT_FLOPPY);
turtle.dropUp();

local diskPath = disk.getMountPath("top");

-- backup original startup.
local stPath = "/" .. diskPath .. "/startup";
local bkPath = "/" .. diskPath .. "/startup_bk_by_autoRefuel";
fs.delete(bkPath);
if fs.exists(stPath) then
  fs.move(stPath, bkPath)
end

local hFile = fs.open(stPath, "w");
hFile.writeLine("local ARMSG__IM_NOT_LABELED          = " .. ARMSG__IM_NOT_LABELED          .. ";");
hFile.writeLine("local ARMSG__GIVE_ME_FUEL_MORE       = " .. ARMSG__GIVE_ME_FUEL_MORE       .. ";");
hFile.writeLine("local ARMSG__REFUELING_WAS_COMPLETED = " .. ARMSG__REFUELING_WAS_COMPLETED .. ";");
hFile.writeLine("local ARG_FUEL_LEVEL = " .. fuelLV .. ";");
hFile.writeLine(floppySource);
hFile.close();

turtle.turnRight();
turtle.down();

local unlabeledFlg = false;

while true do
  turtle.down();
  turtle.select(1);
  turtle.suck();

  if 0 == turtle.getItemCount(1) then
    break;
  end

  turtle.placeUp();

  if "turtle" ~= peripheral.getType("top") then
    print("not turtle.");
    turtle.digUp();
    turtle.up();
    for i = 1, 16 do
      if 1 <= turtle.getItemCount(i) then
        turtle.select(i);
        turtle.drop();
      end
    end
    turtle.down();
  else
    print("turnOn.");
    peripheral.call("top", "turnOn");

    for i = 1, 16 do
      if 1 <= turtle.getItemCount(i) then
        turtle.select(i);
        turtle.drop();
      end
    end
    
    turtle.turnLeft();
    turtle.turnLeft();

    local lastSlot = -1;

    while true do
      sleep(0);
      local rcvdMsg = rs.getAnalogInput("top");
      if rcvdMsg == ARMSG__IM_NOT_LABELED then
        unlabeledFlg = true;
        print("Unlabeled turtle.");
        break;

      elseif rcvdMsg == ARMSG__GIVE_ME_FUEL_MORE then
        print("Fueling mode.");
        
        if not turtle.suck() then
          print("<< Chest for fuels is empty. >>");
          sleep(3);
        end
        
        if -1 ~= lastSlot and 1 <= turtle.getItemCount(lastSlot) then
          turtle.dropUp();
        else
          for i = 1, 16 do
            if 1 <= turtle.getItemCount(i) then
              turtle.select(i);
              lastSlot = i;
              turtle.dropUp();
              break;
            end
          end
        end

      elseif rcvdMsg == ARMSG__REFUELING_WAS_COMPLETED then
        print("Surplus fuel capture mode.");
        for i = 1, 16 do
          turtle.suckUp();
        end
        for i = 1, 16 do
          if 1 <= turtle.getItemCount(i) then
            turtle.select(i);
            turtle.drop();
          end
        end
        break;
      end
    end

    turtle.turnRight();
    turtle.turnRight();

    turtle.digUp();
    turtle.up();
    turtle.drop();
  end
end

-- restore original startup.
fs.delete(stPath);
if fs.exists(bkPath) then
  fs.move(bkPath, stPath)
end
fs.delete(bkPath);

turtle.down();

turtle.turnLeft();
print("autoRefuel was completed.");
if unlabeledFlg then
  print("* unlabeled turtle was not refueled.");
end
PR

コメント

プロフィール

HN:
kssr
性別:
非公開

Twitter

最古記事

(04/25)
(04/26)
(04/27)
(04/28)
(04/29)

アンテナ・ランキング