This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
nitrogenfingers's profile picture

Teaching with Minecraft- Request for a program

Started by nitrogenfingers, 30 May 2012 - 12:44 AM
nitrogenfingers #1
Posted 30 May 2012 - 02:44 AM
Hi Everyone, this is a bit of an odd post but bear with me.

The university I'm working at is looking at using the ComputerCraft mod as part of a workshop session to inspire interest computer science and engineering. On Friday a class of 20 students aged 14-16 will be sitting in a virtual campus while an academic teaches them to make turtles build walls and bomb targets. I've been absolutely ecstatic to see it go through- it's one way I feel that communities like this one are really making a difference in the world.

But the reason I've made this post is because the next 3 days for both me and the presenter are going to be flat-out, being so close to the end of semester so I'm actually putting out a request for a piece of software we're hoping to use in the system. I'd hope to make something like this earlier but have not yet had the chance.

The program needs to be a text editor, similar (or if possible) identical in function to the edit program pre-installed on the system but with the ability to detect any monitor peripherals attached to the computer (in most instances there are two, left and right, but some only have one), and update them to display that text file whenever changes to the file are made. This way it works kind of like a projector- the presenter edits his code files and whatever he sees is also displayed on the monitors so students can follow along.

I don't imagine it's a tricky job but I just don't have time to look into it, so if anyone is interested in having a go at this program, or already has something that will work in a similar way, let me know. Thanks for reading!

NF
MysticT #2
Posted 30 May 2012 - 03:10 AM
I changed the term api for my os so it can show the output on the console and monitors at the same time. I haven't released it yet, but I could make the api to work on CraftOS so you can use it. Just let me know if you want me to do it.
nitrogenfingers #3
Posted 30 May 2012 - 05:15 AM
That'd be fantastic if possible!
ComputerCraftFan11 #4
Posted 30 May 2012 - 07:15 AM
That'd be fantastic if possible!

Hello, I just made a program that does something like this,

this projects your screen onto the monitor and updates it everytime you press Save

local tArgs = { ... }
if #tArgs == 0 then
print( "Usage: edit <path>" )
return
end
local sPath = shell.resolve( tArgs[1] )
local bReadOnly = fs.isReadOnly( sPath )
if fs.exists( sPath ) and fs.isDir( sPath ) then
print( "Cannot edit a directory" )
return
end
local w,h = term.getSize()
local x,y = 1,1
local scrollX, scrollY = 0,0
local bMenu = false
local nMenuItem = 1
local sStatus = ""
local tLines = {}
local function load()
tLines = {}
if fs.exists( sPath ) then
  local file = io.open( sPath, "r" )
  local sLine = file:read()
  while sLine do
   table.insert( tLines, sLine )
   sLine = file:read()
  end
  file:close()
else
  table.insert( tLines, "" )
end
end
local function save()
local file = io.open( sPath, "w" )
if file then
  for n, sLine in ipairs( tLines ) do
   file:write( sLine .. "n" )
  end
  file:close()
  return true
end
for k,sSide in pairs(redstone.getSides()) do
  if peripheral.isPresent(sSide) and peripheral.getType(sSide) == "monitor" then
   term.redirect(peripheral.warp(sSide))
   redrawText()
   term.restore()
  end
end
return false
end
local function redrawText()
for y=1,h-1 do
  term.setCursorPos( 1 - scrollX, y )
  term.clearLine()
  local sLine = tLines[ y + scrollY ]
  if sLine ~= nil then
   term.write( sLine )
  end
end
term.setCursorPos( x - scrollX, y - scrollY )
end
local function redrawLine()
local sLine = tLines[y]
term.setCursorPos( 1 - scrollX, y - scrollY )
term.clearLine()
term.write( sLine )
term.setCursorPos( x - scrollX, y - scrollY )
end
local tMenuItems = { "Save", "Exit" }
local function redrawMenu()
    term.setCursorPos( 1, h )
term.clearLine()
if not bMenu then
  term.write( sStatus )
else
  for n,sItem in ipairs( tMenuItems ) do
   if n == nMenuItem then
    term.write( "["..sItem.."]" )
   else
    term.write( " "..sItem.." " )
   end
  end
end

    term.setCursorPos( x - scrollX, y - scrollY )
end
local function setStatus( _sText )
sStatus = _sText
redrawMenu()
end
local function setCursor( x, y )
local screenX = x - scrollX
local screenY = y - scrollY

local bRedraw = false
if screenX < 1 then
  scrollX = x - 1
  screenX = 1
  bRedraw = true
elseif screenX > w then
  scrollX = x - w
  screenX = w
  bRedraw = true
end

if screenY < 1 then
  scrollY = y - 1
  screenY = 1
  bRedraw = true
elseif screenY > h-1 then
  scrollY = y - (h-1)
  screenY = h-1
  bRedraw = true
