wm: glendy

Download patch

ref: dd155881cf69b09d8e33ad2f4d6ef5a96eaa097c
parent: 1986f3905eca9114442405d2b3180eea9bc709bc
author: mkf <mkf@cloud9p.org>
date: Mon Oct 21 05:17:15 EDT 2024

fix build on plan 9 (lots of changes)

--- a/cli.c
+++ b/cli.c
@@ -10,7 +10,8 @@
 #include "unix.h"
 #include "engine.h"
 
-char *gface[2] = {"☺", "☹"}; /* glenda's face(es) */
+char *gface[2] = {"☹", "☺"}; /* glenda's face(es) */
+
 int debug = 0;
 
 void
--- a/engine.c
+++ b/engine.c
@@ -5,7 +5,7 @@
 #include "netclient.h"
 
 /*
- * Sets up a new level
+ * Sets up a new level and fills it
  */
 void
 initlevel(Game *game)
@@ -14,9 +14,9 @@
 
 	for(x = 0; x < SzX; x++)
 		for(y = 0; y < SzY; y++)
-			game.ogrid[x][y] = Prev;
+			game->ogrid[x][y] = Prev;
 
-	switch(game.difficulty)
+	switch(game->difficulty)
 	{
 		case DEasy:
 			cnt = 10 + nrand(5);
@@ -32,26 +32,26 @@
 			cnt = 0;
 			break;
 	}
-	game.ogrid[SzX/2][SzY/2] = Glenda;
+	game->ogrid[SzX/2][SzY/2] = Glenda;
 
 setmap:
 	for(i = 0 ; i < cnt ; i++)
 	{
-		/* ensure we don't over place walls in glenda or walls (again) */
+		/* ensure walls dont overlap with other walls or glenda */
 		do
 		{
 			x = nrand(SzX);
 			y = nrand(SzY);
-		}while(game.ogrid[x][y] == Glenda || game.ogrid[x][y] == Wall);
-		game.ogrid[x][y] = Wall;
+		}while(game->ogrid[x][y] == Glenda || game->ogrid[x][y] == Wall);
+		game->ogrid[x][y] = Wall;
 	}
 	/* ensure we don't make an unfair map */
 	if(checkstate(game) == Won && findmin(game, Pt(SzX/2, SzY/2)) > 100)
 		goto setmap;
 
-	memcpy(game.grid, game.ogrid, sizeof(game.grid));
-	game.state = Start;
-	game.turn = 0;
+	memcpy(game->grid, game->ogrid, sizeof(game->grid));
+	game->state = Start;
+	game->turn = 0;
 }
 
 /*
@@ -101,10 +101,10 @@
 }
 
 /*
- * Moves glenda from direction
+ * Moves glenda into direction
  */
 int
-domove(Game game, int dir)
+domove(Game *game, int dir)
 {
 	Point src, dst;
 		
@@ -111,59 +111,62 @@
 	src = findglenda(game);
 	dst = movedir(dir, src);
 
-	if(game.grid[dst.x][dst.y] == Wall)
+	if(game->grid[dst.x][dst.y] == Wall)
 		return Wall;
 
-	if(game.networked)
-		return netmove(game.dir);
+	if(game->networked)
+		return netmove(dir);
 	
-	game.grid[dst.x][dst.y] = Glenda;
-	game.grid[src.x][src.y] = Prev;
+	game->grid[dst.x][dst.y] = Glenda;
+	game->grid[src.x][src.y] = Prev;
 
-	turn++;
+	game->turn++;
 	
 	/* we shouldn't guess, server should tell us */
-	if(game.ptype[1] == Human && !game.networked)
+	if(game->ptype[1] == Human && !game->networked)
 		checkstate(game);
 	return Ok;
 }
 
+/*
+ * Puts a wall inside a point
+ */
 int
