🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

3 total messages Started by Jay Lawlor Fri, 16 Nov 1990 05:16
playing gnuchess against another program
#6108
Author: Jay Lawlor
Date: Fri, 16 Nov 1990 05:16
19 lines
1472 bytes
I hope this hasn't been asked lately.  I especially hope it isn't
already in the documentation, which I have read but not thoroughly.

Well, I got the latest gnuchess and have everyone hooked on chess for
awhile.  Anyway, I notice that the documentation talks about how
gnuchess is stronger some other impressive programs when run on a
Sparcstation, etc.  What I'm wondering is whether there is a
convenient way to play gnuchess against another program, or itself,
that might be running on the same or a different machine. 

I know about the 'both' command but that's not what I want.  I'd like
to be able to run gnuchess on machine A and on machine B, where A
might be a significantly faster computer, and have them play each
other.  I don't want to enter the moves by hand since that would
affect the move times too much.

Has anyone done this already?

Jay
Re: playing gnuchess against another program
#6111
Author: Eugene Stark
Date: Sat, 17 Nov 1990 16:16
499 lines
13380 bytes
I wrote a program to do what you are asking, except it was to pit
two chinese checkers programs against each other.  I think slight
modifications to the program would enable it to work with GNUCHESS.
I enclose the source below.  I'd appreciate receiving any changes
that you make that end up doing anything interesting.

						- Gene Stark
						  SUNY at Stony Brook

/*
 * Versus:  A program to connect two Chinese checkers programs together
 *          so they can play against each other in automatic mode.
 *          Utility for the Stony Brook Dept. of Computer Science
 *          1989/90 Student Programming Competition
 *
 * Author:  E.W. Stark (stark@sbcs.sunysb.edu)
 * Date:    10/21/89
 *
 * Copyright (c) 1990 Eugene W. Stark
 * Permission is hereby granted for anyone to freely copy and modify this
 * program, as long as it is not for profit, and as long as my name and
 * copyright notice remain intact on all copies and modified versions.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY.  No author or distributor
 * accepts responsibility to anyone for the consequences of using it
 * or for whether it serves any particular purpose or works at all,
 * unless he says so in writing.
 *
 *
 * Synopsis: To pit two Chinese checkers programs against each other,
 *          when they are potentially running on different machines,
 *          the player having the white pieces first executes the
 *          following:
 *
 *              % versus -w <White command line>
 *
 *          Versus will first create a socket for communicating moves
 *          with the Black program and print its port number.
 *          It will then allocate a pty pair and start up the White
 *          program.  Versus will then goes into a communication loop
 *          in which it transfers moves back and forth between the pty
 *          and the socket.
 *
 *          After the port number has been printed out, the player
 *          having the black pieces executes the following:
 *
 *              % versus -b <hostname> <portno> <Black command line>
 *
 *          Versus attempts to connect to its counterpart, and if successful
 *          allocates a pty pair and invokes the Black program.  It then
 *          goes into a communication loop.
 *
 *          Versus identifies the moves to be transferred to the opposing
 *          program by looking for lines of the form:
 *
 *              @@@<color>: <move>
 *
 *          output on the pty.  When it sees such a line, it sends a line
 *          consisting just of <move> to the socket.
 */

/*
 * Define HPUX if compiling for HP-UX System.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <stdio.h>
#ifdef HPUX
#include <bsdtty.h>
#include <termio.h>
#include <sys/ptyio.h>
#else
#include <sgtty.h>
#endif
#include <signal.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/file.h>

#ifdef HPUX
#define bcopy(a,b,s)	memcpy (b,a,s)
#endif

#define PATHLEN 512
#define MSGSIZ 512

int White;                            /* Are we White or Black? */
char MsgBuf[MSGSIZ];                  /* Buffer for reading and writing */
char PtyName[32], TtyName[32];        /* Names of pty devices */
int Pty;                              /* Master side pty file descriptor */
int Sock0, Sock;                      /* Communication socket id's */
int Port;                             /* Server port number */
char System[64];                      /* Name of server host */

