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

multiple options?

Started by ironwiccan, 02 May 2013 - 07:47 PM
ironwiccan #1
Posted 02 May 2013 - 09:47 PM
I have searched the forums and the wiki and I cant find anything. What I'm looking for is the option to make multiple choices. Example

What would you like to do?
[1] shut down
[2] reboot
[3] open door

Any hints?
Bubba #2
Posted 02 May 2013 - 10:07 PM
Huh. Actually now that I've looked around in the tutorials section, I'm not seeing anything that's very simple to follow while at the same time making use of good coding habits. I myself have made a tutorial on menus, but it's more for intermediate-advanced Lua programmers than for those new to programming.

Anyway, here's how I would go about it (note - please read the comments and don't just copy/paste! :)/>)

local termX, termY = term.getSize() --Get the terminal size
local function centerPrint(text, y) --Pretty self explanatory: just writes text to the center of the screen
  term.setCursorPos(termX/2-#text/2, y)
  term.write(text)
end

local menu_options = { --Our menu options: you can increase or decrease this list as you wish
[1] = "menu option 1";
[2] = "menu option 2";
[3] = "menu option 3";
}
term.clear() --Just clear the screen first
local startY = termY/2-#menu_options/2 --This is the starting position that we'll draw at.
for i=1, #menu_options do --A for loop which will write our menu options to the screen.
  centerPrint("["..i.."] "..menu_options[i], startY)
  startY = startY + 1
end

term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")

local selected = false --This will be our selected menu item, but since nothing has been selected yet we''ll just set it to false
while true do
  local e = {os.pullEvent()} --This will take events and put them into an event table
  if e[1] == "char" then --If the returned event is a character then
    if menu_options[tonumber(e[2])] then --Check if the pressed key is inside of the menu_options table
	  selected = tonumber(e[2]) --If so, set selected to the index and break out of our loop
	  break
    end
  end
end

print("You've selected: ".. menu_options[selected])


In case you're confused by anything in this tutorial, here's a small list of the important stuff:
  • Tables - signified by brackets { }, this contains a number of items that correlate to the given index.
  • tonumber(e[2]) - This simply converts the event returned by os.pullEvent() into a number, if it is one. If it is not a number, it will return a nil value (essentially nothing)
  • term.setCursorPos(termX/2-#text/2, y) - This divides the length of the terminal in half, and then subtracts the length of the text/2 from that so we can center the text nicely
And that's about it. If you've got any more questions, feel free to ask.
theoriginalbit #3
Posted 02 May 2013 - 10:08 PM
EDIT: Haha damn ninja's :ph34r:/>

Something like this would do the trick.

local function openDoor()
  rs.setOutput('back', true)
  sleep(4)
  rs.setOutput('back', false)
end

local options = {
  {"shut down" = os.shutdown},
  {"reboot" = os.reboot},
  {"open door" = openDoor},
}
print("What would you like to do?")
for i = 1, #options do
  print('['..i..'] '..options[i][1])
end

while true do
  local input = read()
  if not tonumber(input) then
	print('Not a number between 1 and '..#options)
  elseif options[tonumber(input)] then
	options[tonumber(input)]()
  else
	print('Not a valid number between 1 and '..#options)
  end
end
Edited on 02 May 2013 - 08:08 PM
ironwiccan #4
Posted 02 May 2013 - 10:12 PM
Huh. Actually now that I've looked around in the tutorials section, I'm not seeing anything that's very simple to follow while at the same time making use of good coding habits. I myself have made a tutorial on menus, but it's more for intermediate-advanced Lua programmers than for those new to programming.

Anyway, here's how I would go about it:

local termX, termY = term.getSize()
local function centerPrint(text, y)
  term.setCursorPos(termX/2-#text/2, y)
  term.write(text)
end

local menu_options = {
[1] = "menu option 1";
[2] = "menu option 2";
[3] = "menu option 3";
}

local startY = termY/2-#menu_options/2
for i=1, #menu_options do
  centerPrint("["..i.."] "..menu_options[i], startY)
  startY = startY + 1
end

local selected = false
while true do
  local e = {os.pullEvent()
  if e[1] == "char" then
	if menu_options(tonumber(e[2])) then
	  selected = tonumber(e[2])
	  break
	end
  end
end

print("You've selected: ".. menu_options[selected])
would that allow me to just press the corespding number? Cause that's what I'm trying to do. Sorry about all the questions, Im new to programming.
Bubba #5
Posted 02 May 2013 - 10:21 PM
would that allow me to just press the corespding number? Cause that's what I'm trying to do. Sorry about all the questions, Im new to programming.

Indeed it would. Sorry, I tend to type out a quick reply and then edit my post to add more detail (hence the ninja :lol:/>). I've added comments now, so hopefully that'll help you out some.