Archive for November, 2010

Nov 29 2010

Fictional telephone numbers

Published by Dougal under Culture

US-made film and television use the 555 telephone prefix for fake telephone numbers. According to the IMDb trivia page for Fight Club:

Marla Singer’s phone number, 555-0134, is the same as Teddy’s number in Memento (2000). It is also the same as the Hong Kong Restaurant in Harriet the Spy (1996), Eddie Alden’s in Animal Attraction (2001) and a Mental institution in an episode of “Millennium” (1996/I).

In fact there are only a hundred telephone numbers sanctioned for fictional use in this way — 555-0100 to 555-0199. There must be an awful lot of overlap. So which are the most common fictional telephone numbers? Which ones have never been used? Well, this is the internet so someone has compiled a list of numbers and the films they appear in, for your personal delight and instruction.

One response so far

Nov 25 2010

Perdido Street Station enjoyable but inconsistent

Published by Dougal under Books, Reviews

It’s about this time of the month when I finish whatever book that I picked up from book group and decide to write about it. Then when the next meeting comes around I’ve forgotten what I said at the time and just blabber incoherently about some vague ideas I had. Or is that what I do here?

Just finished Perdido Street Station by China Miéville (first book I’ve read by him). Probably most neatly described as “fantasy steampunk” since it gathers in all of the elements you’d expect from these genres: a land of strange beasts and many sapient species, real magic, mechanical calculating machines and steam-driven engines in an early industrial society.

The book is quite hefty and nothing definite happens until halfway. Then it got very compelling and I raced through the second half in much shorter time. Initially I found the descriptive language quite ponderous and found myself rereading paragraphs more often than normal because I couldn’t wring sense out of it. (I was also reading quite late at night, which doesn’t help.) The language didn’t get any more direct the further I read, but I got used to it and it was easier when I was more engaged.

It was hard to take some of the creatures in the story seriously for a long time. They’re the kind of bad scifi/fantasy that really bugs me about Dr Who — sentient walking cactus people? (They have to file down their spines so they can hold stuff properly.) A species that has human female bodies but the entire body of a scarab beetle as a head? Of course these are entirely logical evolutionary outcomes for any world…

Once you’re over the absurdity of what you’re reading it’s an enjoyable book. One of the later characters, the Weaver, is a brilliant trickster — a kind of Ungoliant character with the personality of the Cheshire cat — a huge, dangerous spider that hums nonsense verse to itself while flitting through the world to fix things for its own aesthetic purposes.

For all that, I have come to the conclusion that the story doesn’t really hang together. The threat to be defeated is a natural one, but one which is almost-invincible and has an insatiable appetite for people. I fully understand that invading predators can be an incredible threat to an ecosystem, but normally they fit somewhere into their own environment. But it’s a bit of a stretch to claim that magical, soul-sucking, hypnotising eight-metre dragons which can taste conscious thought on the wind… would be a localised phenomenon wherever they live.

So while I did enjoy the book, it’s not one you want to think about — in fact, it helps if you think about it less than a traditional “high fantasy” novel.

Comments Off

Nov 23 2010

Rounded rectangles

Published by Dougal under Programming

The latest addition to ComicBake is speech bubbles with rounded corners. The GD library bindings don’t currently support many drawing operations (though the library itself is quite complete) so I’m having to awkwardly construct shapes using the few primitives I have at my disposal.

The problem is simple — to round off the edges of an otherwise brutish rectangle:

roundRectExample0

The method is quite straightforward. The rounded rectangle is decomposed into six separate shapes. There is a full-height rectangle overlaid with a full-width rectangle, resulting in a fat cross shape. The little gaps in the corners are where the rounded corners need to go.

roundRectExample1

At this stage we’ve already decided something vital: how much of a curve should these rectangles have? I started off with the assumption that the radius of the curve shouldn’t be so large that two adjacent curves meet. There should always be a bit of straight line in between them.

I also wanted the radius of the horizontal and the vertical to be the same, so that the resulting shape is a proper circle not an ellipse. This cuts down on the number of things to reason about.

The radius here is calculated as 1/3 of the smallest dimension (width or height) of the rectangle. This works okay in the “middle ground” but gets silly if the rectangle is too big or too small. If the rectangle is too small then the curves look a bit rubbish because they get too triangular. So the minimum radius of the curve is set to the font size.

If the rectangle gets too big then the corner pieces become huge and the curved area starts to look more like a blob, which encroaches on the text inside. So the maximum is 3 times the font size.

