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

Split A Variable

Started by arongy, 09 February 2012 - 08:35 PM
arongy #1
Posted 09 February 2012 - 09:35 PM
Hello, I am making a In Game clock with lamps and computer.
What i want to know is how i could split a variable as the time.

for the minutes computer i want to take the minutes number.
Exemple:
In minecraft it is 12:47 PM
I want to have the number 7 alone.
then number 4 for the second computer
etc for 2 and 1.

I know how to get the time but not how to split the variable into 4 variables.

Thanks!
Advert #2
Posted 09 February 2012 - 09:40 PM
Hello, I am making a In Game clock with lamps and computer.
What i want to know is how i could split a variable as the time.

for the minutes computer i want to take the minutes number.
Exemple:
In minecraft it is 12:47 PM
I want to have the number 7 alone.
then number 4 for the second computer
etc for 2 and 1.

I know how to get the time but not how to split the variable into 4 variables.

Thanks!

Take a look at string.sub("string", startN, endN)
example:

string.sub("Hello", 1, 1) --> "H"
string.sub("Hello", 3, 3) --> "l"


So, for you: (assuming os.time() always returns 1.234 (numbers change, period stays in place)

string.sub(os.time(), 1, 1) -> Number 1
-- We don't want the 2nd character, since it's just a period.
string.sub(os.time(), 3, 3) -> Number 2
string.sub(os.time(), 4, 4) -> Number 3
string.sub(os.time(), 5, 5) -> Number 4

Above is wrong, but you can still fix it yourself (os.time returns 1-24.000-999) use it to check and fix. I'll post a fixed version in a few minutes.


Fixed version:


local function getDigits()
local digits = {0, 0, 0, 0} -- Sets digits[1-4] at default of 0, not nil
local time = tostring(os.time())

if time:byte(2) == 46 then
  -- ^ This is essentially just a shortcut to 'if time:sub(2,2) == "." then'
  digits[2] = tonumber(time:sub(1,1))
  digits[3] = tonumber(time:sub(3,3))
  digits[4] = tonumber(time:sub(4,4))
else
  digits[1] = tonumber(time:sub(1,1))
  digits[2] = tonumber(time:sub(2,2))
  digits[3] = tonumber(time:sub(4,4))
  digits[4] = tonumber(time:sub(5,5))
end
return digits
end

print(textutils.tabulate(getDigits())) -- You can remove this line, it was for debugs.


getDigits() will return the digits of the clock, in a table with 4 numbers.

So, if you have computer1, which will display the first hour digit: use getDigits()[1] – make sure that the above function is defined BEFORE you call getDigits(), or you'll error.
Edited on 09 February 2012 - 09:02 PM
Brigander #3
Posted 09 February 2012 - 10:59 PM
This should serve you perfectly. I just did this project 2 nights ago myself and this is what I came up with.
First block is a modification of the textutils api function that forces both the hour and minute to be 2 digits.
Second block takes the in-game time and converts it to the specified time scale then breaks the string into the necessary hour and minute segments.


function formatTime(nTime)
  local nHour = math.floor(nTime)
  --Uncomment this chunk to convert to 12 hour time, commenting makes it 24 hour.
  --[[if nHour >= 13 then
    nHour = nHour/2
  end]]
  local nMinute = math.floor((nTime - nHour)*60)
  return string.format( "%02d:%02d", nHour, nMinute )
end

function encodeTime()
  gameTime = os.time()
  eTime = formatTime(gameTime)
  hour1 = string.sub(eTime, 1, 1)
  hour2 = string.sub(eTime, 2, 2)
  minute1 = string.sub(eTime, 4, 4)
  minute2 = string.sub(eTime, 5, 5)
end
arongy #4
Posted 10 February 2012 - 12:03 AM
Here the topic with pictures and coming soon video
http://www.computercraft.info/forums2/index.php?/topic/62-minecraft-time-clock/
Advert #5
Posted 10 February 2012 - 08:42 AM

...
--Uncomment this chunk to convert to 12 hour time, commenting makes it 24 hour.
  --[[if nHour >= 13 then
	nHour = nHour/2
...

That won't covert it to 12 hour! What'll happen is:
1-12: 1-2
13: 6/7,
14: 7
15: 7/8
etc.

What you want is:

if nHour > 12 then
nHour = nHour - 12
end

Other than that, your function will be more accurate than mine (mine won't convert minute to 60 seconds).
However, you should really use a return statement, and local variables (it's just good practice, and will help show your program's flow):

function encodeTime()
  gameTime = os.time()
  eTime = formatTime(gameTime)
  local hour1 = string.sub(eTime, 1, 1)
  local hour2 = string.sub(eTime, 2, 2)
  local minute1 = string.sub(eTime, 4, 4)
  local minute2 = string.sub(eTime, 5, 5)
  return hour1, hour2, minute1, minute2 -- Comment this and uncomment below if you want it in a table, instead of multiple arguments.
  -- return {"hour1" = hour1, "hour2" = hour2, "minute1" = minute1, "minute2" = minute2} -- You can remove the "hour1" = parts if you want table.1-4 to be used instead.
end
arongy #6
Posted 10 February 2012 - 01:33 PM
I did as this, for one of my computer:

function formatTime(nTime)
  local nHour = math.floor(nTime)
  local nMinute = math.floor((nTime - nHour)*60)
  return string.format( "%02d:%02d", nHour, nMinute )
end
function encodeTime()
  gameTime = os.time()
  eTime = formatTime(gameTime)
  hour1 = string.sub(eTime, 1, 1)
  hour2 = string.sub(eTime, 2, 2)
  minute1 = string.sub(eTime, 4, 4)
  minute2 = string.sub(eTime, 5, 5)
  return minute1
end
timetostring = "0"
while true do
timetostring = encodeTime()

    if timetostring == "0" then
shell.run("rom/zero")
elseif timetostring == "1" then
shell.run("rom/one")
elseif timetostring == "2" then
shell.run("rom/two")
elseif timetostring == "3" then
shell.run("rom/three")
elseif timetostring == "4" then
shell.run("rom/four")
elseif timetostring == "5" then
shell.run("rom/five")
elseif timetostring == "6" then
shell.run("rom/six")
elseif timetostring == "7" then
shell.run("rom/seven")
elseif timetostring == "8" then
shell.run("rom/eight")
elseif timetostring == "9" then
shell.run("rom/nine")
end

sleep(0.50)
end