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

Advanced Data Storage and/or Looping through Data

Started by Bobtank, 27 February 2015 - 04:50 AM
Bobtank #1
Posted 27 February 2015 - 05:50 AM
I recently started working on some CC signs for a new spawn being built on my server and I decided I wanted the text to be somewhat animated. For the animation I wanted just a simple change in color, changing each letter 1 at a time. I thought of different ways to go about this and I ended up with 2 dimensional array filled with booleans. It was a pain to write out the small changes and I figured someone here might have an idea of a more efficient / expandable method of approaching it. I thought the Bit API might be able suit my needs but haven't thought of a way to use it effectively yet. My question towards Ask a Pro is how would you go about this in a more effective manner?

The code for anyone interested: http://pastebin.com/F4LDwuUm (It's intended to be run on a computer with 3 monitors stacked vertically above it)

Also I wasn't very sure what to title this so I hope its not too misleading
Edited on 27 February 2015 - 05:06 AM
Bomb Bloke #2
Posted 27 February 2015 - 06:48 AM
Well, you could use the bit API for this, and I for one would have great fun explaining how it'd work… but that's really not the easiest or most dynamic way to go about it.

Let's say you define "text" as a simple string, set to "ARENA". You can then use #text to get the length of that string, and you can use text:sub(x,y) to get substrings from "text" (eg, text:sub(2,4) would be "REN"). You can do all sorts of other things with strings - this article is well worth a read.

So if you combine those concepts with a couple of tracking variables, you should be able to simply the script down to something along the lines of:

local text, counter, flip, mon = "ARENA", 1, false, peripheral.wrap("top")

mon.clear()
mon.setTextScale(2.5)

while true do
	mon.setTextColour(flip and colours.lime or colours.white)  -- See http://lua-users.org/wiki/TernaryOperator
		
	for i = 1, #text do
		mon.setCursorPos(2, i + 2)
		mon.write(text:sub(i, i))
		
		if i == counter then mon.setTextColour(flip and colours.white or colours.lime) end
	end
	
	counter = counter + 1
	if counter > #text then
		flip = not flip  -- flip becomes true if false, or false if true.
		counter = 1
	end
	
	sleep(1)
end
Edited on 27 February 2015 - 05:50 AM
Bobtank #3
Posted 27 February 2015 - 07:21 AM
This is exactly what I was looking for for my current project, Thank you! Also I presume this method would only really work when I want to circulate between 2 colors in the same fashion over and over again. Lets say I wanted to switch the animation to something such as:

if the current animation / table I made was written as
Spoiler00000
10000
11000
11100
11110
11111
01111
00111
00011
00001
(Where 0's would be white text and 1's as lime)

And I wanted something a bit more random such as
Spoiler00100
10101
00011
11101
etc
Would it be best to make use of the Bit API? If I wanted to expand into multiple colors would it be best to use the sub method of strings to dissect it?

An aside: I've wanted to learn the Bit API more and the only information I really found on it was the documentation on the site. Should I just keep practicing it as I see it documented or is there someplace I can learn a few tricks of when and how to use it effectively?
Bomb Bloke #4
Posted 27 February 2015 - 07:36 AM
The search term you're looking for is "bitwise operators". They're not covered in great detail on the ComputerCraft wiki as they're not a ComputerCraft-exclusive thing. This article is probably a good place to start reading.

If you really wanted a random pattern, then I'd just check whether math.random(2) > 1 every time you go to draw a character, and set the colour accordingly.

But assuming you wanted to follow that precise set, yes, bitwise operators would provide a simple means of doing so. Take the number each binary pattern represents (eg, from your example, 4, 21, 3, and 29). As you iterate through your characters when rendering to the screen, take the binary AND of the current pattern you're using with the number 1 bitshifted to the right left (edit: where's my head at…) an amount of times equal to one less than the current letter you're up to. If the result is non-zero, use one colour, otherwise use the other.

Eg, with the binary representation of 29, we have:

11101

First letter, lbitshift 1 zero times, stays as 1. 1 AND 11101 is 1 (non-zero).

Second letter, lbitshift 1 one times, get 0b10 (or "two", in decimal). 10 AND 11101 is 0.

Third letter, lbitshift 1 two times, get 0b100 (or "four", in decimal). 100 AND 11101 is 100 (non-zero).

Etc.
Edited on 27 February 2015 - 06:44 AM
Bobtank #5
Posted 27 February 2015 - 07:52 AM
Ah thank you! These 2 posts from you should help a lot in the future and gives me more to thank about! I always enjoy expanding my skills in computercraft so this is perfect. Thanks again for taking some time to help me with this :)/>