Thread View: gnu.chess
3 messages
3 total messages
Started by Jay Lawlor
Fri, 16 Nov 1990 05:16
playing gnuchess against another program
Author: Jay Lawlor
Date: Fri, 16 Nov 1990 05:16
Date: Fri, 16 Nov 1990 05:16
19 lines
1472 bytes
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
Author: Eugene Stark
Date: Sat, 17 Nov 1990 16:16
Date: Sat, 17 Nov 1990 16:16
499 lines
13380 bytes
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
Author: Philip Leong
Date: Mon, 19 Nov 1990 00:22
Date: Mon, 19 Nov 1990 00:22
106 lines
4598 bytes
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