-doput(Game game, Point p)
+doput(Game *game, Point p)
 {
 	/* clients are expected to do their own error checking */
 	if(p.x > SzX || p.x < 0 || p.y > SzY || p.y < 0)
 		return Err;
 
-	if(game.grid[p.x][p.y] == Wall)
+	if(game->grid[p.x][p.y] == Wall)
 		return Wall;
 
-	if(game.grid[p.x][p.y] == Glenda)
+	if(game->grid[p.x][p.y] == Glenda)
 		return Glenda;
 
-	if(game.networked)
-		return netput(game, p.x, p.y);
+	if(game->networked)
+		return netput(p.x, p.y);
 	
 	/* take a copy for undo */
-	memcpy(game.pgrid, game.grid, sizeof(game.grid));
-	grid[p.x][p.y] = Wall;
+	memcpy(game->pgrid, game->grid, sizeof(game->grid));
+	game->grid[p.x][p.y] = Wall;
 
 
 	/* assumes defenders start game first */
-	if(game.state == Start)
-		game.state = Playing;
+	if(game->state == Start)
+		game->state = Playing;
 
-	turn++;
+	game->turn++;
 	/* reset the board scores */
 	for(int x = 0; x < SzX; x++)
 		for(int y = 0; y < SzY; y++)
-			if(game.grid[x][y] != Wall && game.grid[x][y] != Glenda)
-				game.grid[x][y] = 100;
+			if(game->grid[x][y] != Wall && game->grid[x][y] != Glenda)
+				game->grid[x][y] = 100;
 
 	/* we need it to check game state, even if not playing with computer */
-	if(game.ptype[1] == Computer)
+	if(game->ptype[1] == Computer)
 		nextglenda(game);
-	else if(game.ptype[1] == Human && !networked)
+	else if(game->ptype[1] == Human && !game->networked)
 		checkstate(game);
 
 	return Ok;
@@ -173,11 +176,11 @@
  * Returns glenda's position
  */
 Point
-findglenda(Game game)
+findglenda(Game *game)
 {
 	for(int x = 0; x < SzX; x++)
 		for(int y = 0; y < SzY; y++)
-			if(game.grid[x][y] == 1000)
+			if(game->grid[x][y] == 1000)
 				return Pt(x, y);
 	
 	return Pt(-1, -1);
@@ -195,7 +198,7 @@
  * traversing the board
  */
 int 
-score1(Game game, Point p)
+score1(Game *game, Point p)
 {
 	int min = 999;
 
@@ -215,14 +218,14 @@
  * O(n³), but why?
  */
 void
-calc(void)
+calc(Game *game)
 {
 	/* assumes SzX = SzY */
 	for(int i = 0; i < SzX; i++)
 		for(int x = i; x < SzX-i; x++)
 			for(int y = i; y < SzY-i; y++)
-				if(game.grid[x][y] != Wall && game.grid[x][y] != Glenda)
-					game.grid[x][y] = score1(Pt(x, y));
+				if(game->grid[x][y] != Wall && game->grid[x][y] != Glenda)
+					game->grid[x][y] = score1(game, Pt(x, y));
 }
 
 /*
@@ -229,13 +232,15 @@
  * finds the node with least score around the p
  */
 int
-findmin(Point p)
+findmin(Game *game, Point p)
 {
+	Point tmp;
 	int next, min = 998;
 
 	for(int dir = NE; dir <= NW; dir++)
 	{
-		next = checknext(game, dir, p);
+		tmp = movedir(dir, p);
+		next = game->grid[tmp.x][tmp.y];
 		if(next < min)
 			min = next;
 	}
@@ -244,15 +249,15 @@
 
 /*
  * Makes a move for glenda
- * only use in single player
+ * only used in single player
  */
 void
-nextglenda(Game game)
+nextglenda(Game *game)
 {
 	int min = 999, next, dir, nextdir = 0, count = 0;
-	Point p = findglenda(game);
+	Point tmp, p = findglenda(game);
 
-	if(networked)
+	if(game->networked)
 		return;
 
 	calc(game);
@@ -261,7 +266,8 @@
 
 	for(dir = NE; dir <= NW; dir++)
 	{
-		next = checknext(game, dir, p);
+		tmp = movedir(dir, p);
+		next = game->grid[tmp.x][tmp.y];
 		if(next < min)
 		{
 			min = next;
@@ -272,13 +278,13 @@
 			nextdir = (nrand(++count) == 0) ? dir : nextdir;
 	}
 	if(min > 100)
-		state = Won;
+		game->state = Won;
 	else
-		domove(nextdir);
+		domove(game, nextdir);
 
 	p = findglenda(game);
 	if(p.x == 0 || p.x == SzX-1 || p.y == 0 || p.y == SzY-1)
-		game.state = Lost;
+		game->state = Lost;
 }
 
 /*
@@ -285,7 +291,7 @@
  * See if game is over
  */
 int
-checkstate(Game game)
+checkstate(Game *game)
 {
 	Point p = findglenda(game);
 
@@ -294,11 +300,11 @@
 	calc(game);
 
 	if(findmin(game, p) > 100)
-		game.state = Won;
+		game->state = Won;
 	if(p.x == 0 || p.x == SzX-1 || p.y == 0 || p.y == SzY-1)
-		game.state = Lost;
+		game->state = Lost;
 
-	return game.state;
+	return game->state;
 }
 
 /*
@@ -305,11 +311,11 @@
  * Resets the game position
  */
 void
-restart(Game game)
+restart(Game *game)
 {
-	game.turn = 0;
-	memcpy(game.grid, game.ogrid, sizeof(game.grid));
-	game.state = Start;
+	game->turn = 0;
+	memcpy(game->grid, game->ogrid, sizeof(game->grid));
+	game->state = Start;
 }
 
 /*
@@ -316,18 +322,24 @@
  * Undos last move
  */
 void
-undo(Game game)
+undo(Game *game)
 {
 	int g[SzX][SzY];
 
-	if(state == Start || turn < 2)
+	if(game->state == Start || game->turn < 2)
 		return;
 
 	/* revert turn counter, can be abused by one side */
-	turn -= 2;
+	game->turn -= 2;
 
 	/* swap grids */
-	memcpy(g, game.grid, sizeof g);
-	memcpy(game.grid, game.pgrid, sizeof g);
-	memcpy(game.pgrid, g, sizeof g);
+	memcpy(g, game->grid, sizeof g);
+	memcpy(game->grid, game->pgrid, sizeof g);
+	memcpy(game->pgrid, g, sizeof g);
+}
+
+int
+isplaying(Game *game)
+{
+	return game->state == Playing || game->state == Start;
 }
--- a/engine.h
+++ b/engine.h
@@ -1,5 +1,3 @@
-#define isplaying (state == Playing || state == Start)
-
 enum
 {
 	/* difficulty levels (how many circles are initially occupied) */
@@ -63,28 +61,27 @@
 	/* we maybe be able to merge all this into one bit-array */
 	int waitbit; /* 0 is go, 1 is wait */
 	int networked; /* 0 is local, 1 is networked */
-	int pside; /* Trapper, Glenda */
 }Game;
 
 /* client code */
 int debug;
+int pside; /* Trapper, Glenda */
 
-void initlevel(void);
+void initlevel(Game *game);
 Point movedir(int dir, Point p);
 int pointdir(Point src, Point dst);
+Point findglenda(Game *game);
 
-int domove(int dir);
-int doput(Point p);
+int domove(Game *game, int dir);
+int doput(Game *game, Point p);
 
-Point findglenda(void);
-int checknext(int dir, Point p);
+int score1(Game *game, Point p);
+void calc(Game *game);
+void nextglenda(Game *game);
 
-int score1(Point p);
-void calc(void);
-void nextglenda(void);
+int findmin(Game *game, Point p);
+int checkstate(Game *game);
+int isplaying(Game *game);
 
-int findmin(Point p);
-int checkstate(void);
-
-void restart(void);
-void undo(void);
+void restart(Game *game);
+void undo(Game *game);
--- a/gui9.c
+++ b/gui9.c
@@ -2,9 +2,10 @@
 #include <libc.h>
 #include <draw.h>
 #include <event.h>
-#include "netclient.h"
 #include "engine.h"
+#include "netclient.h"
 
+Game game;
 
 Font *font;
 
@@ -18,6 +19,7 @@
 
 int debug;
 char *server = nil;
+
 enum
 {
 	New = 0,
@@ -166,9 +168,9 @@
 	int  x, y, rx, ry, d;
 	char *s = nil;
 
-	if(state == Won)
+	if(game.state == Won)
 		draw(screen, screen->r, won, nil, ZP);
-	else if(state == Lost)
+	else if(game.state == Lost)
 		draw(screen, screen->r, lost, nil, ZP);
 	else
 		draw(screen, screen->r, bg, nil, ZP);
@@ -181,7 +183,7 @@
 		for(y = 0; y < SzY; y++)
 		{
 			p = board2pix(x, y);
-			switch(grid[x][y])
+			switch(game.grid[x][y])
 			{
 				case Wall: 
 					fillellipse(screen, addpt(screen->r.min, p), rx, ry, cc, ZP);
@@ -197,11 +199,10 @@
 					USED(s);
 					if(debug)
 					{
-						s = smprint("%d", grid[x][y]);
+						s = smprint("%d", game.grid[x][y]);
 						string(screen, addpt(screen->r.min, p), display->black, ZP, font, s);
 						free(s);
 					}
-	
 					break;
 			}
 		}
@@ -208,6 +209,7 @@
 	}
 	flushimage(display, 1);
 }
+
 void
 move(Point m)
 {
@@ -218,15 +220,15 @@
 
 	/* figure out where the click falls */
 	p = pix2board(nm.x, nm.y);
-	g = findglenda();
+	g = findglenda(&game);
 	
 	dir = pointdir(g, p);
 	
-	if(grid[p.x][p.y] >= 999 || dir == Err)
+	if(game.grid[p.x][p.y] >= 999 || dir == Err)
 		return;
 
 	/* find the direction to p from our currently pos, then move */
-	domove(dir);
+	domove(&game, dir);
 }
 
 void
@@ -239,10 +241,10 @@
 	/* figure out where the click falls */
 	p = pix2board(nm.x, nm.y);
 	
-	if(grid[p.x][p.y] >= 999)
+	if(game.grid[p.x][p.y] >= 999)
 		return;
 
-	doput(p);
+	doput(&game, p);
 }
 
 void
@@ -286,7 +288,7 @@
 	Mouse m;
 	Event ev;
 	Netmsg *msg;
-	int e, mousedown=0;
+	int e, mousedown = 0;
 
 	pnick = getenv("user");
 	/* todo, add flags for human playing */
@@ -299,7 +301,7 @@
 			sysfatal("No computer player for defenders yet");
 			break;
 		case 'g':
-			ptype[1] = Computer;
+			game.ptype[1] = Computer;
 			break;
 		case 's':
 			side = EARGF(usage());
@@ -306,9 +308,9 @@
 			pside = atoi(side);
 			break;
 		case 'n':
-			ptype[0] = Net;
-			ptype[1] = Net;
-			networked = 1;
+			game.ptype[0] = Net;
+			game.ptype[1] = Net;
+			game.networked = 1;
 			server = EARGF(usage());
 			break;
 		case 'N':
@@ -327,25 +329,24 @@
 
 	allocimages();
 
-	if(server != nil && networked)
+	if(server != nil && game.networked)
 	{
 		srvfd = dial(server, nil, nil, nil);
 		if(srvfd < 0)
 			sysfatal("unable to connect: %r");
 
-		netinit();
+		netinit(&game);
 		drawlevel();
 	}
 	else
-		initlevel();	/* must happen before "eresized" */
+		initlevel(&game);	/* must happen before "eresized" */
 
 	eresized(0);
 	for(;;)
 	{
-	//	fprint(2, "XXX %d\n", state);
-		if(networked && waitbit && isplaying)
+		if(game.networked && game.waitbit && isplaying(&game))
 		{
-			msg = netmain();
+			msg = netmain(&game);
 			if(msg->tokens[0] != nil && strcmp(msg->tokens[0], "SYNC"))
 				drawlevel();
 		}
@@ -358,14 +359,14 @@
 					m = ev.mouse;
 					if(m.buttons == 0)
 					{
-						if(mousedown && isplaying)
+						if(mousedown && isplaying(&game))
 						{
 							mousedown = 0;
-							if(turn % 2 == 0)
+							if(game.turn % 2 == 0)
 								put(m.xy);
 							else
 								move(m.xy);
-							if(!networked)
+							if(!game.networked)
 								drawlevel();
 						}
 					}
@@ -378,20 +379,20 @@
 						switch(emenuhit(2, &m, &mmenu))
 						{
 						case 0:
-							difficulty = DEasy;
-							initlevel();
+							game.difficulty = DEasy;
+							initlevel(&game);
 							break;
 						case 1:				
-							difficulty = DMed;
-							initlevel();
+							game.difficulty = DMed;
+							initlevel(&game);
 							break;
 						case 2:
-							difficulty = DHard;
-							initlevel();
+							game.difficulty = DHard;
+							initlevel(&game);
 							break;
 						case 3:
-							difficulty = DImp;
-							initlevel();
+							game.difficulty = DImp;
+							initlevel(&game);
 							break;
 						}
 						drawlevel();
@@ -401,13 +402,13 @@
 						switch(emenuhit(3, &m, &rmenu))
 						{
 							case New:
-								initlevel();
+								initlevel(&game);
 								break;
 							case Undo:
-								undo();
+								undo(&game);
 								break;
 							case Restart:
-								restart();
+								restart(&game);
 								break;
 							case Exit:
 								exits(nil);
--- a/netclient.c
+++ b/netclient.c
@@ -62,12 +62,12 @@
 }
 
 int
-nethi(char *name, int game, int side, int opts)
+nethi(Game *game, char *name, int gameset, int side, int opts)
 {	
 	int len;
 	char *msg;
 
-	msg = himsg(name, game, side, opts);
+	msg = himsg(name, gameset, side, opts);
 	if(msg == nil)
 		return Err;
 	
@@ -78,7 +78,7 @@
 	/* otherwise client wont read socket to confirm */
 	waitbit = 1;
 	free(msg);
-	state = Init;
+	game->state = Init;
 	return Ok;
 }
 
@@ -96,9 +96,7 @@
 	len = strlen(msg);
 	if(write(srvfd, msg, len) < len)
 		sysfatal("netmove(): half written?");
-
-	/* otherwise client wont read socket to confirm */
-	waitbit = 1;
+	
 	free(msg);
 	return Ok;
 }
@@ -118,26 +116,27 @@
 	if(write(srvfd, msg, len) < len)
 			sysfatal("netput(): half written?: %r");
 
-	/* otherwise client wont read socket to confirm */
-	waitbit = 1;
 	free(msg);
 	return Ok;
 }
 
 static void
-netproc(Netmsg *msg, char *in)
+netproc(Game *game, Netmsg *msg, char *in)
 {
-	int i, dir;
+	int i = 0, dir;
 	char *tmp, *xpos, *ypos;
 	char **tokens = (char**)emalloc(64 * sizeof(char*));
 	Point p;
 	
 	msg->omsg = strdup(in);
-	dprint("msg->omsg: %s\n", in);
+	dprint("msg->omsg: %s\n", msg->omsg);
 	
 	tokens[0] = strtok(in, " ");
 	for(i = 1 ; tokens[i-1] != nil ; i++)
+	{
 		tokens[i] = strtok(nil, " ");
+		fprint(2, "token[%d] = %s\n", i, tokens[i]);
+	}
 	
 	msg->ntoken = i;
 	msg->tokens = tokens;
@@ -167,9 +166,9 @@
 
 	else if(!strcmp(tokens[0], "INIT"))
 	{
-		dprint("INIT XXX in INIT\n");
-		state = Init;
-		while(state == Init)
+		waitbit = 0;
+		game->state = Init;
+		while(game->state == Init)
 		{
 			tmp = netread();
 			/* lots of assuming goes here,
@@ -187,7 +186,7 @@
 					p.x = atoi(xpos);
 					p.y = atoi(ypos);
 					
-					grid[p.x][p.y] = Wall;
+					game->grid[p.x][p.y] = Wall;
 					break;
 				case 'g':
 					xpos = strtok(nil, " ");
@@ -198,17 +197,16 @@
 					p.x = atoi(xpos);
 					p.y = atoi(ypos);
 					
-					grid[p.x][p.y] = Glenda;
+					game->grid[p.x][p.y] = Glenda;
 					break;
 				default:
 					if(!strcmp("SENT", tmp))
-						state = Start;
+						game->state = Start;
 					else
 						dprint("netproc(): Init: unknown command: %s\n", tmp);
 				
 			}
 		}
-	dprint("XXX INIT: state = %d\n", state);
 	}
 	else if(!strcmp(tokens[0], "SENT"))
 		/* sent is handled in INIT */
@@ -219,41 +217,37 @@
 
 	else if(!strcmp(tokens[0], "SYNC"))
 	{
-		if(state == Start)
-			state = Playing;
+		if(game->state == Start)
+			game->state = Playing;
 		if(msg->ntoken < 2)
 			sysfatal("netproc(): not enough toknes?");
 		
-		/* TODO: very ugly hack, get rid of this */
-		networked = 0;
 		if(atoi(msg->tokens[1]) % 2 == 0)
 		{
-			/* glenda's turn is done */
-			if(msg->ntoken < 3)
-				sysfatal("netproc(): not enough tokens to SYNC glenda's move");
-			dir = strtodir(tokens[2]);
-			domove(dir);
-			dprint("in glenda's turn\n");
-		}
-		else
-		{
 			/* trapper's turn is done */
-			if(msg->ntoken < 4)
+			if(msg->ntoken != 4)
 				sysfatal("netproc(): not enough tokens to SYNC trapper's move");
 			
 			p = parseput(tokens[2], tokens[3]);
-			doput(p);
+			doput(game, p);
 		}
-		/* TODO: very ugly hack, get rid of this */
-		networked = 1;
+		else
+		{
+			/* glenda's turn is done */
+			if(msg->ntoken != 3)
+				sysfatal("netproc(): not enough tokens to SYNC glenda's move");
+			dir = strtodir(tokens[2]);
+			domove(game, dir);
+		}
 	}
 	else if(!strcmp(tokens[0], "WON"))
-		state = Won;
-	
+	{
+		msg->err = Won;
+	}
 	else if(!strcmp(tokens[0], "LOST"))
-		state = Lost;
-	else if(!strcmp(tokens[0], ""))
-		state = Finished;
+	{
+		msg->err = Lost;
+	}
 	else 
 		sysfatal("netproc(): unkown message: 0x%x %s", *tokens[0], tokens[0]);
 }
@@ -278,7 +272,7 @@
 }
 
 void
-netinit(void)
+netinit(Game *game)
 {
 	Netmsg *msg;
 	char *s;
@@ -285,18 +279,18 @@
 
 	msg = (Netmsg*)emalloc(sizeof(Netmsg));
 
-	state = Connect;
-	nethi(pnick, 0, pside, 0);
+	game->state = Connect;
+	nethi(game, pnick, 0, pside, 0);
 	
 	for(;;)
 	{
 		s = netread();
-		netproc(msg, s);
+		netproc(game, msg, s);
 
 		dprint("msg->tokens[0]: %s\n", msg->tokens[0]);
-
 		if(msg->tokens[0] != nil && !strcmp(msg->tokens[0], "INIT"))
 			break;
+		
 		free(s);
 	}
 	free(s);
@@ -303,7 +297,7 @@
 }
 
 Netmsg*
-netmain(void)
+netmain(Game *game)
 {
 	Netmsg *msg;
 	char *s;
@@ -310,7 +304,7 @@
 	msg = (Netmsg*)emalloc(sizeof(Netmsg));
 	
 	s = netread();
-	netproc(msg, s);
+	netproc(game, msg, s);
 	free(s);
 	return msg;
 }
--- a/netclient.h
+++ b/netclient.h
@@ -16,5 +16,5 @@
 int netmove(int dir);
 int netput(int x, int y);
 char* netread(void);
-void netinit(void);
-Netmsg* netmain(void);
+void netinit(Game *game);
+Netmsg* netmain(Game *game);