#ifdef HPUX
char PtyProto[] = "/dev/ptym/ptyXY";
char TtyProto[] = "/dev/pty//ttyXY";  /* XY positions must correspond */
#else
char PtyProto[] = "/dev/ptyXY";
char TtyProto[] = "/dev/ttyXY";
#endif

struct mode {
#ifdef HPUX
    struct termio m_termio;
#else
    struct sgttyb m_ttyb;
    struct tchars m_tchars;
#endif
    struct ltchars m_ltchars;
    int m_ldisc;
    int m_lmode;
} OldMode, NewMode;

main(argc, argv)
int argc;
char *argv[];
{
  if (argc <= 2) Usage(argv[0]);
  if (*argv[1] != '-') Usage(argv[0]);
  switch(*(argv[1]+1)) {
  case 'b':
    if (argc <= 4) Usage(argv[0]);
    strcpy(System, argv[2]);
    Port = atoi(argv[3]);
    printf("Invoking Black program...\n");
    SetupSignals();
    MakeBlackSocket();
    GetPty();
    StartPlayer(&argv[4]);
    ComLoop(); /* No return */
  case 'w':
    White++;
    printf("Invoking White program...\n");
    SetupSignals();
    MakeWhiteSocket();
    GetPty();
    StartPlayer(&argv[2]);
    printf("White program started.\n");
    printf("Now execute: %s -b %s %d (Black program command line)\n",
	   argv[0], System, Port);
    AcceptConnection();
    ComLoop(); /* No return */
  default:
    Usage(argv[0]);
  }
}

/*
 * Print a usage error message and die.
 */

Usage(n)
char *n;
{
    printf("Usage: %s -w (White program command line)\n", n);
    printf("or: %s -b hostname portnum (Black program command line)\n", n);
    exit(1);
}

/*
 * Print an error message and die.
 */

Error(fmt, p1, p2, p3, p4, p5, p6)
char *fmt;
{
  printf(fmt, p1, p2, p3, p4, p5, p6);
  close(Sock0); close(Sock);
  exit(1);
}

/*
 * Signal Handler.
 */

SigHandler()
{
  Error("Unexpected signal received.\n");
}

/*
 * Arrange to handle signals.
 */

SetupSignals()
{
	signal (SIGHUP, SigHandler);
	signal (SIGINT, SigHandler);
	signal (SIGQUIT, SigHandler);
	signal (SIGTERM, SigHandler);
}

/*
 * Start up the White or Black program
 */

StartPlayer(argv)
char *argv[];
{
  int f, mypid;
  switch (fork()) {
  case -1:
    Error ("Can't fork subprocess.\n");
  case 0:
    signal (SIGHUP, SIG_DFL);
    signal (SIGINT, SIG_DFL);
    signal (SIGQUIT, SIG_DFL);
    signal (SIGTERM, SIG_DFL);
    mypid = getpid ();
    if ((f = open ("/dev/tty", O_RDWR)) != -1) {
#ifdef HPUX
      setpgrp();  /* Disown any controlling terminal */
#else
      ioctl (f, TIOCNOTTY, (char *)0);
#endif
      close (f);
    }
    if ((f = open (TtyName, O_RDWR)) == -1) {
      printf("Can't open Pty %s\n", TtyName);
      exit (1);
    }
    dup2 (f, 0);
    dup2 (f, 1);
    dup2 (f, 2);
    for (f = NOFILE - 1; f > 2; f--)
      close (f);
    ioctl (0, TIOCSPGRP, &mypid);
#ifdef HPUX
    setpgrp ();
#else
    setpgrp (0, mypid);
#endif
    sprintf(MsgBuf, "SYNC\n");
    write(1, MsgBuf, 5);  /* send synchronization message to parent */
    execvp(argv[0], &argv[0]);
    printf("Can't execute %s\n", argv[0]);
    exit(1);
  default:  /* wait for synchronization message from child process */
    while(1) {
#ifdef DEBUG
      printf("Waiting for program to start.\n");
#endif
      if (read(Pty, MsgBuf, 5) <= 0) {
	  sleep(1);
	  continue;
      }
      break;
    }
  }
}

