ref: d5c2af3bcb04031bd6f2724a480b9c7758eeacbb
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;
}