FredoNook 19 Опубликовано: 4 июля, 2015 Привет! Небольшое предисловие. Программа которую я подготовил сделана специально для того чтобы получить доступ на сервер. Код может быть ужасен, потому что это моя первая программа на Lua. Да сегодня утром я еще ничего не знал о Lua, а пару дней назад я не знал о OpenComputers и вообще что в к майнкрафту появилась куча интересных плагинов. Последний раз я играл в майнкрафт в 2012 году и это была ванилла. А теперь к делу - программа эта одновременно интерпритатор макроязыка который я назвал IronMacros и библиотека которая позволяет его расширять. Синтаксис довольно аутистский но очень краткий. Пример тестового макроса (скрины результата приложены): S1# select 1st slot R020C# make 2 R060B# 6 cubes R0502# x5 cubes planes P0M# place cube go up >^<WWWWW#move next stripe S2# select pickaxe R0502 XFM <^>WWWWW XFM<^>#star cut U R030A R0402 XFM <^>WWWW WXF<^> R0502 XFM#star cut R W<^>XF WWXFWW <^> R030C XFMXFMMXF <^>WWW <^> R0502 XFM Можно одной строкой (жесть): S1R020CR060BR0502P0M>^<WWWWWS2R0502XFM<^>WWWWWXFM<^>R030AR0402XFM<^>WWWWWXF<^>R0502XFMW<^>XFWWXFWW<^>R030CXFMXFMMXF<^>WWW<^>R0502XFM Результат: Сама библиотека/интерпритатор: -- ==================== -- IronMacros.lua -- Created by FredoNook -- ==================== local rb = require("robot") local sh = require("shell") -- module table local im = {} -- symbols restricted to unregister local restrictedSymbols = {"#"} -- macros queue local macros = {} -- macros execution register im.pc = {["x"] = 1, ["y"] = 1} -- registred macro commands local macroses = {} -- =========================== -- MACROS MANAGEMENT FUNCTIONS -- =========================== -- Register an macro symbol with func function im.registerMacros(symbol, func) if #symbol > 1 then error("Macro command can't be longer then one symbol") end if isSymbolRestricted(symbol) then error("Symbol \""..symbol.."\" is restricted") return end macroses[tostring(symbol)] = func end -- unregister an macro symbol function im.unregisterMacros(symbol) if #symbol > 1 then error("Macro command can't be longer then one symbol") end if isSymbolRestricted(symbol) then error("Symbol \""..symbol.."\" is restricted") return end macroses[tostring(symbol)] = nil end -- ==================== -- PC REGISTER FUNCTION -- ==================== -- register x step forward im.pc.fstep = function(count) if count == nil then im.pc.x = im.pc.x + 1 else im.pc.x = im.pc.x + count end end -- register y step down im.pc.dstep = function(count) if count == nil then im.pc.y = im.pc.y + 1 else im.pc.y = im.pc.y + count end im.pc.x = 1 end -- set register reg to value val im.pc.set = function(reg, val) if reg == "x" then im.pc.x = val elseif reg == "y" then im.pc.y = val else error("Wrong register idintificator") end end -- =================== -- EXECUTION FUNCTIONS -- =================== -- run macro file with filename function im.run(filename) local file = io.open(filename) local i = 1 for line in file:lines() do macros[i] = line i = i + 1 end file:close() local cmd = " " while cmd do cmd = im.readCmd() if cmd == nil then break end im.exec(cmd) end end -- exec macro command cmd function im.exec(cmd) if cmd ~= nil then macroses[cmd]() end end -- read command from registers position function im.readCmd() local cmd if im.pc.x == #macros[im.pc.y] + 1 then if #macros == im.pc.y then io.write("MACROS COMPLETED") return nil else im.pc.dstep() cmd = macros[im.pc.y]:sub(im.pc.x, im.pc.x) im.pc.fstep() io.write("CURRENT CMD: "..cmd.."\n") return cmd end end cmd = macros[im.pc.y]:sub(im.pc.x, im.pc.x) im.pc.fstep() io.write("CURRENT CMD: "..cmd.."\n") return cmd end -- ================ -- MODULE FUNCTIONS -- ================ -- check symbol for restriction local function isSymbolRestricted(symbol) for key, value in pairs(restrictedSymbols) do if value == symbol then return true end end end -- ========================= -- REGISTER DEFAULT MACROSES -- ========================= -- set # as commentary command macroses["#"] = function() if #macros == im.pc.y then im.pc.x = #macros[im.pc.y] + 1 else im.pc.dstep() end end -- set " " as NOP command macroses[" "] = function() end -- set ^ as forward command macroses["^"] = function() rb.forward() end -- set > as turn right command macroses[">"] = function() rb.turnRight() end -- set V as backward command macroses["V"] = function() rb.back() end -- set < as turn left command macroses["<"] = function() rb.turnLeft() end -- set M as up command macroses["M"] = function() rb.up() end -- set W as down command macroses["W"] = function() rb.down() end -- set R as repeat command. -- format: RXXYY where -- XX loop count in hex -- YY count of forward command to repeat -- except # " " and parameters of other commands macroses["R"] = function() local cycleCount = tonumber(im.readCmd()..im.readCmd(), 16) local cmdCount = tonumber(im.readCmd()..im.readCmd(), 16) local cycleStartPoint = {["x"] = im.pc.x, ["y"] = im.pc.y} local cycc, cmdc = 1, 1 while cycc < cycleCount do while cmdc <= cmdCount do local cmd = im.readCmd() if cmd == "#" then cmdc = cmdc - 1 end if cmd == " " then cmdc = cmdc - 1 end im.exec(cmd) cmdc = cmdc + 1 end cmdc = 1 im.pc.x = cycleStartPoint.x im.pc.y = cycleStartPoint.y cycc = cycc + 1 end end -- set S as select inventory slot command -- format: SX -- where X number of slot to select in hex macroses["S"] = function() local item = tonumber(im.readCmd(), 16) rb.select(item) end -- set P as place command -- format: PX -- where X number of placing block side macroses["P"] = function() local side = tonumber(im.readCmd(), 16) rb.place(side) end -- set X as remove/attack command -- format: XY -- where Y number of removing block side macroses["X"] = function() local side = tonumber(im.readCmd(), 16) local remfin = true while remfin do if side == 15 then rb.swing() else rb.swing(side) end if not rb.detect() then remfin = false end end end --- =========== --- ENTRY POINT --- =========== -- get execution args local args = sh.parse(...) if #args == 0 then io.write("Usage: ironmacros <macrosfile> [repeatly(true/false)]") elseif #args == 1 then im.run(args[1]) else -- TODO: Repeatly execution end return im Как использовать:1. Пишем макрос сохраняем в файл2. В терминале пишем ironmacros <filename> filename это имя нашего макроса3. Profit Имплементированные макрокоманды# - комментарий, после символа вся строка пропускается^ - двигаться вперед V - двигаться назад> - повернуться вправо< - повернуться влевоM - двигаться вверхW - двигаться внизRXXYY - цикл, где XX количество повторов в 16тиричной системе. YY количество команд, которые следует повторять в 16тиричной системе ( считаются только команды, аргументы, передаваемые командам, упускаются)SX - выбрать слот инвентаря с номером X, номер X 16тиричныйPX - поставить блок впереди себя X - на какой сайд ставить (аналог place([side]))XY - махнуть активным слотом (атака/поломка блоков) где Y по какому сайду бить (аналог swing([side]) при передаче в качестве параметра F вызывается подефолту swing() Ну и как вы уже заметили (я надеюсь) сейчас все это заточено исключительно под робота. Вкратце о внутренностях: 1. функции управления литералами макрокомандregisterMacros(symbol, func)unregisterMacros(symbol)регистрирует или снимает регистрацию заданного символа. func функция обработчикнапример так: im = require("ironmacros") local func = function() print("ZzzZzzZzzZ") end im.registerMacros("Z",func) теперь если записать в макрос Z будет в терминал будет напечатано "ZzzZzzZzzZ"Эти функции нужны лишь для того что бы расширять язык. Для пользования текущей версией они не нужны. 2. функции исполненияrun(filename) - открывает файл в котором записана последовательность макрокоманд и запускает ее. filename - имя файлаreadCmd() - читает макрокоманду соответственно значению регистра pc(pc.x pc.y)exec(cmd) - запускает команду cmd на исполнение. Под командой имеется ввиду макрокоманда "Z" или ">"Эти функции нужны лишь для того что бы расширять язык. Для пользования текущей версией они не нужны. 3. Функции управления регистромfstep([count]) - функция инкрементирует значение регистра pc.x (если требуется инкрементировать pc.y , pc.x присваивается 1 ). count опционально коллчество шаговdstep([count]) - функция инкрементирует pc.y присваивает pc.x 1 если больше нет команд на исполнение заканчивает скрипт. count опционально коллчество шаговset(reg, val) - установить регистр reg ("x" или "y") на значение valЭти функции нужны лишь для того что бы расширять язык. Для пользования текущей версией они не нужны. 4. Добавление своей макро командыВ исходнике все макрокоманды добавлены используя вышеприведенные функции.Можно ознакомится, там все просто. Раздел REGISTRED DEFAULT MACROSES PS Да забыл pastebin.com: lib: http://pastebin.com/eBbZrRGimacros: http://pastebin.com/Q4DRDKDV 6 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Doob 2 749 Опубликовано: 4 июля, 2015 Круто, на CC делал подобное, но теперь там есть http://www.computercraft.info/2015/07/01/introducing-computercraftedu/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
FredoNook Автор темы 19 Опубликовано: 4 июля, 2015 Круто, на CC делал подобное, но теперь там есть http://www.computercraft.info/2015/07/01/introducing-computercraftedu/ Интересно, но я не люблю визуальное программирование, если это не behaviour-tree или fsm ну или какой нибудь граф типа диалога или квеста). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 6 июля, 2015 (изменено) Это сделал человек, который "сегодня утром ничего не знал о Луа"? Не верю! Изменено 6 июля, 2015 пользователем Zer0Galaxy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy 1 169 Опубликовано: 6 июля, 2015 (изменено) Фрэдо, правда, а сделай графический редактор? Пусть эти макросы действительно как в CCedu будут блоками. Объеденись с кем нибудь и замути. Будет ведь суперски. Изменено 6 июля, 2015 пользователем Krutoy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
FredoNook Автор темы 19 Опубликовано: 6 июля, 2015 Фрэдо, правда, а сделай графический редактор? Пусть эти макросы действительно как в CCedu будут блоками. Объеденись с кем нибудь и замути. Будет ведь суперски. Теоретически можно, но сейчас я тут разбираюсь в модах поскольку я ничего о них не знаю, и обживаюсь на сервере. Как маломальски адекватный уровень будет, можно разбираться будет с gpu'ом, как оно там все работает и рисует. Я мельком взглянул на апи не совсем понял что там к чему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах