忍者ブログ

cc-memo

Computer Craft のメモ

build craftの水門とタートルを使ったバケツフィラー(動画有り)

×

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

コメント

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

build craftの水門とタートルを使ったバケツフィラー(動画有り)


・空バケツで液体を汲む作業の自動化。バケツフィラーのタートル版。
・前回作った「autoRefuel」で面倒くさかった、溶岩バケツの補充を楽にする為に作成。
・この ”システム” から、どこかの「autoRefuel」施設までバケツを運ぶ部分は未完なので、
 まだ面倒くさいままですが。

・溶岩以外の液体でも使用可能。Build Craftのオイルとか。
・作っている途中で「Minecraftとタートルと僕」の中の人に、
 MoreTurtlesの「液体タートル」を使う方法を教えていただいたのですが、
 作りかけを捨てるのももったいないので、意地で作成。
 (早くこれを終わらせてえさやりタートル使いたい、、、)

【構成要素の説明】

[1] Build Craft の「水門」
 ・液体パイプで送り込んだ液体を「だばぁ」してくれるブロック。
 ・画像では見えていませんが、底面に液体パイプが接続されています。
 ・レッドストーン入力で、液体の設置を停止する機能有り。※
[2] 「turtle buckets filler」
 ・「turtle buckets filler」と名付けた自作のプログラムを「startup」として保存したタートル。
 ・スロット1に、サンプルとして溶岩バケツを配置する必要有り。
 ・タートルの直下の空間に「水門」によって、溶岩が設置されたらそれを空バケツで汲んで、
  出来上がった「溶岩バケツ」を手前のチェストに納品する。(サンプルは保持する。)
 ・空バケツも手前のチェストから取得する。
 ・空バケツが無い場合は、背面からレッドストーン動力を出力して、水門を停止させる。※
 ・一歩も動かないので、燃料不要。
[3] ブース用のチェスト
 ・[2] と [4] が、空バケツ/溶岩バケツをやり取りする為のチェスト
 ・(このチェストとそれに連なるタートル([2])と水門([1])から成る部分を、
  「ブース」と呼ぶことにしています。)
[4] 「turtle buckets filler manager」
 ・「turtle buckets filler manager」と名付けた自作のプログラムを
  「startup」として保存したタートル。
 ・スロット1に、サンプルとして「溶岩バケツ」を配置する必要有り。
 ・スロット2に、サンプルとして「空バケツ」を配置する必要有り。
 ・サンプル以外の「溶岩バケツ」を [3] から [5] へ運搬。
 ・サンプル以外の「空バケツ」を [6] から [3] へ運搬。
 ・点線で示した部分を前後に移動する。
  ⇒ので燃料を消費する。
 ・無駄な燃料消費を抑える為に、以下のような制御を入れてある。
  外部から空バケツが供給されなくなり、かつ、全ブースのどこからも溶岩バケツが
  納品されなくなった場合は、sleepを入れつつ、空バケツの供給を待つ。
 ・燃料が足りない場合には [5] のアイテムを ”つまみ食い” する機能有り。
  ⇒ [6] のチェストも ”つまみ食い” しないと駄目かと今気づいたが、もうリリースします。
   後で直すと思います。
[5] 溶岩バケツ用チェスト
 ・この ”システム” の外部に「溶岩バケツ」を「出荷」する為のチェスト
[6] 空バケツ用チェスト
 ・この ”システム” の外部から「空バケツ」を「入荷」する為のチェスト

※これを行わずに放置すると液体がどんどんなくなっていく気がしたので
そう実装しているが、ひょっとしたら気のせいかもしれない。
 ⇒水門を使い始めたころに、これから汲む予定だったBuildCraftの「オイル源」が、
  いつのまにか空っぽになっていることがあったのだが、
  それに水門が関係あるかもしれないし、無いかもしれない。

【動画です】


