SCRAM -- for beta users

The massive strings for the library are causing some problems on github as text files. But for nbeta users, here’s the code.

Any feedback appreciated.

http://devilstower.posterous.com/scram-10-aug-2012

I just got the “hello world” project for that.

Hmm. Dependency issue? I forgot that there’s a couple of classes pulled from a simple library. Does that need to be loaded first?

I loaded the library and the code again.

http://devilstower.posterous.com/mcslibrary

http://devilstower.posterous.com/scram-beta-2

Hmmm, @Mark, I got the same thing as Andrew: a big file but only one tab. It is Main and the Hello World program… :slight_smile: no dependencies that I could see.

I’ve sometimes created tab-less files like this when I use another program to load the files in to the iPad. If you don’t alter the plist file they won’t show up.

Both just give me the “hello world” program, but have the first line as, for example -- Scram. Is export broken?

Fred, but still Main would be the right main

yes, @Andrew_Stacey, I guess this main wouldn’t even be the Scram main because there Are no function calls. Perhaps these are the mains for the libraries, but without the tabs?

You’re right – the program is fine, but export/import doesn’t work. Somewhere along the line, the process is failing. Sorry about that.

That’s very odd, not sure why import/export stopped working. I’ll look into it.

I’ve just run the .codea files through Bortels’ decodea decoder (I downloaded the script since his code stores the decoded files in perpetuity on his website and I didn’t know if that would be okay) and the files are all there so export is working okay - it’s import that isn’t.

Incidentally, if @Bortels is listening, your script doesn’t extract the .plist files. Now that the order of tabs matters, it should. If I can see how to do it, I’ll make the necessary adjustments.

Okay, so the problem seems to occur at the unpacking stage. The right .codea file gets into the Inbox directory but not into the project. All I get is the default project. Also, when I exit the imported project I’m back at the home screen still with the dialog about creating a new project. Clicking Cancel (which used to work) now crashes Codea.

After all that, I do have Scram now loaded into Codea and will give it a spin. I might make use of those dictionaries as well for a couple of my projects.

Which reminds me: Mark, could you explicitly licence your code that you share? Not that I’ve any plans to release stuff on the App store, but now that people are starting to do this it might be worth introducing explicit licences for code shared on the forums earlier rather than later.

I think this might be an ARC issue. Thanks for digging into this issue and finding it occurs on import.

@Andrew _Stacey Will do. Basically, the library, the dictionaries, etc. are all up for grabs. About the only thing I’d like to hang onto out of his one is the design for the boards and tokens.

Great! Am I right in thinking that the graph drawing stuff I use in my pendulum simulation came from you? I couldn’t find the original code in a cursory search of the forum. If so, could you stick some licence on that? (I’m not planning on making an app any time soon, so I’m asking purely for clarity - see my recent post about my library).

Also, I now have Scram working. I just had a quick go - to check that it worked - and already like it and already have some comments!

First, really to @Simeon: I know that importing via .codea is not your top priority, or really importing at all since to do it one has to be at least circumventing the spirit of Apple’s rules (though I’m using libimobiledevice so amn’t even jailbroken). Still, when importing then I had to disable and then re-enable the project dependency, and I had to load the library project and exit it again. Not sure which actually did anything, but it took a few tries to get the library importing correctly.

Now, to the game. I keep saying this to juaxix (or whatever his “name” is): Instructions! The “Clear” and “Word” are not obviously “touchable”, and it’s not obvious from the word “Word” that this is how you invoke the checker. I realise you don’t want automatic checking, but I’d consider doing an autocheck when a tile is dropped on the target square.

The other comment was that it didn’t take me long to get a word not in your dictionary: Tor. It’s one of my best-used boggle words!

My other ponderment was as to whether this is a puzzle or a game. In a puzzle, there is always a solution and I must find it. In a game, there’s an amount of luck involved. I wasn’t sure if there would always be a next word that I could put in. Maybe this will become clear after playing it a few times - but then people aren’t going to play it a few times before downloading it from the app store!

And now I’m curious as to the rationale behind using string.find as opposed to loading the words as keys of a table and simply testing the existence of, say, dictionary[word].

Yeah, the dictionaries still need some work. I’m adding words as I run into gaps, but it’s definitely frustrating at the moment when a common word (I hit “stash” this morning) isnt there.