/*
 * Perform communication loop until interrupted or partner dies.
 */
 
ComLoop()
{
  int r, w, x = 0;
  extern int errno;

  while (1) {
    r = (1 << Sock) | (1 << Pty);
    if (select (32, &r, NULL, NULL, 0) == -1)
      Error("Error in select.\n");
#ifdef DEBUG
    printf("Select returns %d\n", r);
#endif
    if (r & 1 << Sock)
      SocketToPTY(Sock, Pty);
    if (r & 1 << Pty)
      PTYToSocket(Sock, Pty);
  }
}

/*
 * Allocate a pty pair for communication with program.
 */

GetPty()
{
    char *p, *l, *d;
    int i, f, tf;

    strcpy (PtyName, PtyProto);
    strcpy (TtyName, TtyProto);
    for (p = PtyName, i = 0; *p != 'X'; ++p, ++i) ;
    for (l = "pqr"; *p = *l; ++l) {
	for (d = "0123456789abcdef"; p[1] = *d; ++d) {
	    if ((f = open (PtyName, O_RDWR)) != -1) {
		TtyName[i] = p[0];
		TtyName[i+1] = p[1];
		if ((tf = open (TtyName, O_RDWR)) != -1) {
		    close (tf);
		    Pty = f;
		    fcntl (f, F_SETFL, O_NDELAY);
		    GetTTY(f, &OldMode);
		    SetMode(&OldMode, &NewMode);
		    SetTTY(f, &NewMode);
		    return;
		}
		close (f);
	    }
	}
    }
    Error("Can't get a Pty.\n");
}

GetTTY (fd, mp)
struct mode *mp;
{
#ifdef HPUX
    ioctl (fd, TCGETA, &mp->m_termio);
#else
    ioctl (fd, TIOCGETP, &mp->m_ttyb);
    ioctl (fd, TIOCGETC, &mp->m_tchars);
    ioctl (fd, TIOCGETD, &mp->m_ldisc);
#endif
    ioctl (fd, TIOCGLTC, &mp->m_ltchars);
    ioctl (fd, TIOCLGET, &mp->m_lmode);
}

SetTTY (fd, mp)
struct mode *mp;
{
  int zero = 0;
#ifdef HPUX
    ioctl (fd, TCSETAW, &mp->m_termio);
    ioctl (fd, TIOCTTY, &zero);
#else
    ioctl (fd, TIOCSETP, &mp->m_ttyb);
    ioctl (fd, TIOCSETC, &mp->m_tchars);
    ioctl (fd, TIOCSETD, &mp->m_ldisc);
#endif
    ioctl (fd, TIOCSLTC, &mp->m_ltchars);
    ioctl (fd, TIOCLSET, &mp->m_lmode);
}

SetMode (op, np)
struct mode *op, *np;
{
    *np = *op;
#ifdef HPUX
     np->m_termio.c_line = 0;
     np->m_termio.c_iflag &= ~INLCR;
     np->m_termio.c_iflag &= ~ICRNL;
     np->m_termio.c_oflag &= ~OCRNL;
     np->m_termio.c_oflag &= ~ONLCR;
     np->m_termio.c_lflag &= ~ECHO;
     np->m_termio.c_iflag &= ~(IXOFF|IXON);
     np->m_termio.c_cc[VINTR] = -1;
     np->m_termio.c_cc[VQUIT] = -1;
#else
    np->m_ttyb.sg_flags &= ~(CRMOD|ECHO);
/*    np->m_ttyb.sg_flags |= CBREAK; */
    np->m_tchars.t_intrc = -1;
    np->m_tchars.t_quitc = -1;
    np->m_tchars.t_startc = -1;
    np->m_tchars.t_stopc = -1;
#endif
    np->m_ltchars.t_suspc = -1;
    np->m_ltchars.t_dsuspc = -1;
    np->m_ltchars.t_flushc = -1;
    np->m_ltchars.t_lnextc = -1;
}