With the given radius we draw the rectangles above and then create little circles of that size in the corners, centred on point which is 1 radius-length in from each edge:

roundRectExample2

When we use white instead of lots of bright colours for this we get a uniform shape which I’m happy to call a rounded rectangle.

roundRectExample3

Comments Off

Nov 21 2010

Hurling dwarves over other dwarves: probably not legal

Published by Dougal under Bugs, Games, Programming

It’s been a quiet week on the programming front but I’ve made steady changes to Thud since committing the initial code to BitBucket ten days ago.

I’ve added some unit tests, which was a simple thing to do but not very easy to get right. Unit tests are a bit like Cluedo, in that you have to convince yourself of something very complicated with a few well-chosen questions. And it’s easy to forget your assumptions and miss something vital.

Just today I spotted something by playing with the game. I realised it was possible to hurl or shove a piece over another to reach the enemy on the far side. The logic only checked that the target was within reach but not that it was within proper line of sight. (This goes back to the original implementation too, so it’s not just a feature of my mucking about with the code that deals with the game rules and breaking something.) The rules are silent on whether this is even allowed (I suspect not) so I’ve disallowed it for now.

This is not the kind of bug I would have caught with unit tests because it would never have occurred to me to check for it. Of course the butler didn’t commit the murder, that’s preposterous! I only spotted it during play because I was purposely lining up foes next to each other in order to manually test their capture capabilities and realised that I could hurl a dwarf further than necessary… and the game allowed it.

So I’ve been repeatedly rewriting the file that deals with game rules so that scenarios like this become more obvious. I’m getting to the point where I’m happy with this small segment so I need to push on to other things.

As I mentioned on another post it’s nice having an issue tracker for the code so I can write down any ideas that occur to me, whether they’re short-term or long-term concerns. I think it’s time to look at some of the more medium-term goals now, such as network interaction, otherwise I’ll spend the rest of my days endlessly fiddling with the game rules.

Comments Off

Nov 16 2010

Blog post title

Published by Dougal under Bugs, Humour

Description of screenshot included in blog post:

3 responses so far

Nov 15 2010

Arkham Horror: insane in the boardgame

Published by Dougal under Friends, Games

Had a go at Nick’s brand new copy of Arkham Horror last night. It’s a co-operative board game based around HP Lovercraft’s Cthulhu mythos, set in the New England town of Massachusetts and connected alien worlds.

I arrived at about 3pm. They’d already started laying out the board, sorting the pieces (more than 700…) and identifying the main game elements. We didn’t get started properly until Mat arrived which might have been about half an hour later. The same game was still going at 10.30 when I had to leave to catch the bus home. I learned on Facebook when I got home that the Ancient Ones had been defeated while I rode the bus home. So on a first attempt it appears the game took 6–7 hours to play.

Now I think you understand the scale and scope of the undertaking, we should look in more detail at how it works.

Interdimensional gates between Arkham and horrific other worlds open up at various spots around town. It’s your job to investigate these worlds by diving into the gates, and coming back to close the gates behind you. Oh yes, and killing all the monsters that flood through onto the streets of Arkham every time a gate opens.

This game plays like a regimented role-playing game, particularly battling monsters. Most things you do involve examining your own stats, examining the stats of your enemy, rolling dice for the numerical difference and seeing if you won/lost that bout. It’s quite a fast process to do when you get the hang of it, but because everything is stats-based it can be hard to remember which number gets subtracted from which number at each point.

(A detailed example. You are travelling the streets of Arkham and come across a monster. You’re on an errand and don’t want to dally so you attempt to sneak past. Roll N dice, where N is the difference between your Sneak and the monster’s Awareness. You’re aiming to throw a 5 or 6 to win. N will be large if you have a high Sneak value and your monster has a low Awareness, and the higher N is the more likely you’ll throw at least one 5 or 6. If you win, you can continue on your way. If you lose, receive damage for being caught unprepared while sneaking past, then proceed to do battle with the monster. First, test your mental fortitude: is this monster so horrific you go mad at the sight of it? As above, roll N dice where N is the difference between your Will and the monster’s Horror. Receive damage to your sanity if you lose. If you still retain your sanity, roll N dice where N is the difference between your Fight and its Combat rating. Many monsters have a toughness rating greater than one, and that’s the number of successful rolls you need to throw in order to kill it. If the number of dice you can throw is less than its toughness rating there is no way you can win this fight. Run away!)

The basic mechanism is quite straight-forward but the number of modifiers, special-cases and special adapted rules quickly spirals out of control.

