diff -uprN -x *.o ../../circle/src/Makefile ./Makefile
--- ../../circle/src/Makefile	Fri Apr 23 09:58:51 1999
+++ ./Makefile	Fri Apr 23 10:37:34 1999
@@ -29,14 +29,14 @@ OBJFILES = act.comm.o act.informative.o 
 	boards.o castle.o class.o comm.o config.o constants.o db.o fight.o \
 	graph.o handler.o house.o interpreter.o limits.o magic.o mail.o \
 	mobact.o modify.o objsave.o olc.o random.o shop.o spec_assign.o \
-	spec_procs.o spell_parser.o spells.o utils.o weather.o
+	spec_procs.o spell_parser.o spells.o utils.o weather.o chess.o
 
 CXREF_FILES = act.comm.c act.informative.c act.item.c act.movement.c \
 	act.offensive.c act.other.c act.social.c act.wizard.c alias.c ban.c \
 	boards.c castle.c class.c comm.c config.c constants.c db.c fight.c \
 	graph.c handler.c house.c interpreter.c limits.c magic.c mail.c \
 	mobact.c modify.c objsave.c olc.c random.c shop.c spec_assign.c\
-	spec_procs.c spell_parser.c spells.c utils.c weather.c
+	spec_procs.c spell_parser.c spells.c utils.c weather.c chess.c
 
 default: all
 
@@ -199,3 +199,6 @@ utils.o: utils.c conf.h sysdep.h structs
 weather.o: weather.c conf.h sysdep.h structs.h utils.h comm.h handler.h \
   interpreter.h db.h
 	$(CC) -c $(CFLAGS) weather.c