MakeWhiteSocket ()
{
    register s;
    int id, len;
    struct sockaddr_in a;

    gethostname(System, sizeof(System));
    if ((id = socket (AF_INET, SOCK_STREAM, 0)) == -1)
        Error("Can't create new socket.\n");
    a.sin_family = AF_INET;
    a.sin_addr.s_addr = INADDR_ANY;
    a.sin_port = 0;
    if (bind (id, (struct sockaddr *)&a, sizeof(a)) == -1)
      Error("Can't bind socket to address.\n");
    len = sizeof(a);
    if (getsockname(id, (struct sockaddr *)&a, &len) == -1)
      Error("Can't get socket name.\n");
    if (listen (id, 5) == -1)
        Error("Unable to listen on socket.\n");
    Sock0 = Sock = id;
    Port = htons(a.sin_port);
}

MakeBlackSocket ()
{
    int id;
    struct sockaddr_in a;
    struct hostent *h;

    if ((id = socket (AF_INET, SOCK_STREAM, 0)) == -1)
      Error("Can't create new socket.\n");
    a.sin_family = AF_INET;
    a.sin_port = htons(Port);
    if ((h = gethostbyname(System)) == 0)
      Error("Unknown host: %s\n", System);
    bcopy(h->h_addr, &a.sin_addr, h->h_length);
    if (connect (id, (struct sockaddr *)&a, sizeof(a)) == -1)
      Error("Can't connect to White program.\n");
    Sock0 = Sock = id;
}

/*
 * Accept a connection on Sock0
 */

AcceptConnection()
{
  struct sockaddr_in a;
  int len = sizeof (a);
  printf("Waiting for connection to Black program...\n");
  if ((Sock = accept (Sock0, &a, &len)) == -1)
    Error("Error in accepting connection.\n");
  printf("Got connection.\n");
}

/*
 * Transfer data from PTY to socket
 */

PTYToSocket(s, f)
{
  int len;
  char *mbp;
  static char linebuf[MSGSIZ], *lbp = linebuf;
#ifdef DEBUG
  printf("PtoS called.\n");
#endif
  if((len = read(f, MsgBuf, MSGSIZ)) == -1) {
    if (errno == EWOULDBLOCK) {
#ifdef DEBUG
      printf("No data there.\n");
#endif
      return;
    }
    Error("Error reading from Pty.\n");
  }
  if(len == 0)
    Error("End of file on Pty.\n");
  write(1, MsgBuf, len);
  mbp = MsgBuf;
  for ( ; len > 0; len--) {
    if (lbp - linebuf >= MSGSIZ-1) lbp--;   /* Truncate long lines */
    if ((*lbp++ = *mbp++) != '\n') continue;
    *lbp = '\0';
    ProcessLine(s, linebuf, lbp);
    lbp = linebuf;
  }
}

/*
 * Determine if line has format @@@<color>:<move>\n
 * If so, send <move>\n to opponent
 */

ProcessLine(fd, buf, ebuf)
int fd;
char *buf, *ebuf;
{
  if (*buf++ == '@')
    if (*buf++ == '@')
      if (*buf++ == '@') {
	while (*buf != ':') if (*buf++ == '\n') return;
	buf++;
	printf("=> %s", buf);
	fflush(stdout);
	write(fd, buf, ebuf - buf);
      }
}

/*
 * Transfer data from socket to PTY
 */

SocketToPTY (s, f)
{
  struct sockaddr_in a;
  int len;
#ifdef DEBUG
  printf("StoP called.\n");
#endif
  if ((len = read (s, MsgBuf, MSGSIZ)) == -1)
    Error("Error reading from socket.\n");
  if(len == 0)
    Error("End of file on socket.\n");
  if (write(f, MsgBuf, len) < len) Error("Incomplete write\n"); 
#ifdef DEBUG
  write (1, MsgBuf, len);
#endif
}
Re: playing gnuchess against another program
#6113
Author: Philip Leong
Date: Mon, 19 Nov 1990 00:22
106 lines
4598 bytes
In article <9011160518.AA22499@ucbvax.Berkeley.EDU> jlol@ee.byu.edu writes:
>...  What I'm wondering is whether there is a
>convenient way to play gnuchess against another program, or itself,
>that might be running on the same or a different machine. 

