ref: aa0761be97fc5a0ba0fb80ca364c24d9dbd56c4d
dir: /cli.c/
/* * cli glendy, based on mitrchoviski's gui for plan 9 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include "unix.h" #include "engine.h" int debug = 0; char *gface[2] = {"☹", "☺"}; /* glenda's face(es) */ Game game; void drawlevel(Game *g) { int x, y; /* prints first row, this assumes SzX = SzY, is there a better way? */ print("T%2d|", g->turn); for(int i = 0 ; i < SzX ; i++) print("%2d |", i); print("\n"); for(x = 0; x < SzX; x++) { for(int i = 0 ; i < SzY+1 ; i++) print("----"); print(x % 2 ? "\\" : "/"); print("\n"); /* show column number and have a zig-zag effect */ print("%2d%s |", x, x % 2 ? " " : ""); // print("%2d |", x); for(y = 0; y < SzY; y++) { /* it's [y][x], not [x][y] */ switch(g->grid[y][x]) { case PIECE_WALL: print(" * |"); break; case PIECE_GLENDA: /* fancy effect for glenda's face */ print(" %s |", g->turn % 2 ? gface[0] : gface[1]); break; default: print(" |"); break; } } print("\n"); } if(g->state == STATE_WON){ print("trapper won\n"); exits(nil); } else if(g->state == STATE_LOST){ print("glenda won\n"); exits(nil); } } /* p x y */ void proc_put(Game *g, char *s) { unsigned int x, y, r; /* replace these by better alternatives */ sscanf(s, "%u %n", &x, &r); sscanf(s+r, "%u", &y); if(x > SzX || y > SzY){ fprint(2, "proc_put(): invalid input, x = %d, y = %d\n", x, y); return; } r = doput(g, Pt(x, y)); if(r == PIECE_WALL) fprint(2, "There is already a wall in x = %d, y = %d\n", x, y); else if(r == PIECE_GLENDA) fprint(2, "You can't put a wall on glenda!\n"); } /* m x y */ void proc_move(Game *g, char *s) { int d; if(strcmp(s, "NE") == 0) d = NE; else if(strcmp(s, "E") == 0) d = E; else if(strcmp(s, "SE") == 0) d = SE; else if(strcmp(s, "W") == 0) d = W; else if(strcmp(s, "SW") == 0) d = SW; else if(strcmp(s, "NW") == 0) d = NW; else { fprint(2, "proc_move(): huh?\n"); return; } /* should check if there is a wall or something this way */ if(domove(g, d) == PIECE_WALL) { fprint(2, "There is a wall there!\n"); return; } } /* * handle input, which is in the form of * p1> p xx yy * which puts a wall in xx yy * p2> m {NE, E, SE, W, SW, NW} * which moves the bunny * > r * restarts the game * > u * undos last move * > q * quits the game */ void proc(Game *g, char *s) { char *t; int oturn; /* skip \n, so we don't need to process it later */ t = strchr(s, '\n'); *t = '\0'; oturn = g->turn; /* s+2 skips command and first space after it */ switch(*s) { case 'p': if(g->turn % 2 == 0) proc_put(g, s+2); else if(g->turn % 2 == 1) fprint(2, "glendy can't put!\n"); break; case 'm': if(g->turn % 2 == 0) fprint(2, "trapper can't move!\n"); else if(g->turn % 2 == 1) proc_move(g, s+2); break; case 'u': undo(g); break; case 'r': /* maybe we need to put a confirm message here */ restart(g); break; case 'q': exits(nil); break; case '\0': break; default: fprint(2, "unknown command\n"); } /* only print the map if turn have changed */ if(g->turn != oturn) drawlevel(g); } int input(Game *g) { char s[32], *r; print("%s> ", g->turn % 2 ? "glendy" : "trapper"); fflush(stdout); /* plan 9 */ r = fgets(s, 32, stdin); if(r == nil){ fprint(2, "input(): error\n"); return Err; } else { proc(g, s); return Ok; } } int main(int argc, char **argv) { /* * todo: handle argv properly */ game.ptype[0] = Human; game.ptype[1] = Human; /* OpenBSD ignores this */ srand(time(nil)); initlevel(&game); drawlevel(&game); while(input(&game) != Err) ; return 0; }