+
+chess.o: conf.h sysdep.h structs.h utils.h db.h comm.h chess.h
+	$(CC) -c $(CFLAGS) chess.c
diff -uprN -x *.o ../../circle/src/chess.c ./chess.c
--- ../../circle/src/chess.c	Wed Dec 31 18:00:00 1969
+++ ./chess.c	Fri Apr 23 10:38:49 1999
@@ -0,0 +1,637 @@
+#include "conf.h"
+#include "sysdep.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "structs.h"
+#include "utils.h"
+#include "screen.h"
+#include "db.h"
+#include "comm.h"
+#include "chess.h"
+
+/* multiple games neh? */
+struct board_type *world_boards = NULL;
+
+/* lets make a counter for the games, for unique idnum */
+int chess_world_number = 1;
+
+void delete_board(struct obj_data *obj) {
+  int val2 = GET_OBJ_VAL(obj,2);
+  struct board_type *temp=world_boards;
+  struct board_type *tert=NULL;
+
+  if(!temp) {
+    return;
+  }
+  while(temp) {
+    tert=temp->next;
+    if(temp->unique_board_num == val2) {
+      free(temp);
+    }
+    temp=tert;
+  }
+}
+  
+void init_board(struct obj_data *obj) {
+  int tcol=0,trow=0;
+  struct board_type *new_board=NULL;
+
+  GET_OBJ_VAL(obj,1) = 0;
+  GET_OBJ_VAL(obj,2) = chess_world_number++;
+  
+  CREATE(new_board,struct board_type,1);
+  new_board->playerone=0;
+  new_board->playertwo=0;
+  new_board->win = 0;
+  new_board->unique_board_num = GET_OBJ_VAL(obj,2);
+
+  if(random()%2) {
+    new_board->player=BLACK;
+  } else {
+    new_board->player=WHITE;
+  }
+
+  for (trow = 0; trow < NUM_ROWS; trow++) {
+    for (tcol = 0; tcol < NUM_COLS; tcol++) {
+      new_board->board[trow][tcol] = NO_PIECE;
+    }
+  }
+
+  for(tcol=0;tcol < NUM_COLS; tcol++) {
+    SET_BIT(new_board->board[1][tcol],PAWN|BLACK);
+    SET_BIT(new_board->board[NUM_ROWS-2][tcol],PAWN|WHITE);
+  }
+
+  SET_BIT(new_board->board[0][0],ROOK|BLACK);
+  SET_BIT(new_board->board[0][NUM_COLS-1],ROOK|BLACK);
+  SET_BIT(new_board->board[NUM_ROWS-1][0],WHITE|ROOK);
+  SET_BIT(new_board->board[NUM_ROWS-1][NUM_COLS-1],WHITE|ROOK);
+
+  SET_BIT(new_board->board[0][1],BLACK|KNIGHT);
+  SET_BIT(new_board->board[0][NUM_COLS-2],BLACK|KNIGHT);
+  SET_BIT(new_board->board[NUM_ROWS-1][1],WHITE|KNIGHT);
+  SET_BIT(new_board->board[NUM_ROWS-1][NUM_COLS-2],WHITE|KNIGHT);
+
+
+  SET_BIT(new_board->board[0][2],BLACK|BISHOP);
+  SET_BIT(new_board->board[0][NUM_COLS-3],BLACK|BISHOP);
+  SET_BIT(new_board->board[NUM_ROWS-1][2],WHITE|BISHOP);
+  SET_BIT(new_board->board[NUM_ROWS-1][NUM_COLS-3],WHITE|BISHOP);
+
+  SET_BIT(new_board->board[0][3],BLACK|QUEEN);
+  SET_BIT(new_board->board[0][4],BLACK|KING);
+  SET_BIT(new_board->board[NUM_ROWS-1][3],WHITE|QUEEN);
+  SET_BIT(new_board->board[NUM_ROWS-1][4],WHITE|KING);
+
+  /* add board to global structure */
+  new_board->next = world_boards;
+  world_boards = new_board;
+
+  return;
+}
+
+void display_board(struct obj_data *obj,struct char_data *ch) {
+  int val2 = GET_OBJ_VAL(obj,2);
+  int trow,tcol;
+  char outbuf[32635];
+  struct board_type *board = find_chess_board(val2);
+
+  if(!board) {
+    return;
+  }
+  sprintf(outbuf,CLEAR_SCREEN);
+  sprintf(outbuf + strlen(outbuf),"\t      %sChess%s\t\t  %sRow%s\r\n",
+        BYEL,CNRM,BWHT,CNRM);
+  /* Guess we'll print each piece */
+  sprintf(outbuf + strlen(outbuf), "%s",connect_strip(TRUE));
+
+  for(trow=0;trow < NUM_ROWS;trow++) {
+    for(tcol=0;tcol < NUM_COLS;tcol++) {
+      sprintf(outbuf + strlen(outbuf),"%s", printpiece(board,trow,tcol));
+    }
+
+    /* col is used, so, hum, no prob */
+
+    sprintf(outbuf + strlen(outbuf),"%s|%s  %s%d%s\r\n",CGRE,CNRM,
+                BWHT,NUM_ROWS-trow,CNRM);
+    sprintf(outbuf + strlen(outbuf),
+         "%s", connect_strip(FALSE));
+
+  }
+  sprintf(outbuf + strlen(outbuf),
+     "%s  A   B   C   D   E   F   G   H%s\r\n\r\n",BWHT,CNRM);
+
+  send_to_char(outbuf,ch);
+
+  display_whos_turn(board,ch);
+
+  return;
+}
+
+char *connect_strip(int topbot) {
+    char outbuf[32536];
+    int trow;
+
+    sprintf(outbuf, "%s+%s",BGRN,CNRM);
+
+    for(trow=0;trow< NUM_COLS-1;trow++) {
+      sprintf(outbuf + strlen(outbuf),
+         "%s---%s%s%c%s",CGRE,CNRM,BGRN,!topbot ? '+' : '-',CNRM);
+    }
+
+    sprintf(outbuf + strlen(outbuf), "%s---%s%s+%s\r\n",
+                CGRE,CNRM,BGRN,CNRM);
+
+  return strdup(outbuf);
+
+}
+
+void display_whos_turn(struct board_type *board,struct char_data *ch) {
+   if (board->player==BLACK) {
+     sprintf(buf,"%sIt is %sBlack%s (%s) player's turn.%s\r\n",
+        BWHT,BRED,BWHT,get_name_by_id(board->playerone),CNRM);
+     send_to_char(buf,ch);
+   }
+   else {
+     sprintf(buf,"%sIt is %sWhite%s (%s) player's turn.%s\r\n",
+        BWHT,BBLU,BWHT,get_name_by_id(board->playertwo),CNRM);
+      send_to_char(buf,ch);
+   }
+}
+
+  /* this is simple enough */
+
+void perform_chess_move(struct move_type *move, struct board_type *board)
+{
+  /* here's where we check for winning/loosing */
+  if(IS_SET(TARGET,KING)) {
+    if(IS_SET(TARGET,BLACK)) {
+      board->win=WHITE;
+    } else {
+      board->win=BLACK;
+    }
+  }
+  if((IS_SET(PIECE,PAWN) && IS_SET(PIECE,WHITE) && move->row2==0) ||
+     (IS_SET(PIECE,PAWN) && IS_SET(PIECE,BLACK) && move->row2==7)) {
+    REMOVE_BIT(PIECE,PAWN);
+    SET_BIT(PIECE,QUEEN); /* woohoo! */
+  }
+  TARGET = PIECE;
+  PIECE = NO_PIECE;
+}
+
+/* returns true if there is an object between the start and end points of
+   a move */
+
+int horvert_path(struct move_type *move, struct board_type *board) {
+  int temp1,temp2;
+  int tcount;
+
+  if(move->row1 != move->row2 && move->col1 != move->col2) {
+    return TRUE;
+  }
+  /* look for horiz */
+  if(move->row1 == move->row2) {
+    if(move->col1 < move->col2) {
+      temp1=move->col2;
+      temp2=move->col1;
+    } else {
+      temp1=move->col1;
+      temp2=move->col2;
+    }
+    for(tcount=temp1-1;tcount > temp2;tcount--) {
+      if(board->board[move->row1][tcount] != NO_PIECE) {
+        return TRUE;
+      }
+    }
+    return FALSE; /* false is good, nothing in the way */
+  } else if (move->col1 == move->col2) {
+    if(move->row1 < move->row2) {
+      temp1=move->row2;
+      temp2=move->row1;
+    } else {
+      temp1=move->row1;
+      temp2=move->row2;
+    }
+
+    for(tcount=temp1-1;tcount > temp2;tcount--) {
+      if(board->board[tcount][move->col1] != NO_PIECE) {
+        return TRUE;  /* something's blocking */
+      }
+    }
+    return FALSE;
+  }
+  /* blocking regardless, we can't allow this move */
+  return TRUE;
+}
+
+/* same thing as horizonal checking, but slightly different because it
+   is diagonal */
+#define NW              1
+#define NE              2
+#define SW              3
+#define SE              4
+
+int diagonal_path(struct move_type *move, struct board_type *board) {
+  int temp1,temp2;
+  int dir;
+
+  /* check if it's actually diagonal */
+  if(abs(move->row1 - move->row2) !=
+        abs(move->col1 - move->col2)) {
+    return TRUE;
+  }
+
+  /* determine if it's nw-se or ne-sw. Sigh */
+        /* 0 to 1 with row is south, 1 to 0 north */
+  if(move->row1 < move->row2) {         /* sudlich */
+    if(move->col1 > move->col2) {
+      dir=SW;
+    } else {
+      dir=SE;
+    }
+  } else {      /* nordlich */
+    if(move->col1 > move->col2) {
+      dir=NW;
+    } else {
+      dir=NE;
+    }
+  }
+
+        /* pjd - no longer need this, but it's not horrid to keep */
+        /* quick check if they're only one space away */
+  if(abs(move->row1 - move->row2) == 1
+        ||  abs(move->col1 - move->col2) == 1) {
+    return FALSE;
+  }
+        /* okay, we know direction so we know which way to iterate */
+  temp1=move->row1;
+  temp2=move->col1;
+
+        /* wish there was a nice way to do this, but this works..
+                iterate it to the next space.. then follow the loop-
+        return true if current space is the end point.
+        else, return false if current space is occupied,
+        else, iterate to next space and continue.       */
+
+    if(dir == SW) {
+      temp1++;
+      temp2--;
+    } else if(dir == SE) {
+      temp1++;
+      temp2++;
+    } else if(dir == NW) {
+      temp1--;
+      temp2--;
+    } else {
+      temp1--;
+      temp2++;
+    }
+  while(temp1 != move->row2 && temp2 != move->col2) {
+    if(board->board[temp1][temp2] != NO_PIECE) {
+      return TRUE;
+    }
+    if(dir == SW) {
+      temp1++;
+      temp2--;
+    } else if(dir == SE) {
+      temp1++;
+      temp2++;
+    } else if(dir == NW) {
+      temp1--;
+      temp2--;
+    } else {
+      temp1--;
+      temp2++;
+    }
+  }
+  if(temp1 == move->row2 && temp2 == move->col2) {
+    return FALSE;
+  }
+  return TRUE;
+}
+char *printpiece(struct board_type *board,int row, int col) {
+  char outbuf[32356];
+  long piece;
+
+  piece = board->board[row][col];
+
+  if(piece == NO_PIECE) {
+    sprintf(outbuf,"%s|%s   ", CGRE,CNRM);
+  } else {
+    sprintf(outbuf,"%s|%s %s",CGRE,CNRM,
+       IS_SET(piece,WHITE) ? BBLU : BRED);
+
+    if(IS_SET(piece,ROOK)) {
+      sprintf(outbuf + strlen(outbuf), "R ");
+    } else if (IS_SET(piece,BISHOP)) {
+      sprintf(outbuf + strlen(outbuf), "B ");
+    } else if (IS_SET(piece,KNIGHT)) {
+      sprintf(outbuf + strlen(outbuf), "N ");
+    } else if (IS_SET(piece,QUEEN)) {
+      sprintf(outbuf + strlen(outbuf), "Q ");
+    } else if (IS_SET(piece,KING)) {
+      sprintf(outbuf + strlen(outbuf), "K ");
+    } else if (IS_SET(piece,PAWN)) {
+      sprintf(outbuf + strlen(outbuf), "P ");
+    } else {
+      sprintf(outbuf + strlen(outbuf), "  ");
+    }
+
+    sprintf(outbuf+strlen(outbuf),"%s",CNRM);
+  }
+  return strdup(outbuf);
+}
+
+int check_valid(struct move_type *move,int player,struct board_type *board,
+	struct char_data *ch) {
+  
+  if(PIECE == NO_PIECE) {
+    send_to_char("There is no piece there.\r\n",ch);
+    return FALSE;
+  }
+  if((IS_SET(PIECE,BLACK) && player == WHITE) ||
+    (IS_SET(PIECE,WHITE) && player == BLACK)) {
+    send_to_char("That is not your piece.\r\n",ch);
+    return FALSE;
+  }
+
+  if((IS_SET(PIECE,BLACK) && IS_SET(TARGET,BLACK)) ||
+    (IS_SET(PIECE,WHITE) && IS_SET(TARGET,WHITE))) {
+    return FALSE;
+  }
+
+  if(IS_SET(PIECE, PAWN)) {
+    return valid_pawn(move,player,board,ch);
+  } else if (IS_SET(PIECE,ROOK)) {
+    return valid_rook(move,player,board,ch);
+  } else if(IS_SET(PIECE,BISHOP)) {
+    return valid_bishop(move,player,board,ch);
+  } else if (IS_SET(PIECE,KNIGHT)) {
+    return valid_knight(move,player,board,ch);
+  } else if (IS_SET(PIECE, KING)) {
+    return valid_king(move,player,board,ch);
+  } else if (IS_SET(PIECE,QUEEN)) {
+    return valid_queen(move,player,board,ch);
+  } else {
+    return FALSE;
+  }
+
+}
+
+int valid_pawn(struct move_type *move,int player,struct board_type *board,
+	struct char_data *ch)
+{
+/* pawns always move forward */
+  if(player == BLACK && move->row1 > move->row2) {
+    return FALSE;
+  } else if (player == WHITE && move->row1 < move->row2) {
+    return FALSE;
+  }
+
+/* check for first move  - they can move 2 spaces in this case */
+  if(player==BLACK && move->row1 == 1 &&
+        (move->col1 == move->col2) && (abs(move->row1 - move->row2) == 2)) {
+    if(board->board[3][move->col1] != NO_PIECE) {
+      return FALSE;
+    }
+    if(TARGET != NO_PIECE) {
+      return FALSE;
+    }
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+  if(player==WHITE && move->row1 == 6 &&
+        (move->col1 == move->col2) && (abs(move->row2 - move->row1) == 2)) {
+    if(board->board[5][move->col1] != NO_PIECE) {
+      return FALSE;
+    }
+    if(TARGET != NO_PIECE) {
+      return FALSE;
+    }
+
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+
+
+/* now, check for normal move */
+  if(player==BLACK &&
+        (move->col1 == move->col2) && ((move->row2 - move->row1) == 1)) {
+    if(TARGET != NO_PIECE) {
+      return FALSE;
+    }
+    perform_chess_move(move,board);
+    return TRUE;
+
+  }
+
+  if(player==WHITE &&
+        (move->col1 == move->col2) && ((move->row1 - move->row2) == 1)) {
+    if(TARGET != NO_PIECE) {
+      return FALSE;
+    }
+
+    perform_chess_move(move,board);
+    return TRUE;
+
+  }
+
+/* now check for capture */
+
+  if(IS_SET(TARGET,WHITE) && IS_SET(PIECE,BLACK) &&
+        (abs(move->col1 - move->col2) == 1) &&
+        (move->row2 - move->row1 ==1)) {
+    perform_chess_move(move,board);
+    return TRUE;
+
+  }
+
+  if(IS_SET(TARGET,BLACK) && IS_SET(PIECE,WHITE) &&
+        (abs(move->col1 - move->col2) == 1) &&
+        (move->row1 - move->row2 ==1)) {
+
+    perform_chess_move(move,board);
+    return TRUE;
+
+  }
+
+  /* add a check to become a queen */
+        /* nope, we do it in perform move */
+  return FALSE;
+}
+
+int valid_bishop(struct move_type *move,int player,struct board_type
+*board, struct char_data *ch) {
+        /* terribly simple, check and make sure that it's a valid
+           non-jumping diagonal move, and if so, allow it */
+  if(!diagonal_path(move,board)) {
+    /* false means nothings in the way */
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+int valid_knight(struct move_type *move,int player,struct board_type
+*board, struct char_data *ch) {
+  int tcol,trow;
+
+  /* what we have to check for is the 2 and 1 - we don't care about
+     anything else at all */
+  tcol=abs(move->row1 - move->row2);
+  trow=abs(move->col1 - move->col2);
+
+  if((tcol+trow != 3) || (tcol >= 3 || tcol == 0) ||
+      (trow >= 3 || trow == 0) ||
+      (tcol == 2 && trow != 1) ||
+      (trow == 2 && tcol != 1)) {
+    return FALSE;
+  }
+        /* otherwise, it's all good */
+  perform_chess_move(move,board);
+  return TRUE;
+}
+
+int valid_rook(struct move_type *move,int player,struct board_type
+*board, struct char_data *ch)
+{
+  if(!horvert_path(move,board)) {
+    /* false means nothings in the way */
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+int valid_queen(struct move_type *move,int player,struct board_type
+*board, struct char_data *ch) {
+  if(!horvert_path(move,board)) {
+    /* false means nothings in the way */
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+
+  if(!diagonal_path(move,board)) {
+    /* false means nothings in the way */
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+
+  return FALSE;
+
+}
+
+int valid_king(struct move_type *move,int player,struct board_type
+*board, struct char_data *ch) {
+
+  if(abs(move->row1 - move->row2) > 1 || abs(move->col1 - move->col2) > 1) {
+    return FALSE;
+  } else {
+    perform_chess_move(move,board);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+char *get_chess_player(struct obj_data *board, int player) {
+  int val2 = GET_OBJ_VAL(board,2);
+  struct board_type *temp = find_chess_board(val2);
+
+  if(temp) {
+    if(player == 1) {
+      if(temp->playerone) {
+        return strdup(get_name_by_id(temp->playerone));
+      } else {
+        return strdup("No one");
+      }
+    } else {
+      if(temp->playertwo) {
+        return strdup(get_name_by_id(temp->playertwo));
+      } else {
+        return strdup("No one");
+      }
+    }
+  }
+  log("Error, board asked for player, and we could not find the board!");  
+  return strdup("Error.");
+
+}
+
+struct board_type *find_chess_board(int uid) {
+  struct board_type *temp= world_boards;
+  
+  while(temp) {
+    if(uid == temp->unique_board_num) {
+      return temp;
+    } else {
+      temp=temp->next;
+    }
+  }
+  return NULL;
+}
+
+void add_chess_player(struct char_data *ch, int player, 
+	struct obj_data *board) {
+  int val2=GET_OBJ_VAL(board,2);
+  struct board_type *temp = world_boards;
+
+  while(temp) {
+    if(temp->unique_board_num == val2) {
+      if(player == 1) {
+        temp->playerone = GET_IDNUM(ch);
+      } else {
+        temp->playertwo = GET_IDNUM(ch);
+      }
+    }
+    temp=temp->next;
+  }
+  return;  
+}
+
+struct move_type *check_input(char *inbuf) {
+  int row1,row2;
+  char col1,col2;
+  struct move_type *joy;
+
+  if(sscanf(inbuf," %c %d %c %d",&col1,&row1,&col2,&row2) != 4) {
+    log("failed at # inputs.");
+    log(inbuf);
+    return NULL;
+  }
+
+  if(toupper(col1) < 'A'  || toupper(col1) > 'H') {
+    return NULL;
+  }
+
+  if(toupper(col2) < 'A'  || toupper(col2) > 'H') {
+    return NULL;
+  }
+
+  if(row1 < 1 || row1 > 8) {
+    return NULL;
+  }
+
+  if(row2 < 1 || row2 > 8) {
+    return NULL;
+  }
+  if( row2 == row1 && col2 == col1) {
+    return NULL;
+  }
+
+  CREATE(joy, struct move_type,1);
+/* here's where we change the coordinate system to virtual nums */
+
+  joy->row1=NUM_ROWS - row1;
+  joy->row2=NUM_ROWS - row2;
+  joy->col1=toupper(col1) - 'A';
+  joy->col2=toupper(col2) - 'A';
+
+  return joy;
+}
+
+
diff -uprN -x *.o ../../circle/src/chess.h ./chess.h
--- ../../circle/src/chess.h	Wed Dec 31 18:00:00 1969
+++ ./chess.h	Fri Apr 23 10:39:00 1999
@@ -0,0 +1,79 @@
+#define NUM_ROWS        8
+#define NUM_COLS        8
+
+void init_board(struct obj_data *obj);
+void display_board(struct obj_data *board,struct char_data *ch);
+char *connect_strip(int topbot);
+
+struct board_type {
+  long playerone;		/* black */
+  long playertwo;			/* white */
+  int unique_board_num;
+  struct board_type *next;
+  long board[NUM_ROWS][NUM_COLS];
+  int win;
+  int player;
+};
+
+struct move_type {
+  int row1;
+  int col1;
+  int row2;
+  int col2;
+};
+
+void display_whos_turn(struct board_type *board,struct char_data *ch);
+void perform_chess_move(struct move_type *move,struct board_type *board);
+int horvert_path(struct move_type *move, struct board_type *board);
+int diagonal_path(struct move_type *move, struct board_type *board);
+
+#define NO_PIECE        (1 << 0)
+
+#define ROOK            (1 << 1)
+#define BISHOP          (1 << 2)
+#define KNIGHT          (1 << 3)
+#define KING            (1 << 4)
+#define QUEEN           (1 << 5)
+#define PAWN            (1 << 6)
+
+#define WHITE           (1 << 7)
+#define BLACK           (1 << 8)
+
+/* as confusing as that is... */
+#define PIECE           (board->board[move->row1][move->col1])
+#define TARGET          (board->board[move->row2][move->col2])
+
+char *printpiece(struct board_type *board, int row, int col);
+#define INVALID_MOVE    "Invalid Move\r\n"
+
+int check_valid(struct move_type *move,int player, struct board_type *board,
+	struct char_data *ch );
+int valid_pawn(struct move_type *move, int player , struct board_type *board,
+	struct char_data *ch);
+int valid_knight(struct move_type *move, int player, struct board_type
+*board, struct char_data *ch);
+int valid_rook(struct move_type *move, int player, struct board_type
+*board, struct char_data *ch);
+int valid_bishop(struct move_type *move, int player, struct board_type
+*board, struct char_data *ch);
+int valid_king(struct move_type *move, int player, struct board_type
+*board, struct char_data *ch);
+int valid_queen(struct move_type *move, int player, struct board_type
+*board, struct char_data *ch);
+
+/* these are colors */
+#define CGRE  "\x1B[0;0m\x1B[0;30;40;1m"
+#define CNRM  "\x1B[0;0m"
+#define BRED  "\x1B[0;0m\x1B[1;31m" /* 11 */
+#define BGRN  "\x1B[0;0m\x1B[1;32m"
+#define BBLU  "\x1B[0;0m\x1B[1;34m"
+#define BWHT  "\x1B[0;0m\x1B[1;37m"
+#define BYEL  "\x1B[0;0m\x1B[1;33m"
+#define CLEAR_SCREEN  "\033[2J" /* Clear screen */
+
+char *get_chess_player(struct obj_data *board, int player);
+struct board_type *find_chess_board(int uid);
+void delete_board(struct obj_data *obj);
+void add_chess_player(struct char_data *ch, int player, 
+		struct obj_data *board );
+struct move_type *check_input(char *inbuf);
diff -uprN -x *.o ../../circle/src/db.c ./db.c
--- ../../circle/src/db.c	Thu Mar  4 23:44:29 1999
+++ ./db.c	Fri Apr 23 10:47:52 1999
@@ -73,6 +73,7 @@ char *immlist = NULL;		/* list of peon g
 char *background = NULL;	/* background story		 */
 char *handbook = NULL;		/* handbook for new immortals	 */
 char *policies = NULL;		/* policies page		 */
+char *chess_rules = NULL;	/* chess rules			 */
 
 struct help_index_element *help_table = 0;	/* the help table	 */
 int top_of_helpt = 0;		/* top of help index table	 */
@@ -181,6 +182,7 @@ ACMD(do_reboot)
     file_to_string_alloc(HELP_PAGE_FILE, &help);
     file_to_string_alloc(INFO_FILE, &info);
     file_to_string_alloc(POLICIES_FILE, &policies);
+    file_to_string_alloc(CHESS_FILE, &chess_rules);
     file_to_string_alloc(HANDBOOK_FILE, &handbook);
     file_to_string_alloc(BACKGROUND_FILE, &background);
   } else if (!str_cmp(arg, "wizlist"))
@@ -201,6 +203,8 @@ ACMD(do_reboot)
     file_to_string_alloc(INFO_FILE, &info);
   else if (!str_cmp(arg, "policy"))
     file_to_string_alloc(POLICIES_FILE, &policies);
+  else if (!str_cmp(arg, "chess"))
+    file_to_string_alloc(CHESS_FILE, &chess_rules);
   else if (!str_cmp(arg, "handbook"))
     file_to_string_alloc(HANDBOOK_FILE, &handbook);
   else if (!str_cmp(arg, "background"))
@@ -280,6 +284,7 @@ void boot_db(void)
   file_to_string_alloc(WIZLIST_FILE, &wizlist);
   file_to_string_alloc(IMMLIST_FILE, &immlist);
   file_to_string_alloc(POLICIES_FILE, &policies);
+  file_to_string_alloc(CHESS_FILE, &chess_rules);
   file_to_string_alloc(HANDBOOK_FILE, &handbook);
   file_to_string_alloc(BACKGROUND_FILE, &background);
   if (file_to_string_alloc(GREETINGS_FILE, &GREETINGS) == 0)
diff -uprN -x *.o ../../circle/src/db.h ./db.h
--- ../../circle/src/db.h	Thu Dec 10 01:52:07 1998
+++ ./db.h	Fri Apr 23 10:46:01 1999
@@ -80,6 +80,7 @@
 #define BACKGROUND_FILE	LIB_TEXT"background"/* for the background story	*/
 #define POLICIES_FILE	LIB_TEXT"policies" /* player policies/rules	*/
 #define HANDBOOK_FILE	LIB_TEXT"handbook" /* handbook for new immorts	*/
+#define CHESS_FILE	LIB_TEXT"chess"	/* chess rules */
 
 #define IDEA_FILE	LIB_MISC"ideas"	/* for the 'idea'-command	*/
 #define TYPO_FILE	LIB_MISC"typos"	/*         'typo'		*/
diff -uprN -x *.o ../../circle/src/interpreter.c ./interpreter.c
--- ../../circle/src/interpreter.c	Thu Mar  4 23:55:38 1999
+++ ./interpreter.c	Fri Apr 23 11:28:49 1999
@@ -343,6 +343,7 @@ cpp_extern const struct command_info cmd
   { "invis"    , POS_DEAD    , do_invis    , LVL_IMMORT, 0 },
 
   { "junk"     , POS_RESTING , do_drop     , 0, SCMD_JUNK },
+  { "join"     , POS_DEAD    , do_not_here , 0, 0},
 
   { "kill"     , POS_FIGHTING, do_kill     , 0, 0 },
   { "kick"     , POS_FIGHTING, do_kick     , 1, 0 },
@@ -361,6 +362,7 @@ cpp_extern const struct command_info cmd
 
   { "moan"     , POS_RESTING , do_action   , 0, 0 },
   { "motd"     , POS_DEAD    , do_gen_ps   , 0, SCMD_MOTD },
+  { "move"     , POS_DEAD    , do_not_here , 0, 0},
   { "mail"     , POS_STANDING, do_not_here , 1, 0 },
   { "massage"  , POS_RESTING , do_action   , 0, 0 },
   { "mute"     , POS_DEAD    , do_wizutil  , LVL_GOD, SCMD_SQUELCH },
@@ -441,6 +443,7 @@ cpp_extern const struct command_info cmd
   { "sell"     , POS_STANDING, do_not_here , 0, 0 },
   { "send"     , POS_SLEEPING, do_send     , LVL_GOD, 0 },
   { "set"      , POS_DEAD    , do_set      , LVL_GOD, 0 },
+  { "setup"    , POS_DEAD    , do_not_here , 0, 0},
   { "shout"    , POS_RESTING , do_gen_comm , 0, SCMD_SHOUT },
   { "shake"    , POS_RESTING , do_action   , 0, 0 },
   { "shiver"   , POS_RESTING , do_action   , 0, 0 },
diff -uprN -x *.o ../../circle/src/spec_procs.c ./spec_procs.c
--- ../../circle/src/spec_procs.c	Thu Dec 10 01:56:08 1998
+++ ./spec_procs.c	Fri Apr 23 10:44:04 1999
@@ -18,7 +18,7 @@
 #include "handler.h"
 #include "db.h"
 #include "spells.h"
-
+#include "chess.h"
 
 /*   external vars  */
 extern struct room_data *world;
@@ -727,4 +727,166 @@ SPECIAL(bank)
   } else
     return (0);
 }
+
+/* chess board takes the following types of commands:
+   look (at) board      - results depend on value 0
+        0 - looking for players
+        1 - looking for one more player
+        2 - display board
+        3/4 - game over, player 1 - 2 wins, waiting for reset
+   look (at) rules      - results in a listing of rules.
+
+   setup                - results depend on value 2
+        0 - sends confirmation message
+        1 - actually init's the board
+
+   join                 - depends on the val 0
+        0/1 - okay.
+        2 - 'sorry no players'
+        3/4 - use 'setup' to clear board for new game
+
+   move <col> <row> <col> <row>
+        attempts to have a player enter a move
+*/
+SPECIAL(chessboard) {
+  struct obj_data *board = (struct obj_data *) me;
+  extern char *chess_rules;
+  struct move_type *move;
+  struct board_type *board2=find_chess_board(GET_OBJ_VAL(board,2));
+  int valid_move=0;
+  long player=0;
+
+  /* npcs will not play chess */
+  if (IS_NPC(ch))
+    return 0;
+
+  if(!CMD_IS("look") && !CMD_IS("move") && !CMD_IS("setup") &&
+        !CMD_IS("join")) {
+    return 0;
+  }
+  one_argument(argument,arg);
+
+  /* now, we'll look for look */
+  if(CMD_IS("look")) {
+    if(!str_cmp("rules",arg)) {
+      page_string(ch->desc, chess_rules, TRUE);
+      return 1;
+    } else if (!str_cmp("board",arg)) {
+      if(GET_OBJ_VAL(board,0) == 0) {
+         send_to_char("The chess board looks like it's ready for some players.\r\n",ch);
+        send_to_char("type 'join' to join the game.\r\n",ch);
+        return 1;
+      } else if (GET_OBJ_VAL(board,0) == 1) {
+        sprintf(buf,"Looks like %s needs an opponent.\r\n"
+                "type 'join' to join the game.\r\n",
+                get_chess_player(board,1));
+        send_to_char(buf,ch);
+        return 1;
+      } else if (GET_OBJ_VAL(board,0) == 2) {
+        display_board(board,ch);
+      } else if (GET_OBJ_VAL(board,0) == 3) {
+        sprintf(buf,"We have a winner: %s.\r\n",
+get_chess_player(board,1));
+        send_to_char(buf,ch);
+        display_board(board,ch);
+      } else if (GET_OBJ_VAL(board,0) == 4) {
+        sprintf(buf,"We have a winner: %s.\r\n", get_chess_player(board,2));
+        send_to_char(buf,ch);
+        display_board(board,ch);
+      } else {
+        log("Error, unknown obj val on chessboard.\r\n");
+        send_to_char("Error with this board, please contact gods.",ch);
+      }
+      return 1;
+    } else {
+      return 0; /* end of 'look board' */
+    }
+  } else if(CMD_IS("setup")) {   /* end of look */
+    if(GET_OBJ_VAL(board,1) == 0) {
+      send_to_char("Type setup again to start a new game.\r\n",ch);
+      GET_OBJ_VAL(board,1) = 1;
+    } else {
+      GET_OBJ_VAL(board,1) = 0;
+      GET_OBJ_VAL(board,0) = 0;
+      GET_OBJ_VAL(board,2) = 0;
+      send_to_char("Setting up new game.\r\n",ch);
+      delete_board(board);
+      init_board(board);
+    }
+    return 1;
+  } else if(CMD_IS("join")) {
+    if(board2 == NULL) {
+      send_to_char("You have to set up the board first. Use 'setup'\r\n",ch);
+      return 1;
+    }
+    if(GET_OBJ_VAL(board,0) == 0) {
+      send_to_char("You join the game.\r\n",ch);
+      add_chess_player(ch,1,board);
+      GET_OBJ_VAL(board,0) = 1;
+      return 1;
+    } else if (GET_OBJ_VAL(board,0) == 1) {
+      send_to_char("You join the game.\r\n",ch);
+      add_chess_player(ch,2,board);
+      GET_OBJ_VAL(board,0) = 2;
+      return 1;
+    } else if (GET_OBJ_VAL(board,0) == 2) {
+      send_to_char("There is already a game in progress.\r\n",ch);
+      return 1;
+    } else {
+       send_to_char("This game is over - you can use 'setup' to start a new one though.\r\n",ch);
+      return 1;
+    }
+  } else if(CMD_IS("move")) {
+        /* we have to figure out if the person is supposed to be moving */
+    if(!board2) {
+      send_to_char("No game started yet.\r\n",ch);
+      return 1;
+    }
+
+    if(GET_IDNUM(ch) != board2->playerone && GET_IDNUM(ch) !=
+                board2->playertwo) {
+      send_to_char("You're not a player.\r\n",ch);
+      return 1;
+    }
+
+    if(board2->player == 1) {
+      log("had to set player to white?!?!");
+      board2->player = WHITE;
+    }
+    if((GET_IDNUM(ch) == board2->playerone &&
+                board2->player != BLACK) ||
+        (GET_IDNUM(ch) == board2->playertwo && board2->player !=WHITE)) {
+      send_to_char("It is not your turn!\r\n",ch);
+      return 1;
+    }
+
+    valid_move=0;
+
+    if((move=check_input(argument))!= NULL) {
+      if(GET_IDNUM(ch) == board2->playerone) {
+        player=BLACK;
+      } else {
+        player = WHITE;
+      }
+      valid_move=check_valid(move,player,board2,ch);
+      free(move);
+    }
+    if(!valid_move) {
+      send_to_char("Invalid move.\r\n",ch);
+      return 1;
+    }
+    if(board2->player==BLACK) {
+      board2->player=WHITE;
+    } else {
+      board2->player = BLACK;
+    }
+    send_to_char("You move your piece.\r\n",ch);
+    act("$n moves a piece on the chessboard.\r\n",FALSE,ch,0,0,TO_ROOM);
+    return 1;
+  }
+  return 0;
+}
+
+
+
 