【以下ソース】
turtle buckets filler(startup として保存)
http://pastebin.com/z2S63hzL
-- turtle bucket filler
-- slot1 : sample backet (oil, lava, etc)
rs.setOutput("back", true);
while true do
  print("turtle bucket filler");
  for i=2, 16 do
    turtle.suck();
  end
  local foundIdx = -1;
  for i=2, 16 do
    turtle.select(i);
    if -1 == foundIdx then
      cnt = turtle.getItemCount(i);
      if 0 < cnt then
        if true == turtle.compareTo(1) then
          turtle.drop();
        else
          foundIdx = i;
          turtle.drop(cnt - 1);
        end
      end
    else
      turtle.drop();
    end
  end
  if -1 ~= foundIdx then
    rs.setOutput("back", false);
    while true do
      turtle.select(foundIdx);
      turtle.placeDown();
      if true == turtle.compareTo(1) then
        rs.setOutput("back", true);
        turtle.drop();
        print("filled one bucket.");
        break;
      end
      sleep(1);
      print("no liquid. retry.");
    end
  else
    print("no empty bucket.");
  end
  sleep(1);
end


turtle buckets filler manager(startup として保存)
http://pastebin.com/B5zBKRiT
local function dropAllExceptSample(sampleSlot, dropFunc)
  local keepCnt;
  for i = 1, 16 do
    turtle.select(i);
    if true == turtle.compareTo(sampleSlot) then
      if i == sampleSlot then
        keepCnt = 1;
      else
        keepCnt = 0;
      end
 
      local tmpRslt = dropFunc(math.max(0, turtle.getItemCount(i) - keepCnt));
      if not tmpRslt then
        return false;
      end
    end
  end
  return true;
end
 
local function dropItems(sampleSlot, dropCnt, dropFunc)
 
  turtle.select(sampleSlot);
  local norm = dropCnt;
  local keepCnt;
  for i = 1, 16 do
    if norm <= 0 then
      break;
    end
    local tgtCnt = 0;
    if i == sampleSlot then
      tgtCnt = math.max(0, turtle.getItemCount(i) - 1);
    else
      if turtle.compareTo(i) then
        tgtCnt = turtle.getItemCount(i);
      end
    end
    if 0 < tgtCnt then
      local feed = math.min(norm, tgtCnt);
      turtle.select(i);
      dropFunc(feed);
      turtle.select(sampleSlot);
      norm = norm - feed;
    end
  end
end
 
local function calcSpecificItemCount(sampleSlot)
  local count = 0;
  turtle.select(sampleSlot);
  for i = 1, 16 do
    if i == sampleSlot then
      count = count + turtle.getItemCount(i);
    elseif turtle.compareTo(i) then
      count = count + turtle.getItemCount(i);
    end
  end
  return count;
end
 
local function calcCntParBooth(sampleSlot, boothCount)
 
  local count = calcSpecificItemCount(sampleSlot);
  count = count - 1;
 
  local cntParBooth = math.floor(count / boothCount);
  if 0 < count % boothCount then
    cntParBooth = cntParBooth + 1;
  end
  return cntParBooth;
end
 
local function retryLoop(func, sleepSec, waitMsg)
  while true do
    if true == func() then
      break;
    end
    print(waitMsg);
    sleep(sleepSec);
  end
end
 
-- turtle bucket filler manager
-- slot1 : sample backet (filled : oil, lava, etc.)
-- slot2 : sample backet (empty)
local BOOTH_CNT = 4;
local FILLED_BKT_SLOT = 1;
local EMPTY_BKT_SLOT  = 2;
local OTHER_SLOTS = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
 
local filledBucketsReleaseFunc   = turtle.dropUp;
local emptyBucketsSupplementFunc = turtle.suck;
local filledBucketsSuckFunc      = turtle.suckUp;
 
local function returnFilledBuckets()
  return dropAllExceptSample(FILLED_BKT_SLOT, filledBucketsReleaseFunc);
end
 
local function refuelAction(requiredFuelLv, filledBucketsSuckFunc)
  while true do
    for i = 1, 16 do
      filledBucketsSuckFunc();
    end
    local cmpl = false;
    for _, i in ipairs(OTHER_SLOTS) do
      turtle.select(i);
      turtle.refuel();
      local tmp = turtle.getFuelLevel();
      print("  fuel level -> " .. tmp);
      if requiredFuelLv <= tmp then
        print("  refueling was completed.");
        cmpl = true;
        break;
      end
    end
    retryLoop(returnFilledBuckets, 5, "Inventory full? sleep(5)");
    if cmpl then
      break;
    else
      term.write("(sleep)");
      for i = 1, 20 do
        sleep(1);
        term.write(".");
      end
    end
  end