The complexity of the rules is made so much worse by the awful manual which describes them. It’s 24 pages long and is terrible. It introduces terms which it makes no reasonable attempt to define, has an incomplete index, introduces descriptions out of order and sometimes omits them altogether. Sometimes whole paragraphs are devoted to making simple scenarios more complex, less transparent and altogether harder to follow. We wasted so much time hunting backwards and forwards through the book looking for “what to do in event of…” and eventually gave up. We probably accidentally omitted about 20% of the rules just because they’re not introduced in any sensible order. It seems altogether unlikely that we would win the game on the first attempt, doesn’t it?

But for all my complaints — and there are many — the game itself seemed powerful and worth investing time in. Once the rules are internalised (or easy to research: there are manuals written by fans available online) it should be easier to gather some momentum. In the last hour or so of play we seemed to move through the steps faster and with more fluidity, although there’s a good chance that’s because we all wanted the damn thing to finish.

If anyone does sit down for a game of this I have a couple recommendations: start earlier than you’re thinking and get more table space than you think you’ll need.

One response so far

Nov 11 2010

Thud now visible on Bitbucket

Published by Dougal under Friends, Programming

I’ve set up an account on BitBucket and published the initial commits into a Thud repository. Mat’s also joined up so hopefully we can get this project ticking along nicely with some good changes. Also some testing, which it is currently lacking. I’ll have to look into whatever unit test frameworks are used in the C# world. (I’ve just started contributing to Banshee too, so I hope to take some of the practices from that larger project and try my hand at them on Thud.)

Most of what I’ve done to Thud so far is just importing the old code into Mercurial and uploading it to the BitBucket servers. Since the original code is all Mat’s my first problem was learning how to commit code in someone else’s name. Thankfully that wasn’t a difficult problem:

$ hg commit --user "A N Other <another@example.com"

Visual Studio and MonoDevelop both spew auto-generated files around your project directory and I’m not sure what most of them do. I tried not to include anything that wasn’t too much like source code, but it’s still possible I’ve included useless extras or omitted something that is needed for building the project. So that’ll be another learning curve where I must patch in necessary files.

The only new code I have added cleans up the logic used when moving pieces on the board. There are still plenty more changes to be made, especially to improve testability, and I’ve started storing these in the bug tracker. Having a bug tracker is quite cool. :-)

Comments Off

Nov 08 2010

Rewriting COND as a series of nested IF statements

Published by Dougal under Programming

It’s been a while since I mentioned SICP and this time I’ve got something worth mentioning. We’re on section 4 of the book now, which is writing a Scheme interpreter in Scheme. At the start the idea is just to get the basic syntax down but later on you change the evaluation model for fun and effect.

I’ve been working on exercise 4.5, which involves supported an “extended” syntax for conditional evaluation. It lets you pass the result from a test to a receiving function if the result evaluates to “true”.

(cond ((cons 1 2) => cdr)
      (else false))

That evalutes to 2. The standard is not clear if the predicate has to be pure. If I run the following in DrScheme:

(cond ((begin (print "once") (cons 1 2)) (cdr)))

I receive 2 back and see “once” printed once to the screen. But if the interpreter assumes that the test is (a) pure and (b) cheap to compute we can rewrite it like this:

(if (cons 1 2)
    (cdr (cons 1 2))
    (else false))

Rewriting the side-effecting code in this fashion would print “once” twice. Not good.

The following is more-or-less the way the book presents it to you, with my small changes to evaluate the extended syntax. It rewrites a series of cond expressions into nested if statements, which are evaluated until you find something that’s true or you reach the final else.

;; Assumes pure test predicates for (test => func) syntax because
;; the test is evaluated twice.
(define (expand-clauses clauses)
  (if (null? clauses)
      'false                          ; no else clause
      (let ((first (car clauses))
            (rest (cdr clauses)))
        (if (cond-else-clause? first)
            (if (null? rest)
                (sequence->exp (cond-actions first))
                (error "ELSE clause isn't last -- COND->IF" clauses))
            (make-if
             (cond-predicate first)
             (if (cond-extended? first)
                 (list (cond-extended-actions first) (cond-predicate first))
                 (sequence->exp (cond-actions first)))
             (expand-clauses rest))))))

The alternative is not to rewrite the cond syntax as a series of nested if statements. Instead we evaluate the predicate and pass that pre-evaluated value to the receiving function if it’s true. But damn if that isn’t a really difficult thing to do.

In the end I had to interleave evaluation and application of values, since the evaluator would always attempt to further evaluate any primitive value I gave it. (If I’m missing something really obvious here I’ll kick myself.)

