Showing posts with label games. Show all posts
Showing posts with label games. Show all posts

Learning emacs the fun way

Welcome to keywiz
There are currently 366 commands.

Only 366, yet I still don't know most of them...

Keywiz is a game for learning emacs commands. This is something like the second best way to help users learn an interface. (The best is to unobtrusively show them what commands are available, as menus do, but that's hard to do for hundreds of commands.) It's not a great game - it's obnoxiously modal, its difficulty isn't variable, and it rudely stops play after two minutes. Nor is it thorough - it appears to only cover global keybindings, so it misses mode-specific goodies and anything requiring M-x. All it does is give you the names and docstrings of functions bound to keys, and ask you to type the key sequence. But as a training tool it's better than any documentation ever written.

tab-to-tab-stop
Insert spaces or tabs to next defined tab-stop column.

Well, that's easy. Tab.

Incorrect.  The correct answer is: M-i

There's another kind of tab? Ohhh, it's the manual indent, not autoindent. Hey, I needed that yesterday!

describe-coding-system
Display information about CODING-SYSTEM.

That's guessable. C-h c, right?

Wrong.  The correct answer is: C-h C, <f1> C, <help> C

Case-sensitivity, how do I hate thee...

isearch-backward
Do incremental search backward.

At last, one I know!

Indeed.  The answer is: C-r

Time's up
You made 4 points.

Ouch. I've been using emacs for years, and I still only know a tiny fraction of it. Maybe if I play a few more games...

Via Marco Baringer (probably) on Cliki.

The game of carnivorous math

You know how sometimes something cool comes along and wows you with its novelty, and then you look at the date and realize it's eight months old? And everyone already knows about it but you? This is one of those times.

But just in case it's not, and you don't know about it yet: Alligator Eggs is a children's game about - well, read it and see.

OK. Read it? Now for the criticism.

1. Old alligators are a wart. They're a wart in the form of parentheses too, but they're even worse here. In either case, the problem is that they arise purely from syntax - there's no corresponding feature in the math; all they do is patch up an ambiguity in the surface representation.

There has to be a better way. Perhaps predator-prey pairs could be disambiguated by just putting a piece of paper underneath, to serve as a visual box and a way to move them. This could also help delimit very large families, which are easy to lose track of when playing with bits of paper. It's hard when your alligators don't magically change size to cover their nests.

2. After only a few η-adoptions and β-devourings, I missed combinators and global variables. I'm not sure they would make a better game (adding random features doesn't usually improve a game), so maybe this is just my programmerhood talking, but I think they would at least increase the range of concepts you can teach with the game. It shouldn't be hard to get players to give names to a few of the simpler alligator families. Indeed, I suspect they'd eagerly adopt them, because they save so much paper-shuffling. They could be represented as non-alligator animals - the ibis, who is replaced by whatever she eats; the kangaroo, who hops away and leaves his dinner in the care of an alligator; the ωombat, who feeds anything to itself; the kitten, who turns anything into an ibis; and so on. (How do kittens turn whole families of alligators into ibises? Well, have you ever seen what a kitten does to a board game? That's how.)

3. You could add non-carnivorous data like integers, and operators on them. But I have a better idea: despite my functional preference, I think side-effecting operators could be fun. A puzzle that does something is more interesting than one that only puzzles. State makes reduction order matter, but that's not a bad thing - the order exists anyway, so it might as well mean something. A suitable choice of initial configuration and state objectives offers the bizarre prospect of controlling a game by choosing evaluation order.

Another application of state is in multiplayer play. Suppose players take turns, each independently performing one operation on their own menagerie. This game becomes much more interesting if the players can interact - and stateful operators provide a natural way to do that. Operations could have side effects on the opponent's alligators - feeding them things, for example. But their power is restrained by the difficulty of handling them.

And you could draw animals from a deck of cards... Okay, this is getting too complicated. But the complexity does have one advantage: it makes it easier to not think too hard about the biology.

(Via Philip Wadler.)

A glance is too far

Recently I tried Sauerbraten, a free first-person shooter. (It's like Quake, with an emphasis on network play and in-game map editing.) I got schooled, of course. And in addition to the lesson in how (not) to dodge, I got a lesson in user interfaces.

In any such game, your current hit points are one of the most important pieces of information. Your remaining ammunition is nearly as important. Therefore Sauerbraten shows both numbers in big numerals in the corners, where you can see them at a glance.

But a glance takes too long. Sauerbraten is a fast and twitchy game, and you can't afford to take your eyes off a fight, even for a fraction of a second. Looking at the number and back to the fight takes perhaps a third of a second, but that's enough time to lose track of an opponent, or to fatally delay your reaction to a shot.

So hit points, ammo, and other information needed in the heat of battle should be displayed in a form that can be read with peripheral vision, so you don't need to move your eyes. A large bar graph - at least half as tall as the screen - works fine.

One of the rules for presenting information more efficiently is to let the users navigate with their eyes, not their hands, because the eyes are faster. In general, it's faster to look at something that's already visible than to push a button to display it. An efficient interface minimizes the number of places the user's eye needs to look, just as it minimizes the number of operations their hands need to do. But in the real-time extreme of a game, even one glance is too many. The most urgent information needs to be visible without moving the eye, because the eye is too slow.

Speaking of emacs...

Today I played M-x dunnet for the first time in ten years. I'm surprised by how much I remembered. I remembered what the coconuts and the sauna do; I remembered where to look for the password to Pokey; I even remembered how to turn an essential item into a worthless pile of protoplasm.

I didn't remember the daze of thirsty little cabbages, all alike, but I remembered the problem it exhibits. Dunnet forces the player to guess far too much. In the maze, this is just tedious - you have to exhaustively try to move in every direction and draw a map. But there are also many deathtraps which are impossible to anticipate, and these inevitably force the player to restart the game, or to give up in frustration. (Once you die, there is no obvious way to restart the game without restarting the whole emacs!) Despite its cute bits, Dunnet is not much good as a game.

It is, however, good as a teaching tool. Ten years ago, I reacted to its frustration in the obvious way: I read the source for hints. (You might call that cheating, if you like text adventures more than I do.) I didn't know much Lisp at the time, so this was quite educational. I was well aware of this, and didn't mind, although the everything-is-a-list data structures were confusing. However, its effectiveness was limited for an ironic reason: the code is too clean.

Not that it's a shining example or anything - rooms are represented by a bunch of parallel lists in globals, for one thing - but data about rooms and such is mostly separated from code. So I was able to figure out most of what I wanted without having to understand much of the code. A similar game with less separation of concerns might be a better teacher, because it would force students to read more code. It would help to have more puzzles which depend on understanding the code, not just looking at literal strings for the answer. It would also be nice if early parts of the game had simpler, easier-to-read implementations, so the student could learn gradually.

By the way, here's an interesting use of eval. Dunnet uses eval to move object names from its data structures to its environment, so its code can refer to objects by name instead of by indexes into those parallel arrays:

(let (a)
  (setq a 0)
  (dolist (x dun-room-shorts)
    (eval (list 'defconst (intern x) a))
    (setq a (+ a 1))))

It's not very clean, but it is convenient. It would be more convenient if every name didn't have to have a dun- or obj- prefix, to avoid collisions. This is not a habit you want to be teaching students, but it's necessary, because Elisp doesn't have any kind of module system. That's something else to avoid in an educational version of Dunnet.

But keep the frustration, so players have a reason to look at the source. And by all means keep the unsettling leakage between different realities (in the game, I mean, not in the names of objects). That's what makes Dunnet fun. And it's definitely something you want to be teaching your students.