228 lines
4.7 KiB
Lua
228 lines
4.7 KiB
Lua
-- 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 |