I wrote a GNU emacs program to play gnuchess against itself and it is
included in this posting. It was written in July 1990 and I'm not sure if
there has been a new release since then. If it doesn't work, let me know
and I'll fix any problems. It is called playchess.el. Another program 
pchess.el (also included) plays against /usr/games/chess on Suns.

You must have gnuchessr as generated in the distributed makefile
WITHOUT -DCHESSTOOL (or else you can't see the board displays).
The program should be able to play on different machines by invoking the
chess progams with an 'rsh'. You probably only need to change white-program
or black-program to do this.

Hope that someone finds these useful.

Philip Leong.
--
Department of Electrical Engineering	Tel. (+61 2) 692 3297
University of Sydney 2006		Fax. (+61 2) 692 3847
Australia				Internet: phwl@ee.su.oz.au

;;	playchess.el - plays gnuchess against itself
;;
;;				Philip Leong (phwl@ee.su.oz.au)
;;

(defvar chess-buffer "chess")
(defvar white-program "gnuchessr")
(defvar black-program "gnuchessr")

(defun other-proc (proc)
  (cond ((equal (get-process "white") proc) "black")
	((equal (get-process "black") proc) "white")
	(t (insert "bad proc"))))

(defun chess-filter (proc string)
  (set-buffer (process-buffer proc))
  (goto-char (point-max))
  (insert string)
  (if (not (string-match "[0-9]+\. \.\.\. ...." string))
      nil
      (let ((str (concat (substring string
				    (- (match-end 0) 4)
				    (match-end 0)))))
	   (insert ">" str "<\n" )
	   (process-send-string (other-proc proc) "bd\n" )
	   (process-send-string (other-proc proc) (concat str "\n")))))

(defun chess ()
  (interactive)
  (start-process "white" chess-buffer white-program)
  (start-process "black" chess-buffer black-program)
  (switch-to-buffer chess-buffer)
  ;; set startup options on each side
  (process-send-string "black" "30 2\n1\nbeep\n")
  (process-send-string "white" "30 2\n1\nbeep\n")
  ;; tell the white one that it is white
  (process-send-string "white" "white\n")
  (set-process-filter (get-process "white") 'chess-filter)
  (set-process-filter (get-process "black") 'chess-filter))

-------------------------------------------------------------------

;;	pchess.el - plays gnuchess against chess
;;
;;				Philip Leong (phwl@ee.su.oz.au)
;;

(defvar chess-buffer "chess")
(defvar white-program "gnuchessr")
(defvar black-program "chess")

(defun other-proc (proc)
  (cond ((equal (get-process "white") proc) "black")
	((equal (get-process "black") proc) "white")
	(t (insert "bad proc"))))

(defun chess-filter (proc string)
  (set-buffer (process-buffer proc))
  (goto-char (point-max))
  (insert string)
  (if (not (string-match "[0-9]+\. \.\.\. ...." string))
      nil
      (let ((str (concat (substring string
				    (- (match-end 0) 4)
				    (match-end 0)))))
	   (insert ">" str "<\n" )
	   (process-send-string (other-proc proc) "bd\n" )
	   (process-send-string (other-proc proc) (concat str "\n")))))

(defun chess ()
  (interactive)
  (start-process "white" chess-buffer white-program)
  (start-process "black" chess-buffer black-program)
  (switch-to-buffer chess-buffer)
  ;; set startup options on each side
  ;; (process-send-string "black" "30 2\n1\nbeep\n")
  (process-send-string "white" "30 2\n1\nbeep\n")
  ;; tell the white one that it is white
  (process-send-string "white" "white\n")
  (set-process-filter (get-process "white") 'chess-filter)
  (set-process-filter (get-process "black") 'chess-filter))
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads