turtleutils.lua
turtleutils.lua
タートル便利関数集ですが、今のところ大したものではないです。
----------------------------------------------------------- -- turtleutils.lua -- タートルのちょっと便利?な関数周 -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- ----------------------------------------------------------- -- turtleのスロットを初期化するよ -- つうてもいまんとこ最初のスロットを選択するだけやで -- なんかふさわしい処理とか思いついたら追加するよ ----------------------------------------------------------- function resetSlot() turtle.select(1) end ----------------------------------------------------------- -- 形式化されたタートル(とコンピューター)の識別文字列を返すよ -- ID表示を統一しといたらわかりやすいかもしれんからな ----------------------------------------------------------- function getCompName() local label = os.getComputerLabel() if not label then label = 'no_label' -- labelはついてないこともあるねん end return string.format('[%03d]%s', os.getComputerID(), label ) end
turtlefuel.lua
turtlefuel.lua
タートル補給クラスです。
----------------------------------------------------------- -- @name turtlefuel(lua) -- @description タートルの燃料を扱う関数群 -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- os.loadAPI('/lib/apis/akaneutils') os.loadAPI('/lib/apis/turtleapis') ----------------------------------------------------------- -- タートルの燃料レベルを表す文字列を返すよ ----------------------------------------------------------- function getFuelLevelString() return 'FL:'.. tostring(turtle.getFuelLevel()) end ----------------------------------------------------------- -- 燃料補給を管理するオブジェクトを作って返すよ -- 前に作った補給関数なんかも含まれてるよ -- -- オブジェクトは燃料の最初の量と、補給量の合計を覚えてるよ -- その合計から、現在の燃料の量を引いて -- 燃料をどれだけ使ったか計算できるよ -- -- @param setting 燃料補給管理オブジェクトの設定テーブル -- @return 補給管理オブジェクト ----------------------------------------------------------- function new(setting) -- テーブル作成。デフォルト値も設定するよ ----------------------------------------------------------- -- @class table -- @name hokyu -- @description 燃料補給管理オブジェクト -- タートルの燃料補給と、燃料使用量を計算する機能があるよ -- @field direction 補給チェストがどっちにあるか -- @field wait 燃料確認間隔 -- @field threashold 燃料補給閾値 これより少なかったら補給するよ -- @field enough 燃料十分量 補給時はコレより多くなったら補給をやめるよ -- @field sleep 待機に使用する関数 ----------------------------------------------------------- local hokyu = { direction = const.FORWARD, wait = 60, threashold = 1000, enough = threashold, sleep = sleep, } -- クロージャOOP local self = hokyu -- private -- 燃料の最初の量と、補給量の合計 local total_fuel = turtle.getFuelLevel() -- 引数で渡された設定テーブルで上書き if setting then akaneutils.overwrite(hokyu, setting) end ----------------------------------------------------------- -- 燃料の総使用量を計算して返すよ -- -- 計算方法は、最初にあった量 + 総補給料 - 現在の燃料 やで -- どっかおかしかったら教えてな -- @return 燃料の総使用量 ----------------------------------------------------------- function hokyu.getTotalUsage() return total_fuel - turtle.getFuelLevel() end ----------------------------------------------------------- -- 燃料の総使用量に加算するよ -- @param fuel_level [in]加算する量 ----------------------------------------------------------- function hokyu.addUsage(fuel_level) total_fuel = total_fuel + fuel_level end ----------------------------------------------------------- -- 選択スロットから燃料を補給して、補給量を記憶するよ -- 補給する時はかならずこっちを使うようにしないとあかんで -- turtle.refuel()を直接使ってしまうと、補給量を記憶できんねん -- @param quantity 補給するアイテムの数 -- @return turtle.refuel()の戻り値 ----------------------------------------------------------- function hokyu.refuel(quantity) quantity = quantity or math.huge local pre_level = turtle.getFuelLevel() -- 補給前の燃料レベルを覚えとくよ local result = turtle.refuel() total_fuel = total_fuel + turtle.getFuelLevel() - pre_level -- 補給量を加算するで return result end ----------------------------------------------------------- -- hokyu()のループ内容やで -- -- @param take_fuel [in]燃料を補給する関数やで -- @param threashold [in]燃料補給する閾値やで -- @param enough [in]補給後の必要量や ----------------------------------------------------------- function hokyu.hokyu_(take_fuel, threashold, enough) if turtle.getFuelLevel() >= threashold then return end -- 燃料があったら何もしないよ -- 補給するよ print('hokyu suruyo ('.. getFuelLevelString() ..')') while true do -- 必要量を超えるまで補給するで local selected_slot = turtle.getSelectedSlot() -- 選択スロットを覚えとくよ turtle.select(16) -- インベントリの最後のスロットを使うよ if take_fuel() and self.refuel() then -- 燃料補給するよ print('hokyu sitayo ('.. getFuelLevelString() ..')') else print('hara hetta') -- 燃料ないよー end turtle.select(selected_slot) -- 乙女のたしなみや if turtle.getFuelLevel() >= enough then break end -- 必要量以上なら補給終わりや self.sleep(self.wait) end end ----------------------------------------------------------- -- 燃料がなかったら補給するよ<br> -- -- 燃料がthreasholdより低かったら補給を開始するよ。 -- enoughを超えるまで補給するよ。 -- 引数省略時はselfの値を使うよ -- -- @param threashold [in]燃料補給する閾値やで -- @param enough [in]補給後の必要量や ----------------------------------------------------------- function hokyu.hokyu(threashold, enough) -- 引数の初期化 threashold = threashold or self.threashold enough = enough or self.enough local takeFuel = turtleapis.SUCK[self.direction] while true do -- メインループや self.hokyu_(takeFuel, threashold, enough) self.sleep(self.wait) -- しばらく待機するで end end return self end
turtleapis.lua
turtleapis.lua
方向別のタートルAPIをまとめて管理するためのAPIです。
わりと誰でも作るやつだと思いますが、これには right / left / back なんかも追加してあって思ったより便利です。
ぼちぼち良く出来た気がします。
前進/後退のみで一歩移動する STEPF/STEPB を追加予定です。
----------------------------------------------------------- -- @file turtleapis(lua) -- @brief turtle API で方向別のものを簡易に取得できるテーブル集 -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- os.loadAPI('/lib/apis/const') ----------------------------------------------------------- -- 回転 ----------------------------------------------------------- TURN = { [const.RIGHT] = turtle.turnRight, [const.LEFT] = turtle.turnLeft, [const.BACK] = function() -- 真後ろに回転するやつや local turn = turtle.turnRight -- 右回りやで if not turn() then return false end -- 1回目の回転に失敗したらそこまでや return turn() -- 2回めの回転や end } ----------------------------------------------------------- -- タートルが右か左を向いて、関数を実行して、元の向きに戻る -- っていう関数を作って返すよ -- 後ろまで向くのもついでに作るけど、TURN[BACK]の途中で失敗するとどうなるかわからん -- そもそもタートルが回転に失敗することあるかどうか知らんけど -- -- @param func [in]実行する関数 -- @param direction [in]タートルが向く向き -- @return 作った関数 ----------------------------------------------------------- local function createSideFunc(func, direction) -- タートルが横向く関数や。とりあえず右向くもんとして設定しとくで local turn1st, turn2nd = TURN[const.RIGHT], TURN[const.LEFT] if direction == const.LEFT then -- 左に向く時は入れ替えればええで turn1st, turn2nd = turn2nd, turn1st elseif direction == BACK then -- 後ろ向く場合や turn1st = TURN[const.BACK] -- 後ろ向くで turn2nd = turn1st -- 同じ方向でまた後ろ向くで end -- 関数を作って返すよ return function(not_return) if not turn1st() then return false end -- 最初の横向くの失敗したらどうにもならん local result = func() -- 戻り値は関数の戻り値をそのまま返すんや if not not_return then turn2nd() end -- 引数が真でなければ元の向きに戻るよ return result, not_return and turn2nd end end ----------------------------------------------------------- -- 方向別のタートルAPIを格納したテーブルを作るよ -- 例えばDROP[方向]で必要な関数がもらえる感じのやつや -- -- 横向くやつは使い途が限られるかもなあ -- -- @param methods [in]FORWARD UP DOWNの順にAPIメソッドを格納した配列 -- @return 作ったテーブル ----------------------------------------------------------- local function createFuncsTable(methods) local methods_table = {} -- 前・上・下やで for i, v in ipairs { const.FORWARD, const.UP, const.DOWN } do methods_table[v] = methods[i] end -- 横向くやつや for _i, v in ipairs { const.RIGHT, const.LEFT, const.BACK } do methods_table[v] = createSideFunc(methods[1], v) end return methods_table end ----------------------------------------------------------- -- 方向別のタートルAPIメソッドを取得するためのテーブルやで -- DROP[方向]でメソッドがもらえるで DROP = createFuncsTable { turtle.drop, turtle.dropUp, turtle.dropDown, } -- 以下、似たようなのが続くで ATTACK = createFuncsTable { turtle.attack, turtle.attackUp, turtle.attackDown, } DIG = createFuncsTable { turtle.dig, turtle.digUp, turtle.digDown, } PLACE = createFuncsTable { turtle.place, turtle.placeUp, turtle.placeDown, } DETECT = createFuncsTable { turtle.detect, turtle.detectUp, turtle.detectDown, } INSPECT = createFuncsTable { turtle.inspect, turtle.inspectUp, turtle.inspectDown, } COMPARE = createFuncsTable { turtle.compare, turtle.compareUp, turtle.compareDown, } SUCK = createFuncsTable { turtle.suck, turtle.suckUp, turtle.suckDown, } ----------------------------------------------------------- -- 一歩移動 ----------------------------------------------------------- STEP = createFuncsTable { turtle.forward, turtle.up, turtle.down, } STEP[const.BACK] = turtle.back -- 一歩移動の[BACK]だけは他と違って回らずそのまま下がるよ
simattyau.lua
simattyau.lua
しまっちゃうクラスを記述したAPIです。
クラス名とAPI名(= ファイル名)が同一なのは、simattyau.new()と書けてそれっぽいからです。
----------------------------------------------------------- -- simattyau.lua -- アイテム収納 API -- 収納したアイテムと数の記憶機能付き -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- os.loadAPI('/lib/apis/akaneutils') os.loadAPI('/lib/apis/turtleapis') os.loadAPI('/lib/apis/identify') ----------------------------------------------------------- -- アイテムをしまって、しまった種類と数を記憶するオブジェクトを作るよ -- @param setting [in]アイテム収納オブジェクトの設定テーブル -- @return アイテム収納オブジェクト ----------------------------------------------------------- function new(setting) -- テーブル作成。デフォルト値も設定するよ ----------------------------------------------------------- -- @class table -- @name simau -- @description アイテム収納オブジェクト -- @field counts 収納したアイテムの数を記憶するテーブル ----------------------------------------------------------- local simau = { counts = {}, } -- クロージャOOP local self = simau ----------------------------------------------------------- -- アイテム数記憶テーブルのkeyを生成する ----------------------------------------------------------- function simau.createKey(itemID, itemDV) if not itemDV then print('nil') end return string.format('%s,%d', itemID, tonumber(itemDV)) -- どうせcsvにするんやしなあ end ----------------------------------------------------------- -- 指定スロットのアイテムを分類するよ -- 分類には引数で渡されたコールバック関数を使うよ -- コールバック関数を実行して、戻り値の方向のチェストにしまうよ -- 戻り値がfalseならなにもしないよ -- -- @param callback [in]分類に使うコールバック関数 -- @param slot_no [in]対象スロット番号 -- @return しまったらture / しまわなかったらfalse ----------------------------------------------------------- function simau.simau(callback, slot_no) local direction = callback(slot_no) if not direction then return false end return self.simauAny(slot_no, direction) end ----------------------------------------------------------- -- 指定スロットのアイテムをチェストにしまうよ -- -- @param slot_no [in]対象スロット番号 -- @param direction [in]アイテムをしまう方向 -- @return しまったらture / しまわなかったらfalse ----------------------------------------------------------- function simau.simauAny(slot_no, direction) if not turtle.getItemDetail(slot_no) then return false end local selected_slot = turtle.getSelectedSlot() -- 選択スロットを覚えとくよ turtle.select(slot_no) local result = self.insert(direction) -- チェストにしまうよ turtle.select(selected_slot) -- 選択スロットを戻しとくんのが乙女のたしなみやで return result end ----------------------------------------------------------- -- 選択中のスロットのアイテムをチェストにしまうよ -- しまったアイテムの種類と数を記憶するよ -- -- @param direction [in]アイテムをしまう方向 -- @return しまったらture / しまわなかったらfalse ----------------------------------------------------------- function simau.insert(direction) local item = turtle.getItemDetail() -- アイテムは何やろ if not turtleapis.DROP[direction]() then -- アイテムをしまうよ return false end -- しまったアイテムを記憶するよ self.addCount( identify.getItemID(item), identify.getItemDV(item), item.count - turtle.getItemCount() ) return true end ----------------------------------------------------------- -- アイテムの種類と数を記憶するよ -- -- @param itemID [in]しまったアイテムのID -- @param itemDV [in]しまったアイテムのDV -- @param count [in]しまったアイテムの数 ----------------------------------------------------------- function simau.addCount(itemID, itemDV, count) local key = self.createKey(itemID, itemDV) local old_count = self.counts[key] or 0 self.counts[key] = old_count + count end ----------------------------------------------------------- -- しまったアイテムの種類と数を(csv)ファイルに書き込むよ -- @param path [in]ファイルパス ----------------------------------------------------------- function simau.saveStats(path) akaneutils.prepareToWrite(path) -- 書き込み準備や local h = fs.open(path, 'w') for k, v in pairs(self.counts) do h.writeLine(string.format('%s,%d', k, v)) -- 書くよ~ end h.close() end ----------------------------------------------------------- -- しまったアイテムの種類と数を書き込んだファイル(csv)を読み込むよ -- @param path [in]ファイルパス ----------------------------------------------------------- function simau.loadStats(path) self.counts = {} -- 初期化するで if not fs.exists(path) then return end -- ファイルが無かったら何もしないよ -- csvを読み込んで行ごとに処理するよ for columns in akaneutils.csvEachLine(path) do if #columns == 3 then -- 読み込んだデータを格納するよ self.counts[self.createKey(columns[1], columns[2])] = columns[3] end end end return self end
identify.lua
identify.lua
アイテム識別のためのAPIです。
処理効率に無視できないレベルの問題があり、またModに対する拡張性も今ひとつなので、改修予定です。
----------------------------------------------------------- -- identify(lua) -- アイテム識別モジュール -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- -- アイテムID local ID_FISH = 'minecraft:fish' local ID_LEATHER_BOOTS = 'minecraft:leather_boots' local ID_TURIZAO = 'minecraft:fishing_rod' local ID_POTION = 'minecraft:potion' local ID_SADDLE = 'minecraft:saddle' local ID_WATER = 'minecraft:water' local ID_FLOWING_WATER = 'minecraft:flowing_water' ----------------------------------------------------------- -- turtle.getItemDetailまたはinspectの戻り値から -- アイテムIDを取得するよ<br> -- これ要るんやろか -- @param item_detail [in]アイテム詳細テーブル -- @return アイテムID ----------------------------------------------------------- function getItemID(item_detail) return item_detail.name end ----------------------------------------------------------- -- turtle.getItemDetailの戻り値からアイテムのDVを取得する<br> -- -- CCのアイテム詳細テーブルではDVは'damage'に格納されるぽいな -- minecraft wikiによるとDVはデータ値(Data values)てことになっとるけど -- なんでdamageなんやろ -- -- @param item_detail [in]アイテム詳細テーブル -- @return アイテムのDV ----------------------------------------------------------- function getItemDV(item_detail) return item_detail.damage end ----------------------------------------------------------- -- turtle.inspectの戻り値からメタデータを取得するよ -- @param data [in]ブロック詳細テーブル -- @return アイテムID ----------------------------------------------------------- function getMetadata(data) return data.metadata end ----------------------------------------------------------- -- turtle.getItemDetailの戻り値からアイテムのDVを取得する<br> -- -- CCのアイテム詳細テーブルではDVは'damage'に格納されるぽいな -- minecraft wikiによるとDVはデータ値(Data values)てことになっとるけど -- なんでdamageなんやろ -- -- @param item_detail [in]アイテム詳細テーブル -- @return アイテムのDV ----------------------------------------------------------- function getItemDV(item_detail) return item_detail.damage end ----------------------------------------------------------- -- 指定アイテムを識別するよ<br> -- -- 引数で与えられた識別用テーブルを使ってアイテムを識別するよ -- 識別用テーブルから、アイテムIDをkeyにしてvalueを取得し、 -- valueが関数ならば、item_detailを引数に実行し、 -- その戻り値を戻り値として返すよ。 -- -- valueが関数以外ならば(booleanまたはnilを想定)、 -- そのまま戻り値として返すよ。 -- -- @param identifier [in]アイテム識別用テーブル -- @param item_detail [in]アイテム詳細テーブル -- @return 識別結果 ----------------------------------------------------------- local function identify(identifier, item_detail) if not item_detail then return false end local value = identifier[getItemID(item_detail)] if type(value) == 'function' then return value(item_detail) end return value end ----------------------------------------------------------- -- 簡単に識別関数を作るよ<br> -- 下のisFish()みたいなのをいちいち作ってたらメンドくて失踪あるのみやから -- 単純な場合はサクッと作れる方法を用意するよ -- (isFish()はサンプルとしてそのままのこすよ) -- @param IDs [in]アイテムIDの配列 -- 使用例は下のisLeatherBootsとかを見てな ----------------------------------------------------------- local function makeSimply(IDs) local t = {} for i, v in ipairs(IDs) do t[v] = true end return function(item_detail) return identify(t, item_detail) end end ----------------------------------------------------------- -- 指定アイテムが生魚かどうか調べるよ<br> -- @param item_detail [in]アイテム詳細テーブル -- @return true 魚や! / false 魚やないで! ----------------------------------------------------------- function isFish(item_detail) local t = {} t[ID_FISH] = true return identify(t, item_detail) end ----------------------------------------------------------- -- 指定アイテムが焼き魚にできる生魚かどうか調べるよ<br> -- アイテムIDが'minecraft:fish'で、DVが0または1なら焼ける魚や -- -- @param item_detail [in]アイテム詳細テーブル -- @return true 焼ける魚や! / false 焼ける魚やないで! ----------------------------------------------------------- function isRoastableFish(item_detail) local t = {} t[ID_FISH] = function(item) return getItemDV(item) < 2 end return identify(t, item_detail) end ----------------------------------------------------------- -- 指定アイテムがポーションという名のただの水かどうか調べるよ<br> -- DVが0のポーション、つまりアイテムIDが'minecraft:potion'が -- 水入り瓶や -- -- @param item_detail [in]アイテム詳細テーブル -- @return true 水入り瓶や / false 水入り瓶やないで! ----------------------------------------------------------- function isWaterPotion(item_detail) local t = {} t[ID_POTION] = function(item) return getItemDV(item) == 0 end return identify(t, item_detail) end ----------------------------------------------------------- -- こっから下は単純なやつ ----------------------------------------------------------- -- 革ブーツ isLeatherBoots = makeSimply { ID_LEATHER_BOOTS, } -- 釣り竿 isFishingRod = makeSimply { ID_TURIZAO, } -- サドル isSaddle = makeSimply { ID_SADDLE, } -- 水ブロック isWaterBlock = makeSimply { ID_WATER, ID_FLOWING_WATER, }
const.lua
const.lua
定数(ぽいもの)の定義です。
ぽいもの、というのは、Luaには定数がないからです。
これはAPIにするより単にグローバル変数にしたほうが良いかもしれません。
現状、グローバル名前空間の汚染を考慮してこのようなAPIにしてあります。
----------------------------------------------------------- -- const.lua -- 定数(ぽいもの)定義 -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- ----------------------------------------------------------- -- 方向 ----------------------------------------------------------- FORWARD = 'forward' UP = 'up' DOWN = 'down' RIGHT = 'right' LEFT = 'left' BACK = 'back' ----------------------------------------------------------- -- 方角 ----------------------------------------------------------- NORTH = 'north' SOUTH = 'south' EAST = 'east' WEST = 'west'
application.lua
application.lua
アプリケーション実行に関わる関数集です。
まだ大したプログラムを作ってないので簡素なものです。
----------------------------------------------------------- -- application.lua -- プログラム実行に関わるAPI -- @author 琴葉茜(さとうけい) ----------------------------------------------------------- os.loadAPI('/lib/apis/turtleutils') ----------------------------------------------------------- -- turtleで実行されるプログラムの一般的な初期化処理をするよ -- @param program_name [in]実行中のプログラム名 ----------------------------------------------------------- function turtleInit(program_name) -- 起動メッセージを表示しとくよ print(string.format('%s(%dDay) %s: <%s> ikude!!', textutils.formatTime(os.time(), true), os.day(), turtleutils.getCompName(), program_name )) turtleutils.resetSlot() -- タートルの選択スロットをリセットしとくよ -- 他になんか思いついたら追加するよ end ----------------------------------------------------------- -- コンフィグファイルを読み込んで返すよ -- メッセージ表示もするよ -- @param path [in]コンフィグファイルのpath -- @return 読み込んだコンフィグテーブル ----------------------------------------------------------- function loadConfig(path) print('config<'.. path ..'> wo load suru yo!') local config = dofile(path) assert(config, 'config load SIPPAI SITADE nande yanenn...') print('config load seikou!!') return config end