Now for something completely different …

  • Imagine a two-dimensional space.
  • Imagine a Letter object.
    • It has a location.
    • It has a preferred direction
    • It can be told to move one step in its preferred direction.
  • Imagine a LetterMaker
    • It can make four letters at a time.
    • It has an index X starting at zero.
    • Every time it is touched.
      • It tells all existing letters to move.
      • It creates four instances of letter X
      • It places them all at Y = 0
      • It places two at -X and two at X
      • It increments X

The result might look something like this.

As you see if you looked at the video above, I coded this up in Codea. It’s just a few files, a Main, a LetterMaker class, and a Letter class. Here’s the code, then some discussion below:

-- Diamond
-- Main

function setup()
    Letters = {}
    table.insert(Letters,LetterMaker())
end

function draw()
    background(40, 40, 50)
    strokeWidth(5)
    for _,o in pairs(Letters) do
        o:draw()
    end
end

function touched(touch)
    for _,o in pairs(Letters) do
        o:touched(touch)
    end
end

-- LetterMaker

LetterMaker = class()

function LetterMaker:init()
    self.i = 0
    self.alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
end

function LetterMaker:draw()
end

function LetterMaker:move()
end

function LetterMaker:touched(touch)
    if (touch.state) ~= BEGAN then return end
    print("touched")
    for _,o in pairs(Letters) do
        o:move()
    end
    local letter = string.sub(self.alpha,self.i+1,self.i+1)
    table.insert(Letters,Letter(letter,self.i,0,true))
    table.insert(Letters,Letter(letter,self.i,0,false))
    table.insert(Letters,Letter(letter,-self.i,0,true))
    table.insert(Letters,Letter(letter,-self.i,0,false))
    print(letter)
    self.i = self.i + 1
end

-- Letter

Letter = class()

function Letter:init(s,x,y,up)
    print("creating", s)
    self.s = s
    self.x = x
    self.y = y
    self.step = -1
    if up then self.step = 1 end
end

function Letter:draw()
    pushMatrix()
    translate(WIDTH/2 + self.x*30, HEIGHT/2 + self.y*30)
    scale(2,2)
    text(self.s, 0,0)
    popMatrix()
end

function Letter:move()
    self.y = self.y + self.step 
ends

function Letter:touched(touch)
end

Discussion, as threatened

Well, the operation of the thing is perfect, I think you’ll have to admit that. Every time you touch the screen, all the letters that are there move up or down as they should. At the center row, it appears that there’s just one A, which splits into two A’s, one going up, one going down. Two B’s appear. On the next cycle, they split, two going up, two down. C’s appear. And so on.

Now the truth is there are four A’s, not two, all on top of each other at first, then two going up and two going down. That may be deeply troubling to you: I rather like it.

Similarly there are four B’s, nicely spaced where they should be, and then two go up and two go down. That makes perfect sense, it seems to me.

I know the voices in my head aren’t real, but sometimes they have good ideas.

No, not quite, but things do just come to us. If we’re programmers, they are often programming ideas. I had been thinking about a string transformation version, such as Bill Tozier and I discussed. I had even tried it, but it went so badly that even I won’t publish it, and I’ll publish even the most stupid things I try.

So I was thinking about that and imagining a rectangle like we draw, not a flat string as one would for a string transform. I imagined wrapping each “line” in dashes, then splitting the middle line, then moving half up and half down, then inserting a new letter line in the middle gap. As one would.

The only tool I have where I could build something that looked like that is Codea, so I started thinking about doing it there.

Game of Life

Well, now, that gets interesting. I drew some pictures of transitions and that made me think of Game of Life for some reason. Ha, just what we need, a cellular automaton solution where space begets an A and a single letter begets two on top of each other, and so on. Unfortunately, that seems to require action at a distance, which seemed right out for a cellular automaton.

I do think it might be possible to do that way. Since the universe is made up of cellular automata, at least according to some, it surely is. But it seemed not to be simple enough in the context of the Diamond and what we’ve seen so far.

Letters running around in Codea

The automaton seemed right out but I was still musing about creating letters and having them run around the screen in Codea.

My intial notion was to have the letters spawn the next letters, and to have them duplicate, making two rows from one in the center. Just a little code sketching told me that was still too tricky. A letter would spawn new ones if it was in the center, and tell them which way to go and then next time … I don’t know, it got to feeling too complicated to make all the letters autonomous. Basically it was the automaton all over again, as I think about it now.

But if you think about what has to happen a bit, you see that the operation of building the diamond like in the video is rather simple. On each triggering event (a touch in our case):

  • The letters above and below center move up or down respectively
  • The letters at center split, one goes up, one goes down
  • New letters appear at center, one letter down the alphabet, wider apart

It’s not a big insight – at least it wasn’t for me – to realize that if I spawned duplicates at center, some tending up and some down, it would appear that they spit but in fact they were there all along. So the program becomes:

  • The letters above and below center move up or down respectively
  • New letters appear (four, on top of each other) one down the alphabet, wider apart.

So I wrote it …

No TDD. I have built a little TDD tool for Codea but I find it nearly useless. Everything that happens is so atomic: move yourself, draw yourself, touch yourself, no, well, handle being touched oh never mind deal with a touch event.

Anyway, everything is so atomic, and the results so visible that I find TDD style not to be helpful. I still go in very small steps, but the tests are in my head, not in code.

That will bite me, from time to time, when I change something in a larger program, but even then, frequent testing by running the game seems to suffice.

Bottom Line

It’s fascinating to me how many different ways there are of looking at this problem. I’ve done a few myself, and linked to other examples here. And there are three or four more examples in my Twitter stream, which I’ll write about soon.

Thanks for stopping by and keep those cards and letters coming in.

And if you have time and a place to do so, please link to ronjeffries.com to aid in the transition between xprogramming and here. It might be best to link to the top of the site, there’s a good chance I’ll be changing some details of the article links. Thanks again!