[Commit] rrserver array.5c,1.1,1.2 boards.5c,1.1,1.2 connect.5c,1.1,1.2 dispatch.5c,1.1,1.2 games.5c,1.1,1.2 lex.5c,1.1,1.2 server.5c,1.1,1.2 show.5c,1.1,1.2
Keith Packard
commit@keithp.com
Thu, 29 May 2003 01:15:47 -0700
Committed by: keithp
Update of /local/src/CVS/rrserver
In directory home.keithp.com:/tmp/cvs-serv15854
Modified Files:
array.5c boards.5c connect.5c dispatch.5c games.5c lex.5c
server.5c show.5c
Log Message:
add robot movement
Index: array.5c
===================================================================
RCS file: /local/src/CVS/rrserver/array.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- array.5c 29 May 2003 06:45:37 -0000 1.1
+++ array.5c 29 May 2003 08:15:44 -0000 1.2
@@ -37,6 +37,21 @@
return v;
}
+ public poly push (&poly[*] a, poly v) {
+ a = (poly[dim(a)+1]) { [i] = i < dim(a) ? a[i] : v };
+ return v;
+ }
+
+ public exception empty (&poly[*] a);
+
+ public poly pop (&poly[*] a) {
+ if (dim(a) == 0)
+ raise empty (a);
+ poly v = a[dim(a)-1];
+ a = (poly[dim(a)-1]) { [i] = a[i] };
+ return v;
+ }
+
public void iterate (&poly[*] a, void (poly v) f) {
for (int i = 0; i < dim (a); i++)
f(a[i]);
Index: boards.5c
===================================================================
RCS file: /local/src/CVS/rrserver/boards.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- boards.5c 29 May 2003 06:45:37 -0000 1.1
+++ boards.5c 29 May 2003 08:15:44 -0000 1.2
@@ -390,7 +390,6 @@
target = TargetOrNone.none,
robot = RobotOrNone.none,
walls = walls (W.below, W.right) }};
- printf ("placing %v\n", TransformLoc (l, transforms[i]));
PlaceObject (&b, l, transforms[i]);
}
@@ -454,7 +453,7 @@
return ol;
}
- public ObjectLoc[*] find_robot (&Board b, Color color)
+ public ObjectLoc[*] find_robots (&Board b, Color color)
{
bool match (Object o) {
union switch (o.robot) {
@@ -468,6 +467,15 @@
return find (&b, match);
}
+ public exception invalid_robot (Color color);
+
+ public ObjectLoc find_robot (&Board b, Color color) {
+ ObjectLoc[*] ol = find_robots (&b, color);
+ if (dim (ol) != 1)
+ raise invalid_robot (color);
+ return ol[0];
+ }
+
public ObjectLoc[*] find_active_robot (&Board b)
{
bool match (Object o) {
@@ -482,7 +490,7 @@
return find (&b, match);
}
- public ObjectLoc[*] find_target (&Board b, Color color, Shape shape)
+ public ObjectLoc[*] find_targets (&Board b, Color color, Shape shape)
{
bool match (Object o) {
union switch (o.target) {
@@ -496,8 +504,7 @@
return find (&b, match);
}
- public ObjectLoc[*] find_active_target (&Board b)
- {
+ public ObjectLoc[*] find_active_target (&Board b) {
bool match (Object o) {
union switch (o.target) {
case target t:
@@ -510,8 +517,7 @@
return find (&b, match);
}
- public void set_target (&Board b, Color color, Shape shape)
- {
+ public void set_target (&Board b, Color color, Shape shape) {
void set_robot_active (ObjectLoc[*] ol, bool active) {
for (int o = 0; o < dim (ol); o++)
b[ol[o].x, ol[o].y].robot.robot.active = active;
@@ -523,8 +529,76 @@
set_robot_active (find_active_robot (&b), false);
set_target_active (find_active_target (&b), false);
- set_robot_active (find_robot (&b, color), true);
- set_target_active (find_target (&b, color, shape), true);
+ set_robot_active (find_robots (&b, color), true);
+ set_target_active (find_targets (&b, color, shape), true);
+ }
+
+ public void position_robot (&Board b, Color color, int x, int y) {
+ ObjectLoc ol = find_robot (&b, color);
+ b[ol.x, ol.y].robot = RobotOrNone.none;
+ b[x, y].robot = ol.object.robot;
+ }
+
+ typedef struct {
+ int dx;
+ int dy;
+ } Delta;
+
+ bool blocked_wall (Direction direction, Walls walls) {
+ switch (direction) {
+ case Direction.North: return walls.above;
+ case Direction.East: return walls.right;
+ case Direction.South: return walls.below;
+ case Direction.West: return walls.left;
+ }
+ return false;
+ }
+
+ bool blocked_robot (&Board b, int x, int y) {
+ if (x < 0 || Width <= x) return true;
+ if (y < 0 || Height <= y) return true;
+ return b[x,y].robot != RobotOrNone.none;
+ }
+
+ Delta delta (Direction direction) {
+ switch (direction) {
+ case Direction.North: return (Delta) { dx = 0, dy = -1 };
+ case Direction.East: return (Delta) { dx = 1, dy = 0 };
+ case Direction.South: return (Delta) { dx = 0, dy = 1 };
+ case Direction.West:
+ default:
+ }
+ return (Delta) { dx = -1, dy = 0 };
+ }
+
+ ObjectLoc find_dst (&Board b, int x, int y, Direction direction) {
+ Delta d = delta (direction);
+ while (!blocked_wall (direction, b[x,y].walls) &&
+ !blocked_robot (&b, x + d.dx, y + d.dy))
+ {
+ x += d.dx;
+ y += d.dy;
+ }
+ return (ObjectLoc) { x = x, y = y, object = b[x,y] };
+ }
+
+ public ObjectLoc move_robot (&Board b, Color color, Direction direction) {
+ ObjectLoc src = find_robot (&b, color);
+ ObjectLoc dst = find_dst (&b, src.x, src.y, direction);
+ return dst;
+ }
+
+ public bool solved (&Board b) {
+ ObjectLoc[*] target = find_active_target (&b);
+
+ if (dim(target) != 1)
+ return false;
+ union switch (target[0].object.robot) {
+ case robot r:
+ return r.active;
+ default:
+ }
+ return false;
}
}
}
Index: connect.5c
===================================================================
RCS file: /local/src/CVS/rrserver/connect.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- connect.5c 29 May 2003 06:45:37 -0000 1.1
+++ connect.5c 29 May 2003 08:15:44 -0000 1.2
@@ -56,7 +56,8 @@
reference ((Client) {
f = f,
user = User.none,
- game = GameRef.none
+ game = GameRef.none,
+ score = 0
})
};
return &clients[dim(clients)-1];
Index: dispatch.5c
===================================================================
RCS file: /local/src/CVS/rrserver/dispatch.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dispatch.5c 29 May 2003 06:45:37 -0000 1.1
+++ dispatch.5c 29 May 2003 08:15:44 -0000 1.2
@@ -27,6 +27,7 @@
autoload Server::Connect
autoload Server::Readreq
autoload Server::Show
+autoload Server::Games
extend namespace Server {
public namespace Dispatch {
@@ -42,20 +43,66 @@
File::fprintf (f, "HELO \"%s\"\n", server_id);
}
+ void print_client (&Client c) {
+ union switch (c.user) {
+ case none:
+ break;
+ case username u:
+ File::fprintf (f, " \"%s\"", u);
+ break;
+ }
+ }
+
+ void print_client_score (&Client c) {
+ union switch (c.user) {
+ case none:
+ break;
+ case username u:
+ File::fprintf (f, " \"%s\" %d", u, c.score);
+ break;
+ }
+ }
+
void who () {
File::fprintf (f, "WHO");
- Connect::iterate (void func(&Client c) {
- union switch (c.user) {
- case none:
- break;
- case username u:
- File::fprintf (f, " \"%s\"", u);
- break;
- }
+ Connect::iterate (print_client);
+ File::fprintf (f, "\n");
+ }
+
+ void games() {
+ File::fprintf (f, "GAMES");
+ Games::iterate (void func(&Game g) {
+ File::fprintf (f, " \"%s\"", g.name);
});
File::fprintf (f, "\n");
}
+ void users(string game) {
+ try {
+ &Game g = Games::find (game);
+ File::fprintf (f, "USERS");
+ Games::iterate_client (&g, print_client_score);
+ File::fprintf (f, "\n");
+ } catch Games::no_such_game (string name) {
+ File::fprintf (f, "ERROR NOGAME\n");
+ }
+ }
+
+ void join (string game) {
+ try {
+ &Game g = Games::find (game);
+ Games::add_client (&g, &c);
+ } catch Games::no_such_game (string game) {
+ File::fprintf (f, "ERROR NOGAME\n");
+ }
+ }
+
+ void new(string game) {
+ &Game g = Games::new (game);
+ join (g.name);
+ File::fprintf (f, "NEW \"%s\"\n", g.name);
+ }
+
void show () {
union switch (c.game) {
case none:
@@ -69,6 +116,82 @@
}
}
+ void bid (int number) {
+ File::fprintf (f, "BID\n");
+ }
+
+ void move (Color color, Direction direction) {
+ union switch (c.game) {
+ case none:
+ File::fprintf (f, "ERROR NOTINGAME\n");
+ break;
+ case game g:
+ try {
+ Games::move (&g, &c, color, direction);
+ File::fprintf (f, "MOVE\n");
+ } catch Games::notactive (&Game g, &Client c) {
+ File::fprintf (f, "ERROR NOTACTIVE\n");
+ }
+ break;
+ }
+ }
+
+ void undo () {
+ union switch (c.game) {
+ case none:
+ File::fprintf (f, "ERROR NOTINGAME\n");
+ break;
+ case game g:
+ try {
+ Games::undo (&g, &c);
+ File::fprintf (f, "UNDO\n");
+ } catch Games::notactive (&Game g, &Client c) {
+ File::fprintf (f, "ERROR NOTACTIVE\n");
+ }
+ break;
+ }
+ }
+
+ void reset () {
+ union switch (c.game) {
+ case none:
+ File::fprintf (f, "ERROR NOTINGAME\n");
+ break;
+ case game g:
+ try {
+ Games::reset (&g, &c);
+ File::fprintf (f, "RESET\n");
+ } catch Games::notactive (&Game g, &Client c) {
+ File::fprintf (f, "ERROR NOTACTIVE\n");
+ }
+ break;
+ }
+ }
+
+ void turn () {
+ union switch (c.game) {
+ case none:
+ File::fprintf (f, "ERROR NOTINGAME\n");
+ break;
+ case game g:
+ if (Games::solved (&g))
+ Games::next_target (&g);
+ File::fprintf (f, "TURN\n");
+ break;
+ }
+ }
+
+ void pass () {
+ }
+
+ void message (string text) {
+ Connect::iterate (void func (&Client c) {
+ File::fprintf (c.f, "NOTICE MESSAGE \"%s\"\n", text);
+ File::flush (c.f);
+ });
+ File::fprintf (f, "MESSAGE\n");
+ }
+
void quit () {
File::fprintf (f, "QUIT\n");
raise Readreq::request_closed();
@@ -87,14 +210,47 @@
case WHO:
who ();
break;
+ case GAMES:
+ games ();
+ break;
+ case USERS u:
+ users (u.game);
+ break;
+ case NEW n:
+ new (n.game);
+ break;
+ case JOIN j:
+ join (j.game);
+ break;
+ case WATCH w:
+# watch (w.game);
+ break;
case SHOW:
show ();
break;
+ case BID b:
+ bid (b.number);
+ break;
+ case MOVE m:
+ move (m.color, m.direction);
+ break;
+ case UNDO:
+ undo ();
+ break;
+ case RESET:
+ reset ();
+ break;
+ case TURN:
+ turn ();
+ break;
+ case PASS:
+ pass ();
+ break;
+ case MESSAGE m:
+ message (m.text);
+ break;
case QUIT:
quit ();
- break;
- default:
- printf ("not done yet %v\n", r);
break;
}
} catch Readreq::invalid_request (string w) {
Index: games.5c
===================================================================
RCS file: /local/src/CVS/rrserver/games.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- games.5c 29 May 2003 06:45:37 -0000 1.1
+++ games.5c 29 May 2003 08:15:44 -0000 1.2
@@ -95,6 +95,8 @@
public void next_target (&Game g) {
Target t = g.targets[0];
g.targets = (Target[dim(g.targets)-1]) { [i] = g.targets[i+1] };
+ g.history = (ObjectLoc[*]) {};
+ g.time = Time.none;
Boards::set_target (&g.board, t.color, t.shape);
}
@@ -110,23 +112,67 @@
g.clients = ((&Client)[*]) {};
g.board = Boards::random_board ();
g.targets = random_targets ();
- g.time = Time.none;
g.active = ClientRef.none;
- g.history = (ObjectLoc[*]) {};
next_target (&g);
return &g;
}
- public &Client add_client (&Game g, &Client c) {
- return Array::append (&g.clients, &c);
- }
-
public void remove_client (&Game g, &Client c) {
Array::remove (&g.clients, &c);
+ c.score = 0;
+ }
+
+ public &Client add_client (&Game g, &Client c) {
+ if (c.game != GameRef.none)
+ remove_client (&c.game.game, &c);
+ c.game = (GameRef.game) (&g);
+ if (g.active == ClientRef.none)
+ g.active = (ClientRef.client) (&c);
+ return Array::append (&g.clients, &c);
}
public void iterate_client (&Game g, void (&Client c) f) {
Array::iterate (&g.clients, f);
+ }
+
+ public ClientRef active_client (&Game g) {
+ return g.active;
+ }
+
+ public exception notactive (&Game g, &Client c);
+
+ public bool undo (&Game g, &Client c) {
+ try {
+ ObjectLoc ol = Array::pop (&g.history);
+ Boards::position_robot (&g.board, ol.object.robot.robot.color,
+ ol.x, ol.y);
+ } catch Array::empty (&ObjectLoc[*] a) {
+ return false;
+ }
+ return true;
+ }
+
+ public void reset (&Game g, &Client c) {
+ if (g.active != (ClientRef.client) (&c))
+ raise notactive (&g, &c);
+ while (dim (g.history) > 0)
+ undo (&g, &c);
+ }
+
+ public bool move (&Game g, &Client c, Color color, Direction dir) {
+ if (g.active != (ClientRef.client) (&c))
+ raise notactive (&g, &c);
+ ObjectLoc src = Boards::find_robot (&g.board, color);
+ ObjectLoc dst = Boards::move_robot (&g.board, color, dir);
+ if (src == dst)
+ return false;
+ Array::push (&g.history, src);
+ Boards::position_robot (&g.board, color, dst.x, dst.y);
+ return true;
+ }
+
+ public bool solved (&Game g) {
+ return Boards::solved (&g.board);
}
}
}
Index: lex.5c
===================================================================
RCS file: /local/src/CVS/rrserver/lex.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- lex.5c 29 May 2003 06:45:37 -0000 1.1
+++ lex.5c 29 May 2003 08:15:44 -0000 1.2
@@ -91,7 +91,6 @@
}
s = s + String::new(c);
}
- printf ("word: %s\n", s);
return s;
}
Index: server.5c
===================================================================
RCS file: /local/src/CVS/rrserver/server.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- server.5c 29 May 2003 06:45:37 -0000 1.1
+++ server.5c 29 May 2003 08:15:44 -0000 1.2
@@ -46,16 +46,11 @@
&Game game;
} GameRef;
- public typedef union {
- void none;
- thread t;
- } UserThread;
-
public typedef struct {
- file f;
- User user;
- GameRef game;
- UserThread t;
+ file f;
+ User user;
+ GameRef game;
+ int score;
} Client;
public typedef union {
Index: show.5c
===================================================================
RCS file: /local/src/CVS/rrserver/show.5c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- show.5c 29 May 2003 06:45:37 -0000 1.1
+++ show.5c 29 May 2003 08:15:44 -0000 1.2
@@ -33,7 +33,7 @@
File::fprintf (f, " ");
}
- void show_color (Color c, bool active) {
+ void show_color (file f, Color c, bool active) {
int ch;
switch (c) {
case Color.Red: ch = 'r'; break;
@@ -44,10 +44,10 @@
}
if (active)
ch = Ctype::toupper (ch);
- printf ("%c", ch);
+ File::fprintf (f, "%c", ch);
}
- void show_shape (Shape s, bool active) {
+ void show_shape (file f, Shape s, bool active) {
int ch;
switch (s) {
case Shape.Triangle: ch = 't'; break;
@@ -58,7 +58,7 @@
}
if (active)
ch = Ctype::toupper (ch);
- printf ("%c", ch);
+ File::fprintf (f, "%c", ch);
}
void show_second_object (file f, &Object o) {
@@ -71,8 +71,8 @@
File::fprintf (f, "..");
break;
case robot r:
- show_color (r.color, r.active);
- show_color (r.color, r.active);
+ show_color (f, r.color, r.active);
+ show_color (f, r.color, r.active);
break;
}
}
@@ -87,8 +87,8 @@
File::fprintf (f, "..");
break;
case target t:
- show_color (t.color, t.active);
- show_shape (t.shape, t.active);
+ show_color (f, t.color, t.active);
+ show_shape (f, t.shape, t.active);
break;
}
}
@@ -125,9 +125,9 @@
for (int col = 0; col < Width; col++)
{
if (b[col,Height-1].walls.below)
- printf (" ==");
+ File::fprintf (f, " ==");
else
- printf (" ");
+ File::fprintf (f, " ");
}
}