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

writing random characters

Started by samdeman22, 21 November 2012 - 09:43 AM
samdeman22 #1
Posted 21 November 2012 - 10:43 AM
I'm trying to make a fallout style lock and to do this I need to write out characters randomly.

will it work like this? (putting things like quotation marks in quotes)


randomchars = { "!", """, "#", "$", "%", "&", "'", "(", ")", "*", ",", "-", ".", "/", "\", "|", "{", "}", "@", "+", "=", "_" } -- 22 random characters

so if I do this

ypos = 4
for 1, 17*12 do -- this will be repeated twice, there are 17 lines in each collumn and 12 characters in each entry.
   if ypos ~= 18 then
   local rand = math.random( 1, 22 ) -- there are 22 characters
   term.setCursorPos( 6, ypos )
   term.write( randomchars[rand] )
   ypos = ypos + 1
end
-- I'll figure out the second collumn later

will it work?
billysback #2
Posted 21 November 2012 - 10:58 AM
I don't know if what you did will work, but you COULD do:

local chars = "!#£$%&amp;'[]{}()/><~"..'"'
local l = 12 --length of each line
local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
    local line = ""
    for i=1,l do
	    local n = math.random(string.len(chars))
	    line = line..chars:sub(n,n)
    end
    term.setCursorPos(offset[1], offset[2]+(y-1))
    term.write(line)
end

Sharing is caring!
also """ won't work, you have to do '"' or """ or something
samdeman22 #3
Posted 22 November 2012 - 05:21 AM
I don't know if what you did will work, but you COULD do:

local chars = "!#£$%&amp;'[]{}()/><~"..'"'
local l = 12 --length of each line
local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
	local line = ""
	for i=1,l do
		local n = math.random(string.len(chars))
		line = line..chars:sub(n,n)
	end
	term.setCursorPos(offset[1], offset[2]+(y-1))
	term.write(line)
end

Sharing is caring!
also """ won't work, you have to do '"' or """ or something

what does the colon and "sub" do?

"line = line..chars:sub(n,n)"
samdeman22 #4
Posted 22 November 2012 - 05:48 AM
I don't know if what you did will work, but you COULD do:

local chars = "!#£$%&amp;'[]{}()/><~"..'"'
local l = 12 --length of each line
local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
	local line = ""
	for i=1,l do
		local n = math.random(string.len(chars))
		line = line..chars:sub(n,n)
	end
	term.setCursorPos(offset[1], offset[2]+(y-1))
	term.write(line)
end

Sharing is caring!
also """ won't work, you have to do '"' or """ or something

hmm and what do I do if I want 3 out of the 17 lines to have a word on them?
This feels way more complicated than it should.
billysback #5
Posted 22 November 2012 - 06:03 AM
string:sub(x, y) is exactly the same as string.sub(string, x, y)

In case you don't know what string.sub does, it gets a section of the string from index "x" to index "y", 1 to length of string or -1 to -length of string, so
string:sub(1, -1) will get the whole string but string:sub(2, -2) will cut off the first and last letters of the string, so
string:sub(1, 4) will get the first 4 letters (from 1 to 4) so if it was:
"Hello World" and you did:
string:sub(1, 4) you would get "Hell" in return, if you did string:sub(2, -2) you would get "ello Worl", the string you are using the function on does not have the changes applied to it but instead a new string is returned with the changes done.

to add a line to the word at a random point amongst the characters then (if you want the word to be random do this):

local words = {"Hello", "World", "Random", "Word", "", "", "", "", ""} -- A table containing all of the words that could get randomly put in to a line
local chars = "!#£$%&amp;'[]{}()/><~"..'"' --string containing all possible random character
local l = 12 --length of each line

local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
		local line = ""
		for i=1,l do
				local n = math.random(string.len(chars)) --get a random character index from the string "chars"
				line = line..chars:sub(n,n) -- put the random character on the end of the line
		end
		local n = math.random(string.len(line)) --get a random index of the string "line"
		local str = {line:sub(1, n-1), line:sub(n, -1)} --split the string "line" before and after this index
		line = str[1]..(words[math.random(#words)])..[2] --put a random word either side of this n
		term.setCursorPos(offset[1], offset[2]+(y-1))
		term.write(line)
end

NOTE:
this won't stick to your string length any more, there would be more code needed if you want that :(/>/>
samdeman22 #6
Posted 22 November 2012 - 06:16 AM
Cool, thankyou!

But to complicate it even more, I want to be able to select each character unless it is a part of the word table (then it selects the whole word), and you see I don't have the slightest bit of knowlege on the new colour stuff, and it boggles my mind thinking about how to take strings out of this random jumble of text (and highlighting them in colour).
samdeman22 #7
Posted 22 November 2012 - 06:20 AM
would it be an idea if every line of these columns were in a table then it would be easier to position a selection.
billysback #8
Posted 22 November 2012 - 06:30 AM
that would require a slight recode of the loop, heres an example of doing it with color:

local words = {"Hello", "World", "Random", "Word", "", "", "", "", ""} -- A table containing all of the words that could get randomly put in to a line
local chars = "!#£$%&amp;'[]{}()/><~"..'"' --string containing all possible random character
local cols = {colors.pink, colors.purple, colors.blue, colors.green, colors.orange, colors.red, colors.lightBlue}
local word_col = colors.white
local l = 12 --length of each line

local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
				local line = ""
				for i=1,l do
								local n = math.random(string.len(chars)) --get a random character index from the string "chars"
								line = line..chars:sub(n,n) -- put the random character on the end of the line
				end
				local n = math.random(string.len(line)) --get a random index of the string "line"
				local str = {line:sub(1, n-1), line:sub(n, -1)} --split the string "line" before and after this index
				local word = words[math.random(#words)]
				line = str[1]..(word)..[2] --put a random word either side of this n
				for x=1,string.len(line) do
					 term.setCursorPos(offset[1]+(x-1), offset[2]+(y-1))
					 local col = cols[math.random(#cols)]
					 if x >= n and x <= (n+string.len(word)) then col = word_col end
					 term.setTextColor(col)
					 term.write(line)
				end
end

Tabbing messed up like usual, dunno why sorry :(/>/>
Lyqyd #9
Posted 22 November 2012 - 06:39 AM
As clarification, text:sub(1) is the same as string.sub(text, 1). One cannot use the same name for two different variables.
samdeman22 #10
Posted 22 November 2012 - 06:40 AM
that would require a slight recode of the loop, heres an example of doing it with color:

local words = {"Hello", "World", "Random", "Word", "", "", "", "", ""} -- A table containing all of the words that could get randomly put in to a line
local chars = "!#£$%&amp;'[]{}()/><~"..'"' --string containing all possible random character
local cols = {colors.pink, colors.purple, colors.blue, colors.green, colors.orange, colors.red, colors.lightBlue}
local word_col = colors.white
local l = 12 --length of each line

local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
				local line = ""
				for i=1,l do
								local n = math.random(string.len(chars)) --get a random character index from the string "chars"
								line = line..chars:sub(n,n) -- put the random character on the end of the line
				end
				local n = math.random(string.len(line)) --get a random index of the string "line"
				local str = {line:sub(1, n-1), line:sub(n, -1)} --split the string "line" before and after this index
				local word = words[math.random(#words)]
				line = str[1]..(word)..[2] --put a random word either side of this n
				for x=1,string.len(line) do
					 term.setCursorPos(offset[1]+(x-1), offset[2]+(y-1))
					 local col = cols[math.random(#cols)]
					 if x >= n and x <= (n+string.len(word)) then col = word_col end
					 term.setTextColor(col)
					 term.write(line)
				end
end

Tabbing messed up like usual, dunno why sorry :(/>/>

WOW you're fast but I guess you are a "pro" right? :(/>/>

I will test this once i can get to a computer with minecraft….
samdeman22 #11
Posted 22 November 2012 - 09:17 AM
hmm, I'm getting nowhere I might just commission billysback to make this because I just cant get my head round any of it. Do you know what the fallout console looks like?
billysback #12
Posted 22 November 2012 - 09:38 AM
Google is my friend!;
Spoiler
This doesn't seem too hard :(/>/>
I won't be able to code it, I'm going to have to take a stupid break from coding (RSI)
I'll try and help you as much as I can :(/>/>
remiX #13
Posted 22 November 2012 - 09:59 AM
With billysback code I got a nice mixture but the first 10 or so were the same:

Spoiler

So I tried it out but got rid of the words ^^

Spoiler


Code:
Spoiler
local chars = "!#£$%&amp;'[]{}()/><~"." --string containing all possible random character
local cols = {colors.pink, colors.purple, colors.blue, colors.green, colors.orange, colors.red, colors.lightBlue, colours.white}
local l = 12 --length of each line
local h = 17 --amount of lines

term.clear() term.setCursorPos(1,1)

for y = 1, h do
    local line = ""
    for i = 1, l do
        local n = math.random(1, #chars) --get a random character index from the string "chars"
        line = line..chars:sub(n,n) -- put the random character on the end of the line
        term.setTextColor(cols[math.random(#cols)])
        local n = math.random(1, #line)
        w = line:sub(n,n)
        term.write(w)
    end
    print("")
end
billysback #14
Posted 22 November 2012 - 10:03 AM
WOOPS, do:

local words = {"Hello", "World", "Random", "Word", "", "", "", "", ""} -- A table containing all of the words that could get randomly put in to a line
local chars = "!#£$%&amp;'[]{}()/><~"..'"' --string containing all possible random character
local cols = {colors.pink, colors.purple, colors.blue, colors.green, colors.orange, colors.red, colors.lightBlue}
local word_col = colors.white
local l = 12 --length of each line

local h = 17 --amount of lines
local offset = {1,1} --offset of x,y cursor pos
for y=1,17 do
                                local line = ""
                                for i=1,l do
                                                                local n = math.random(string.len(chars)) --get a random character index from the string "chars"
                                                                line = line..chars:sub(n,n) -- put the random character on the end of the line
                                end
                                local n = math.random(string.len(line)) --get a random index of the string "line"
                                local str = {line:sub(1, n-1), line:sub(n, -1)} --split the string "line" before and after this index
                                local word = words[math.random(#words)]
                                line = str[1]..(word)..[2] --put a random word either side of this n
                                for x=1,string.len(line) do
                                         term.setCursorPos(offset[1]+(x-1), offset[2]+(y-1))
                                         local col = cols[math.random(#cols)]
                                         if x >= n and x <= (n+string.len(word)) then col = word_col end
                                         term.setTextColor(col)
                                         term.write(line:sub(x,x))
                                end
end
remiX #15
Posted 22 November 2012 - 10:10 AM
If I'm not mistaken this line

line = str[1]..(word)..[2] --put a random word either side of this n
should be
line = str[1]..word -- the [2] gives an error ;)/>/>
With that, the length of each line isn't constant :/
Spoiler
billysback #16
Posted 22 November 2012 - 10:12 AM
should be:

line = str[1]..word..str[2]
you could do:

local l = string.len(world)
if l > string.len(str[2]) then l = -1 end
local aft = string.sub(str[2], 1, l)
local nline = str[1]..word..str[2]
line = nline:sub(1, string.len(line))
samdeman22 #17
Posted 23 November 2012 - 09:55 AM
ok I understand, I will try. I was never good at making UIs because I find the whole loop thing confusing. How am I meant to select each character (unless its a word, in which case select the whole word), by select I mean make the colour negative (text = green and background = lime, instead of text = lime and background = green. )
samdeman22 #18
Posted 23 November 2012 - 09:57 AM
ahh, I have an idea to change the whole thing, at the beginning it randomly generates text into a 17 section table then it selects 6 or so of the table positions and puts words into them, that way it would be easy to reference your selection to the table. Do you know what I mean?
billysback #19
Posted 23 November 2012 - 10:36 AM
wait is the second post you made a solution to the first one?
to make the color always lime and the background always green just make the cols table contain only one colour, you could make a new table for back_cols and edit my program (it should be pretty obvious) by just copying all of the cols code and renaming the values back_col or back_cols etc. then doing term.setBackgroundColor(back_col) at the same point as term.setTextColor()
samdeman22 #20
Posted 24 November 2012 - 06:45 AM
no, its just something think would make it easier.