+int get_action_key (struct KeyBinding * keybindings, char * name) {
+// Return key matching name in keybindings.
+ int i = 0;
+ while (strcmp(keybindings[i].name, name) )
+ i++;
+ return keybindings[i].key; }
+
+char * get_keyname(int keycode) {
+// Translate some keycodes to readable names of max 9 chars.
+ char * keyname;
+ keyname = malloc(15);
+ if (32 < keycode && keycode < 127)
+ sprintf(keyname, "%c", keycode);
+ else if (keycode == 9)
+ sprintf(keyname, "TAB");
+ else if (keycode == 10)
+ sprintf(keyname, "RETURN");
+ else if (keycode == 27)
+ sprintf(keyname, "ESCAPE");
+ else if (keycode == 32)
+ sprintf(keyname, "SPACE");
+ else if (keycode == KEY_UP)
+ sprintf(keyname, "UP");
+ else if (keycode == KEY_DOWN)
+ sprintf(keyname, "DOWN");
+ else if (keycode == KEY_LEFT)
+ sprintf(keyname, "LEFT");
+ else if (keycode == KEY_RIGHT)
+ sprintf(keyname, "RIGHT");
+ else if (keycode == KEY_HOME)
+ sprintf(keyname, "HOME");
+ else if (keycode == KEY_BACKSPACE)
+ sprintf(keyname, "BACKSPACE");
+ else if (keycode >= KEY_F0 && keycode <= KEY_F(63)) {
+ int f = keycode - KEY_F0;
+ sprintf(keyname, "F%d", f); }
+ else if (keycode == KEY_DC)
+ sprintf(keyname, "DELETE");
+ else if (keycode == KEY_IC)
+ sprintf(keyname, "INSERT");
+ else if (keycode == KEY_NPAGE)
+ sprintf(keyname, "NEXT PAGE");
+ else if (keycode == KEY_PPAGE)
+ sprintf(keyname, "PREV PAGE");
+ else if (keycode == KEY_END)
+ sprintf(keyname, "END");
+ else
+ sprintf(keyname, "(unknown)");
+ return keyname; }
+
+char is_passable (struct World * world, int x, int y) {
+// Check if coordinate on (or beyond) map is accessible to movement.
+ char passable = 0;
+ if (0 <= x && x < world->map->width && 0 <= y && y < world->map->height)
+ if ( '.' == world->map->cells[y * world->map->width + x]
+ && (y != world->monster->y || x != world->monster->x))
+ passable = 1;
+ return passable; }
+
+void move_player (struct World * world, char d) {
+// Move player in direction d, increment turn counter and update log.
+ static char prev = 0;
+ char success = 0;
+ char * dir;
+ if ('s' == d) {
+ dir = "south";
+ if (is_passable(world, world->player->x, world->player->y + 1)) {
+ world->player->y++;
+ success = 1; } }
+ else if ('n' == d) {
+ dir = "north";
+ if (is_passable(world, world->player->x, world->player->y - 1)) {
+ world->player->y--;
+ success = 1; } }
+ else if ('w' == d) {
+ dir = "west";
+ if (is_passable(world, world->player->x - 1, world->player->y)) {
+ world->player->x--;
+ success = 1; } }
+ else if ('e' == d) {
+ dir = "east";
+ if (is_passable(world, world->player->x + 1, world->player->y)) {
+ world->player->x++;
+ success = 1; } }
+ if (success * d == prev)
+ update_log (world, ".");
+ else {
+ char * msg = calloc(25, sizeof(char));
+ char * msg_content = "You fail to move";
+ if (success)
+ msg_content = "You move";
+ sprintf(msg, "\n%s %s.", msg_content, dir);
+ update_log (world, msg);
+ free(msg); }
+ prev = success * d;
+ update_info (world); }
+