This commit is contained in:
Igor Timofeev 2016-04-05 15:48:09 +03:00
parent d869a4b833
commit 3c2f6b2e5e
6 changed files with 597 additions and 186 deletions

View File

@ -1,206 +1,277 @@
local c = require("component")
local modem = c.modem
local gpu = c.gpu
local component = require("component")
local buffer = require("doubleBuffering")
local unicode = require("unicode")
local serialization = require("serialization")
local context = require("context")
local event = require("event")
local keyboard = require("keyboard")
local modem = component.modem
local port = 512
modem.open(port)
--------------------------------------------------------------------------------------------------------------------------------------
local direction = 1
buffer.start()
local xStart = math.floor(buffer.screen.width / 2)
local yStart = math.floor(buffer.screen.height / 2 + 2)
local port = 1337
local xSize, ySize = gpu.getResolution()
local topBarElements = { "Карта", "Инвентарь", "Редстоун", "Геоанализатор", "Бак" }
local currentTopBarElement = 2
local xPos, yPos = math.floor(xSize/2), math.floor(ySize/2)
local xScreen, yScreen = 0, 0
local points = {
local map = {
robotPosition = {
x = 0, y = 0, z = 0,
rotation = 1,
},
currentLayer = 0,
{ type = "empty", x = 0, y = 0, z = 0 },
}
local robotPicture = {
"", "", "", ""
}
local homePoint = {x = xPos, y = yPos}
local colors = {
white = 0xFFFFFF,
lightGray = 0xCCCCCC,
gray = 0x333333,
black = 0x000000,
robot = 0xFF3333,
entity = 0xFFCC33,
homePoint = 0x6699FF,
passable = 0xFF3333,
keyPoint = 0xFF3333,
keyPointText = 0xFFFFFF,
}
local function checkRange(xCoord, yCoord)
local xRelative, yRelative = xCoord, yCoord
if xRelative >= (0 + xScreen) and xRelative <= (xSize + xScreen) and yRelative >= (0 + yScreen) and yRelative <= (ySize + yScreen) then return true end
modem.open(port)
--------------------------------------------------------------------------------------------------------------------------------------
local function sendMessage(...)
modem.broadcast(port, "ECSRobotControl", ...)
end
local function drawTurtle()
if checkRange(xPos, yPos) then
ecs.square(xPos - xScreen - 2, yPos - yScreen - 1, 5, 3, 0x880000)
ecs.colorText(xPos - xScreen, yPos - yScreen, 0xffffff, "R")
local xDir, yDir = xPos - xScreen, yPos - yScreen
if direction == 1 then
gpu.set(xDir, yDir - 1, "^")
elseif direction == 2 then
gpu.set(xDir + 2, yDir, ">")
elseif direction == 4 then
gpu.set(xDir - 2, yDir, "<")
else
gpu.set(xDir, yDir + 1, "|")
end
end
local function drawTopBar()
buffer.square(1, 1, buffer.screen.width, 3, colors.gray)
local x = 1
for i = 1, #topBarElements do
local textLength = unicode.len(topBarElements[i]) + 4
if i == currentTopBarElement then
buffer.square(x, 1, textLength, 3, colors.lightGray)
buffer.text(x + 2, 2, colors.gray, topBarElements[i])
else
buffer.text(x + 2, 2, colors.lightGray, topBarElements[i])
end
x = x + textLength
end
end
local function drawPoints()
if #points > 0 then
for i = 1, #points do
if points[i] then
if not points[i].completed then
if checkRange(points[i].x, points[i].y) then
ecs.colorTextWithBack(points[i].x - xScreen, points[i].y - yScreen, 0xffffff - points[i].color, points[i].color, tostring(i))
end
end
end
end
end
local function drawMap()
--Рисуем карту
for i = 1, #map do
--Если слой совпадает с текущим Y
if map[i].y == map.currentLayer then
--Если координаты в границах экрана
if map[i].type == "empty" then
buffer.set(xStart + map[i].x, yStart - map[i].z, colors.gray, 0x000000, " ")
elseif map[i].type == "solid" then
buffer.set(xStart + map[i].x, yStart - map[i].z, colors.lightGray, colors.gray, "")
elseif map[i].type == "passable" then
buffer.set(xStart + map[i].x, yStart - map[i].z, colors.lightGray, colors.passable, "")
elseif map[i].type == "entity" then
buffer.text(xStart + map[i].x, yStart - map[i].z, colors.entity, "")
end
end
end
--Рисуем точку дома
if map.currentLayer == 0 then buffer.set(xStart, yStart, colors.homePoint, colors.gray, "") end
--Рисуем ключевые точки
if map.keyPoints and #map.keyPoints > 0 then
for i = 1, #map.keyPoints do
buffer.set(xStart + map.keyPoints[i].x, yStart + map.keyPoints[i].z, colors.keyPoint, colors.keyPointText, "*")
end
end
--Рисуем робота
buffer.text(xStart + map.robotPosition.x, yStart - map.robotPosition.z, colors.robot, robotPicture[map.robotPosition.rotation])
end
local function drawHome()
if checkRange(homePoint.x, homePoint.y) then
ecs.colorTextWithBack(homePoint.x - xScreen, homePoint.y - yScreen, 0xffffff, ecs.colors.blue, "H")
end
local function requestInventoryInfo()
sendMessage("giveMeInfoAboutInventory")
end
local function drawInventory()
-- sendMessage("giveMeInfoAboutInventory")
local x, y = 3, 5
local xPos, yPos = x, y
if map.robotInventory and #map.robotInventory > 0 then
for i = 1, #map.robotInventory do
--Квадратик
buffer.square(xPos, yPos, 8, 4, colors.gray)
--Имя шмотки
local name = unicode.sub(map.robotInventory[i].label, 1, 16)
local firstPart = unicode.sub(name, 1, 8)
local secondPart = unicode.sub(name, 9, 16) or ""
buffer.text(xPos, yPos, colors.lightGray, firstPart)
buffer.text(xPos, yPos + 1, colors.lightGray, secondPart)
--Колво шмотки
buffer.text(xPos, yPos + 2, 0xFFFFFF, tostring(map.robotInventory[i].size))
--Процент износа
if map.robotInventory[i].maxDamage ~= 0 then
local percentOfNotDamage = 1 - (map.robotInventory[i].damage / map.robotInventory[i].maxDamage)
local widthOfNotDamage = math.floor(percentOfNotDamage * 6)
buffer.text(xPos + 1, yPos + 3, 0x000000, "━━━━━━")
buffer.text(xPos + 1, yPos + 3, 0x33CC33, string.rep("", widthOfNotDamage))
end
xPos = xPos + 10
if i % 4 == 0 then xPos = x; yPos = yPos + 5 end
end
end
end
local function drawMain()
--Очищаем главную зону
buffer.square(1, 4, buffer.screen.width, buffer.screen.height - 3, colors.lightGray)
if topBarElements[currentTopBarElement] == "Карта" then
drawMap()
elseif topBarElements[currentTopBarElement] == "Карта" then
drawInventory()
end
end
local function drawAll()
gpu.setBackground(0xffffff)
gpu.setForeground(0xcccccc)
gpu.fill(1, 1, xSize, ySize, "*")
drawHome()
drawTurtle()
drawPoints()
drawTopBar()
drawMain()
buffer.draw()
end
local function turtleExecute(command)
modem.broadcast(port, command)
os.sleep(0.4)
local function getTargetCoords(direction)
if direction == "forward" then
if map.robotPosition.rotation == 1 then
return map.robotPosition.x, map.robotPosition.y, map.robotPosition.z + 1, xStart, yStart + 1
elseif map.robotPosition.rotation == 2 then
return map.robotPosition.x + 1, map.robotPosition.y, map.robotPosition.z, xStart - 1, yStart
elseif map.robotPosition.rotation == 3 then
return map.robotPosition.x, map.robotPosition.y, map.robotPosition.z - 1, xStart, yStart - 1
elseif map.robotPosition.rotation == 4 then
return map.robotPosition.x - 1, map.robotPosition.y, map.robotPosition.z, xStart + 1, yStart
end
elseif direction == "back" then
if map.robotPosition.rotation == 1 then
return map.robotPosition.x, map.robotPosition.y, map.robotPosition.z - 1, xStart, yStart - 1
elseif map.robotPosition.rotation == 2 then
return map.robotPosition.x - 1, map.robotPosition.y, map.robotPosition.z, xStart + 1, yStart
elseif map.robotPosition.rotation == 3 then
return map.robotPosition.x, map.robotPosition.y, map.robotPosition.z + 1, xStart, yStart + 1
elseif map.robotPosition.rotation == 4 then
return map.robotPosition.x + 1, map.robotPosition.y, map.robotPosition.z, xStart - 1, yStart
end
elseif direction == "up" then
return map.robotPosition.x, map.robotPosition.y + 1, map.robotPosition.z, xStart, yStart
elseif direction == "down" then
return map.robotPosition.x, map.robotPosition.y - 1, map.robotPosition.z, xStart, yStart
end
end
local function changeDirection(newDirection)
if newDirection ~= direction then
if direction == 1 then
if newDirection == 2 then
turtleExecute("turnRight")
elseif newDirection == 3 then
turtleExecute("turnRight")
turtleExecute("turnRight")
elseif newDirection == 4 then
turtleExecute("turnLeft")
end
elseif direction == 2 then
if newDirection == 1 then
turtleExecute("turnLeft")
elseif newDirection == 3 then
turtleExecute("turnRight")
elseif newDirection == 4 then
turtleExecute("turnRight")
turtleExecute("turnRight")
end
elseif direction == 3 then
if newDirection == 1 then
turtleExecute("turnLeft")
turtleExecute("turnLeft")
elseif newDirection == 2 then
turtleExecute("turnLeft")
elseif newDirection == 4 then
turtleExecute("turnRight")
end
elseif direction == 4 then
if newDirection == 1 then
turtleExecute("turnRight")
elseif newDirection == 2 then
turtleExecute("turnRight")
turtleExecute("turnRight")
elseif newDirection == 3 then
turtleExecute("turnLeft")
end
end
direction = newDirection
end
local function getOptimalKeyPoint()
local optimalID
local optimalDistance = math.huge
for i = 1, #map.keyPoints do
local distance = math.sqrt(map.keyPoints.x ^ 2 + map.keyPoints.y ^ 2 + map.keyPoints.x ^ z)
if distance < optimalDistance then
optimalID = i
optimalDistance = distance
end
end
return optimalID
end
local function moveTurtle()
if direction == 1 then
yPos = yPos - 1
elseif direction == 2 then
xPos = xPos + 1
elseif direction == 3 then
yPos = yPos + 1
else
xPos = xPos - 1
end
turtleExecute("forward")
end
local function moveToPoint(number)
local xToMove, yToMove = points[number].x + xScreen, points[number].y + yScreen
local xDifference, yDifference = xPos + xScreen - xToMove, yPos + yScreen - yToMove
--ecs.error("xDifference = "..tostring(xDifference)..", yDifference = "..tostring(yDifference))
if yDifference > 0 then
changeDirection(1)
elseif yDifference < 0 then
changeDirection(3)
end
for i = 1, math.abs(yDifference) do
moveTurtle()
drawAll()
end
if xDifference > 0 then
changeDirection(4)
elseif xDifference < 0 then
changeDirection(2)
end
for i = 1, math.abs(xDifference) do
moveTurtle()
drawAll()
end
drawAll()
end
local function moveToEveryPoint()
for i = 1, #points do
moveToPoint(i)
points[i].completed = true
end
points = {}
drawAll()
--ecs.error("Все точки пройдены!")
end
----------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------
drawAll()
requestInventoryInfo()
while true do
local e = {event.pull()}
if e[1] == "key_down" then
if e[4] == 200 then
yScreen = yScreen - 1
elseif e[4] == 208 then
yScreen = yScreen + 1
elseif e[4] == 203 then
xScreen = xScreen - 1
elseif e[4] == 205 then
xScreen = xScreen + 1
elseif e[4] == 28 then
moveToEveryPoint()
end
drawAll()
elseif e[1] == "touch" then
local xPoint, yPoint = e[3] + xScreen, e[4] + yScreen
table.insert(points, {x = xPoint, y = yPoint, color = math.random(0x000000, 0xffffff)})
drawAll()
end
local e = { event.pull() }
if e[1] == "touch" then
map.keyPoints = map.keyPoints or {}
table.insert(map.keyPoints, { x = e[3] - xStart, y = map.currentLayer, z = e[4] - yStart })
drawAll()
elseif e[1] == "key_down" then
--W
if e[4] == 17 then
sendMessage("forward")
--S
elseif e[4] == 31 then
sendMessage("back")
--SHIFT
elseif e[4] == 42 then
sendMessage("down")
--SPACE
elseif e[4] == 57 then
sendMessage("up")
--A
elseif e[4] == 30 then
sendMessage("turnLeft")
--D
elseif e[4] == 32 then
sendMessage("turnRight")
--E
elseif e[4] == 18 then
if keyboard.isControlDown() then sendMessage("use") else sendMessage("swing") end
--Q
elseif e[4] == 16 then
sendMessage("drop")
-- elseif e[4] == 28 then
-- if map.keyPoints and #map.keyPoints > 0 then
-- sendMessage("executeKeyPoints", serialization.serialize(map.keyPoints))
-- end
end
elseif e[1] == "modem_message" then
if e[4] == port then
if e[6] == "ECSRobotAnswer" then
if e[7] == "cantMoveTo" then
local x, y, z = getTargetCoords(e[8])
table.insert(map, { type = e[9], x = x, y = y, z = z })
drawAll()
elseif e[7] == "successfullyMovedTo" then
local x, y, z; x, y, z, xStart, yStart = getTargetCoords(e[8])
if e[8] == "up" then
map.currentLayer = map.currentLayer + 1
elseif e[8] == "down" then
map.currentLayer = map.currentLayer - 1
end
map.robotPosition.x = x; map.robotPosition.y = y; map.robotPosition.z = z
table.insert(map, { type = "empty", x = x, y = y, z = z })
drawAll()
elseif e[7] == "successfullyRotatedTo" then
local adder = -1; if e[8] == "turnRight" then adder = 1 end
map.robotPosition.rotation = map.robotPosition.rotation + adder
if map.robotPosition.rotation < 1 then
map.robotPosition.rotation = 4
elseif map.robotPosition.rotation > 4 then
map.robotPosition.rotation = 1
end
drawAll()
elseif e[7] == "successfullySwingedTo" then
if e[8] == "swing" then e[8] = "forward" elseif e[8] == "swingUp" then e[8] = "up" elseif e[8] == "swingDown" then e[8] = "down" end
local x, y, z = getTargetCoords(e[8])
table.insert(map, { type = "empty", x = x, y = y, z = z })
drawAll()
elseif e[7] == "inventoryInfo" then
map.robotInventory = serialization.unserialize(e[8])
drawAll()
end
end
end
end
end

View File

@ -0,0 +1,74 @@
local event = require("event")
local robot = require("robot")
local component = require("component")
local serialization = require("serialization")
local modem = component.modem
local inventoryController = component.inventory_controller
local port = 1337
local moveSleepDelay = 0.05
modem.open(port)
------------------------------------------------------------------------------------------
local function sendMessage(...)
modem.broadcast(port, "ECSRobotAnswer", ...)
end
local function try(functionName, successMessage, errorMessage)
local success, reason = robot[functionName]()
if success then
sendMessage(successMessage, functionName)
else
print("Ошибка try:", functionName, reason)
sendMessage(errorMessage, functionName, reason)
end
os.sleep(moveSleepDelay)
end
local function sendInventory()
local inventory = {}
local inventorySize = robot.inventorySize()
for slot = 1, inventorySize do
table.insert(inventory, inventoryController.getStackInInternalSlot(slot))
end
sendMessage("inventoryInfo", serialization.serialize(inventory))
end
------------------------------------------------------------------------------------------
while true do
local e = { event.pull() }
if e[1] == "modem_message" then
if e[4] == port then
if e[6] == "ECSRobotControl" then
if e[7] == "forward" or e[7] == "back" or e[7] == "up" or e[7] == "down" then
try(e[7], "successfullyMovedTo", "cantMoveTo")
elseif e[7] == "turnLeft" or e[7] == "turnRight" then
try(e[7], "successfullyRotatedTo", "cantRotateWTF")
elseif e[7] == "swing" then
try(e[7], "successfullySwingedTo", "cantSwingTo")
elseif e[7] == "use" then
robot.use()
elseif e[7] == "drop" then
robot.drop(e[8] or 1)
elseif e[7] == "giveMeInfoAboutInventory" then
sendInventory()
end
end
end
end
end

View File

@ -0,0 +1,249 @@
---------------------------------------------------- Библиотеки ----------------------------------------------------------------
local serialization = require("serialization")
local event = require("event")
local ecs = require("ECSAPI")
local fs = require("filesystem")
local buffer = require("doubleBuffering")
local unicode = require("unicode")
local component = require("component")
---------------------------------------------------- Константы ----------------------------------------------------------------
buffer.start()
local tablica = {}
-------------------------------------------------------------------------------------------------------------------------------
local function drawGrid(x, y)
local gridWidth = 74
local gridHeight = 39
buffer.clear(0xFFFFFF)
local lines = {
" ┃ ┃ ",
" ┃ ┃ ",
" ┃ ┃ ",
"━━━━━━━╋━━━━━━━╋━━━━━━━",
" ┃ ┃ ",
" ┃ ┃ ",
" ┃ ┃ ",
"━━━━━━━╋━━━━━━━╋━━━━━━━",
" ┃ ┃ ",
" ┃ ┃ ",
" ┃ ┃ ",
}
--Тонкие
local xPos, yPos = x, y
for a = 1, 3 do
for j = 1, 3 do
for i = 1, #lines do
buffer.text(xPos, yPos, 0x000000, lines[i])
yPos = yPos + 1
end
yPos = yPos + 1
end
yPos = y
xPos = xPos + unicode.len(lines[1]) + 2
end
--Толстые
--Горизонтальные
buffer.square(x, y + (#lines + 1) - 1, (unicode.len(lines[1]) + 2) * 3, 1, 0x000000)
buffer.square(x, y + (#lines + 1) * 2 - 1, (unicode.len(lines[1]) + 2) * 3, 1, 0x000000)
--Вертикальные
buffer.square(x + (unicode.len(lines[1]) + 1) - 1, y, 2, (#lines + 1) * 3, 0x000000)
buffer.square(x + (unicode.len(lines[1]) * 2 + 3 ) - 1, y, 2, (#lines + 1) * 3, 0x000000)
--Значения
yPos = y
for j = 1, #tablica do
xPos = x + 1
for i = 1, #tablica[j] do
if i == 4 or i == 7 then xPos = xPos + 1 end
if tablica[j][i].value then
buffer.set(xPos + 2, yPos + 1, 0xFFFFFF, 0x000000, tostring(tablica[j][i].value))
elseif tablica[j][i].possibleValues and #tablica[j][i].possibleValues > 0 then
local xPossible, yPossible = xPos, yPos
for a = 1, #tablica[j][i].possibleValues do
local background, foreground = 0xFFFFFF, 0xAAAAAA
if #tablica[j][i].possibleValues == 1 then background = 0x88FF88; foreground = 0x000000 end
buffer.set(xPossible, yPossible, background, foreground, tablica[j][i].possibleValues[a])
xPossible = xPossible + 2
if a % 3 == 0 then xPossible = xPos; yPossible = yPossible + 1 end
end
end
xPos = xPos + 8
end
yPos = yPos + 4
end
buffer.draw()
end
local function checkCellValue(xCell, yCell, requestedValue)
if tablica[yCell][xCell].value and tablica[yCell][xCell].value == requestedValue then
return false
end
return true
end
local function checkCellForRules(xCell, yCell, requestedValue)
--Чекаем горизонтально, включая эту же ячейку
for i = (xCell + 1), 9 do if not checkCellValue(i, yCell, requestedValue) then return false end end
for i = 1, (xCell - 1) do if not checkCellValue(i, yCell, requestedValue) then return false end end
--Вертикально
for i = (yCell + 1), 9 do if not checkCellValue(xCell, i, requestedValue) then return false end end
for i = 1, (yCell - 1) do if not checkCellValue(xCell, i, requestedValue) then return false end end
--И вокруг
local xFrom, yFrom = 1, 1
if xCell >= 4 and xCell <= 6 then xFrom = 4 elseif xCell >= 7 and xCell <= 9 then xFrom = 7 end
if yCell >= 4 and yCell <= 6 then yFrom = 4 elseif yCell >= 7 and yCell <= 9 then yFrom = 7 end
for j = yFrom, (yFrom + 2) do
for i = xFrom, (xFrom + 2) do
if not checkCellValue(i, j, requestedValue) then return false end
end
end
return true
end
local function clearTablica()
tablica = {}
for i = 1, 9 do table.insert(tablica, { {},{},{}, {},{},{}, {},{},{} }) end
end
local function generateSudoku(startCountOfNumbers)
clearTablica()
for i = 1, startCountOfNumbers do
while true do
local randomNumber = math.random(1, 9)
local randomX = math.random(1, 9)
local randomY = math.random(1, 9)
if not tablica[randomY][randomX].value and checkCellForRules(randomX, randomY, randomNumber) then
tablica[randomY][randomX].value = randomNumber
break
end
end
end
end
local function getpossibleValuesForCell(xCell, yCell)
--Получаем невозможные числа
local impossibleValues = {}
--Горизонтально
for i = 1, (xCell - 1) do if tablica[yCell][i].value then impossibleValues[tablica[yCell][i].value] = true end end
for i = (xCell + 1), 9 do if tablica[yCell][i].value then impossibleValues[tablica[yCell][i].value] = true end end
--Вертикально
for i = 1, (yCell - 1) do if tablica[i][xCell].value then impossibleValues[tablica[i][xCell].value] = true end end
for i = (yCell + 1), 9 do if tablica[i][xCell].value then impossibleValues[tablica[i][xCell].value] = true end end
--Квадратно
local xFrom, yFrom = 1, 1
if xCell >= 4 and xCell <= 6 then xFrom = 4 elseif xCell >= 7 and xCell <= 9 then xFrom = 7 end
if yCell >= 4 and yCell <= 6 then yFrom = 4 elseif yCell >= 7 and yCell <= 9 then yFrom = 7 end
for j = yFrom, (yFrom + 2) do
for i = xFrom, (xFrom + 2) do
if tablica[j][i].value then impossibleValues[tablica[j][i].value] = true end
end
end
--А теперь берем возможные числа из невозможных
local possibleValues = {}
for i = 1, 9 do
if not impossibleValues[i] then table.insert(possibleValues, i) end
end
return possibleValues
end
local function getpossibleValues()
local countOfPossibleValues = 0
for j = 1, 9 do
for i = 1, 9 do
if not tablica[j][i].value then
local possibleValues = getpossibleValuesForCell(i, j)
tablica[j][i].possibleValues = possibleValues
countOfPossibleValues = countOfPossibleValues + #possibleValues
end
end
end
return countOfPossibleValues
end
local function loadSudokuFromFile(path)
clearTablica()
local file = io.open(path, "r")
local counter = 1
for line in file:lines() do
if unicode.len(line) > 9 then error("Неверный файл Судоку: длина линии больше 9 символов") end
for i = 1, 9 do
local symbol = unicode.sub(line, i, i)
if symbol ~= " " and not tonumber(symbol) then error("Неверный файл Судоку: символ не может быть представлен как число") end
tablica[counter][i].value = tonumber(symbol)
end
counter = counter + 1
end
file:close()
end
local function convertSinglePossibleValuesToValues()
for j = 1, 9 do
for i = 1, 9 do
if tablica[j][i].possibleValues and #tablica[j][i].possibleValues == 1 then
tablica[j][i].value = tablica[j][i].possibleValues[1]
tablica[j][i].possibleValues = nil
end
end
end
end
local function solveEasySudoku()
while true do
ecs.wait()
local countOfPossibleValues = getpossibleValues()
if countOfPossibleValues <= 0 then
drawGrid(1, 1)
ecs.wait()
ecs.error("Все решено!")
buffer.clear(0x262626)
ecs.prepareToExit()
break
end
drawGrid(1, 1)
convertSinglePossibleValuesToValues()
end
end
loadSudokuFromFile("testSudokuFile.txt")
drawGrid(1, 1)
solveEasySudoku()

View File

@ -0,0 +1,9 @@
2 8
169 32
37 94
257 94
8 6 3
95 287
95 21
41 685
5 9

View File

@ -0,0 +1,9 @@
9 2 5
8 2 9 1
4 6 3 2
4 2 9 6
3 4
5 8 1 7
3 9 5 8
6 1 3 7
8 7 1

View File

@ -7,16 +7,15 @@
" корпусе было подобрано лучшими специалистами ",
" нашей компании специально для вас. ",
" ",
" Данный компьютер оснащен квантовым генератором, ",
" что позволит вам навсегда забыть о бесконечных ",
" счетах за свет. Также в нем установлена передовая ",
" материнская плата без ограничений на уровень ",
" компонентов. Кроме того, мы встроили сверхбыстрый ",
" преобразователь энергии, распределяющий ее между ",
" компонентами более эффективно.",
" Хотим напомнить, что простые смертные ",
" не имеют права открывать содержимое корпуса, ",
" это сделал автор мода OpenComputers. Однако ",
" вы можете спользовать хопперы и закидывать",
" нужные компоненты в компьютер через них ;) ",
" ",
" Ну, или используйте этот корпус для создания ",
" крутых и мощных роботов.",
" ",
" Спасибо за покупку!",
" "
]
}
}