Aka “diving in and doing stuff”.
I realise I am no authority on the subject, but the last few days have had me engulfed in a project where I started out knowing almost nothing, and now it’s in a half-decent on-it’s-way-to-completion state. And I got to this point completely by googling the hell out of every roadblock I came up against and using as many readily available open source thingies as possible.
Yes, I’ve been coding. A game, to be particular. A game some nice Japanese people made (play store link). Why? I have no idea. It just seemed like a cool thing to do. I’ve always wanted to make a game. I’ve tinkered with another one before (I’ll talk about this later) but I’ve never built one before. And now I have a game idea to build upon!
The last time I did something like this, in the summer, I recorded progress on my app on my Facebook. In an album full of screenshots and annotations. Now I have a blog so a blog post it shall be. Ever-updating, of course.
First. Some preliminaries. I used XCode for this project partly because I was familiar with it and mostly because when I started it, I had nothing else with me. The mac stays at home though, so I’ll need to transfer the code to something like HTML5 if I want to be able to work on it in college. Or use one of the XCode windows ports for the computer in my hostel room. Whatever. Now that that’s out of the way, what I did:
One aspect of “game programming” that’s always daunting for me is the simple act of getting a window up that then displays an image. This is like Everest for me. It is such a steep mental block that I have given up countless roguelike game ideas because I could never get a window up in Python. I know PyGame and stuff exist but I was too “purist” a few years ago. I wanted to write everything myself. Now I know better.
Now I know, for instance, that being a purist is simply not feasible, at least for me. There are people out there who have done all the work for me. I just need to find those people and use their work. This is not exactly trivial. For instance, I use Cocos2D to do all the graphicy stuff. (I say “do” rather loosely). It is ridiculously simple to set up and use. But it took me the better part of a couple of hours to find it, or indeed that it was what I was looking for. I know this might not seem like much time, but it is when you take into consideration that I want to do this for fun. Not much fun if I can’t get started.
So. I was lucky to find Cocos2D. I had a thing that could put stuff on the screen. Yay.
What will I put up, exactly? Well.
Oh dammit. I haven’t explained the game to you yet.
Sigh. Hold on.
Okay. This is a screenshot from the game so far. (Thank you!)
See those little white or black squares here and there? And see those shapes that the lines form, boxy little things? I call those shapes regions and those squares crossings. A white crossing is off, a black one is on. If you tap a region, all the crossings along its boundary are toggled. Your goal is to turn every crossing on.
Now, if you notice, that picture might seem complicated to make. If you think about it for a second, though, you’ll see that it’s actually composed of little tiles, of which you only need 9. These 9, to be precise:
Cool, right? So all I have to do is figure out a way to put those tiles together in order to make whatever knot I want. How do I put them together? Well. There’s a thing called the arc presentation of a knot, which is an array of coordinates from which you can generate these images. I won’t bore you with the details but I will point you to the website that will: Knot Atlas.
Next problem. How do I get these arrays? That same website (a sort of Wikipedia for knots) also has these arrays for the first 250 prime knots. Aaand they have a database you can download of all the info they have. Perfect? Not quite. That database doesn’t include these arrays (because they’re not unique.) So I need some other way to get what I need.
Every mac comes with a brilliant little program called Automator that you can use to automate little everyday things. For instance, you can make an app whose sole purpose is, when clicked, to close all other apps. Or you can stitch together loads of images into a PDF. Or you can mass rename things. Or. Or. You can do this:
Too perfect. The first bit spits out a list of all the links on the page given to it. The page I sent it to was this one. It has links to all the knots I need plus some extraneous things. I cut out the stuff I didn’t need and fed that into the second bit that, in ten minutes, dumped a biiig text file containing aaaaaall the text from those webpages.
Now. I need to locate the arrays. And convert them into this thing called a .plist file which is what XCode understands very easily. Easy enough, Python! I wrote a Python script that sifts through the text, finds the array, yanks it out, and dumps all them into a neat plist.
(I like screenshots.)
Anyway. Now I have a bunch of arrays that I can make knots from. Oh, and by the way. This isn’t in strict chronological order. There’s no way I would go through all this without first having a working piece of code.
And that code was by turns easy and frustrating to write. What I basically had to do was follow the rules of the arc presentation to go from the array of the website to the array of image files I needed to call in order to draw the damn knot. Not difficult. The difficult bits were then recognising which region you tapped in. And once you’ve recognised it, how the hell do you then associate the crossings of that region to the region itself? I had no idea.
For a few hours anyway. Then I broke the problem down. Like this:
Well. I’ll worry about how I get the regions and crossings and all later. First, given the vertices of a polygon, how do I detect when I’ve tapped inside it?
Easy enough. Googleable. Found a website that I want to link to but I can’t seem to find it now. Ah well. After that, I needed a way to actually get those vertices from the array.
I don’t quite know how I arrived at the Jordan Curve Theorem but I did. What the theorem states is basically this: if you have a closed simple curve and you attach a direction to it, travelling along the curve in that direction, the “inside” of that curve will always be to one side of you. Obvious enough no? But this was the catalyst I needed, the guarantee to continue, essentially.
Basically, if you start at one of the corners or a crossing, and follow the path defined by the above rules, you’ll always get back to your original point and you’ll have described a region in the process. You can pick up any crossings along the way and make them “belong” to the region. Done!
Let me illustrate:
The 10s are top-left corners, (the “aa” image from the second screenshot). The 3s are crossings. Fill in the rest yourselves. What I mean is, start at every 10 or 3 (nothing else; I’ll explain why in a bit) and then keep following the curve until you hit another corner or crossing, whereupon you then turn in the manner indicated. If you do this, you will have mapped out all the regions on the knot, except for the outside region. Some duplicates exist. The reason I say don’t start at 11s or anything else is because they are always duplicates (think about it). Or, with 11s in particular, they usually map the outside region. Why? Because starting at the bottom most 11, if you go right, you are mapping “down” as a region. And “down” points to the outside. You will traverse all the vertices on the outermost fold of the knot. Cool no?
Anyway. I have all the info I need. (I’m skipping over a bug from repeated regions in the interest of now laughable brevity.) I wrote it all down and boom. I can draw any of 249 knots. I can tap away at any region and all the correct crossings toggle instantly. I’ve even included the outside region. Some knots are ridiculously easy to solve because the crossings are all off to begin with. So I made it so that each time a knot is drawn a random number of crossings are already on. This makes it not as straightforward for easy knots and quite fiendishly hard on the normal knots. Yay.
Ish. I still need a menu and buttons and a counter for how many moves you’ve made and a display that tells you the minimum number you actually need and sits and mocks you when you exceed it. All in good time.
Further thoughts I shall add later. When I’m optimising the thing because right now it leaks memory like crazy.
Thanks for reading! (If you survived this far, that is!) Do comment. Or if you code yourself, feel free to tell me better ways to do stuff, especially a non-mac way to yank text from webpages.