-- robot api local api = {} local ROBOT_DEFAULT_STATE_FILE = '/.robotstate' local DEFAULT_CONFIG = { autosave = false, autoload = false, stateFilePath = ROBOT_DEFAULT_STATE_FILE } local function identity(x) return x end local function getConfig(givenConfig) if givenConfig.onSave and not givenConfig.onLoad then error('robot.getConfig: custom "onSave" passed in config but no "onLoad"') end if givenConfig.onLoad and not givenConfig.onSave then error('robot.getConfig: custom "onLoad" passed in config but no "onSave"') end return { autosave = givenConfig.autosave or DEFAULT_CONFIG.autosave, autoload = givenConfig.autoload or DEFAULT_CONFIG.autoload, stateFilePath = givenConfig.stateFilePath or DEFAULT_CONFIG.stateFilePath, onSave = givenConfig.onSave or identity, onLoad = givenConfig.onLoad or identity } end local function createDefaultState() return { y = 0, x = 0, z = 0, dir = 'FORWARD' -- FORWARD | BACKWARD | LEFT | RIGHT } end local saveRobotState = function(stateFile, onSave, state) state = state or createDefaultState() local file = fs.open(stateFile, 'w') if not file then error('saveRobotState: cannot open ' .. stateFile .. ' file!') end local transformedState = onSave(state) file.write(textutils.serializeJSON(transformedState)) file.close() return transformedState end local loadRobotState = function(stateFile, onLoad, onSave) local file = fs.open(stateFile, 'r') if not file then return robot.saveRobotState(stateFile, onSave) end local serializedRobotState = file.readAll() file.close() local parsedResult = textutils.unserializeJSON(serializedRobotState) if not parsedResult then return robot.saveRobotState(stateFile, onSave) end return onLoad(parsedResult) end local getAutoSave = function(config, state) local autoSave = function() end if config.autosave then autoSave = function() saveRobotState(config.stateFilePath, config.onSave, state) end end return autoSave end api.create = function(state, givenConfig) state = state or createDefaultState() local config = getConfig(givenConfig) if config.autoload then state = loadRobotState(config.stateFilePath, config.onLoad, config.onSave) end local autoSave = getAutoSave(config, state) local mutateRobotPosition = function(isBackward) local incValue = 1 if isBackward then incValue = -1 end if state.dir == 'FORWARD' then state.z = state.z + incValue elseif state.dir == 'BACKWARD' then state.z = state.z - incValue elseif state.dir == 'LEFT' then state.x = state.x - incValue elseif state.dir == 'RIGHT' then state.x = state.x + incValue end end local robot = {} robot.forward = function() local ok, err = turtle.forward() if ok then mutateRobotPosition(false) autoSave() end return ok, err end robot.back = function() local ok, err = turtle.back() if ok then mutateRobotPosition(true) autoSave() end return ok, err end robot.backward = robot.back robot.up = function() local ok, err = turtle.up() if ok then state.y = state.y + 1 autoSave() end return ok, err end robot.down = function() local ok, err = turtle.down() if ok then state.y = state.y - 1 autoSave() end return ok, err end robot.turnLeft = function() local ok, err = turtle.turnLeft() if ok then if state.dir == 'FORWARD' then state.dir = 'LEFT' elseif state.dir == 'LEFT' then state.dir = 'BACKWARD' elseif state.dir == 'RIGHT' then state.dir = 'FORWARD' elseif state.dir == 'BACKWARD' then state.dir = 'RIGHT' end autoSave() end return ok, err end robot.turnRight = function() local ok, err = turtle.turnRight() if ok then if state.dir == 'FORWARD' then state.dir = 'RIGHT' elseif state.dir == 'LEFT' then state.dir = 'FORWARD' elseif state.dir == 'RIGHT' then state.dir = 'BACKWARD' elseif state.dir == 'BACKWARD' then state.dir = 'LEFT' end autoSave() end return ok, err end robot.turnBack = function() local ok, errorMessage = robot.turnLeft() if not ok then error('turnBack: cannot turn left because ' .. tostring(errorMessage)) end return robot.turnLeft() end robot.getState = function() return state end robot.saveState = function() return saveRobotState(config.stateFilePath, config.onSave, state) end robot.loadState = function() return loadRobotState(config.stateFilePath, config.onLoad, config.onSave) end return robot end return api