end

if bRedraw then
  redrawText()
end
term.setCursorPos( screenX, screenY )
end
load()
term.clear()
term.setCursorPos(x,y)
term.setCursorBlink( true )
redrawText()
setStatus( "Press Ctrl to access menu" )
local bRunning = true
local tMenuFunctions = {
["Exit"] = function()
  bRunning = false
end,
["Save"] = function()
  if save() then
   setStatus( "Saved to "..sPath )
  else
   setStatus( "Access denied" )
  end
end,
}
local function doMenuItem( _n )
local fnMenu = tMenuFunctions[ tMenuItems[_n] ]
if fnMenu then
  fnMenu()
end
bMenu = false
term.setCursorBlink( true )
redrawMenu()
end
while bRunning do
  local sEvent, param = os.pullEvent()
  if sEvent == "key" then
    if param == 200 then
  -- Up
  if not bMenu then
   -- Move cursor up
   if y > 1 then
    y = y - 1
    x = math.min( x, string.len( tLines[y] ) + 1 )
    setCursor( x, y )
   end
  end
 
elseif param == 208 then
  -- Down
  if not bMenu then
   -- Move cursor down
   if y < #tLines then
    y = y + 1
    x = math.min( x, string.len( tLines[y] ) + 1 )
    setCursor( x, y )
   end
  end

elseif param == 203 then
  -- Left
  if not bMenu then
   -- Move cursor left
   if x > 1 then
    x = x - 1
    setCursor( x, y )
   end
  else
   -- Move menu left
   nMenuItem = nMenuItem - 1
   if nMenuItem < 1 then
    nMenuItem = #tMenuItems
   end
   redrawMenu()
  end
  
 
elseif param == 205 then
  -- Right
  if not bMenu then
   -- Move cursor right
	   if x < string.len( tLines[y] ) + 1 then
    x = x + 1
    setCursor( x, y )
	 end
  else
   -- Move menu right
   nMenuItem = nMenuItem + 1
	 if nMenuItem > #tMenuItems then
    nMenuItem = 1
	 end
	 redrawMenu()
  end
 
elseif param == 14 then
  -- Backspace
  if not bMenu then
	   if x > 1 then
    -- Remove character
    local sLine = tLines[y]
    tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)
    redrawLine()
 
    x = x - 1
    setCursor( x, y )
  
   elseif y > 1 then
    -- Remove newline
    local sPrevLen = string.len( tLines[y-1] )
    tLines[y-1] = tLines[y-1] .. tLines[y]
    table.remove( tLines, y )
    redrawText()
  
    x = sPrevLen + 1
    y = y - 1
    setCursor( x, y )
	 end
  end
 
elseif param == 28 then
  -- Enter
  if not bMenu then
   -- Newline
   local sLine = tLines[y]
   tLines[y] = string.sub(sLine,1,x-1)
   table.insert( tLines, y+1, string.sub(sLine,x) )
   redrawText()
 
   x = 1
   y = y + 1
   setCursor( x, y ) 
  
  else
   -- Menu selection
   doMenuItem( nMenuItem )
  end
 
elseif param == 29 then
  -- Menu toggle
  bMenu = not bMenu
  if bMenu then
   term.setCursorBlink( false )
   nMenuItem = 1
  else
   term.setCursorBlink( true )
  end
  redrawMenu()

end
 
  elseif sEvent == "char" then
if not bMenu then
	 -- Input text
  local sLine = tLines[y]
  tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
  redrawLine()

  x = x + string.len( param )
  setCursor( x, y )

else
  -- Select menu items
  for n,sMenuItem in ipairs( tMenuItems ) do
   if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then
    doMenuItem( n )
    break
   end
  end
end
  end
end
term.clear()
term.setCursorBlink( false )
term.setCursorPos( 1, 1 )

But this one prints your screen onto the monitor and your PC at the same time:

local nativeTerm = term.native or term
local function invoke(sMethod, ...)
nativeTerm[sMethod](...)
for k,sSide in pairs(redstone.getSides()) do
  if peripheral.isPresent(sSide) and peripheral.getType(sSide) == "monitor" then
   peripheral.call(sSide, sMethod, ...)
  end
end
end
term.write = function(text) invoke("write", text) end
term.scroll = function(n) invoke("scroll", n) end
term.setCursorPos = function(x, y) invoke("setCursorPos", x, y) end
term.setCursorBlink = function(:)/>/> invoke("setCursorBlink", :)/>/> end
term.clear = function() invoke("clear") end
term.clearLine = function() invoke("clearLine") end
nativeTerm.clear()
nativeTerm.setCursorPos(1, 1)
print(os.version())
nitrogenfingers #5
Posted 01 June 2012 - 05:19 AM
I've passed the code on. Thanks for your help!