The reason the dictionary strings are implemented as they are is more mechanical than anything else. I downloaded lists into Excel, sorted, dropped duplicates, and tried to drive toward a standard (in this case, Americanized) spelling. Then I turned the whole mess into comma delimited strings that I could copy paste into email. From there I copy pasted again into Codea. I suppose I could have then turned around and piped it into global data and used it from an array, but I was concerned over how I would share it or how I would get it into the project for Xcode. I realize it’s a pretty ugly implementation, and I’m open to suggestions.

On the buttons: I was going to put some instructions on the title screen, but I think I’ll first make it clear that the buttons are actually buttons. Youre right that its non-obvious. Thanks.

On the nature of the game: it’s definitely a game. The overall distribution of tiles should match that of Scrabble (Super Scrabble, actually) but they are being pulled from a bottomless bag, so it’s quite easy to end up with an unplayable mix. Which is why my first inclination it to let you punch up a new tray of letters whenever you want.

Yep, the real time graphs are mine. Feel free to designate that code public domain.

I’ve just run some tests and looking up a key in a table beats string.find quite comprehensibly. My tests are probably not gold standard, though. My basic script runs the checkStringA function 100000 times, once with your checkStringA function and once with loading a file which starts:

function checkStringA(w)
    return words.A[w]
end

words = {}
words.A = {}

words.A["aardvark"] = true
words.A["aardwolf"] = true
-- etc

Then I timed the execution. I should note very clearly that I ran these on my laptop rather than on Codea - my intention was to benchmark lua, not particularly Codea. At 100000 iterations, your string.find was taking a noticeable amount of time: about 9s. The table lookup method was at 0.02s:

tmp% repeat 10 time lua testDict.lua
lua testDict.lua  8.41s user 0.00s system 99% cpu 8.410 total
lua testDict.lua  8.39s user 0.00s system 99% cpu 8.393 total
lua testDict.lua  8.40s user 0.00s system 99% cpu 8.406 total
lua testDict.lua  8.35s user 0.00s system 99% cpu 8.357 total
lua testDict.lua  8.41s user 0.00s system 99% cpu 8.409 total
lua testDict.lua  8.40s user 0.00s system 99% cpu 8.408 total
lua testDict.lua  8.47s user 0.00s system 99% cpu 8.477 total
lua testDict.lua  8.33s user 0.00s system 99% cpu 8.334 total
lua testDict.lua  8.35s user 0.00s system 99% cpu 8.352 total
lua testDict.lua  8.39s user 0.00s system 99% cpu 8.394 total
tmp% repeat 10 time lua testDict.lua
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.026 total
lua testDict.lua  0.02s user 0.00s system 95% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 94% cpu 0.021 total
lua testDict.lua  0.02s user 0.00s system 95% cpu 0.021 total

On the other hand, you do seem to end up using about twice the memory (first one is the string method):

tmp% /usr/bin/time -l lua testDict.lua
        0.84 real         0.84 user         0.00 sys
    700416  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
       179  page reclaims
tmp% /usr/bin/time -l lua testDict.lua
        0.01 real         0.00 user         0.00 sys
   1560576  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
       389  page reclaims

So: twice the memory, but about 40 times faster.

Incidentally, for the game, I’d make it cost something to reload the tiles. Otherwise you could keep hitting reload until you get something easy.

Also, it seemed that when the board loaded a new design that the new version was there already while it was also spinning out.

The board transition was more than a little ugly I that beta. I think it’s a bit neater now (in the working version).

I think my real concern with doing the table version of the dictionary is that it won’t fit in the editor (with several thousand words per letter) and I don’t know how to get Codea data to travel with the project. The crunched mass of words seemed like an ugly but functional approach.

Besides, I only check one word at a time, 9/100,000 seconds doesn’t seem so bad.

Two options:

  1. calling for a new set of times costs 5 seconds
  2. you’re limited to two new sets

Which do you like?

Oh, and what if I make the timer run faster, but give you time back for each word you play?

Frankly, I’d make it possible to have different modes of game play. I like all those ideas, but for me then I’d play one where I got time back because I’m a slow thinker so there’s a significant delay when I get a set of new letters.

Haven’t tried this, but I presume I can’t rearrange letters once I’ve “checked the word” on the board. In which case, it might be an idea to change their colour slightly to indicate that they are now immutable.

As for the table version of the dictionary you can still split it into several files. That is, in effect, what you are doing right now. Admittedly, the table list is 117k versus 33k (for the “A” letters) but actually a table makes it easier to split than the strings. If, say, you double the dictionary then at some point you have to think about splitting the string but then you have to rework the checking function. With a table, you don’t have to worry about that.

Moreover, think about other programs that might use the dictionary. Some might find themselves doing a dictionary check every draw() cycle. Then those precious seconds will be useful.