;; Attempt to evaluate test predicate only once so that impure code
;; can be used without affecting program state twice.
(define (eval-cond-extended clauses env)
  (if (null? clauses)
      'false
      (let ((this (car clauses))
            (rest (cdr clauses)))
        (if (cond-else-clause? this)
            (if (null? rest)
                (eval (sequence->exp (cond-actions this)) env)
                (error "ELSE clause isn't last -- EVAL-COND" clauses))
            (let ((testval (eval (cond-predicate this) env)))
              (if (true? testval)
                  (if (cond-extended? this)
                      (apply (eval (cond-extended-actions this) env) (list testval))
                      (eval (sequence->exp (cond-actions this)) env))
                  (eval-cond-extended rest env)))))))

Notice the (apply (eval .. a few lines from the end there? That’s where it gets very ugly because the evaluator doesn’t accept pre-computed values.

The third alternative, and one that I haven’t looked at too closely because it seems fraught with other “interesting” issues, is inserting the computed value back into the environment so that the evaluator can see it.

Basically we would translate to this statement:

(let (result (test))
  (if result
      (function result)
      false))

This avoids the issue of computing something twice and running state-changing code twice but you have to drop variables into the interpreted environment which might already be used. If you go this route you either use some variable naming scheme that you can ensure doesn’t clash or deal with it. And for a toy evaluator, I think that’s too deep for me.

4 responses so far

Nov 04 2010

Do you know C-pound? How about C-thud?

Published by Dougal under Friends, Programming, Work

During this period of tedious and unfruitful job applications I’ve come to the conclusion that I’m either a horrible person on paper (I refuse to believe I’m a horrible person in real life) or I need more experience in the object-oriented managed-runtime languages. To wit, Java and C#.

The Java language has failed to get its act together in the last few years and, at least on paper, I have some experience with it since all my university work used Java. (I’m also watching Nick’s updates to remind myself. An RSS feed attached to his bitbucket account makes him dead easy to stalk learn from.) So I thought I’d get myself some experience in C#. I’ve nabbed a project that Mat made a couple of years ago (a game of Thud! from the Terry Pratchett novel of the name, itself based on a Norse board game) and, with his permission, I’m going to whip it into shape.

I know for a fact that it runs fine in Mono, since I knew that two years ago when he first knocked it out, and Mono has come on a long way since then. At the moment it doesn’t do very much and Mat admits that it isn’t great code on the inside either. That’s all fine by me though. I can familiarise myself with the code base by cleaning it up before I decide where the new features need to go.

I hope to keep this and ComicBake going alongside each other, since there are a number of differences besides the subject matter:

  1. Thud! doesn’t have to think much for itself. The program pits two users against each other across the network, so there’s no AI involved. The set of valid moves is very small so the game logic is not tricky. ComicBake, on the other hand, is me trying to encode a set of heuristics to simulate what an artist would do in the same situation.
  2. One is old-fashioned imperative code, in the object-oriented style. It’s fairly staid C# too, not using many of the recent innovations of the language which make it differ nowadays from Java. The other is obviously purely-functional Haskell: higher-order, expressively-typed and immutable.
  3. I can update and release ComicBake when I like. I haven’t checked with Mat whether he’s happy for me to publish the code/changes or whether he wants it just “between friends”. It can just be a learning experience, though obviously it’s a better one if I can point potential employers to it and say look, I can code.

The title is a reference to this Daily WTF classic.

Comments Off

Nov 03 2010

Horror movies, horror songs

Published by Dougal under Films, Friends, Music

On Sunday night we were invited to a Hallowe’en party (and very nice it was too) with horror movies. When we arrived a film was on but the sound was down and there was music playing instead. We spent the rest of the evening watching a series of films without any sound, which was remarkable fun. To be clear, these were black-and-white horror B-movies such as The Killer Shrews (in the long tradition of horror movies it used dogs dressed in hairy coats to simulate the giant shrews, ineffectually). Guessing the plot and laughing at the effects was much more fun than following the story was ever going to be. I’ll have to remember that trick for future occasions.

The evening’s party playlist was also interesting because it seemed more-or-less random apart from the titles being each related in some way to horror. It’s great that we now have the technology to create random playlists by entering keywords into the computer, and get out the eclectic variety of Voodoo Chile (Slight Return), Born as Ghosts, the Rocky Horror Show soundtrack, Monster Mash and the Cranberries’ Zombie.

Comments Off

Next »