end
 
print("-- status check");
while true do
  if  0 == turtle.getItemCount(FILLED_BKT_SLOT) or
      0 == turtle.getItemCount(EMPTY_BKT_SLOT) then
    print("Set items as follows.");
    print("slot1 : filled bucket x 1");
    print("        (lava, oil, etc.)");
    print("slot2 : empty bucket  x 1");
    print("Hit enter key when ready.");
    read();
  else
    break;
  end
end
 
print("-- reset position");
for i=1, BOOTH_CNT * 2 do
  turtle.forward();
end
 
local earnedFlg      = true;
local distributedFlg = true;
local turn = 0;
while true do
  term.clear();
  term.setCursorPos(1, 1);
  print("---------------------------------");
  print("-- turtle bucket filler manager");
  print("---------------------------------");
  print("[turn] = " .. tostring(turn));
  local fuelLevel = turtle.getFuelLevel();
  print("[fuel level] = " .. fuelLevel);
  local tmp = BOOTH_CNT - 1;
  local requiredFuelLv = (math.min(tmp, 1) * 4 + tmp * 4) * (tmp / 2);
  print("[required  ] = " .. requiredFuelLv);
  if fuelLevel < requiredFuelLv then
    print("<< out of fuel. >>");
    refuelAction(requiredFuelLv, filledBucketsSuckFunc);
  end
  if not earnedFlg and not distributedFlg then
    print("[skip] capture filled buckets");
  else
    earnedFlg = false;
    print("capture filled buckets");
    for i = 1, BOOTH_CNT do
      print("  booth No. " .. tostring(i));
      for j = 2, i do
        turtle.back();
        turtle.back();
      end
      for j = 1, 16 do
        turtle.suckDown();
      end
      dropAllExceptSample(EMPTY_BKT_SLOT, turtle.dropDown);
      for j = 2, i do
        turtle.forward();
        turtle.forward();
      end
      if 1 < calcSpecificItemCount(FILLED_BKT_SLOT) then
        earnedFlg = true;
      end
      retryLoop(returnFilledBuckets, 5, "Inventory full? sleep(5)");
    end
    if earnedFlg then
      print("got new filled buckets.");
    else
      print("no new filled buckets.");
    end
  end
 
  for j = 1, 16 do
    emptyBucketsSupplementFunc();
  end
  if 1 < calcSpecificItemCount(EMPTY_BKT_SLOT) then
    distributedFlg = true;
  end
  if not earnedFlg and not distributedFlg then
    print("[skip] distribute empty buckets. (no empty buckets.)");
  else
    print("distribute empty buckets");
    dropAllExceptSample(FILLED_BKT_SLOT, filledBucketsReleaseFunc);
    local cntParBooth = calcCntParBooth(EMPTY_BKT_SLOT, BOOTH_CNT);
    if 0 < cntParBooth then
      distributedFlg = true;
    else
      distributedFlg = false;
    end
 
    if 0 < cntParBooth then
      local currentSlot = 2;
      for i = 1, BOOTH_CNT do
        print("  booth No. " .. tostring(i));
        if 1 < i then
          turtle.back();
          turtle.back();
        end
        currentSlot = dropItems(EMPTY_BKT_SLOT, cntParBooth, turtle.dropDown);
      end
      for i = 1, BOOTH_CNT do
        if 1 < i then
          turtle.forward();
          turtle.forward();
        end
      end
    end
  end
  if not earnedFlg and not distributedFlg then
    term.write("(sleep)");
    for i = 1, 20 do
      sleep(0.4);
      term.write(".");
    end
  end
  turn = turn + 1;
end
PR

コメント

プロフィール

HN:
kssr
性別:
非公開

Twitter

最古記事

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

アンテナ・ランキング