home *** CD-ROM | disk | FTP | other *** search
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # CHANGES
- # Goban.c
- # Goban.h
- # GobanP.h
- # Imakefile
- # Makefile
- # Makefile.hand
- # README
- # README.AMIGO
- # TODO
- # Xamigo.ad
- # amigo.c
- # amigo.h
- # blackstone.bm
- # check16.xbm
- # go.h
- # goplayer.c
- # goplayutils.c
- # goplayutils.h
- # graystone.bm
- # killable.c
- # main.c
- # menus.c
- # stonemask.bm
- # whitestone.bm
- # xamigo.h
- # xamigo.man
- # xinterface.c
- # This archive created: Thu Aug 20 16:51:28 1992
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'CHANGES'
- then
- echo shar: "will not over-write existing file 'CHANGES'"
- else
- cat << \SHAR_EOF > 'CHANGES'
-
- Changes from xamigo-1.0 to xamigo-1.1
- -------------------------------------
-
- o mouse pointer changes according to player's color.
- changes to grey stone when game over.
-
- o tweaked Imakefile.
-
- o fixed bug which let you play a suicide move.
-
- o added end-of-game support: removing dead stones
- and counting up.
-
- o the 'P' key can be used as a short-cut for `pass' on the
- Move menu. Any other shortcuts you can think of?
-
- o "I'm thinking..." is displayed in the message window,
- so you know when it is AmiGo's turn.
-
- o the last stone placed by each player is marked on the board.
-
- o changed the menu organisation
-
- o added a checkmark bitmap, rather than using xlogo16,
- it looks nice (IMHO) and someone reported problems with
- xlogo16 anyway.
-
-
- First release of xamigo-1.0
- ---------------------------
-
- Quick and dirty job to get AmiGo ported and a simple X interface to it.
-
- SHAR_EOF
- fi
- if test -f 'Goban.c'
- then
- echo shar: "will not over-write existing file 'Goban.c'"
- else
- cat << \SHAR_EOF > 'Goban.c'
- /****************************************************************************************************************
- *
- * Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful.
- * Use and copying of this software and preparation of derivative works
- * based upon this software are permitted, so long as the following
- * conditions are met:
- * o credit to the authors is acknowledged following current
- * academic behaviour
- * o no fees or compensation are charged for use, copies, or
- * access to this software
- * o this copyright notice is included intact.
- * This software is made available AS IS, and no warranty is made about
- * the software or its performance.
- *
- * Bug descriptions, use reports, comments or suggestions are welcome.
- * Send them to dumesnil@etca.fr or to:
- *
- * Antoine de Maricourt
- * ETCA CREA-SP
- * 16 bis, avenue Prieur de la Cote d'Or
- * 94114 Arcueil Cedex
- * France
- */
-
- #include <X11/IntrinsicP.h>
- #include <X11/StringDefs.h>
- #include <X11/Xlib.h>
- #include <X11/cursorfont.h>
-
- #include "GobanP.h"
-
- #include "whitestone.bm"
- #include "blackstone.bm"
- #include "graystone.bm"
- #include "stonemask.bm"
-
- #define offset(field) XtOffset (GobanWidget, goban.field)
-
- static XtResource resources[] = {
- { XtNautoRedisplay , XtCAutoRedisplay , XtRBoolean , sizeof (Boolean) ,
- offset (auto_redisplay) , XtRImmediate , (caddr_t) TRUE },
- { XtNviewBottom , XtCPosition , XtRPosition , sizeof (Position) ,
- offset (bottom) , XtRImmediate , (caddr_t) 1 },
- { XtNcursor , XtCCursor , XtRInt , sizeof (int) ,
- offset (cursor) , XtRImmediate , (caddr_t) GbCGrayStone },
- { XtNfont , XtCFont , XtRFontStruct, sizeof (XFontStruct *),
- offset (font) , XtRString , "fixed" },
- { XtNforeground , XtCForeground , XtRPixel , sizeof (Pixel) ,
- offset (foreground) , XtRString , XtDefaultForeground },
- { XtNgameSize , XtCSize , XtRDimension , sizeof (Dimension) ,
- offset (game_size) , XtRImmediate, (caddr_t) 19 },
- { XtNviewLeft , XtCPosition , XtRPosition , sizeof (Position) ,
- offset (left) , XtRImmediate, (caddr_t) 1 },
- { XtNdisplayCoordinates, XtCDisplayCoordinates, XtRBoolean , sizeof (Boolean) ,
- offset (display_coordinates), XtRImmediate, (caddr_t) TRUE },
- { XtNpointSize , XtCSize , XtRDimension , sizeof (Dimension) ,
- offset (point_size) , XtRImmediate , (caddr_t) 26 },
- { XtNviewRight , XtCPosition , XtRPosition , sizeof (Position) ,
- offset (right) , XtRImmediate , (caddr_t) 19 },
- { XtNviewTop , XtCPosition , XtRPosition , sizeof (Position) ,
- offset (top) , XtRImmediate , (caddr_t) 19 },
- { XtNwhiteStoneForeground, XtCForeground , XtRPixel , sizeof (Pixel) ,
- offset (white_fg) , XtRString , "black" },
- { XtNwhiteStoneBackground, XtCBackground , XtRPixel , sizeof (Pixel) ,
- offset (white_bg) , XtRString , "white" },
- { XtNwhiteStoneBorder , XtCBorderColor , XtRPixel , sizeof (Pixel) ,
- offset (white_bd) , XtRString , "black" },
- { XtNblackStoneForeground, XtCForeground , XtRPixel , sizeof (Pixel) ,
- offset (black_fg) , XtRString , "white" },
- { XtNblackStoneBackground, XtCBackground , XtRPixel , sizeof (Pixel) ,
- offset (black_bg) , XtRString , "black" },
- { XtNblackStoneBorder , XtCBorderColor , XtRPixel , sizeof (Pixel) ,
- offset (black_bd) , XtRString , "black" },
- };
-
- static void ClassInitialize ();
- static void Initialize ();
- static void Redisplay ();
- static void Realize ();
- static void Destroy ();
- static void Resize ();
- static void DrawPoint ();
- static Boolean SetValues ();
-
- GobanClassRec gobanClassRec = {
- { /* core fields */
- /* superclass */ (WidgetClass) &widgetClassRec,
- /* class_name */ "Goban",
- /* widget_size */ sizeof (GobanRec),
- /* class_initialize */ ClassInitialize,
- /* class_part_initialize */ NULL,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* realize */ Realize,
- /* actions */ NULL,
- /* num_actions */ 0,
- /* resources */ resources,
- /* num_resources */ XtNumber (resources),
- /* xrm_class */ NULLQUARK,
- /* compress_motion */ TRUE,
- /* compress_exposure */ TRUE,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ Destroy,
- /* resize */ Resize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback_private */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ XtInheritQueryGeometry,
- /* display_accelerator */ XtInheritDisplayAccelerator,
- /* extension */ NULL
- }
- };
-
- WidgetClass gobanWidgetClass = (WidgetClass) &gobanClassRec;
-
- /****************************************************************************************************************
- */
-
- void GbRedisplayBoard (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Dimension width = w->core.width;
- Dimension height = w->core.height;
-
- if (XtIsRealized (w))
- XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, 0, 0, width, height, 0, 0);
- }
-
- /****************************************************************************************************************
- */
-
- void GbClearBoard (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Boolean redisplay = gw->goban.auto_redisplay;
- Position x;
- Position y;
-
- gw->goban.auto_redisplay = FALSE;
-
- for (x = 1; x <= gw->goban.game_size; x++)
- for (y = 1; y <= gw->goban.game_size; y++)
- GbSetPoint (w, x, y, GbEmptyPoint);
-
- gw->goban.auto_redisplay = redisplay;
-
- if (redisplay == TRUE)
- GbRedisplayBoard (w);
- }
-
- /****************************************************************************************************************
- */
-
- void GbClearMarks (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Boolean redisplay = gw->goban.auto_redisplay;
- Position x;
- Position y;
-
- gw->goban.auto_redisplay = FALSE;
-
- for (x = 1; x <= gw->goban.game_size; x++)
- for (y = 1; y <= gw->goban.game_size; y++) {
-
- gw->goban.points[x][y].mark1 = 0;
- gw->goban.points[x][y].mark2 = 0;
- gw->goban.points[x][y].num = 0;
-
- if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
- if (gw->goban.points[x][y].free == 1)
- DrawPoint (w, x, y, GbEmptyPoint);
- else
- if (gw->goban.points[x][y].black == 1)
- DrawPoint (w, x, y, GbBlackStone);
- else
- DrawPoint (w, x, y, GbWhiteStone);
- }
-
- gw->goban.auto_redisplay = redisplay;
-
- if (redisplay == TRUE)
- GbRedisplayBoard (w);
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- void GbSetPoint (w, x, y, color)
- Widget w;
- Position x;
- Position y;
- GbPointState color;
- {
- GobanWidget gw = (GobanWidget) w;
-
- if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
- switch (color) {
-
- case GbBlackStone :
- gw->goban.points[x][y].free = 0;
- gw->goban.points[x][y].black = 1;
- break;
-
- case GbWhiteStone :
- gw->goban.points[x][y].free = 0;
- gw->goban.points[x][y].black = 0;
- break;
-
- case GbEmptyPoint :
- gw->goban.points[x][y].free = 1;
- break;
- }
-
- gw->goban.points[x][y].num = 0;
- gw->goban.points[x][y].mark1 = 0;
- gw->goban.points[x][y].mark2 = 0;
-
- if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top)
- DrawPoint (w, x, y, color);
- }
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- Boolean GbGetPositionFromStone (w, x, y)
- GobanWidget w;
- Position *x;
- Position *y;
- {
- if (*x >= w->goban.left && *y >= w->goban.bottom && *x <= w->goban.right && *y <= w->goban.top) {
-
- *x = ((w->goban.x_offset + w->goban.point_size * *x) * 2 + w->goban.point_size) / 2;
- *y = ((w->goban.y_offset - w->goban.point_size * *y) * 2 + w->goban.point_size) / 2;
-
- return TRUE;
- }
-
- else
- return FALSE;
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- Boolean GbGetStoneFromPosition (w, x, y)
- Widget w;
- Position *x;
- Position *y;
- {
- GobanWidget gw = (GobanWidget) w;
- Dimension point_size = gw->goban.point_size;
- Position xmin = gw->goban.x_offset + point_size * gw->goban.left + 1;
- Position ymin = gw->goban.y_offset - point_size * gw->goban.top + 1;
- Position xmax = gw->goban.x_offset + point_size * (gw->goban.right + 1) - 1;
- Position ymax = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
-
- if (*x > xmin && *x < xmax && *y > ymin && *y < ymax) {
-
- *x = (*x - gw->goban.x_offset - 1) / point_size;
- *y = (gw->goban.y_offset - *y + point_size + 1) / point_size;
-
- return TRUE;
- }
-
- return FALSE;
- }
-
- /****************************************************************************************************************
- */
-
- void GbSetNum (w, x, y, num)
- Widget w;
- Position x;
- Position y;
- int num;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- GC draw_gc;
- GC undraw_gc;
- XCharStruct extent;
- XExposeEvent event;
- int ascent;
- int descent;
- int direction;
- int X;
- int Y;
- char s[3];
- int len = 0;
-
- if (num >= 0 && num <= 999 && x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
-
- gw->goban.points[x][y].num = num;
- gw->goban.points[x][y].mark1 = 0;
- gw->goban.points[x][y].mark2 = 0;
-
- if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
-
- if (gw->goban.points[x][y].free == 0) {
-
- if (num == 0) {
- if (gw->goban.points[x][y].black == 1)
- DrawPoint (w, x, y, GbBlackStone);
- else
- DrawPoint (w, x, y, GbWhiteStone);
- }
-
- else {
- if (gw->goban.points[x][y].black == 1) {
- draw_gc = gw->goban.black_fg_gc;
- undraw_gc = gw->goban.black_bg_gc;
- } else {
- draw_gc = gw->goban.white_fg_gc;
- undraw_gc = gw->goban.white_bg_gc;
- }
-
- X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
- Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
-
- if (num > 99)
- s[len++] = '0' + (num % 1000) / 100;
- if (num > 9)
- s[len++] = '0' + (num % 100) / 10;
- s[len++] = '0' + num % 10;
-
- XQueryTextExtents (display, XGContextFromGC (draw_gc),
- s, len, &direction, &ascent, &descent, &extent);
-
- if (extent.width + extent.descent + extent.ascent < gw->goban.point_size - 1) {
- XFillArc (display, gw->goban.picture, undraw_gc,
- (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2,
- (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4,
- 0, 360 * 64);
- XDrawString (display, gw->goban.picture, draw_gc,
- (X - extent.width) / 2 - extent.lbearing + 1,
- (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
- }
-
- if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
- event.x = (X - gw->goban.point_size) / 2;
- event.y = (Y - gw->goban.point_size) / 2;
- event.width = gw->goban.point_size;
- event.height = gw->goban.point_size;
-
- Redisplay (w, &event, (Region) NULL);
- }
- }
- }
- }
- }
- }
-
- /****************************************************************************************************************
- */
-
- void GbSetMark (w, x, y, c1, c2)
- Widget w;
- Position x;
- Position y;
- unsigned char c1;
- unsigned char c2;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- int len = 0;
- XCharStruct extent;
- XExposeEvent event;
- int ascent;
- int descent;
- int direction;
- int X;
- int Y;
- int radius;
- char s[2];
- XSegment segment[4];
- GC mark_gc;
- GC erase_gc;
-
- if (x >= 1 && y >= 1 && x <= gw->goban.game_size && y <= gw->goban.game_size) {
-
- if (c1 != 0 || c2 != 0)
- GbSetMark (w, x, y, 0, 0);
-
- gw->goban.points[x][y].mark1 = c1;
- gw->goban.points[x][y].mark2 = c2;
- gw->goban.points[x][y].num = 0;
-
- if (x >= gw->goban.left && y >= gw->goban.bottom && x <= gw->goban.right && y <= gw->goban.top) {
-
- if (c1 == 0 && c2 == 0) {
- if (gw->goban.points[x][y].free == 0)
- if (gw->goban.points[x][y].black == 1)
- DrawPoint (w, x, y, GbBlackStone);
- else
- DrawPoint (w, x, y, GbWhiteStone);
- else
- DrawPoint (w, x, y, GbEmptyPoint);
- }
-
- else {
- X = (gw->goban.x_offset + gw->goban.point_size * x) * 2 + gw->goban.point_size;
- Y = (gw->goban.y_offset - gw->goban.point_size * y) * 2 + gw->goban.point_size;
-
- if (gw->goban.points[x][y].free == 0)
- if (gw->goban.points[x][y].black == 1) {
- mark_gc = gw->goban.black_fg_gc;
- erase_gc = gw->goban.black_bg_gc;
- }
- else {
- mark_gc = gw->goban.white_fg_gc;
- erase_gc = gw->goban.white_bg_gc;
- }
-
- else {
- mark_gc = gw->goban.foreground_gc;
- erase_gc = gw->goban.background_gc;
- }
-
- if (c1 == 0) {
- radius = 10 * gw->goban.point_size / 15;
-
- if (gw->goban.points[x][y].free == 0)
- XFillArc (display, gw->goban.picture, erase_gc,
- (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2,
- (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4,
- 0, 360 * 64);
- else
- XFillArc (display, gw->goban.picture, erase_gc,
- (int) (X - radius) / 2, (int) (Y - radius) / 2,
- (unsigned int) radius, (unsigned int) radius,
- 0, 360 * 64);
-
- switch (c2) {
-
- case GbMTriangleMark :
- radius -= 4;
-
- segment[0].x1 = (short) X / 2;
- segment[0].x2 = (short) (X / 2 + (86 * radius + 100) / 200);
- segment[0].y1 = (short) (Y / 2 - (radius - 1) / 2);
- segment[0].y2 = (short) (Y / 2 + (radius + 4) / 4);
-
- segment[1].x1 = (short) segment[0].x2;
- segment[1].x2 = (short) (X / 2 - (86 * radius + 100) / 200);
- segment[1].y1 = (short) segment[0].y2;
- segment[1].y2 = (short) (Y / 2 + (radius + 4) / 4);
-
- segment[2].x1 = (short) segment[1].x2;
- segment[2].x2 = (short) segment[0].x1;
- segment[2].y1 = (short) segment[1].y2;
- segment[2].y2 = (short) segment[0].y1;
-
- XDrawSegments (display, gw->goban.picture, mark_gc, segment, 3);
- break;
-
- case GbMSquareMark :
- radius = 10 * radius / 14 - 2;
-
- XDrawRectangle (display, gw->goban.picture, mark_gc,
- (X - radius) / 2, (Y - radius) / 2,
- (unsigned int) radius, (unsigned int) radius);
- break;
-
- case GbMDCrossMark :
- radius = 10 * radius / 14 - 2;
-
- segment[0].x1 = (short) (X - radius) / 2;
- segment[0].x2 = (short) segment[0].x1 + radius;
- segment[0].y1 = (short) (Y - radius) / 2;
- segment[0].y2 = (short) segment[0].y1 + radius;
-
- segment[1].x1 = (short) (X - radius) / 2 + radius;
- segment[1].x2 = (short) segment[1].x1 - radius;
- segment[1].y1 = (short) (Y - radius) / 2;
- segment[1].y2 = (short) segment[1].y1 + radius;
-
- XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
- break;
-
- case GbMVCrossMark :
- radius -= 4;
-
- segment[0].x1 = (short) X / 2;
- segment[0].x2 = (short) segment[0].x1;
- segment[0].y1 = (short) (Y - radius) / 2;
- segment[0].y2 = (short) segment[0].y1 + radius;
-
- segment[1].x1 = (short) (X - radius) / 2;
- segment[1].x2 = (short) segment[1].x1 + radius;
- segment[1].y1 = (short) Y / 2;
- segment[1].y2 = (short) segment[1].y1;
-
- XDrawSegments (display, gw->goban.picture, mark_gc, segment, 2);
- break;
-
- case GbMDiamondMark :
- radius -= 4;
-
- segment[0].x1 = (short) X / 2;
- segment[0].x2 = (short) segment[0].x1 + radius / 2;
- segment[0].y1 = (short) (Y - radius) / 2;
- segment[0].y2 = (short) segment[0].y1 + radius / 2;
-
- segment[1].x1 = (short) segment[0].x2;
- segment[1].x2 = (short) segment[0].x1;
- segment[1].y1 = (short) segment[0].y2;
- segment[1].y2 = (short) segment[1].y1 + radius / 2;
-
- segment[2].x1 = (short) segment[1].x2;
- segment[2].x2 = (short) segment[2].x1 - radius / 2;
- segment[2].y1 = (short) segment[1].y2;
- segment[2].y2 = (short) segment[1].y1;
-
- segment[3].x1 = (short) segment[2].x2;
- segment[3].x2 = (short) segment[0].x1;
- segment[3].y1 = (short) segment[2].y2;
- segment[3].y2 = (short) segment[0].y1;
-
- XDrawSegments (display, gw->goban.picture, mark_gc, segment, 4);
- break;
- }
- }
-
- else {
- s[len++] = c1;
- if (c2 != 0)
- s[len++] = c2;
-
- XQueryTextExtents (display, XGContextFromGC (mark_gc), s, len, &direction, &ascent, &descent, &extent);
-
- radius = extent.width + extent.descent + extent.ascent;
-
- if (radius < gw->goban.point_size - 1) {
- if (gw->goban.points[x][y].free == 0)
- XFillArc (display, gw->goban.picture, erase_gc,
- (int) (X - gw->goban.point_size) / 2 + 2, (int) (Y - gw->goban.point_size) / 2 + 2,
- (unsigned int) gw->goban.point_size - 4, (unsigned int) gw->goban.point_size - 4,
- 0, 360 * 64);
- else
- XFillArc (display, gw->goban.picture, erase_gc,
- (int) (X - radius) / 2, (int) (Y - radius) / 2,
- (unsigned int) radius, (unsigned int) radius,
- 0, 360 * 64);
-
- XDrawString (display, gw->goban.picture, mark_gc,
- (X - extent.width) / 2 - extent.lbearing + 1,
- (Y + extent.ascent - extent.descent) / 2 + 1, s, len);
- }
- }
-
- if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
- event.x = (X - gw->goban.point_size) / 2;
- event.y = (Y - gw->goban.point_size) / 2;
- event.width = gw->goban.point_size;
- event.height = gw->goban.point_size;
-
- Redisplay (w, &event, (Region) NULL);
- }
- }
- }
- }
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- static void Redisplay (w, event, region)
- Widget w;
- XExposeEvent *event;
- Region region;
- {
- GobanWidget gw = (GobanWidget) w;
- Position x = event->x;
- Position y = event->y;
- Dimension width = event->width;
- Dimension height = event->height;
-
- XCopyArea (XtDisplay (w), gw->goban.picture, XtWindow (w), gw->goban.copy_gc, x, y, width, height, x, y);
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- static void CvtStringToCursor (args, num_args, fromVal, toVal)
- XrmValuePtr args; /* unused */
- Cardinal *num_args; /* unused */
- XrmValuePtr fromVal;
- XrmValuePtr toVal;
- {
- static int cursor;
- static XrmQuark QWhiteStone;
- static XrmQuark QBlackStone;
- static XrmQuark QGrayStone;
- XrmQuark quark;
- char lowerName[256];
- static Boolean inited = FALSE;
-
- if (inited == FALSE) {
- QWhiteStone = XrmStringToQuark (XtEgbWhiteStone);
- QBlackStone = XrmStringToQuark (XtEgbBlackStone);
- QGrayStone = XrmStringToQuark (XtEgbGrayStone);
- inited = TRUE;
- }
-
- XmuCopyISOLatin1Lowered (lowerName, (String) fromVal->addr);
- quark = XrmStringToQuark (lowerName);
-
- if (quark == QWhiteStone)
- cursor = GbCWhiteStone;
- else if (quark == QBlackStone)
- cursor = GbCBlackStone;
- else if (quark == QGrayStone)
- cursor = GbCGrayStone;
- else {
- toVal->size = 0;
- toVal->addr = NULL;
- return;
- }
-
- toVal->size = sizeof (cursor);
- toVal->addr = (caddr_t) &cursor;
- }
-
- /****************************************************************************************************************
- */
-
- static void ClassInitialize()
- {
- XtAddConverter (XtRString, XtRInt, (XtConverter) CvtStringToCursor, NULL, 0);
- }
-
- /****************************************************************************************************************
- */
-
- static void InitializePixmap (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- Drawable window = RootWindowOfScreen (XtScreen (w));
- Dimension width = w->core.width;
- Dimension height = w->core.height;
-
- gw->goban.board = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
- gw->goban.picture = XCreatePixmap (display, window, width, height, (unsigned int) DefaultDepthOfScreen (XtScreen (w)));
- }
-
- /****************************************************************************************************************
- */
-
- static void InitializeGC (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- XtGCMask mask = GCForeground | GCBackground | GCFont;
- XGCValues values;
-
- values.font = gw->goban.font->fid;
- values.background = w->core.background_pixel;
-
- values.foreground = gw->goban.white_fg;
- gw->goban.white_fg_gc = XCreateGC (display, gw->goban.picture, mask, &values);
- values.foreground = gw->goban.white_bg;
- gw->goban.white_bg_gc = XCreateGC (display, gw->goban.picture, mask, &values);
- values.foreground = gw->goban.white_bd;
- gw->goban.white_bd_gc = XCreateGC (display, gw->goban.picture, mask, &values);
-
- values.foreground = gw->goban.black_fg;
- gw->goban.black_fg_gc = XCreateGC (display, gw->goban.picture, mask, &values);
- values.foreground = gw->goban.black_bg;
- gw->goban.black_bg_gc = XCreateGC (display, gw->goban.picture, mask, &values);
- values.foreground = gw->goban.black_bd;
- gw->goban.black_bd_gc = XCreateGC (display, gw->goban.picture, mask, &values);
-
- values.foreground = gw->goban.foreground;
- gw->goban.foreground_gc = XCreateGC (display, gw->goban.picture, mask, &values);
-
- if (gw->core.background_pixmap != XtUnspecifiedPixmap) {
- values.tile = gw->core.background_pixmap;
- values.fill_style = FillTiled;
- mask |= GCTile | GCFillStyle;
- }
-
- values.foreground = w->core.background_pixel;
- values.background = gw->goban.foreground;
- gw->goban.background_gc = XCreateGC (display, gw->goban.picture, mask, &values);
-
- gw->goban.copy_gc = XCreateGC (display, gw->goban.picture, (XtGCMask) 0, (XGCValues *) NULL);
- }
-
- /****************************************************************************************************************
- */
- static void InitializeCursor (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- Drawable window = RootWindowOfScreen (XtScreen (w));
- Pixel black = BlackPixel (display, DefaultScreen (display));
- Pixel white = WhitePixel (display, DefaultScreen (display));
-
- static XColor black_color = { 0, 0, 0, 0 }; /* black */
- static XColor white_color = { 0, 65535, 65535, 65535 }; /* white */
-
- /* Some teminals invert the mask with BlackPixel and WhitePixel */
- /* should use black and white instead of 1 and 0 but depth is 1 ... */
- /* will probably have trouble with some special colormaps */
-
- gw->goban.white_stone = XCreatePixmapFromBitmapData
- (display, window, whitestone_bits, whitestone_width, whitestone_height, 1, 0, 1);
- gw->goban.black_stone = XCreatePixmapFromBitmapData
- (display, window, blackstone_bits, blackstone_width, blackstone_height, 1, 0, 1);
- gw->goban.gray_stone = XCreatePixmapFromBitmapData
- (display, window, graystone_bits , graystone_width , graystone_height , 1, 0, 1);
- gw->goban.mouse_mask = XCreatePixmapFromBitmapData
- (display, window, stonemask_bits , stonemask_width , stonemask_height , 1, 0, 1);
-
- gw->goban.white_cursor =
- XCreatePixmapCursor (display, gw->goban.white_stone, gw->goban.mouse_mask,
- &black_color, &white_color, whitestone_x_hot, whitestone_y_hot);
- gw->goban.black_cursor =
- XCreatePixmapCursor (display, gw->goban.black_stone, gw->goban.mouse_mask,
- &black_color, &white_color, blackstone_x_hot, blackstone_y_hot);
- gw->goban.gray_cursor =
- XCreatePixmapCursor (display, gw->goban.gray_stone, gw->goban.mouse_mask,
- &black_color, &white_color, graystone_x_hot , graystone_y_hot );
-
- gw->goban.font_cursor = XCreateFontCursor (display, XC_question_arrow);
- }
-
- /****************************************************************************************************************
- */
-
- static void DestroyPixmap (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
-
- XFreePixmap (display, gw->goban.picture);
- XFreePixmap (display, gw->goban.board );
- }
-
- /****************************************************************************************************************
- */
-
- static void DestroyGC (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
-
- XFreeGC (display, gw->goban.black_fg_gc );
- XFreeGC (display, gw->goban.black_bg_gc );
- XFreeGC (display, gw->goban.black_bd_gc );
- XFreeGC (display, gw->goban.white_fg_gc );
- XFreeGC (display, gw->goban.white_bg_gc );
- XFreeGC (display, gw->goban.white_bd_gc );
- XFreeGC (display, gw->goban.foreground_gc);
- XFreeGC (display, gw->goban.background_gc);
- XFreeGC (display, gw->goban.copy_gc );
- }
-
- /****************************************************************************************************************
- */
-
- static void Destroy (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
-
- DestroyPixmap (w);
- DestroyGC (w);
-
- XFreePixmap (display, gw->goban.white_stone );
- XFreePixmap (display, gw->goban.black_stone );
- XFreePixmap (display, gw->goban.gray_stone );
- XFreePixmap (display, gw->goban.mouse_mask );
-
- XFreeCursor (display, gw->goban.white_cursor );
- XFreeCursor (display, gw->goban.black_cursor );
- XFreeCursor (display, gw->goban.gray_cursor );
- XFreeCursor (display, gw->goban.font_cursor );
- }
-
- /****************************************************************************************************************
- */
-
- static void Realize (w, valuemaskp, attr)
- Widget w;
- XtValueMask *valuemaskp;
- XSetWindowAttributes *attr;
- {
- GobanWidget gw = (GobanWidget) w;
-
- *valuemaskp |= CWCursor;
-
- switch (gw->goban.cursor) {
- case GbCGrayStone : attr->cursor = gw->goban.gray_cursor ; break;
- case GbCBlackStone : attr->cursor = gw->goban.black_cursor; break;
- case GbCWhiteStone : attr->cursor = gw->goban.white_cursor; break;
- default : attr->cursor = gw->goban.font_cursor ; break;
- }
-
- XtCreateWindow (w, InputOutput, (Visual *) CopyFromParent, *valuemaskp, attr);
- }
-
- /****************************************************************************************************************
- */
-
- static char *stars[18] = {
- "", /* 2 */
- "", /* 3 */
- "", /* 4 */
- "", /* 5 */
- "", /* 6 */
- "", /* 7 */
- "cccffcff", /* 8 */
- "cccgeegcgg", /* 9 */
- "ccchhchh", /* 10 */
- "cccfcifcfffiicifii", /* 11 */
- "dddiidii", /* 12 */
- "dddjggjdjj", /* 13 */
- "dddkkdkk", /* 14 */
- "dddhdlhdhhhlldlhll", /* 15 */
- "dddmmdmm", /* 16 */
- "dddidnidiiinndninn", /* 17 */
- "dddoodoo", /* 18 */
- "dddjdpjdjjjppdpjpp", /* 19 */
- };
-
- static void DrawBoard (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- XSegment segment[44];
- int segc;
- Position game_size = (Position) gw->goban.game_size;
- Position point_size = (Position) gw->goban.point_size;
- Position star_size = 4;
- Position xbase = gw->goban.x_offset + point_size / 2;
- Position ybase = gw->goban.y_offset - point_size / 2;
- Position xmin = gw->goban.x_offset + point_size * gw->goban.left + 1;
- Position ymin = gw->goban.y_offset - point_size * gw->goban.top + 1;
- Position xmax = gw->goban.x_offset + point_size * (gw->goban.right + 1) - 1;
- Position ymax = gw->goban.y_offset - point_size * (gw->goban.bottom - 1) - 1;
- char *star;
- int x;
- int y;
-
- XFillRectangle (display, gw->goban.board, gw->goban.background_gc, 0, 0, w->core.width, w->core.height);
-
- if (point_size > 0) {
- segc = 0;
- for (y = gw->goban.bottom - 1; y < gw->goban.top; y++, segc++) {
- segment[segc].x1 = (short) Max ((int) xbase + point_size , xmin);
- segment[segc].x2 = (short) Min ((int) xbase + point_size * game_size, xmax);
- segment[segc].y1 = (short) (ybase - point_size * y);
- segment[segc].y2 = (short) (ybase - point_size * y);
- }
-
- for (x = gw->goban.left; x <= gw->goban.right; x++, segc++) {
- segment[segc].x1 = (short) (xbase + point_size * x);
- segment[segc].x2 = (short) (xbase + point_size * x);
- segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1), ymin);
- segment[segc].y2 = (short) Min (ybase, ymax);
- }
-
- if (gw->goban.top == gw->goban.game_size) {
- segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
- segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
- segment[segc].y1 = (short) (ybase - point_size * (game_size - 1) - 1);
- segment[segc].y2 = (short) (ybase - point_size * (game_size - 1) - 1);
- segc++;
- }
-
- if (gw->goban.bottom == 1) {
- segment[segc].x1 = (short) Max (xbase + point_size - 1, xmin);
- segment[segc].x2 = (short) Min (xbase + point_size * game_size + 1, xmax);
- segment[segc].y1 = (short) (ybase + 1);
- segment[segc].y2 = (short) (ybase + 1);
- segc++;
- }
-
- if (gw->goban.left == 1) {
- segment[segc].x1 = (short) (xbase + point_size - 1);
- segment[segc].x2 = (short) (xbase + point_size - 1);
- segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin);
- segment[segc].y2 = (short) Min (ybase + 1, ymax);
- segc++;
- }
-
- if (gw->goban.right == gw->goban.game_size) {
- segment[segc].x1 = (short) (xbase + point_size * game_size + 1);
- segment[segc].x2 = (short) (xbase + point_size * game_size + 1);
- segment[segc].y1 = (short) Max (ybase - point_size * (game_size - 1) - 1, ymin);
- segment[segc].y2 = (short) Min (ybase + 1, ymax);
- segc++;
- }
-
- XDrawSegments (display, gw->goban.board, gw->goban.foreground_gc, segment, segc);
-
- if (point_size > 8) {
- star_size = (point_size > 10) ? 4 : 2;
- star = stars[game_size - 2];
-
- while (*star != '\0') {
- x = *star++ - 'a' + 1;
- y = *star++ - 'a' + 1;
-
- if (x >= gw->goban.left && x <= gw->goban.right && y >= gw->goban.bottom && y <= gw->goban.top) {
- x = gw->goban.x_offset + (point_size * (2 * x + 1)) / 2;
- y = gw->goban.y_offset - (point_size * (2 * y - 1)) / 2;
-
- XDrawArc (display, gw->goban.board, gw->goban.foreground_gc,
- (int) x - star_size / 2, (int) y - star_size / 2,
- (unsigned int) star_size, (unsigned int) star_size,
- 0, 64 * 360);
- XFillArc (display, gw->goban.board, gw->goban.foreground_gc,
- (int) x - star_size / 2, (int) y - star_size / 2,
- (unsigned int) star_size, (unsigned int) star_size,
- 0, 64 * 360);
- }
- }
- }
- }
-
- XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, 0, 0,
- w->core.width, w->core.height, 0, 0);
- }
-
- /****************************************************************************************************************
- */
-
- static void DrawCoordinates (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- XCharStruct extent;
- int point_size = gw->goban.point_size;
- char s[2];
- int len;
- int ascent;
- int descent;
- int direction;
- int xbase;
- int ybase;
- int x;
- int y;
- unsigned int width;
- unsigned int height;
-
- s[0] = s[1] = '8';
- XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
- s, 2, &direction, &ascent, &descent, &extent);
-
- if ((point_size > extent.width + 2) && (point_size > extent.ascent + extent.descent + 2)) {
- xbase = 2 * gw->goban.x_offset + point_size;
- ybase = 2 * gw->goban.y_offset - point_size;
-
- if (gw->goban.display_coordinates == TRUE) {
-
- for (x = gw->goban.left; x <= gw->goban.right; x++) {
- s[0] = 'A' - 1 + ((x > 8) ? (x + 1) : x);
- XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
- s, 1, &direction, &ascent, &descent, &extent);
-
- XDrawString (display, gw->goban.board, gw->goban.foreground_gc,
- (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1,
- (ybase + extent.ascent - extent.descent) / 2 - point_size * gw->goban.top + 1, s, 1);
- XDrawString (display, gw->goban.board, gw->goban.foreground_gc,
- (xbase - extent.width) / 2 + point_size * x - extent.lbearing + 1,
- (ybase + extent.ascent - extent.descent) / 2 - point_size * (gw->goban.bottom - 2) + 1, s, 1);
- }
- }
-
- x = gw->goban.x_offset + point_size * gw->goban.left;
- y = gw->goban.y_offset - point_size * (gw->goban.top + 1);
- width = point_size * (gw->goban.right - gw->goban.left + 1);
- height = point_size;
-
- if (gw->goban.display_coordinates == FALSE)
- XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
- XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
-
- y = gw->goban.y_offset - point_size * (gw->goban.bottom - 1);
-
- if (gw->goban.display_coordinates == FALSE)
- XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
- XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
-
- ybase += 2 * point_size;
-
- for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
- if (gw->goban.display_coordinates == TRUE) {
- len = 0;
- if (y > 9)
- s[len++] = '1';
- s[len++] = '0' + y % 10;
- XQueryTextExtents (display, XGContextFromGC (gw->goban.foreground_gc),
- s, len, &direction, &ascent, &descent, &extent);
-
- XDrawString (display, gw->goban.board, gw->goban.foreground_gc,
- (xbase - extent.width) / 2 + point_size * (gw->goban.left - 1) - extent.lbearing + 1,
- (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
- XDrawString (display, gw->goban.board, gw->goban.foreground_gc,
- (xbase - extent.width) / 2 + point_size * (gw->goban.right + 1) - extent.lbearing + 1,
- (ybase + extent.ascent - extent.descent) / 2 - point_size * y + 1, s, len);
- }
- }
-
- x = gw->goban.x_offset + point_size * (gw->goban.left - 1);
- y = gw->goban.y_offset - point_size * gw->goban.top;
- width = point_size;
- height = point_size * (gw->goban.top - gw->goban.bottom + 1);;
-
- if (gw->goban.display_coordinates == FALSE)
- XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
- XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
-
- x = gw->goban.x_offset + point_size * (gw->goban.right + 1);
-
- if (gw->goban.display_coordinates == FALSE)
- XFillRectangle (display, gw->goban.board, gw->goban.background_gc, x, y, width, height);
- XCopyArea (display, gw->goban.board, gw->goban.picture, gw->goban.copy_gc, x, y, width, height, x, y);
- }
-
- }
-
- /****************************************************************************************************************
- */
-
- static void InitializeSize (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Position bottom = Min (gw->goban.bottom, gw->goban.top );
- Position left = Min (gw->goban.left , gw->goban.right);
- Position top = Max (gw->goban.bottom, gw->goban.top );
- Position right = Max (gw->goban.left , gw->goban.right);
- Dimension game_size = gw->goban.game_size;
- Dimension width;
- Dimension height;
-
- game_size = (game_size > 1 && game_size < 20 ) ? game_size : 19;
- bottom = (bottom > 0 && bottom < game_size) ? bottom : 1;
- left = (left > 0 && left < game_size) ? left : 1;
- top = (top > bottom && top <= game_size) ? top : game_size;
- right = (right > left && right <= game_size) ? right : game_size;
-
- width = right - left + 3;
- height = top - bottom + 3;
-
- if ((w->core.height == 0) && (w->core.width == 0)) {
- w->core.width = gw->goban.point_size * width ;
- w->core.height = gw->goban.point_size * height;
- }
-
- else
- gw->goban.point_size = Min (w->core.width / width, w->core.height / height);
-
- gw->goban.game_size = game_size;
- gw->goban.bottom = bottom;
- gw->goban.left = left;
- gw->goban.top = top;
- gw->goban.right = right;
- gw->goban.x_offset = (int) (w->core.width - gw->goban.point_size * (width + 2 * left - 2)) / 2;
- gw->goban.y_offset = (int) (w->core.height - gw->goban.point_size * (height - 2 * top - 2)) / 2;
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- static void Initialize (request, new)
- Widget request;
- Widget new;
- {
- InitializeSize (new);
- InitializePixmap (new);
- InitializeGC (new);
- InitializeCursor (new);
- DrawBoard (new);
- DrawCoordinates (new);
- GbClearBoard (new);
- }
-
- /****************************************************************************************************************
- */
-
- static void DrawPoint (w, x, y, color)
- Widget w;
- int x;
- int y;
- GbPointState color;
- {
- GobanWidget gw = (GobanWidget) w;
- Display *display = XtDisplay (w);
- unsigned int size = (unsigned int) gw->goban.point_size - 2;
- XExposeEvent event;
- int X;
- int Y;
-
- if (size > 1) {
- X = gw->goban.x_offset + gw->goban.point_size * x + 1;
- Y = gw->goban.y_offset - gw->goban.point_size * y + 1;
-
- switch (color)
- {
- case GbBlackStone :
- XFillArc (display, gw->goban.picture, gw->goban.black_bg_gc, X, Y, size, size, 0, 360 * 64);
- XDrawArc (display, gw->goban.picture, gw->goban.black_bd_gc, X, Y, size, size, 0, 360 * 64);
- XDrawArc (display, gw->goban.picture, gw->goban.black_fg_gc, X + (int) size / 6, Y + (int) size / 6,
- (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
- break;
- case GbWhiteStone :
- XFillArc (display, gw->goban.picture, gw->goban.white_bg_gc, X, Y, size, size, 0, 360 * 64);
- XDrawArc (display, gw->goban.picture, gw->goban.white_bd_gc, X, Y, size, size, 0, 360 * 64);
- XDrawArc (display, gw->goban.picture, gw->goban.white_fg_gc, X + (int) size / 6, Y + (int) size / 6,
- (size * 2) / 3, (size * 2) / 3, -15 * 64, -60 * 64);
- break;
- case GbEmptyPoint :
- XCopyArea (XtDisplay (w), gw->goban.board, gw->goban.picture, gw->goban.copy_gc,
- X, Y, gw->goban.point_size, gw->goban.point_size, X, Y);
- break;
- }
-
- if (gw->goban.auto_redisplay == TRUE && XtIsRealized (w) == TRUE) {
- event.x = X - 1;
- event.y = Y - 1;
- event.width = gw->goban.point_size;
- event.height = gw->goban.point_size;
-
- Redisplay (w, &event, (Region) NULL);
- }
- }
- }
-
- /****************************************************************************************************************
- */
-
- static void RedrawStones (w)
- Widget w;
- {
- GobanWidget gw = (GobanWidget) w;
- Boolean redisplay = gw->goban.auto_redisplay;
- Position x;
- Position y;
-
- gw->goban.auto_redisplay = FALSE;
-
- for (x = gw->goban.left; x <= gw->goban.right; x++)
- for (y = gw->goban.bottom; y <= gw->goban.top; y++) {
- if (gw->goban.points[x][y].free == 0) {
- if (gw->goban.points[x][y].black == 1)
- DrawPoint (w, x, y, GbBlackStone);
- else
- DrawPoint (w, x, y, GbWhiteStone);
- if (gw->goban.points[x][y].num > 0)
- GbSetNum (w, x, y, (int) gw->goban.points[x][y].num);
- }
-
- if (gw->goban.points[x][y].mark1 != 0 || gw->goban.points[x][y].mark2 != 0)
- GbSetMark (w, x, y, gw->goban.points[x][y].mark1, gw->goban.points[x][y].mark2);
- }
-
- gw->goban.auto_redisplay = redisplay;
-
- if (redisplay == TRUE)
- GbRedisplayBoard (w);
- }
-
- /****************************************************************************************************************
- */
-
- static void Resize (w)
- Widget w;
- {
- DestroyPixmap (w);
- DestroyGC (w);
- InitializeSize (w);
- InitializePixmap (w);
- InitializeGC (w);
- DrawBoard (w);
- DrawCoordinates (w);
- RedrawStones (w);
- }
-
- /****************************************************************************************************************
- */
-
- /* ARGSUSED */
-
- static Boolean SetValues (current, request, new)
- Widget current;
- Widget request;
- Widget new;
- {
- GobanWidget gnew = (GobanWidget) new;
- GobanWidget gcurrent = (GobanWidget) current;
- Boolean redisplay = FALSE;
-
- if (gnew->goban.point_size != gcurrent->goban.point_size)
- gnew->goban.point_size = gcurrent->goban.point_size;
-
- if (XtIsRealized (new)) {
- if (gnew->goban.cursor != gcurrent->goban.cursor) {
-
- switch (gnew->goban.cursor) {
-
- case GbCGrayStone :
- XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.gray_cursor);
- break;
- case GbCBlackStone :
- XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.black_cursor);
- break;
- case GbCWhiteStone :
- XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.white_cursor);
- break;
- default :
- XFreeCursor (XtDisplay (new), gnew->goban.font_cursor );
- gnew->goban.font_cursor = XCreateFontCursor (XtDisplay (new), (unsigned int) gnew->goban.cursor);
- XDefineCursor (XtDisplay (new), XtWindow (new), gnew->goban.font_cursor);
- }
- }
- }
-
- if (gnew->goban.game_size != gcurrent->goban.game_size)
- if (gnew->goban.game_size > 1 && gnew->goban.game_size < 20) {
-
- gnew->goban.bottom = 1;
- gnew->goban.left = 1;
- gnew->goban.top = gnew->goban.game_size;
- gnew->goban.right = gnew->goban.game_size;
-
- InitializeSize (new);
- DrawBoard (new);
- DrawCoordinates (new);
- GbClearBoard (new);
-
- redisplay = TRUE;
- }
- else
- gnew->goban.game_size = gcurrent->goban.game_size;
-
- else if (gnew->goban.top != gcurrent->goban.top ||
- gnew->goban.left != gcurrent->goban.left ||
- gnew->goban.right != gcurrent->goban.right ||
- gnew->goban.bottom != gcurrent->goban.bottom) {
-
- InitializeSize (new);
- DrawBoard (new);
- DrawCoordinates (new);
- RedrawStones (new);
-
- redisplay = TRUE;
- }
-
- else if (new->core.background_pixel != current->core.background_pixel ||
- gnew->goban.foreground != gcurrent->goban.foreground ||
- gnew->goban.white_fg != gcurrent->goban.white_fg ||
- gnew->goban.white_bg != gcurrent->goban.white_bg ||
- gnew->goban.white_bd != gcurrent->goban.white_bd ||
- gnew->goban.black_fg != gcurrent->goban.black_fg ||
- gnew->goban.black_bg != gcurrent->goban.black_bg ||
- gnew->goban.black_bd != gcurrent->goban.black_bd ) {
-
- DestroyGC (new);
- InitializeGC (new);
- DrawBoard (new);
- DrawCoordinates (new);
- RedrawStones (new);
-
- redisplay = TRUE;
- }
-
- if (gnew->goban.display_coordinates != gcurrent->goban.display_coordinates) {
- DrawCoordinates (new);
-
- redisplay = TRUE;
- }
-
- return (gnew->goban.auto_redisplay == True) ? redisplay : False;
- }
-
- /****************************************************************************************************************
- */
- SHAR_EOF
- fi
- if test -f 'Goban.h'
- then
- echo shar: "will not over-write existing file 'Goban.h'"
- else
- cat << \SHAR_EOF > 'Goban.h'
- /****************************************************************************************************************
- *
- * Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful.
- * Use and copying of this software and preparation of derivative works
- * based upon this software are permitted, so long as the following
- * conditions are met:
- * o credit to the authors is acknowledged following current
- * academic behaviour
- * o no fees or compensation are charged for use, copies, or
- * access to this software
- * o this copyright notice is included intact.
- * This software is made available AS IS, and no warranty is made about
- * the software or its performance.
- *
- * Bug descriptions, use reports, comments or suggestions are welcome.
- * Send them to dumesnil@etca.fr or to:
- *
- * Antoine de Maricourt
- * ETCA CREA-SP
- * 16 bis, avenue Prieur de la Cote d'Or
- * 94114 Arcueil Cedex
- * France
- */
-
- #ifndef _Goban_h
- #define _Goban_h
-
- /* Resources:
-
- Name Class RepType Default Value
- ---- ----- ------- -------------
- autoRedisplay AutoRedisplay Boolean True
- background Background Pixel XtDefaultBackground
- blackStoneBackground Background Pixel black
- blackStoneBorder BorderColor Pixel black
- blackStoneForeground Foreground Pixel white
- border BorderColor Pixel XtDefaultForeground
- borderWidth BorderWidth Dimension 1
- cursor Cursor Integer GbGrayCursor
- destroyCallback Callback Pointer NULL
- displayCoordinates DisplayCoordinates Boolean True
- font Font XFontStruct* fixed
- foreground Foreground Pixel XtDefaultForeground
- gameSize Size Dimension 19
- height Height Dimension computed at create
- mappedWhenManaged MappedWhenManaged Boolean True
- pointSize Size Dimension 24
- sensitive Sensitive Boolean True
- viewBottom Position Position computed at create
- viewLeft Position Position computed at create
- viewRight Position Position computed at create
- viewTop Position Position computed at create
- whiteStoneBackground Background Pixel white
- whiteStoneBorder BorderColor Pixel black
- whiteStoneForeground Foreground Pixel black
- width Width Dimension computed at create
- x Position Position 0
- y Position Position 0
- */
-
- /* define any special resource names here that are not in <X11/StringDefs.h> */
-
- #define XtNautoRedisplay "autoRedisplay"
- #define XtNviewBottom "viewBottom"
-
- #ifndef XtNcursor
- #define XtNcursor "cursor"
- #endif
-
- #define XtNgameSize "gameSize"
- #define XtNviewLeft "viewLeft"
- #define XtNdisplayCoordinates "displayCoordinates"
- #define XtNpointSize "pointSize"
- #define XtNviewRight "viewRight"
- #define XtNviewTop "viewTop"
- #define XtNblackStoneBorder "blackStoneBorder"
- #define XtNblackStoneForeground "blackStoneForeground"
- #define XtNblackStoneBackground "blackStoneBackground"
- #define XtNwhiteStoneBorder "whiteStoneBorder"
- #define XtNwhiteStoneForeground "whiteStoneForeground"
- #define XtNwhiteStoneBackground "whiteStoneBackground"
-
- #define XtCAutoRedisplay "AutoRedisplay"
- #define XtCDisplayCoordinates "DisplayCoordinates"
- #define XtCSize "Size"
-
- #define XtEgbWhiteStone "white"
- #define XtEgbBlackStone "black"
- #define XtEgbGrayStone "gray"
-
- /* declare specific GobanWidget class and instance datatypes */
-
- typedef struct _GobanClassRec* GobanWidgetClass;
- typedef struct _GobanRec* GobanWidget;
-
- /* declare the class constant */
-
- extern WidgetClass gobanWidgetClass;
-
- /* cursors */
-
- #define GbCGrayStone 256
- #define GbCBlackStone 257
- #define GbCWhiteStone 258
-
- /* special marks */
-
- #define GbMSquareMark 1
- #define GbMTriangleMark 2
- #define GbMVCrossMark 3
- #define GbMDCrossMark 4
- #define GbMDiamondMark 5
-
- /* colors */
-
- typedef enum { GbEmptyPoint, GbBlackStone, GbWhiteStone } GbPointState;
-
- /* user functions */
-
- #define GbRemoveMark(w,x,y) GbSetMark (w, x, y, 0, 0)
-
- extern void GbRedisplayBoard ( /* Widget w */ );
- extern void GbClearBoard ( /* Widget w */ );
- extern void GbSetPoint ( /* Widget w, Position x, Position y, GbPointState color */ );
- extern void GbSetNum ( /* Widget w, Position x, Position y, int num */ );
- extern void GbSetMark ( /* Widget w, Position x, Position y, unsigned char mark1, unsigned char mark2 */ );
-
- extern Boolean GbGetPositionFromStone ( /* Widget w, Position *x, Position *y */ );
- extern Boolean GbGetStoneFromPosition ( /* Widget w, Position *x, Position *y */ );
-
- #endif /* _Goban_h */
-
- SHAR_EOF
- fi
- if test -f 'GobanP.h'
- then
- echo shar: "will not over-write existing file 'GobanP.h'"
- else
- cat << \SHAR_EOF > 'GobanP.h'
- /****************************************************************************************************************
- *
- * Copyright (c) 1992 by Antoine Dumesnil de Maricourt. All rights reserved.
- *
- * This program is distributed in the hope that it will be useful.
- * Use and copying of this software and preparation of derivative works
- * based upon this software are permitted, so long as the following
- * conditions are met:
- * o credit to the authors is acknowledged following current
- * academic behaviour
- * o no fees or compensation are charged for use, copies, or
- * access to this software
- * o this copyright notice is included intact.
- * This software is made available AS IS, and no warranty is made about
- * the software or its performance.
- *
- * Bug descriptions, use reports, comments or suggestions are welcome.
- * Send them to dumesnil@etca.fr or to:
- *
- * Antoine de Maricourt
- * ETCA CREA-SP
- * 16 bis, avenue Prieur de la Cote d'Or
- * 94114 Arcueil Cedex
- * France
- */
-
- #ifndef _GobanP_h
- #define _GobanP_h
-
- #include "Goban.h"
-
- /* include superclass private header file */
- #include <X11/CoreP.h>
-
- /* define unique representation types not found in <X11/StringDefs.h> */
-
- #define XtRGobanResource "GobanResource"
-
- typedef struct {
- int empty;
- } GobanClassPart;
-
- typedef struct _GobanClassRec {
- CoreClassPart core_class;
- GobanClassPart goban_class;
- } GobanClassRec;
-
- extern GobanClassRec gobanClassRec;
-
- typedef struct {
- unsigned int free : 1;
- unsigned int black : 1;
- unsigned int mark1 : 8;
- unsigned int mark2 : 8;
- unsigned int num : 10;
- } PointState;
-
- typedef struct {
- /* resources */
-
- Boolean auto_redisplay;
- Position bottom;
- int cursor;
- XFontStruct *font;
- Pixel foreground;
- Dimension game_size;
- Position left;
- Boolean display_coordinates;
- Dimension point_size;
- Position right;
- Position top;
-
- /* private state */
-
- PointState points[20][20];
- Position x_offset;
- Position y_offset;
-
- Pixmap black_stone;
- Pixmap board;
- Pixmap gray_stone;
- Pixmap mouse_mask;
- Pixmap picture;
- Pixmap white_stone;
-
- GC background_gc;
- GC foreground_gc;
- GC black_fg_gc;
- GC black_bg_gc;
- GC black_bd_gc;
- GC white_fg_gc;
- GC white_bg_gc;
- GC white_bd_gc;
- GC copy_gc;
-
- Cursor black_cursor;
- Cursor gray_cursor;
- Cursor white_cursor;
- Cursor font_cursor;
-
- Pixel white_bg;
- Pixel white_fg;
- Pixel white_bd;
- Pixel black_bg;
- Pixel black_fg;
- Pixel black_bd;
- } GobanPart;
-
- typedef struct _GobanRec {
- CorePart core;
- GobanPart goban;
- } GobanRec;
-
- #define Min(x,y) ((x) > (y) ? (y) : (x))
- #define Max(x,y) ((x) > (y) ? (x) : (y))
-
- #endif /* _GobanP_h */
- SHAR_EOF
- fi
- if test -f 'Imakefile'
- then
- echo shar: "will not over-write existing file 'Imakefile'"
- else
- cat << \SHAR_EOF > 'Imakefile'
- LOCAL_LIBRARIES = $(XAWLIB) $(XTOOLLIB) $(XMULIB) $(XLIB)
-
- OBJS= main.o Goban.o amigo.o goplayer.o goplayutils.o \
- killable.o xinterface.o menus.o
- SRCS= $(OBJS:%.o=%.c)
-
- ComplexProgramTarget(xamigo)
- InstallAppDefaults(Xamigo)
- SHAR_EOF
- fi
- if test -f 'Makefile'
- then
- echo shar: "will not over-write existing file 'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # Makefile generated by imake - do not edit!
- #
- # The cpp used on this machine replaces all newlines and multiple tabs and
- # spaces in a macro expansion with a single space. Imake tries to compensate
- # for this, but is not always successful.
- #
-
- # -------------------------------------------------------------------------
- # Makefile generated from "Imake.tmpl" and <Imakefile>
- # $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
- #
- # Platform-specific parameters may be set in the appropriate <vendor>.cf
- # configuration files. Site-specific parameters should be set in the file
- # site.def. Full rebuilds are recommended if any parameters are changed.
- #
- # If your C preprocessor does not define any unique symbols, you will need
- # to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
- # "make World" the first time).
- #
-
- # -------------------------------------------------------------------------
- # site-specific configuration parameters that need to come before
- # the platform-specific parameters - edit site.def to change
-
- # site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
-
- # -------------------------------------------------------------------------
- # platform-specific configuration parameters - edit sun.cf to change
-
- # platform: $XConsortium: sun.cf,v 1.71 91/12/20 11:18:34 rws Exp $
-
- # operating system: SunOS 4.1.1
-
- # $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
-
- # -------------------------------------------------------------------------
- # site-specific configuration parameters that go after
- # the platform-specific parameters - edit site.def to change
-
- # site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
-
- SHELL = /bin/sh
-
- TOP = .
- CURRENT_DIR = .
-
- AR = ar clq
- BOOTSTRAPCFLAGS =
- CC = cc
- AS = as
-
- COMPRESS = compress
- CPP = /lib/cpp $(STD_CPP_DEFINES)
- PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
- INSTALL = install
- LD = ld
- LINT = lint
- LINTLIBFLAG = -C
- LINTOPTS = -axz
- LN = ln -s
- MAKE = make
- MV = mv
- CP = cp
-
- RANLIB = ranlib
- RANLIBINSTFLAGS =
-
- RM = rm -f
- TROFF = psroff
- MSMACROS = -ms
- TBL = tbl
- EQN = eqn
- STD_INCLUDES =
- STD_CPP_DEFINES =
- STD_DEFINES =
- EXTRA_LOAD_FLAGS =
- EXTRA_LIBRARIES =
- TAGS = ctags
-
- SHAREDCODEDEF = -DSHAREDCODE
- SHLIBDEF = -DSUNSHLIB
-
- PROTO_DEFINES =
-
- INSTPGMFLAGS =
-
- INSTBINFLAGS = -m 0755
- INSTUIDFLAGS = -m 4755
- INSTLIBFLAGS = -m 0644
- INSTINCFLAGS = -m 0444
- INSTMANFLAGS = -m 0444
- INSTDATFLAGS = -m 0444
- INSTKMEMFLAGS = -g kmem -m 2755
-
- CDEBUGFLAGS = -O
- CCOPTIONS = -pipe
-
- ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
- ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
- CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
- LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
-
- LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
-
- LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS)
-
- LDCOMBINEFLAGS = -X -r
- DEPENDFLAGS =
-
- MACROFILE = sun.cf
- RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
-
- IMAKE_DEFINES =
-
- IRULESRC = $(CONFIGDIR)
- IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
-
- ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
- $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
- $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
-
- # -------------------------------------------------------------------------
- # X Window System Build Parameters
- # $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
-
- # -------------------------------------------------------------------------
- # X Window System make variables; this need to be coordinated with rules
-
- PATHSEP = /
- USRLIBDIR = /usr/lib
- BINDIR = /usr/users/staff/xtools/bin/$(TARGET_ARCH:-%=%)
- INCROOT = /usr/include
- BUILDINCROOT = $(TOP)
- BUILDINCDIR = $(BUILDINCROOT)/X11
- BUILDINCTOP = ..
- INCDIR = $(INCROOT)/X11
- ADMDIR = /usr/adm
- LIBDIR = /usr/users/staff/xtools/lib
- CONFIGDIR = $(LIBDIR)/config
- LINTLIBDIR = $(USRLIBDIR)/lint
-
- FONTDIR = $(LIBDIR)/fonts
- XINITDIR = $(LIBDIR)/xinit
- XDMDIR = $(LIBDIR)/xdm
- TWMDIR = $(LIBDIR)/twm
- MANPATH = /usr/users/staff/xtools/man
- MANSOURCEPATH = $(MANPATH)/man
- MANSUFFIX = n
- LIBMANSUFFIX = 3
- MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
- LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
- NLSDIR = $(LIBDIR)/nls
- PEXAPIDIR = $(LIBDIR)/PEX
- XAPPLOADDIR = /usr/users/staff/xtools/lib/app-defaults
- FONTCFLAGS = -t
-
- INSTAPPFLAGS = $(INSTDATFLAGS)
-
- IMAKE = imake
- DEPEND = makedepend
- RGB = rgb
-
- FONTC = bdftopcf
-
- MKFONTDIR = mkfontdir
- MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
-
- CONFIGSRC = $(TOP)/config
- DOCUTILSRC = $(TOP)/doc/util
- CLIENTSRC = $(TOP)/clients
- DEMOSRC = $(TOP)/demos
- LIBSRC = $(TOP)/lib
- FONTSRC = $(TOP)/fonts
- INCLUDESRC = $(TOP)/X11
- SERVERSRC = $(TOP)/server
- UTILSRC = $(TOP)/util
- SCRIPTSRC = $(UTILSRC)/scripts
- EXAMPLESRC = $(TOP)/examples
- CONTRIBSRC = $(TOP)/../contrib
- DOCSRC = $(TOP)/doc
- RGBSRC = $(TOP)/rgb
- DEPENDSRC = $(UTILSRC)/makedepend
- IMAKESRC = $(CONFIGSRC)
- XAUTHSRC = $(LIBSRC)/Xau
- XLIBSRC = $(LIBSRC)/X
- XMUSRC = $(LIBSRC)/Xmu
- TOOLKITSRC = $(LIBSRC)/Xt
- AWIDGETSRC = $(LIBSRC)/Xaw
- OLDXLIBSRC = $(LIBSRC)/oldX
- XDMCPLIBSRC = $(LIBSRC)/Xdmcp
- BDFTOSNFSRC = $(FONTSRC)/bdftosnf
- BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
- BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
- MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
- FSLIBSRC = $(FONTSRC)/lib/fs
- FONTSERVERSRC = $(FONTSRC)/server
- EXTENSIONSRC = $(TOP)/extensions
- XILIBSRC = $(EXTENSIONSRC)/lib/xinput
- PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
-
- # $XConsortium: sunLib.tmpl,v 1.14 91/12/20 11:19:05 rws Exp $
-
- SHLIBLDFLAGS = -assert pure-text
- PICFLAGS = -pic
-
- DEPEXTENSIONLIB =
- EXTENSIONLIB = -lXext
-
- DEPXLIB = $(DEPEXTENSIONLIB)
- XLIB = $(EXTENSIONLIB) -lX11
-
- DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
- XMULIBONLY = -lXmu
- XMULIB = -lXmu
-
- DEPOLDXLIB =
- OLDXLIB = -loldX
-
- DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
- XTOOLLIB = -lXt
-
- DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
- XAWLIB = -lXaw
-
- DEPXILIB =
- XILIB = -lXi
-
- SOXLIBREV = 4.10
- SOXTREV = 4.10
- SOXAWREV = 5.0
- SOOLDXREV = 4.10
- SOXMUREV = 4.10
- SOXEXTREV = 4.10
- SOXINPUTREV = 4.10
-
- DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
- XAUTHLIB = -lXau
- DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
- XDMCPLIB = -lXdmcp
-
- DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
- PHIGSLIB = -lphigs
-
- DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
- XBSDLIB = -lXbsd
-
- LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
- LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
- LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
- LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
- LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
- LINTXI = $(LINTLIBDIR)/llib-lXi.ln
- LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
-
- DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
-
- DEPLIBS1 = $(DEPLIBS)
- DEPLIBS2 = $(DEPLIBS)
- DEPLIBS3 = $(DEPLIBS)
-
- # -------------------------------------------------------------------------
- # Imake rules for building libraries, programs, scripts, and data files
- # rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
-
- # -------------------------------------------------------------------------
- # start of Imakefile
-
- LOCAL_LIBRARIES = $(XAWLIB) $(XTOOLLIB) $(XMULIB) $(XLIB)
-
- OBJS= main.o Goban.o amigo.o goplayer.o goplayutils.o \
- killable.o xinterface.o menus.o
- SRCS= $(OBJS:%.o=%.c)
-
- PROGRAM = xamigo
-
- all:: xamigo
-
- xamigo: $(OBJS) $(DEPLIBS)
- $(RM) $@
- $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
-
- saber_xamigo:: $(SRCS)
- # load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
-
- osaber_xamigo:: $(OBJS)
- # load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
-
- install:: xamigo
- @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
- else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
- $(INSTALL) -c $(INSTPGMFLAGS) xamigo $(DESTDIR)$(BINDIR)
-
- install.man:: xamigo.man
- @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
- else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
- $(INSTALL) -c $(INSTMANFLAGS) xamigo.man $(DESTDIR)$(MANDIR)/xamigo.$(MANSUFFIX)
-
- depend::
- $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
-
- lint:
- $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
- lint1:
- $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
-
- clean::
- $(RM) $(PROGRAM)
-
- install:: Xamigo.ad
- @if [ -d $(DESTDIR)$(XAPPLOADDIR) ]; then set +x; \
- else (set -x; $(MKDIRHIER) $(DESTDIR)$(XAPPLOADDIR)); fi
- $(INSTALL) -c $(INSTAPPFLAGS) Xamigo.ad $(DESTDIR)$(XAPPLOADDIR)/Xamigo
-
- # -------------------------------------------------------------------------
- # common rules for all Makefiles - do not edit
-
- emptyrule::
-
- clean::
- $(RM_CMD) "#"*
-
- Makefile::
- -@if [ -f Makefile ]; then set -x; \
- $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
- else exit 0; fi
- $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
-
- tags::
- $(TAGS) -w *.[ch]
- $(TAGS) -xw *.[ch] > TAGS
-
- saber:
- # load $(ALLDEFINES) $(SRCS)
-
- osaber:
- # load $(ALLDEFINES) $(OBJS)
-
- # -------------------------------------------------------------------------
- # empty rules for directories that do not have SUBDIRS - do not edit
-
- install::
- @echo "install in $(CURRENT_DIR) done"
-
- install.man::
- @echo "install.man in $(CURRENT_DIR) done"
-
- Makefiles::
-
- includes::
-
- # -------------------------------------------------------------------------
- # dependencies generated by makedepend
-
- SHAR_EOF
- fi
- if test -f 'Makefile.hand'
- then
- echo shar: "will not over-write existing file 'Makefile.hand'"
- else
- cat << \SHAR_EOF > 'Makefile.hand'
- #
- # Example makefile for xamigo
- #
-
- CFLAGS= -O
- LIBS= -lXaw -lXt -lXmu -lXext -lX11 -lm
- TARGET= xamigo
- OBJS= main.o Goban.o amigo.o goplayer.o goplayutils.o \
- killable.o xinterface.o menus.o
-
- $(TARGET): $(OBJS) Makefile
- cc -o $(TARGET) $(OBJS) $(LIBS)
-
- clean:
- /bin/rm -f $(OBJS) $(TARGET)
-
-
- main.o: Goban.h xamigo.h amigo.h
-
- Goban.o: GobanP.h Goban.h
-
- amigo.o: go.h amigo.h
-
- goplayer.o: go.h amigo.h goplayutils.h
-
- goplayutils.o: goplayutils.h amigo.h go.h
-
- killable.o: go.h amigo.h goplayutils.h
-
- xinterface.o: Goban.h amigo.h
-
- menus.o: xamigo.h
- SHAR_EOF
- fi
- if test -f 'README'
- then
- echo shar: "will not over-write existing file 'README'"
- else
- cat << \SHAR_EOF > 'README'
-
- Xamigo 1.1
-
- This is an alpha release of xamigo --- a port (read: quick hack) of the
- Amiga Go program AmiGo. I don't have time to get it real nice now,
- but will spend some more time on it when my thesis is out of the way.
- Sadly this is the second time I've said that :-)
-
- The `readme' from the original distribution is included as README.AMIGO
-
- An Imakefile is included, so you should be able to type
- xmkmf
- make
- to build xamigo. Let me know if you have problems with the Imakefile,
- preferably with fixes :-)
-
- You *have* to install the app-defaults file (Xamigo.ad) before you use
- xamigo. This should either go in /usr/lib/X11/app-defaults,
- or in your own app-defaults directory, as file Xamigo (ie lose the '.ad')
- If you do the latter, you have to:
- setenv XAPPLRESDIR <full path of your app-defaults directory>
-
- Feel free to mail me any comments and suggestions for improvements.
-
- Neil
- neilb@scs.leeds.ac.uk
- SHAR_EOF
- fi
- if test -f 'README.AMIGO'
- then
- echo shar: "will not over-write existing file 'README.AMIGO'"
- else
- cat << \SHAR_EOF > 'README.AMIGO'
- This is version 1.0 of AmiGo --- a Go board and player for the Amiga.
- The Amiga interface and board manager were written by Todd R. Johnson.
- The player is a C port of a Pascal player written by Stoney Ballard.
- The interface allows you to play human vs. human, human vs. Amiga, or
- Amiga vs. Amiga.
-
- The board manager and player could both use some work. Currently,
- you cannot save/load games, take back a move, or automatically score a
- game. It is also limited to a 19 by 19 board. I'm releasing AmiGo
- now because 1) I'm in the final phases of my dissertation and probably
- won't have much time to do any further work on AmiGo, and 2) a lot of
- people have been asking for an Amiga Go player. I am also releasing
- all of the source code so that others can add to and modify AmiGo.
- Note that all of my code in this release is public domain, while the
- ported go player retains the original copyright.
-
- If you distribute AmiGo, I urge you to include the source
- code. If anyone makes changes, I would appreciate a copy. In fact, I
- am willing to act as a clearinghouse for AmiGo changes.
-
- Todd R. Johnson
- tj@cis.ohio-state.edu
- 8/8/89
-
- Here is the message attached to the original USENET posting of Stoney
- Ballard's Pascal code. Note that the board manager mentioned here is
- not included in this distribution.
-
- This go board manager and rudimentary go player was written by
- Stoney Ballard at Perq Systems in 1983-1984. It is written in
- Perq Pascal and utilizes some Perq libraries for I/O. The code
- is offered here if someone is interested to convert it to Unix.
-
- The wonderful part about it is that a game is recorded as a tree
- and can be played forward or backward, branching at any point
- where there were alternate moves.
-
- For some time, this program was also used to generate the go
- boards displayed in the American Go Journal. For this it used
- some large font digits which are now lost.
-
- Fred Hansen
- SHAR_EOF
- fi
- if test -f 'TODO'
- then
- echo shar: "will not over-write existing file 'TODO'"
- else
- cat << \SHAR_EOF > 'TODO'
-
- There are lots of things which need adding/improving.
-
- o smaller board sizes (only supports 19x19 right now)
-
- o take back last move
-
- o log the game/save position
-
- o tidy up the code & include files
-
- o stopwatch cursor when it is AmiGo's turn?
-
- If you have any additions to this list, please mail them to me!
-
- Neil
- neilb@scs.leeds.ac.uk
- SHAR_EOF
- fi
- if test -f 'Xamigo.ad'
- then
- echo shar: "will not over-write existing file 'Xamigo.ad'"
- else
- cat << \SHAR_EOF > 'Xamigo.ad'
- !
- ! Application defaults file for xamigo 1.1
- !
- Xamigo.title: Xamigo v1.1
-
- Xamigo.form.background: burlywood4
- Xamigo.form.buttonBox.background: burlywood4
- Xamigo.form.buttonBox.borderWidth: 0
-
- Xamigo.form.buttonBox.orientation: horizontal
- Xamigo.form.buttonBox.MenuButton.leftBitmap: menu12
- Xamigo.form.buttonBox.gameButton.label: Game
- Xamigo.form.buttonBox.infoButton.label: Info
- Xamigo.form.buttonBox.moveButton.label: Move
- Xamigo.form.buttonBox.MenuButton.shapeStyle: oval
- Xamigo.form.buttonBox.top: chainTop
- Xamigo.form.buttonBox.bottom: chainTop
- Xamigo.form.buttonBox.left: chainLeft
- Xamigo.form.buttonBox.right: chainLeft
-
- Xamigo*statsPopup.title: Game Statistics
- Xamigo*statsPopup.allowResize: TRUE
- Xamigo*statForm.background: tan
- Xamigo*statForm*resizable: TRUE
-
- Xamigo*statForm*background: tan
- Xamigo*statForm.borderWidth: 0
- Xamigo*statForm.resizable: TRUE
-
- Xamigo*statForm*Label.background: tan
- Xamigo*statForm*Label.borderWidth: 0
- Xamigo*blackStatForm.borderWidth: 1
- Xamigo*blackStatForm.borderColor: brown
- Xamigo*whiteStatForm.borderWidth: 1
- Xamigo*whiteStatForm.borderColor: brown
- Xamigo*blackStatForm.playerLabel.label: black
- Xamigo*whiteStatForm.playerLabel.label: white
- Xamigo*blackStatForm.playerScore.label: 0
- Xamigo*whiteStatForm.playerScore.label: 0
-
- Xamigo*scoreLabel.fromHoriz: playerLabel
- Xamigo*scoreLabel.horizDistance: 20
- Xamigo*scoreLabel.label: Captures :
- Xamigo*playerScore.foreground: maroon
- Xamigo*playerScore.fromHoriz: scoreLabel
- Xamigo*playerScore.horizDistance: 10
-
- Xamigo*lastMoveLabel.fromHoriz: playerLabel
- Xamigo*lastMoveLabel.horizDistance: 20
- Xamigo*lastMoveLabel.fromVert: playerScore
- Xamigo*lastMoveLabel.label: Last Move :
- Xamigo*lastMove.fromHoriz: lastMoveLabel
- Xamigo*lastMove.horizDistance: 10
- Xamigo*lastMove.foreground: sea green
- Xamigo*lastMove.fromVert: playerScore
- Xamigo*lastMove.label: \ \ \ \ \ \
-
- Xamigo*whiteStatForm.fromHoriz: blackStatForm
-
- Xamigo*messageWindow.fromVert: blackStatForm
- Xamigo*messageWindow.borderWidth: 1
- Xamigo*messageWindow.borderColor: brown
- Xamigo*messageWindow.width: 400
- Xamigo*messageWindow.height: 70
- Xamigo*messageWindow.displayCaret: FALSE
- Xamigo*messageWindow.scrollVertical: whenNeeded
- Xamigo*messageWindow*font: 6x13
- Xamigo*messageWindow*wrap: word
-
- Xamigo*statDone.fromVert: messageWindow
- Xamigo*statDone.fromHoriz: blackStatForm
- Xamigo*statDone.label: Done
- Xamigo*statDone.shapeStyle: oval
-
- Xamigo.form.goban.width: 400
- Xamigo.form.goban.height: 400
- Xamigo.form.goban.fromVert: buttonBox
- Xamigo.form.goban.vertDistance: 10
- Xamigo.form.goban.top: chainTop
- Xamigo.form.goban.bottom: chainBottom
- Xamigo.form.goban.left: chainLeft
- Xamigo.form.goban.right: chainRight
- Xamigo.form.goban.background: tan
- Xamigo.form.goban.translations: #augment \
- <BtnDown> : inputStone()\n\
- <Key>P : pass()\n\
- <Key>p : pass()
-
- Xamigo*SmeBSB.leftMargin: 16
- Xamigo*SmeBSB.rightMargin: 16
- Xamigo*SmeBSB.vertMargin: 30
-
- Xamigo*gameMenu.newGame.label: New Game
- Xamigo*gameMenu.stats.label: Game Stats
- Xamigo*gameMenu.about.label: About...
- Xamigo*gameMenu.quit.label: Quit
-
- Xamigo*gameMenu.aWhite.label: Amigo Plays White
- Xamigo*gameMenu.aBlack.label: Amigo Plays Black
- Xamigo*gameMenu.group.label: Group Info
- Xamigo*gameMenu.reason.label: Move Reason
- Xamigo*gameMenu.lookahead.label: Show Lookahead
- Xamigo*gameMenu*leftMargin: 24
-
- Xamigo*levelMenu.level1.label: 1
- Xamigo*levelMenu.level2.label: 2
- Xamigo*levelMenu.level3.label: 3
- Xamigo*levelMenu.level4.label: 4
- Xamigo*levelMenu.level5.label: 5
- Xamigo*levelMenu.level6.label: 6
- Xamigo*levelMenu.level7.label: 7
- Xamigo*levelMenu.leftMargin: 24
- Xamigo*levelButton.label: Level
-
- Xamigo*moveMenu.pass.label: Pass
- Xamigo*moveMenu.takeback.label: Take Back Move
- Xamigo*moveMenu.resign.label: Resign
-
- Xamigo*handicapButton.label: Handicap
- Xamigo*handicapMenu*leftMargin: 24
- Xamigo*handicapMenu.handicap0.label: 0
- Xamigo*handicapMenu.handicap2.label: 2
- Xamigo*handicapMenu.handicap3.label: 3
- Xamigo*handicapMenu.handicap4.label: 4
- Xamigo*handicapMenu.handicap5.label: 5
- Xamigo*handicapMenu.handicap6.label: 6
- Xamigo*handicapMenu.handicap7.label: 7
- Xamigo*handicapMenu.handicap8.label: 8
- Xamigo*handicapMenu.handicap9.label: 9
- SHAR_EOF
- fi
- if test -f 'amigo.c'
- then
- echo shar: "will not over-write existing file 'amigo.c'"
- else
- cat << \SHAR_EOF > 'amigo.c'
- /* Go started 4/17/88 by Todd R. Johnson */
- /* 8/8/89 cleaned up for first release */
- /* Public Domain */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include "go.h"
- #include "amigo.h"
-
-
- extern char *playReason;
- extern short playLevel, showTrees;
- extern Widget message;
-
- struct bRec goboard[19][19]; /*-- The main go board --*/
-
- struct Group GroupList[MAXGROUPS]; /*-- The list of Groups --*/
- short DeletedGroups[4]; /*-- Codes of deleted groups --*/
-
- short GroupCount = 0; /*-- The total number of groups --*/
- short DeletedGroupCount; /*-- The total number of groups --*/
- /*-- deleted on a move --*/
- short ko, koX, koY;
- short blackTerritory,whiteTerritory;
- short blackPrisoners, whitePrisoners;
- short showMoveReason = FALSE,
- groupInfo = FALSE,
- whitePassed = FALSE,
- blackPassed = FALSE;
-
-
- /* Arrays for use when checking around a point */
- short xVec[4] = {0, 1, 0, -1};
- short yVec[4] = {-1, 0, 1, 0};
-
- short
- member(group, grouplist, cnt)
- short group;
- short grouplist[4];
- short cnt;
- {
- unsigned short i;
-
-
- for (i = 0; i < cnt; i++)
- if (grouplist[i] == group)
- return TRUE;
- return FALSE;
- }
-
- /* Does a stone at x, y connect to any groups of color? */
- short
- Connect( color, x, y, fGroups, fCnt, eGroups, eCnt)
- enum bVal color;
- short x, y;
- short fGroups[4], eGroups[4];
- short *fCnt, *eCnt;
- {
- unsigned short point = 0;
- short tx, ty, total = 0;
- enum bVal opcolor = WHITE;
-
-
- *fCnt = 0;
- *eCnt = 0;
- if (color == WHITE)
- opcolor = BLACK;
- for (point = 0; point <= 3; point++ )
- {
- tx = x + xVec[point];
- ty = y + yVec[point];
- if (!LegalPoint(tx,ty))
- continue;
- if (goboard[tx][ty].Val == color)
- {
- total++;
- if (!member(goboard[tx][ty].GroupNum, fGroups, *fCnt))
- fGroups[(*fCnt)++] = goboard[tx][ty].GroupNum;
- }
- else if (goboard[tx][ty].Val == opcolor)
- {
- total++;
- if (!member(goboard[tx][ty].GroupNum, eGroups, *eCnt))
- eGroups[(*eCnt)++] = goboard[tx][ty].GroupNum;
- }
- }
- return total;
- }
-
- /* Returns the maximum number of liberties for a given intersection */
- short
- Maxlibs(x, y)
- short x, y;
- {
- short cnt = 4;
-
-
- if (x == 0 || x == 18)
- cnt--;
- if (y == 0 || y == 18)
- cnt--;
- return cnt;
- }
-
- DeleteGroupFromStone(x,y)
- short x,y;
- {
- if (goboard[x][y].Val != EMPTY)
- GroupCapture(goboard[x][y].GroupNum);
- }
-
- /* Determine whether x, y is suicide for color */
- short
- Suicide(color, x, y)
- enum bVal color;
- short x, y;
- {
- enum bVal opcolor = BLACK;
- short friendlycnt, friendlygroups[4],
- enemycnt, enemygroups[4],
- total;
- short maxlibs, i, libcnt = 0;
-
-
- if (color == BLACK)
- opcolor = WHITE;
- maxlibs = Maxlibs( x, y);
- total = Connect(color, x, y, friendlygroups, &friendlycnt,
- enemygroups, &enemycnt);
-
- if (total < maxlibs)
- return FALSE;
-
- /* Check for a capture */
- for (i = 0; i < enemycnt; i++)
- if (GroupList[enemygroups[i]].liberties == 1)
- return FALSE;
- for (i = 0; i < friendlycnt; i++)
- libcnt += (GroupList[friendlygroups[i]].liberties - 1);
- if (libcnt != 0)
- return FALSE;
- return TRUE;
- }
-
- /* Returns the number of liberties for x, y */
- short
- StoneLibs(x, y)
- short x, y;
- {
- short cnt = 0, tx, ty;
- unsigned short point;
-
-
- for (point = 0; point <= 3; point++)
- {
- tx = x + xVec[point];
- ty = y + yVec[point];
- if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY)
- cnt++;
- }
- return cnt;
- }
-
- void
- EraseMarks()
- {
- register short i;
- register struct bRec *gpt = &goboard[0][0];
-
-
- for (i=0; i<361; gpt++,i++)
- gpt->marked = FALSE;
- }
-
- /* Place a stone of color at x, y */
- short
- GoPlaceStone(color, x, y)
- enum bVal color;
- short x, y;
- {
- short fgroups[4], egroups[4]; /* group codes surrounding stone */
- short fcnt, ecnt, i;
- short lowest = GroupCount + 1;
-
-
- DeletedGroupCount = 0;
- if (goboard[x][y].Val != EMPTY || Suicide(color,x,y))
- return FALSE;
-
- if (ko && koX == x && koY == y)
- return FALSE;
-
- ko = FALSE;
- placestone(color, x, y);
- goboard[x][y].Val = color;
- /* Does the new stone connect to any friendly stone(s)? */
- Connect(color, x, y, fgroups, &fcnt, egroups, &ecnt);
- if (fcnt)
- {
- /* Find the connecting friendly group with the lowest code */
- for (i = 0; i < fcnt; i++)
- if (fgroups[i] <= lowest)
- lowest = fgroups[i];
- /*-- Renumber resulting group --*/
- /*-- Raise the stone count of the lowest by one to account --*/
- /*-- for new stone --*/
- goboard[x][y].GroupNum = lowest;
- GroupList[lowest].count++;
- for (i = 0; i < fcnt; i++)
- if (fgroups[i] != lowest)
- MergeGroups(lowest, fgroups[i]);
- /* Fix the liberties of the resulting group */
- CountLiberties(lowest);
- }
- else
- {
- /* Isolated stone. Create new group. */
- GroupCount++;
- lowest = GroupCount;
- GroupList[lowest].color = color;
- GroupList[lowest].count = 1;
- GroupList[lowest].internal = 0;
- GroupList[lowest].external = StoneLibs( x, y);
- GroupList[lowest].liberties = GroupList[lowest].external;
- GroupList[lowest].eyes = 0;
- GroupList[lowest].alive = 0;
- GroupList[lowest].territory = 0;
- goboard[x][y].GroupNum = lowest;
- }
- /* Now fix the liberties of enemy groups adjacent to played stone */
- FixLibs(color, x, y, PLACED); /* Fix the liberties of opcolor */
- ReEvalGroups(color, x, y, lowest);
- RelabelGroups();
- return TRUE;
- }
-
- /* Remove a stone from the board */
- void
- GoRemoveStone(x, y)
- short x, y;
- {
- goboard[x][y].Val = EMPTY;
- goboard[x][y].GroupNum = 0;
- removestone( x, y);
- }
-
- /* Merges two groups -- Renumbers stones and deletes second group from
- list. Fixes stone count of groups. This does not fix anything else.
- FixLibs must be called to fix liberties, etc. */
- void
- MergeGroups(g1, g2)
- short g1, g2;
- {
- short x, y;
-
-
- ForeachPoint(y,x)
- if (goboard[x][y].GroupNum == g2)
- goboard[x][y].GroupNum = g1;
- GroupList[g1].count += GroupList[g2].count;
- DeleteGroup( g2 ); /* Removes group from GroupList */
- }
-
- /* Stores a group code to be deleted */
- void
- DeleteGroup(code)
- short code;
- {
- DeletedGroups[DeletedGroupCount++] = code;
- }
-
- /* Re-evaluate the groups given the last move. This assumes that the
- last move has been merged into adjoining groups and all liberty counts
- are correct. Handles capture. Checks for Ko. Keeps track of captured
- stones. code is the group number of the stone just played. */
- void
- ReEvalGroups(color, x, y, code)
- enum bVal color;
- short x, y, code;
- {
- short fgroups[4], egroups[4],
- fcnt, ecnt, i, killcnt = 0, count = 0;
- enum bVal opcolor = BLACK;
-
- if (color == BLACK)
- opcolor = WHITE;
- /* Check for capture */
- Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt);
- if (ecnt)
- {
- /* See if any of the groups have no liberties */
- for (i = 0; i < ecnt; i++)
- if (GroupList[egroups[i]].liberties == 0)
- {
- killcnt++;
- count = GroupList[egroups[i]].count;
- GroupCapture( egroups[i]);
- }
- }
- /* Check for ko. koX and koY are set in GroupCapture above. */
- if (killcnt == 1 && count == 1 && GroupList[ code ].count == 1
- && GroupList[ code ].liberties == 1)
- {
- ko = TRUE;
- }
- if (killcnt)
- intrPrisonerReport( blackPrisoners, whitePrisoners);
- /* Set eye count for groups */
- CountEyes();
- }
-
- /* Remove a captured group from the board and fix the liberties of any
- adjacent groups. Fixes prisoner count. Sets KoX and KoY */
- /*-- update display of captured stones -neilb --*/
- void
- GroupCapture(code)
- short code;
- {
- short x, y;
-
- if (GroupList[code].color == BLACK)
- blackPrisoners += GroupList[code].count;
- else
- whitePrisoners += GroupList[code].count;
- intrPrisonerReport(blackPrisoners, whitePrisoners);
- ForeachPoint(y,x)
- if (goboard[x][y].GroupNum == code)
- {
- FixLibs(GroupList[code].color,x,y,REMOVED);
- GoRemoveStone(x, y);
- koX = x;
- koY = y;
- }
- DeleteGroup( code);
- }
-
- /* Fix the liberties of groups adjacent to x, y. move indicates
- whether a stone of color was placed or removed at x, y
- This does not change liberty counts of friendly groups when a stone
- is placed. Does not do captures. */
- void
- FixLibs( color, x, y, move)
- enum bVal color;
- short x, y, move;
- {
- short fgroups[4], fcnt, egroups[4], ecnt, i;
- enum bVal opcolor = BLACK;
-
- if (color == BLACK)
- opcolor = WHITE;
- Connect( color, x, y, fgroups, &fcnt, egroups, &ecnt);
- if (move == PLACED)
- for (i = 0; i < ecnt; i++)
- GroupList[egroups[i]].liberties--;
- else /* Stone removed so increment opcolor */
- for (i = 0; i < ecnt; i++)
- GroupList[egroups[i]].liberties++;
- }
-
- void
- goSetHandicap(handicap)
- {
- if (handicap < 2)
- return;
-
- GoPlaceStone(BLACK,3,3);
- GoPlaceStone(BLACK,15,15);
-
- if (handicap >= 3)
- GoPlaceStone(BLACK,15,3);
- if (handicap >= 4)
- GoPlaceStone(BLACK,3,15);
- if (handicap == 5 || handicap == 7 || handicap == 9)
- GoPlaceStone(BLACK,9,9);
- if (handicap >= 6)
- {
- GoPlaceStone(BLACK,15,9);
- GoPlaceStone(BLACK,3,9);
- }
- if (handicap >= 8)
- {
- GoPlaceStone(BLACK,9,15);
- GoPlaceStone(BLACK,9,3);
- }
- }
-
- void
- goRestart(handicap)
- int handicap;
- {
- register short i;
- register struct bRec *gpt = &goboard[0][0];
-
-
- GroupCount = 0;
- ko = FALSE;
- blackPrisoners = whitePrisoners = 0;
- intrPrisonerReport(0, 0);
- for (i=0; i<361; gpt++,i++)
- {
- gpt->Val = EMPTY;
- gpt->GroupNum = 0;
- }
- goSetHandicap(handicap);
- }
-
-
- /* if any groups have been deleted as a result of the last move, this
- routine will delete the old group numbers from GroupList and
- reassign group numbers. */
- void
- RelabelGroups()
- {
- unsigned short i, j, x, y;
-
- for (i = 0; i < DeletedGroupCount; i++)
- {
- /* Relabel all higher groups */
- ForeachPoint(y,x)
- if (goboard[x][y].GroupNum > DeletedGroups[i])
- goboard[x][y].GroupNum--;
- /* Move the groups down */
- for (y = DeletedGroups[i]; y < GroupCount; y++)
- GroupList[y] = GroupList[y+1];
- /* fix the group numbers stored in the deleted list */
- for (j = i+1; j < DeletedGroupCount; j++)
- if (DeletedGroups[j] > DeletedGroups[i])
- DeletedGroups[j]--;
- GroupCount--;
- }
- }
-
- /* Returns liberty count for x, y intersection. Sets marked to true
- for each liberty */
- short
- CountAndMarkLibs( x, y)
- short x, y;
- {
- short tx,ty,i;
- short cnt = 0;
-
-
- for (i=0;i<4;i++)
- {
- tx = x + xVec[i];
- ty = y + yVec[i];
- if (LegalPoint(tx,ty) && goboard[tx][ty].Val == EMPTY
- && goboard[tx][ty].marked == FALSE)
- {
- cnt++;
- goboard[tx][ty].marked = TRUE;
- }
- }
- return cnt;
- }
-
- /* Determine the number of liberties for a group given the group code
- num */
- void
- CountLiberties( code)
- short code;
- {
- short x, y, libcnt = 0;
-
- ForeachPoint(y,x)
- if (goboard[x][y].GroupNum == code)
- libcnt += CountAndMarkLibs( x, y);
- EraseMarks();
- GroupList[code].liberties = libcnt;
- }
-
- void
- CheckForEye( x, y, groups, cnt, recheck)
- short x, y, groups[4], cnt, *recheck;
- {
- short i;
-
- for (i = 0; i < (cnt-1); i++)
- if (groups[i] != groups[i+1])
- {
- /* Mark liberty for false eye check */
- goboard[x][y].marked = TRUE;
- (*recheck)++;
- return;
- }
- /* It is an eye */
- GroupList[groups[i]].eyes += 1;
- }
-
- /* Set the eye count for the groups */
- void CountEyes()
- {
- short i, x, y,
- wgroups[4], bgroups[4], wcnt, bcnt, max, cnt, recheck = 0, eye;
-
- for (i = 1; i <= GroupCount; i++)
- GroupList[i].eyes = 0;
-
- ForeachPoint(y,x)
- {
- if (goboard[x][y].Val != EMPTY)
- continue;
- cnt = Connect(WHITE,x,y,wgroups,&wcnt,bgroups,&bcnt);
- max = Maxlibs( x, y);
- if (cnt == max && wcnt == 1 && bcnt == 0)
- GroupList[wgroups[0]].eyes++;
- else if (cnt == max && bcnt == 1 && wcnt == 0)
- GroupList[bgroups[0]].eyes++;
- else if (cnt == max && ( bcnt == 0 || wcnt == 0 ))
- {
- goboard[x][y].marked = TRUE;
- recheck++;
- }
- }
-
- /*-- Now recheck marked liberties to see if two or more one eye --*/
- /*-- groups contribute to a false eye */
- if (recheck == 0)
- return;
-
- ForeachPoint(y,x)
- if (goboard[x][y].marked)
- {
- recheck--;
- goboard[x][y].marked = FALSE;
- Connect( WHITE, x, y, wgroups, &wcnt, bgroups, &bcnt);
- /* If all the groups have at least one eye then all the
- groups are safe from capture because of the common
- liberty at x, y */
- eye = TRUE;
- for (i = 0; i < wcnt; i++)
- if (GroupList[wgroups[i]].eyes == 0)
- eye = FALSE;
- if (eye)
- for (i = 0; i < wcnt; i++)
- GroupList[wgroups[i]].eyes++;
- for (i = 0; i < bcnt; i++)
- if (GroupList[bgroups[i]].eyes == 0)
- eye = FALSE;
- if (eye)
- for (i = 0; i < bcnt; i++)
- GroupList[bgroups[i]].eyes++;
- if (recheck == 0)
- return;
- }
- }
-
-
- short foo[19][19];
-
- /*----------------------------------------------------------------
- -- CountUp() --
- -- Count up final scores at the end of the game. --
- ----------------------------------------------------------------*/
- CountUp()
- {
- short x,y;
- short CountFromPoint();
- short vv;
- int btotal,wtotal;
- char buff[512];
-
-
- blackTerritory = whiteTerritory = 0;
- ForeachPoint(y,x)
- {
- goboard[x][y].marked = FALSE;
- foo[x][y] = CNT_UNDECIDED;
- }
- ForeachPoint(y,x)
- if (goboard[x][y].Val==EMPTY && foo[x][y]==CNT_UNDECIDED)
- {
- FillPoints(x,y,CountFromPoint(x,y));
- }
-
- wtotal = whiteTerritory + blackPrisoners;
- btotal = blackTerritory + whitePrisoners;
- sprintf(buff,"White : %3d territory + %3d prisoners = %d\n\
- Black : %3d territory + %3d prisoners = %d\n\n%s.",
- whiteTerritory,blackPrisoners,wtotal,
- blackTerritory,whitePrisoners,btotal,
- (btotal>wtotal?"Black wins":(wtotal>btotal?"White wins":
- "A draw")));
- XtVaSetValues(message,XtNstring,buff,0);
- }
-
- FillPoints(x,y,val)
- short x,y,val;
- {
- int i;
- short tx,ty;
-
-
- if ((foo[x][y] = val) == CNT_BLACK_TERR)
- blackTerritory++;
- else if (val == CNT_WHITE_TERR)
- whiteTerritory++;
- for (i=0;i<4;i++)
- {
- tx = x + xVec[i];
- ty = y + yVec[i];
- if (!LegalPoint(tx,ty))
- continue;
- if (goboard[tx][ty].Val==EMPTY && foo[tx][ty]==CNT_UNDECIDED)
- FillPoints(tx,ty,val);
- }
- }
-
- short
- CountFromPoint(x,y)
- short x,y;
- {
- int i;
- short tx,ty;
- short blkcnt=0,whtcnt=0;
- short baz;
-
-
- goboard[x][y].marked = TRUE;
- for (i=0;i<4;i++)
- {
- tx = x + xVec[i];
- ty = y + yVec[i];
- if (!LegalPoint(tx,ty))
- continue;
- if (goboard[tx][ty].Val == BLACK)
- blkcnt++;
- else if (goboard[tx][ty].Val == WHITE)
- whtcnt++;
- else
- {
- if (goboard[tx][ty].marked)
- continue;
- baz = CountFromPoint(tx,ty);
- if (baz == CNT_NOONE)
- return CNT_NOONE;
- else if (baz == CNT_BLACK_TERR)
- blkcnt++;
- else if (baz == CNT_WHITE_TERR)
- whtcnt++;
- }
- if (blkcnt && whtcnt)
- return CNT_NOONE;
- }
- if (blkcnt && !whtcnt)
- return CNT_BLACK_TERR;
- else if (whtcnt && !blkcnt)
- return CNT_WHITE_TERR;
- else
- return CNT_UNDECIDED;
- }
- SHAR_EOF
- fi
- if test -f 'amigo.h'
- then
- echo shar: "will not over-write existing file 'amigo.h'"
- else
- cat << \SHAR_EOF > 'amigo.h'
- /*=========================================================================
- === ===
- === FILE amigo.h ===
- === ===
- === CONTENTS prototypes for the various AmiGo routines. ===
- === added by neilb ===
- === ===
- =========================================================================*/
-
- #ifndef __amigo_h
- #define __amigo_h
-
- #include "go.h"
-
- #ifdef __STDC__
- #define PROTO(fp) fp
- #else
- #define PROTO(fp) ()
- #endif
-
-
- /* From goplayer.c */
-
-
- /* Procedures from amigo.c */
-
- short Connect PROTO((enum bVal, short, short, short[4], short[4], short *, short * ));
- short Maxlibs PROTO((short, short));
- short Suicide PROTO((enum bVal, short, short));
- short StoneLibs PROTO((short, short));
- void EraseMarks PROTO(());
- short GoPlaceStone PROTO((enum bVal, short, short));
- void GoRemoveStone PROTO((short, short));
- void MergeGroups PROTO((short, short));
- void DeleteGroup PROTO((short));
- void ReEvalGroups PROTO((enum bVal, short, short, short));
- void GroupCapture PROTO((short));
- void FixLibs PROTO((enum bVal, short, short, short));
- void main PROTO(());
- void goRestart PROTO(());
- void RelabelGroups PROTO(());
- short CountAndMarkLibs PROTO((short, short));
- void CountLiberties PROTO((short));
- void CheckForEye PROTO((short, short, short[4], short, short *));
- void CountEyes PROTO(());
- void printGroupReport PROTO((short, short));
-
-
- /* killable.c */
-
- int tryPlay PROTO(( short, short, short ));
- int sSpanGroup PROTO(( short, short, sPointList * ));
- int spanGroup PROTO(( short, short, pointList *));
- int pause PROTO(());
-
- int genState PROTO(());
- int initGPUtils PROTO(());
- int genBord PROTO((enum bVal));
-
- short genMove PROTO(( enum bVal, short *, short * ));
- short checkPos PROTO(( short, short, short ));
- short takeCorner PROTO(( short *, short * ));
- short extend PROTO(( short *, short * ));
- short noNbrs PROTO(( short, short ));
- short extend2 PROTO(( short *, short * ));
- short lookForSave PROTO(( short *, short * ));
- short lookForSaveN PROTO(( short *, short * ));
- short lookForKill PROTO(( short *, short * ));
- short doubleAtari PROTO(( short *, short * ));
- short lookForAttack PROTO(( short *, short * ));
- short threaten PROTO(( short *, short * ));
- short connectCut PROTO(( short *, short * ));
- short heCanCut PROTO(( short, short ));
- short safeMove PROTO(( short, short ));
- short extendWall PROTO(( short *, short * ));
- short findAttack2 PROTO(( short *, short * ));
- short blockCut PROTO(( short *, short * ));
- short cutHim PROTO(( short *, short * ));
- short atariAnyway PROTO(( short *, short * ));
- short underCut PROTO(( short *, short * ));
- short dropToEdge PROTO(( short *, short * ));
- short pushWall PROTO(( short *, short * ));
- short reduceHisLiberties PROTO(( short *, short * ));
- short dropToEdge2 PROTO(( short *, short * ));
-
- void removestone PROTO((short, short));
- void placestone PROTO((enum bVal, short, short));
-
- /* goplayutils.c */
-
- short saveable PROTO((short, short, short *, short *));
- short killable PROTO((short, short, short *, short *));
- int initBoolBoard PROTO((boolBoard));
- int intersectPlist PROTO((pointList *, pointList *, pointList *));
- int initArray PROTO((intBoard));
- int initState PROTO(());
- int copyArray PROTO((intBoard, intBoard));
- int stake PROTO(());
- int spread PROTO(());
- int respreicen PROTO(());
- int tryPlay PROTO((short, short, short));
- int saveState PROTO(());
- int restoreState PROTO(());
- short tencen PROTO((short, short));
- int genConnects PROTO(());
- int sortLibs PROTO(());
-
-
- /*-- from xinterface.c --*/
-
- void intrMoveReport PROTO((enum bVal,char *,char *));
- void intrPrisonerReport PROTO(( short, short ));
-
-
- #endif
- SHAR_EOF
- fi
- if test -f 'blackstone.bm'
- then
- echo shar: "will not over-write existing file 'blackstone.bm'"
- else
- cat << \SHAR_EOF > 'blackstone.bm'
- #define blackstone_width 16
- #define blackstone_height 16
- #define blackstone_x_hot 7
- #define blackstone_y_hot 8
- static char blackstone_bits[] = {
- 0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0xfe, 0x77, 0xfe, 0x7b,
- 0xfc, 0x3c, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
- SHAR_EOF
- fi
- if test -f 'check16.xbm'
- then
- echo shar: "will not over-write existing file 'check16.xbm'"
- else
- cat << \SHAR_EOF > 'check16.xbm'
- #define check16_width 16
- #define check16_height 16
- static char check16_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c,
- 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x18, 0x01, 0xb0, 0x01,
- 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00};
- SHAR_EOF
- fi
- if test -f 'go.h'
- then
- echo shar: "will not over-write existing file 'go.h'"
- else
- cat << \SHAR_EOF > 'go.h'
- /* AmiGo Include */
- /* MSG types for getinput() */
-
- #ifndef __go_h
- #define __go_h
-
-
- #define INTERSECTIONMSG 1 /* User buttoned an intersection */
- #define QUITMSG 2 /* User buttoned QUIT icon */
- #define PLAYMSG 3
- #define RESTARTMSG 4
- #define PASSMSG 5
-
- #define TRUE 1
- #define FALSE 0
-
- #define MAXGROUPS 100
-
- #define PLACED 0
- #define REMOVED 1
-
- #define numPoints 19
- #define maxPoint numPoints - 1
-
- /*-- definitions used when counting up --*/
-
- #define CNT_UNDECIDED 0
- #define CNT_BLACK_TERR 1
- #define CNT_WHITE_TERR 2
- #define CNT_NOONE 3
-
- /*-- macro functions --*/
-
- #define LegalPoint(x,y) (x>=0 && x<=18 && y>=0 && y<=18)
- #define ForeachPoint(a,b) for(a=0;a<19;a++) for (b=0;b<19;b++)
-
- enum bVal {BLACK, WHITE, EMPTY};
- typedef enum bVal sType;
- struct Group
- {
- enum bVal color; /* The color of the group */
- short code, /* The code used to mark stones in the group */
- count, /* The number of stones in the group */
- internal, /* The number of internal liberties */
- external, /* The number of external liberties */
- liberties, /* The total number of liberties */
- eyes, /* The number of eyes */
- alive, /* A judgement of how alive this group is */
- territory; /* The territory this group controls */
- };
-
- struct bRec
- {
- enum bVal Val; /* What is at this intersection */
- short xOfs,
- yOfs;
- short mNum;
- short GroupNum; /* What group the stone belongs to */
- short marked; /* TRUE or FALSE */
- };
-
- #endif
- SHAR_EOF
- fi
- if test -f 'goplayer.c'
- then
- echo shar: "will not over-write existing file 'goplayer.c'"
- else
- cat << \SHAR_EOF > 'goplayer.c'
- /* The go player */
- /* Ported from Pascal to C by Todd R. Johnson 4/17/88 */
- /* From the original pascal file:
- Go Move Generator
- Copyright (c) 1983 by Three Rivers Computer Corp.
-
- Written: January 17, 1983 by Stoney Ballard
- Edit History:
- */
-
- #include "go.h"
- #include "amigo.h"
- #include "goplayutils.h"
-
- #define BIGGEST 32767 /* maximum value for short */
-
- /* From go.c */
- extern struct bRec goboard[19][19];
- extern short ko, koX, koY;
-
- /* From goplayutils.c */
- extern intBoard bord;
- extern intBoard ndbord;
- extern intBoard claim;
- extern intBoard legal;
- extern intBoard connectMap;
- extern intBoard threatBord;
- extern short maxGroupID;
- extern short treeLibLim;
- extern short killFlag;
- extern short depthLimit;
- extern short showTrees;
- extern short utilPlayLevel;
- extern groupRec gList[maxGroup];
- extern short sGlist[maxGroup + 1];
- extern pointList pList;
- extern pointList pList1;
- extern pointList plist2;
- extern pointList plist3;
- extern intBoard groupIDs;
- extern intBoard protPoints;
- extern sType mySType;
-
-
- short saveNLibs;
- pointList dapList1, dapList2, dapList3;
- char *playReason;
- short maxPlayLevel = 7;
- short playLevel = 7;
-
- genBord(color)
- enum bVal color;
- {
- short x, y, nomoves = TRUE;
- char mv[8];
-
- maxPlayLevel = 7;
- utilPlayLevel = playLevel;
- mySType = color;
- if (playLevel < 2)
- treeLibLim = 2;
- else
- treeLibLim = 3;
- depthLimit = 100;
- for (y = 0; y <= 18; y++)
- for (x = 0; x <= 18; x++)
- if (goboard[x][y].Val == color)
- {
- bord[x][y] = 1;
- legal[x][y] = FALSE;
- nomoves = FALSE;
- }
- else if (goboard[x][y].Val == EMPTY)
- {
- bord[x][y] = 0;
- legal[x][y] = TRUE;
- }
- else
- {
- bord[x][y] = -1;
- legal[x][y] = FALSE;
- nomoves = FALSE;
- }
- if (ko)
- {
- legal[koX][koY] = FALSE;
- }
-
- if (! nomoves)
- genState();
- else
- initGPUtils();
- }
-
-
- short getMove( x, y )
- short *x, *y;
- {
- if (takeCorner(x, y)) return TRUE;
- if (lookForSave(x, y)) return TRUE;
- if (lookForSaveN(x, y)) return TRUE;
- if (extend(x, y)) return TRUE;
- if (lookForKill(x, y)) return TRUE;
- if (doubleAtari(x, y)) return TRUE;
- if (lookForAttack(x, y)) return TRUE;
- if (threaten(x, y)) return TRUE;
- if (extend2(x, y)) return TRUE;
- if (connectCut(x, y)) return TRUE;
- if (blockCut(x, y)) return TRUE;
- if (cutHim(x, y)) return TRUE;
- if (extendWall(x, y)) return TRUE;
- if (findAttack2(x, y)) return TRUE;
- if (atariAnyway(x, y)) return TRUE;
- if (underCut(x, y)) return TRUE;
- if (dropToEdge(x, y)) return TRUE;
- if (pushWall(x, y)) return TRUE;
- if (reduceHisLiberties(x, y)) return TRUE;
- if (dropToEdge2(x, y)) return TRUE;
- return FALSE;
- }
-
- short genMove( color, x, y )
- enum bVal color;
- short *x, *y;
- {
- if (playLevel > 2)
- saveNLibs = TRUE;
- else
- saveNLibs = FALSE;
- genBord(color);
- if (getMove(x, y))
- return TRUE;
- return FALSE;
- }
-
- short checkPos(x, y, field)
- short x, y, field;
- {
- short ok;
- ok = (((field == 0) && (claim[x][y] == 0)) ||
- ((field > 0) &&
- (claim[x][y] >= 0) && (claim[x][y] <= field)) ||
- ((field < 0) &&
- (claim[x][y] <= 0) && (claim[x][y] >= field))) &&
- (bord[x-1][y] == 0) &&
- (bord[x+1][y] == 0) &&
- (bord[x][y-1] == 0) &&
- (bord[x][y+1] == 0);
- if (ok) return TRUE; else return FALSE;
- }
-
- short takeCorner( x, y )
- short *x, *y;
- {
- short field = -1, i;
- i = 18 - 3;
- playReason = "takeCorner";
- while (field != -4)
- {
- if (field == -1) field = 0;
- else if (field == 0) field = 4;
- else field = -4;
- if (checkPos(2, 3, field)) { *x = 2; *y = 3; return TRUE; }
- if (checkPos(3, 2, field)) { *x = 3; *y = 2; return TRUE; }
- if (checkPos(2, i, field)) { *x = 2; *y = i; return TRUE; }
- if (checkPos(3, i + 1, field)) { *x = 3; *y = i+1; return TRUE; }
- if (checkPos(i, i + 1, field)) { *x = i; *y = i+1; return TRUE; }
- if (checkPos(i + 1, i, field)) { *x = i+1; *y = i; return TRUE; }
- if (checkPos(i, 2, field)) { *x = i; *y = 2; return TRUE; }
- if (checkPos(i + 1, 3, field)) { *x = i+1; *y = 3; return TRUE; }
- if (checkPos(2, 4, field)) { *x = 2; *y = 4; return TRUE; }
- if (checkPos(4, 2, field)) { *x = 4; *y = 2; return TRUE; }
- if (checkPos(2, i - 1, field)) { *x = 2; *y = i-1; return TRUE; }
- if (checkPos(4, i + 1, field)) { *x = 4; *y = i+1; return TRUE; }
- if (checkPos(i - 1, i + 1, field)) { *x = i-1; *y = i+1; return TRUE; }
- if (checkPos(i + 1, i - 1, field)) { *x = i+1; *y = i-1; return TRUE; }
- if (checkPos(i + 1, 4, field)) { *x = i+1; *y = 4; return TRUE; }
- if (checkPos(i - 1, 2, field)) { *x = i-1; *y = 2; return TRUE; }
- }
- return FALSE;
- }
-
- printBoard(brd, name)
- intBoard brd;
- char *name;
- {
- short x, y;
- printf( "%s\n", name );
- for (y = 0; y <= 18; y++)
- {
- for (x = 0; x <= 18; x++)
- printf("%d ", brd[x][y]);
- printf("\n");
- }
- }
-
- short noNbrs( x, y )
- short x, y;
- {
- if (x > 0 && bord[x-1][y] != 0) return FALSE;
- if (x < 18 && bord[x+1][y] != 0) return FALSE;
- if (y > 0 && bord[x][y-1] != 0) return FALSE;
- if (y < 18 && bord[x][y+1] != 0) return FALSE;
- return TRUE;
- }
-
- short extend(x, y)
- short *x, *y;
- {
- short i;
- playReason = "extend";
- for (i = 2; i <= 18-2; i++)
- if (claim[2][i] == 0 && noNbrs( 2, i ))
- {
- *x = 2;
- *y = i;
- return TRUE;
- }
- for (i = 2; i <= 18-2; i++)
- if (claim[i][18-2] == 0 && noNbrs( 2, i ))
- {
- *x = i;
- *y = 18-2;
- return TRUE;
- }
- for (i = 18-2; i >= 2; i--)
- if (claim[18-2][i] == 0 && noNbrs( 18-2, i ))
- {
- *x = 18-2;
- *y = i;
- return TRUE;
- }
- for (i = 18-2; i >= 2; i--)
- if (claim[i][2] == 0 && noNbrs( i, 2 ))
- {
- *x = i;
- *y = 2;
- return TRUE;
- }
- return FALSE;
- }
-
- short extend2( x, y )
- short *x, *y;
- {
- short i, lowest = BIGGEST, value;
- playReason = "extend2";
- for (i = 3; i <= 18-3; i++)
- if (legal[2][i]) /* if there is nobody there */
- {
- value = claim[2][i]; /* get influence */
- if ((value < 7) && /* a reasonable hole in my wall */
- (value > -5) && /* or a reasonable gap in his */
- (bord[2][i + 1] == 0) && /* not in contact with any stones */
- (bord[2][i - 1] == 0))
- if (value < lowest)
- {
- lowest = value; /* lowest gets the smallest value */
- *x = 2; /* that was seen along all the 3-lines */
- *y = i; /* x and y save that location */
- }
- }
- for (i = 3; i <= 18-3; i++)
- if (legal[i][2])
- {
- value = claim[i][2];
- if ((value < 7) &&
- (value > -5) &&
- (bord[i + 1][2] == 0) &&
- (bord[i - 1][2] == 0))
- if (value < lowest)
- {
- lowest = value;
- *x = i;
- *y = 2;
- }
- }
- for (i = 18-3; i >= 3; i--)
- if (legal[18 - 2][i])
- {
- value = claim[18 - 2][i];
- if ((value < 7) &&
- (value > -5) &&
- (bord[18 - 2][i + 1] == 0) &&
- (bord[18 - 2][i - 1] == 0))
- if (value < lowest)
- {
- lowest = value;
- *x = 18 - 2;
- *y = i;
- }
- }
- for (i = 3; i <= 18-3; i++)
- if (legal[i][18 - 2])
- {
- value = claim[i][18 - 2];
- if ((value < 7) &&
- (value > -5) &&
- (bord[i + 1][18 - 2] == 0) &&
- (bord[i - 1][18 - 2] == 0))
- if (value < lowest)
- {
- lowest = value;
- *x = i;
- *y = 18 - 2;
- }
- }
- if (lowest == BIGGEST) return FALSE;
- return TRUE;
- }
-
- /*
- check to see if I can save anything in atari
- */
- short lookForSave(x, y)
- short *x, *y;
- { /* lookForSave */
- short i;
- playReason = "lookForSave";
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((gList[i].libC == 1) &&
- (ndbord[gList[i].lx][gList[i].ly] == 1))
- if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */
- return TRUE;
- return FALSE;
- } /* lookForSave */
-
- /*
- check to see if I can save anything with n libs
- */
- short lookForSaveN(x, y)
- short *x, *y;
- { /* lookForSaveN */
- short i;
- if (saveNLibs)
- {
- playReason = "lookForSaveN";
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((gList[i].libC > 1) &&
- (gList[i].libC <= treeLibLim) &&
- (ndbord[gList[i].lx][gList[i].ly] == 1))
- {
- if (killable(gList[i].lx, gList[i].ly, x, y))
- if (saveable(gList[i].lx, gList[i].ly, x, y)) /* see if I can save it */
- return TRUE;
- }
- }
- return FALSE;
- } /* lookForSaveN */
-
-
- /*----------------------------------------------------------------
- -- lookForKill() --
- -- check to see if I can kill anything. --
- ----------------------------------------------------------------*/
- short
- lookForKill(x, y)
- short *x, *y;
- {
- short i;
- char mv[8];
-
- playReason = "lookForKill";
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((gList[i].libC == 1) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1))
- { /* we found a live enemy group with one liberty */
- /* find the liberty */
- spanGroup(gList[i].lx, gList[i].ly, &pList);
- *x = pList.p[1].px;
- *y = pList.p[1].py;
- if (legal[*x][*y])
- {
- return TRUE;
- }
- }
- return FALSE;
- }
-
- short doubleAtari(x, y)
- short *x, *y;
- { /* doubleAtari */
- short i, j;
- playReason = "doubleAtari";
- for (i = 1; i <= maxGroupID - 1; i++)
- if ((gList[i].libC == 2) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1)) /* found an atariable group of his */
- {
- spanGroup(gList[i].lx, gList[i].ly, &dapList1);
- for (j = i + 1; j <= maxGroupID; j++)
- if ((gList[j].libC == 2) &&
- (ndbord[gList[j].lx][gList[j].ly] == -1))
- {
- spanGroup(gList[j].lx, gList[j].ly, &dapList2);
- intersectPlist(&dapList1, &dapList2, &dapList3);
- if (dapList3.indx > 0)
- if (legal[dapList3.p[1].px][dapList3.p[1].py])
- {
- tryPlay(dapList3.p[1].px, dapList3.p[1].py, 1);
- if (gList[groupIDs[dapList3.p[1].px][
- dapList3.p[1].py]].libC > 1)
- {
- *x = dapList3.p[1].px;
- *y = dapList3.p[1].py;
- restoreState();
- return TRUE;
- }
- restoreState();
- }
- }
- }
- return FALSE;
- } /* doubleAtari */
-
- short lookForAttack(x, y)
- short *x, *y;
- { /* lookForAttack */
- short tx, ty, i;
- playReason = "lookForAttack";
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((! gList[i].isLive) &&
- (gList[i].libC > 1) &&
- (gList[i].libC <= (treeLibLim + 1)) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1))
- {
- if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */
- {
- *x = tx; /* yep - do so */
- *y = ty;
- return TRUE;
- }
- }
- return FALSE;
- } /* lookForAttack */
-
- /*
- Plays a move that requires a response on the opponent's part
- */
- short threaten(x, y)
- short *x, *y;
- { /* threaten */
- short i, j, gx, gy, tNum;
- playReason = "threaten";
- initArray(threatBord);
- for (i = 1; i <= maxGroupID; i++)
- if ((! gList[i].isLive) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1))
- {
- spanGroup(gList[i].lx, gList[i].ly, &pList);
- for (j = 1; j <= pList.indx; j++)
- if (legal[pList.p[j].px][pList.p[j].py])
- {
- tryPlay(pList.p[j].px, pList.p[j].py, 1);
- if (gList[groupIDs[pList.p[j].px][pList.p[j].py]].libC > 1)
- if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
- threatBord[pList.p[j].px][pList.p[j].py] += 1;
- restoreState();
- }
- }
- tNum = 0;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if ((threatBord[i][j] > tNum) &&
- ((threatBord[i][j] > 1) ||
- (connectMap[i][j] > 0)))
- {
- tNum = threatBord[i][j];
- *x = i;
- *y = j;
- }
- if (tNum > 0) return TRUE;
- else return FALSE;
- } /* threaten */
-
- /*
- connects against enemy cuts
- */
- short connectCut(x, y)
- short *x, *y;
- { /* connectCut */
- short i, j, nap, gid, infl;
- playReason = "connectCut";
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (legal[i][j] &&
- (protPoints[i][j] == 0)) /* not a protected point */
- {
- nap = 0; /* how many of my stones am I adjacent to? */
- if ((i > 0) && (bord[i - 1][j] == 1))
- {
- nap = nap + 1;
- pList.p[nap].px = i - 1;
- pList.p[nap].py = j;
- }
- if ((j > 0) && (bord[i][j - 1] == 1))
- {
- nap = nap + 1;
- pList.p[nap].px = i;
- pList.p[nap].py = j - 1;
- }
- if ((i < maxPoint) && (bord[i + 1][j] == 1))
- {
- nap = nap + 1;
- pList.p[nap].px = i + 1;
- pList.p[nap].py = j;
- }
- if ((j < maxPoint) && (bord[i][j + 1] == 1))
- {
- nap = nap + 1;
- pList.p[nap].px = i;
- pList.p[nap].py = j + 1;
- }
- if (nap == 1) /* possible knight's || 2-point extention */
- {
- gid = groupIDs[pList.p[1].px][pList.p[1].py];
- if ((i > 0) && (i < maxPoint) &&
- (ndbord[i - 1][j] == 1) &&
- (ndbord[i + 1][j] == 0)) /* contact on left */
- {
- if (((j > 0) && (ndbord[i][j - 1] == -1) &&
- (ndbord[i + 1][j - 1] == 1) &&
- (gid != groupIDs[i + 1][j - 1])) ||
- ((j < maxPoint) && (ndbord[i][j + 1] == -1) &&
- (ndbord[i + 1][j + 1] == 1) &&
- (gid != groupIDs[i + 1][j + 1])) ||
- ((((j > 0) && (ndbord[i][j - 1] == -1)) ||
- ((j < maxPoint) && (ndbord[i][j + 1] == -1))) &&
- (i < (maxPoint - 1)) &&
- (ndbord[i + 2][j] == 1) &&
- (gid != groupIDs[i + 2][j])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((i < maxPoint) && (i > 0) &&
- (ndbord[i + 1][j] == 1) &&
- (ndbord[i - 1][j] == 0)) /* r */
- {
- if (((j > 0) && (ndbord[i][j - 1] == -1) &&
- (ndbord[i - 1][j - 1] == 1) &&
- (gid != groupIDs[i - 1][j - 1])) ||
- ((j < maxPoint) && (ndbord[i][j + 1] == -1) &&
- (ndbord[i - 1][j + 1] == 1) &&
- (gid != groupIDs[i - 1][j + 1])) ||
- ((((j > 0) && (ndbord[i][j - 1] == -1)) ||
- ((j < maxPoint) && (ndbord[i][j + 1] == -1))) &&
- (i > 1) &&
- (ndbord[i - 2][j] == 1) &&
- (gid != groupIDs[i - 2][j])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((j > 0) && (j < maxPoint) &&
- (ndbord[i][j - 1] == 1) &&
- (ndbord[i][j + 1] == 0)) /* top */
- {
- if (((i > 0) && (ndbord[i - 1][j] == -1) &&
- (ndbord[i - 1][j + 1] == 1) &&
- (gid != groupIDs[i - 1][j + 1])) ||
- ((i < maxPoint) && (ndbord[i + 1][j] == -1) &&
- (ndbord[i + 1][j + 1] == 1) &&
- (gid != groupIDs[i + 1][j + 1])) ||
- ((((i > 0) && (ndbord[i - 1][j] == -1)) ||
- ((i < maxPoint) && (ndbord[i + 1][j] == -1))) &&
- (j < (maxPoint - 1)) &&
- (ndbord[i][j + 2] == 1) &&
- (gid != groupIDs[i][j + 2])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((j > 0) && (j < maxPoint) &&
- (ndbord[i][j + 1] == 1) &&
- (ndbord[i][j - 1] == 0)) /* bottom */
- {
- if (((i > 0) && (ndbord[i - 1][j] == -1) &&
- (ndbord[i - 1][j - 1] == 1) &&
- (gid != groupIDs[i - 1][j - 1])) ||
- ((i < maxPoint) && (ndbord[i + 1][j] == -1) &&
- (ndbord[i + 1][j - 1] == 1) &&
- (gid != groupIDs[i + 1][j - 1])) ||
- ((((i > 0) && (ndbord[i - 1][j] == -1)) ||
- ((i < maxPoint) && (ndbord[i + 1][j] == -1))) &&
- (j > 1) &&
- (ndbord[i][j - 2] == 1) &&
- (gid != groupIDs[i][j - 2])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- else if (nap == 2) /* diagonal or 1-point extention */
- {
- if (groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py])
- {
- if ((pList.p[1].px != pList.p[2].px) &&
- (pList.p[1].py != pList.p[2].py)) /* diag */
- {
- spanGroup(pList.p[1].px,
- pList.p[1].py, &pList1);
- spanGroup(pList.p[2].px,
- pList.p[2].py, &plist2);
- intersectPlist(&pList1, &plist2, &plist3);
- if (plist3.indx == 1)
- if ((i > 0) && (ndbord[i - 1][j] == -1) ||
- (i < maxPoint) && (ndbord[i + 1][j] == -1) ||
- (j > 0) && (ndbord[i][j - 1] == -1) ||
- (j < maxPoint) && (ndbord[i][j + 1] == -1))
- { /* must make direct connection */
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- else if (heCanCut(i, j))
- { /* protect point if possible */
- infl = 1000;
- if ((i > 0) && legal[i - 1][j] &&
- ((i == 1) || (ndbord[i - 2][j] == 0)) &&
- ((j == 0) || (ndbord[i - 1][j - 1] == 0)) &&
- ((j == maxPoint) ||
- (ndbord[i - 1][j + 1] == 0)))
- if (safeMove(i - 1, j))
- if (claim[i - 1][j] < infl)
- {
- *x = i - 1;
- *y = j;
- infl = claim[i - 1][j];
- }
- if ((j > 0) && legal[i][j - 1] &&
- ((j == 1) || (ndbord[i][j - 2] == 0)) &&
- ((i == 0) || (ndbord[i - 1][j - 1] == 0)) &&
- ((i == maxPoint) ||
- (ndbord[i + 1][j - 1] == 0)))
- if (safeMove(i, j - 1))
- if (claim[i][j - 1] < infl)
- {
- *x = i;
- *y = j - 1;
- infl = claim[i][j - 1];
- }
- if ((i < maxPoint) && legal[i + 1][j] &&
- ((i == (maxPoint - 1)) ||
- (ndbord[i + 2][j] == 0)) &&
- ((j == 0) || (ndbord[i + 1][j - 1] == 0)) &&
- ((j == maxPoint) ||
- (ndbord[i + 1][j + 1] == 0)))
- if (safeMove(i + 1, j))
- if (claim[i + 1][j] < infl)
- {
- *x = i + 1;
- *y = j;
- infl = claim[i + 1][j];
- }
- if ((j < maxPoint) && legal[i][j + 1] &&
- ((j == (maxPoint - 1)) ||
- (ndbord[i][j + 2] == 0)) &&
- ((i == 0) || (ndbord[i - 1][j + 1] == 0)) &&
- ((i == maxPoint) ||
- (ndbord[i + 1][j + 1] == 0)))
- if (safeMove(i, j + 1))
- if (claim[i][j + 1] < infl)
- {
- *x = i;
- *y = j + 1;
- infl = claim[i][j + 1];
- }
- if (infl < 1000)
- return TRUE;
- *x = i; /* direct connection */
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else /* 1-point extension, only protect if threatened */
- {
- if ((i > 0) && (ndbord[i - 1][j] == -1) ||
- (j > 0) && (ndbord[i][j - 1] == -1) ||
- (i < maxPoint) && (ndbord[i + 1][j] == -1) ||
- (j < maxPoint) && (ndbord[i][j + 1] == -1))
- {
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- }
- else if (nap == 3) /* unprotected, but me on 3 sides */
- {
- if ((groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py]) ||
- (groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[3].px][pList.p[3].py]) ||
- (groupIDs[pList.p[3].px][pList.p[3].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py]))
- {
- spanGroup(pList.p[1].px, pList.p[1].py, &pList1);
- spanGroup(pList.p[2].px, pList.p[2].py, &plist2);
- intersectPlist(&pList1, &plist2, &plist3);
- spanGroup(pList.p[3].px, pList.p[3].py, &plist2);
- intersectPlist(&plist2, &plist3, &pList1);
- if (pList1.indx == 1) /* a common connect point */
- if (heCanCut(i, j))
- if (safeMove(i, j))
- {
- *x = i;
- *y = j;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- } /* connectCut */
-
- short heCanCut(x, y)
- short x, y;
- { /* heCanCut */
- short gx, gy, result;
- if (playLevel > 3)
- {
- tryPlay(x, y, -1); /* try his cut */
- result = ! killable(x, y, &gx, &gy);
- restoreState();
- return result;
- }
- else
- return FALSE;
- } /* heCanCut */
-
- /*
- Checks out a move.
- If my stone is not killable then true.
- */
- short safeMove(x, y)
- short x, y;
- { /* safeMove */
- short gbx, gby, result;
- tryPlay(x, y, 1); /* try playing at point */
- if (killFlag) /* I shouldn't kill if lookForKill didn't */
- result = FALSE;
- else if (gList[groupIDs[x][y]].libC < 2)
- { /* if it is in atari or dead */
- result = FALSE; /* reject it */
- }
- else if (gList[groupIDs[x][y]].libC <= treeLibLim) /* see if killable */
- if (playLevel > 0)
- result = ! killable(x, y, &gbx, &gby);
- else
- result = TRUE;
- else
- result = TRUE;
- restoreState();
- return result;
- } /* safeMove */
-
- /*
- Extends walls in a connected fashion.
- Finds the lowest influence (mine) point that is connected to one
- of my groups.
- Only looks in the center of the board.
- */
- short extendWall(x, y)
- short *x, *y;
- { /* extendWall */
- short infl, i, j;
- playReason = "extendWall";
- *x = iNil;
- *y = iNil;
- infl = 11;
- for (i = 2; i <= maxPoint - 2; i++)
- for (j = 2; j <= maxPoint - 2; j++)
- if (legal[i][j])
- if (connectMap[i][j] > 0)
- if ((claim[i][j] < infl) &&
- (ndbord[i - 1][j] < 1) &&
- (ndbord[i + 1][j] < 1) &&
- (ndbord[i][j - 1] < 1) &&
- (ndbord[i][j + 1] < 1) &&
- ((claim[i - 1][j] < 0) ||
- (claim[i + 1][j] < 0) ||
- (claim[i][j - 1] < 0) ||
- (claim[i][j + 1] < 0)))
- if (safeMove(i, j))
- {
- infl = claim[i][j];
- *x = i;
- *y = j;
- }
- if (*x != iNil) return TRUE;
- return FALSE;
- } /* extendWall */
-
-
- /*
- check to see if I can attack one of his groups
- uses limited depth search so that it can work on larger lib counts
- */
- short findAttack2(x, y)
- short *x, *y;
- { /* findAttack2 */
- short tx, ty, i, otll;
- if (playLevel < 7)
- return FALSE;
- playReason = "findAttack2";
- depthLimit = 8;
- otll = treeLibLim;
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((! gList[i].isLive) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1) &&
- (gList[i].libC > 1))
- {
- treeLibLim = 6;
- if (killable(gList[i].lx, gList[i].ly, &tx, &ty)) /* can we kill it? */
- {
- *x = tx; /* yep - do so */
- *y = ty;
- return TRUE;
- }
- treeLibLim = otll;
- }
- depthLimit = 100;
- return FALSE;
- } /* findAttack2 */
-
-
- /*
- blocks enemy cuts thru 1-point extensions
- */
- short blockCut(x, y)
- short *x, *y;
- { /* blockCut */
- short i, j;
- playReason = "blockCut";
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (legal[i][j])
- {
- if ((i > 0) && (j > 0) && (j < maxPoint))
- {
- if ((ndbord[i - 1][j] == -1) &&
- (ndbord[i - 1][j - 1] == 1) &&
- (ndbord[i - 1][j + 1] == 1) &&
- (groupIDs[i - 1][j - 1] != groupIDs[i - 1][j + 1]))
- {
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if ((i < maxPoint) && (j > 0) && (j < maxPoint))
- {
- if ((ndbord[i + 1][j] == -1) &&
- (ndbord[i + 1][j - 1] == 1) &&
- (ndbord[i + 1][j + 1] == 1) &&
- (groupIDs[i + 1][j - 1] != groupIDs[i + 1][j + 1]))
- {
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if ((j > 0) && (i > 0) && (i < maxPoint))
- {
- if ((ndbord[i][j - 1] == -1) &&
- (ndbord[i - 1][j - 1] == 1) &&
- (ndbord[i + 1][j - 1] == 1) &&
- (groupIDs[i - 1][j - 1] != groupIDs[i + 1][j - 1]))
- {
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if ((j < maxPoint) && (i > 0) && (i < maxPoint))
- {
- if ((ndbord[i][j + 1] == -1) &&
- (ndbord[i - 1][j + 1] == 1) &&
- (ndbord[i + 1][j + 1] == 1) &&
- (groupIDs[i - 1][j + 1] != groupIDs[i + 1][j + 1]))
- {
- *x = i;
- *y = j;
- if (heCanCut(*x, *y))
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- return FALSE;
- } /* blockCut */
-
-
- /*
- cuts the enemy
- */
- short cutHim(x, y)
- short *x, *y;
- { /* cutHim */
- short i, j, nap, gid;
- playReason = "cutHim";
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (legal[i][j])
- {
- nap = 0; /* how many of his stones am I adjacent to? */
- if ((i > 0) && (ndbord[i - 1][j] == -1))
- {
- nap = nap + 1;
- pList.p[nap].px = i - 1;
- pList.p[nap].py = j;
- }
- if ((j > 0) && (ndbord[i][j - 1] == -1))
- {
- nap = nap + 1;
- pList.p[nap].px = i;
- pList.p[nap].py = j - 1;
- }
- if ((i < maxPoint) && (ndbord[i + 1][j] == -1))
- {
- nap = nap + 1;
- pList.p[nap].px = i + 1;
- pList.p[nap].py = j;
- }
- if ((j < maxPoint) && (ndbord[i][j + 1] == -1))
- {
- nap = nap + 1;
- pList.p[nap].px = i;
- pList.p[nap].py = j + 1;
- }
- if (nap == 1) /* possible knight's or 2-point extention */
- {
- gid = groupIDs[pList.p[1].px][pList.p[1].py];
- if ((i > 0) && (i < maxPoint) &&
- (ndbord[i - 1][j] == -1) &&
- (connectMap[i][j] > 0)) /* contact on left */
- {
- if (((j > 0) &&
- (ndbord[i + 1][j - 1] == -1) &&
- (gid != groupIDs[i + 1][j - 1])) ||
- ((j < maxPoint) &&
- (ndbord[i + 1][j + 1] == -1) &&
- (gid != groupIDs[i + 1][j + 1])) ||
- ((i < (maxPoint - 1)) &&
- (ndbord[i + 1][j] == 0) &&
- (ndbord[i + 2][j] == -1) &&
- (gid != groupIDs[i + 2][j])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((i < maxPoint) && (i > 0) &&
- (ndbord[i + 1][j] == -1) &&
- (connectMap[i][j] > 0)) /* r */
- {
- if (((j > 0) &&
- (ndbord[i - 1][j - 1] == -1) &&
- (gid != groupIDs[i - 1][j - 1])) ||
- ((j < maxPoint) &&
- (ndbord[i - 1][j + 1] == -1) &&
- (gid != groupIDs[i - 1][j + 1])) ||
- ((i > 1) &&
- (ndbord[i - 1][j] == 0) &&
- (ndbord[i - 2][j] == -1) &&
- (gid != groupIDs[i - 2][j])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((j > 0) && (j < maxPoint) &&
- (ndbord[i][j - 1] == -1) &&
- (connectMap[i][j] > 0)) /* top */
- {
- if (((i > 0) &&
- (ndbord[i - 1][j + 1] == -1) &&
- (gid != groupIDs[i - 1][j + 1])) ||
- ((i < maxPoint) &&
- (ndbord[i + 1][j + 1] == -1) &&
- (gid != groupIDs[i + 1][j + 1])) ||
- ((j < (maxPoint - 1)) &&
- (ndbord[i][j + 1] == 0) &&
- (ndbord[i][j + 2] == -1) &&
- (gid != groupIDs[i][j + 2])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else if ((j > 0) && (j < maxPoint) &&
- (ndbord[i][j + 1] == -1) &&
- (connectMap[i][j] > 0)) /* bottom */
- {
- if (((i > 0) &&
- (ndbord[i - 1][j - 1] == -1) &&
- (gid != groupIDs[i - 1][j - 1])) ||
- ((i < maxPoint) &&
- (ndbord[i + 1][j - 1] == -1) &&
- (gid != groupIDs[i + 1][j - 1])) ||
- ((j > 1) &&
- (ndbord[i][j - 1] == 0) &&
- (ndbord[i][j - 2] == -1) &&
- (gid != groupIDs[i][j - 2])))
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- else if (nap == 2) /* diagonal or 1-point extention */
- {
- if (groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py])
- {
- if ((pList.p[1].px != pList.p[2].px) &&
- (pList.p[1].py != pList.p[2].py)) /* diag */
- {
- spanGroup(pList.p[1].px,
- pList.p[1].py, &pList1);
- spanGroup(pList.p[2].px,
- pList.p[2].py, &plist2);
- intersectPlist(&pList1, &plist2, &plist3);
- if (plist3.indx == 1)
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- else /* 1-point extension, only cut if connected */
- {
- if (connectMap[i][j] > 0)
- {
- *x = i;
- *y = j;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- }
- else if (nap == 3) /* unprotected, but him on 3 sides */
- {
- if ((groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py]) ||
- (groupIDs[pList.p[1].px][pList.p[1].py] !=
- groupIDs[pList.p[3].px][pList.p[3].py]) ||
- (groupIDs[pList.p[3].px][pList.p[3].py] !=
- groupIDs[pList.p[2].px][pList.p[2].py]))
- {
- spanGroup(pList.p[1].px, pList.p[1].py, &pList1);
- spanGroup(pList.p[2].px, pList.p[2].py, &plist2);
- intersectPlist(&pList1, &plist2, &plist3);
- spanGroup(pList.p[3].px, pList.p[3].py, &plist2);
- intersectPlist(&plist2, &plist3, &pList1);
- if (pList1.indx == 1) /* a common connect point */
- if (safeMove(i, j))
- {
- *x = i;
- *y = j;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- } /* cutHim */
-
-
- /*
- ataris a group just for the hell of it
- */
- short atariAnyway(x, y)
- short *x, *y;
- { /* atariAnyway */
- short i;
- playReason = "atariAnyway";
- for (i = 1; i <= maxGroupID; i++) /* scan the group list */
- if ((gList[i].libC == 2) &&
- (ndbord[gList[i].lx][gList[i].ly] == -1))
- {
- spanGroup(gList[i].lx, gList[i].ly, &pList);
- if (legal[pList.p[1].px][pList.p[1].py] &&
- ((connectMap[pList.p[1].px][pList.p[1].py] > 0) ||
- ((pList.p[1].px > 0) &&
- (connectMap[pList.p[1].px - 1][pList.p[1].py] > 0)) ||
- ((pList.p[1].px < maxPoint) &&
- (connectMap[pList.p[1].px + 1][pList.p[1].py] > 0)) ||
- ((pList.p[1].py > 0) &&
- (connectMap[pList.p[1].px][pList.p[1].py - 1] > 0)) ||
- ((pList.p[1].py < maxPoint) &&
- (connectMap[pList.p[1].px][pList.p[1].py + 1] > 0))))
- if (safeMove(pList.p[1].px, pList.p[1].py))
- {
- *x = pList.p[1].px;
- *y = pList.p[1].py;
- return TRUE;
- }
- if (legal[pList.p[2].px][pList.p[2].py] &&
- ((connectMap[pList.p[2].px][pList.p[2].py] > 0) ||
- ((pList.p[2].px > 0) &&
- (connectMap[pList.p[2].px - 1][pList.p[2].py] > 0)) ||
- ((pList.p[2].px < maxPoint) &&
- (connectMap[pList.p[2].px + 1][pList.p[2].py] > 0)) ||
- ((pList.p[2].py > 0) &&
- (connectMap[pList.p[2].px][pList.p[2].py - 1] > 0)) ||
- ((pList.p[2].py < maxPoint) &&
- (connectMap[pList.p[2].px][pList.p[2].py + 1] > 0))))
- if (safeMove(pList.p[2].px, pList.p[2].py))
- {
- *x = pList.p[2].px;
- *y = pList.p[2].py;
- return TRUE;
- }
- }
- return FALSE;
- } /* atariAnyway */
-
-
- /*
- undercuts his groups
- */
- short underCut(x, y)
- short *x, *y;
- { /* underCut */
- short i, j;
- playReason = "underCut";
- for (i = 1; i <= maxPoint - 1; i++)
- {
- if (legal[0][i])
- {
- if (ndbord[1][i] == -1)
- if (safeMove(0, i))
- {
- *x = 0;
- *y = i;
- return TRUE;
- }
- }
- if (legal[maxPoint][i])
- {
- if (ndbord[maxPoint - 1][i] == -1)
- if (safeMove(maxPoint, i))
- {
- *x = maxPoint;
- *y = i;
- return TRUE;
- }
- }
- if (legal[i][0])
- {
- if (ndbord[i][1] == -1)
- if (safeMove(i, 0))
- {
- *x = i;
- *y = 0;
- return TRUE;
- }
- }
- if (legal[i][maxPoint])
- {
- if (ndbord[i][maxPoint - 1] == -1)
- if (safeMove(i, maxPoint))
- {
- *x = i;
- *y = maxPoint;
- return TRUE;
- }
- }
- }
- return FALSE;
- } /* underCut */
-
- /*
- drops to the edge of the board if threatened
- */
- short dropToEdge(x, y)
- short *x, *y;
- { /* dropToEdge */
- short i;
- playReason = "dropToEdge";
- for (i = 1; i <= maxPoint - 1; i++)
- {
- if (legal[1][i])
- if ((ndbord[2][i] == 1) &&
- (ndbord[0][i] == 0) &&
- (ndbord[1][i - 1] < 1) &&
- (ndbord[1][i + 1] < 1) &&
- ((ndbord[2][i - 1] == -1) ||
- (ndbord[2][i + 1] == -1) ||
- (ndbord[1][i - 1] == -1) ||
- (ndbord[1][i + 1] == -1)))
- {
- *x = 1;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[maxPoint - 1][i])
- if ((ndbord[maxPoint - 2][i] == 1) &&
- (ndbord[maxPoint][i] == 0) &&
- (ndbord[maxPoint - 1][i - 1] < 1) &&
- (ndbord[maxPoint - 1][i + 1] < 1) &&
- ((ndbord[maxPoint - 2][i - 1] == -1) ||
- (ndbord[maxPoint - 2][i + 1] == -1) ||
- (ndbord[maxPoint - 1][i - 1] == -1) ||
- (ndbord[maxPoint - 1][i + 1] == -1)))
- {
- *x = maxPoint - 1;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[i][1])
- if ((ndbord[i][2] == 1) &&
- (ndbord[i][0] == 0) &&
- (ndbord[i - 1][1] < 1) &&
- (ndbord[i + 1][1] < 1) &&
- ((ndbord[i - 1][2] == -1) ||
- (ndbord[i + 1][2] == -1) ||
- (ndbord[i - 1][1] == -1) ||
- (ndbord[i + 1][1] == -1)))
- {
- *x = i;
- *y = 1;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[i][maxPoint - 1])
- if ((ndbord[i][maxPoint - 2] == 1) &&
- (ndbord[i][maxPoint] == 0) &&
- (ndbord[i - 1][maxPoint - 1] < 1) &&
- (ndbord[i + 1][maxPoint - 1] < 1) &&
- ((ndbord[i - 1][maxPoint - 2] == -1) ||
- (ndbord[i + 1][maxPoint - 2] == -1) ||
- (ndbord[i - 1][maxPoint - 1] == -1) ||
- (ndbord[i + 1][maxPoint - 1] == -1)))
- {
- *x = i;
- *y = maxPoint - 1;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[0][i])
- if ((ndbord[1][i] == 1) &&
- (ndbord[0][i - 1] < 1) &&
- (ndbord[0][i + 1] < 1) &&
- (((ndbord[1][i - 1] == -1) &&
- (ndbord[1][i + 1] == -1)) ||
- (ndbord[0][i - 1] == -1) ||
- (ndbord[0][i + 1] == -1)))
- {
- *x = 0;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[maxPoint][i])
- if ((ndbord[maxPoint - 1][i] == 1) &&
- (ndbord[maxPoint][i - 1] < 1) &&
- (ndbord[maxPoint][i + 1] < 1) &&
- (((ndbord[maxPoint - 1][i - 1] == -1) &&
- (ndbord[maxPoint - 1][i + 1] == -1)) ||
- (ndbord[maxPoint][i - 1] == -1) ||
- (ndbord[maxPoint][i + 1] == -1)))
- {
- *x = maxPoint;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[i][0])
- if ((ndbord[i][1] == 1) &&
- (ndbord[i - 1][0] < 1) &&
- (ndbord[i + 1][0] < 1) &&
- (((ndbord[i - 1][1] == -1) &&
- (ndbord[i + 1][1] == -1)) ||
- (ndbord[i - 1][0] == -1) ||
- (ndbord[i + 1][0] == -1)))
- {
- *x = i;
- *y = 0;
- if (safeMove(*x, *y))
- return TRUE;
- }
- if (legal[i][maxPoint])
- if ((ndbord[i][maxPoint - 1] == 1) &&
- (ndbord[i - 1][maxPoint] < 1) &&
- (ndbord[i + 1][maxPoint] < 1) &&
- (((ndbord[i - 1][maxPoint - 1] == -1) &&
- (ndbord[i + 1][maxPoint - 1] == -1)) ||
- (ndbord[i - 1][maxPoint] == -1) ||
- (ndbord[i + 1][maxPoint] == -1)))
- {
- *x = i;
- *y = maxPoint;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- return FALSE;
- } /* dropToEdge */
-
- /*
- Pushes walls in a tightly connected fashion.
- Finds the lowest influence (mine) point that is connected to one
- of my groups.
- */
- short pushWall(x, y)
- short *x, *y;
- { /* pushWall */
- short infl, i, j, na;
- playReason = "pushWall";
- *x = iNil;
- *y = iNil;
- infl = 11;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (legal[i][j])
- if (connectMap[i][j] > 0)
- if ((claim[i][j] < infl) &&
- (((i > 0) && (ndbord[i - 1][j] == 1)) ||
- ((i < maxPoint) && (ndbord[i + 1][j] == 1)) ||
- ((j > 0) && (ndbord[i][j - 1] == 1)) ||
- ((j < maxPoint) && (ndbord[i][j + 1] == 1)) ||
- ((i > 0) && (j > 0) && (ndbord[i - 1][j - 1] == 1)) ||
- ((i < maxPoint) && (j > 0) && (ndbord[i + 1][j - 1] == 1)) ||
- ((i > 0) && (j < maxPoint) && (ndbord[i - 1][j + 1] == 1)) ||
- ((i < maxPoint) && (j < maxPoint) &&
- (ndbord[i + 1][j + 1] == 1))) &&
- (((i > 0) && (claim[i - 1][j] < 0)) ||
- ((i < maxPoint) && (claim[i + 1][j] < 0)) ||
- ((j > 0) && (claim[i][j - 1] < 0)) ||
- ((j < maxPoint) && (claim[i][j + 1] < 0))))
- {
- na = 0;
- if ((i > 0) && (ndbord[i - 1][j] != 0))
- na = na + 1;
- if ((i < maxPoint) && (ndbord[i + 1][j] != 0))
- na = na + 1;
- if ((j > 0) && (ndbord[i][j - 1] != 0))
- na = na + 1;
- if ((j < maxPoint) && (ndbord[i][j + 1] != 0))
- na = na + 1;
- if (na < 3)
- if (safeMove(i, j))
- {
- infl = claim[i][j];
- *x = i;
- *y = j;
- }
- }
- if (*x != iNil) return TRUE;
- return FALSE;
- } /* pushWall */
-
-
- /*
- reduces the liberty count of one of his groups
- */
- short reduceHisLiberties(x, y)
- short *x, *y;
- { /* reduceHisLiberties */
- short i, j;
- playReason = "reduceHisLiberties";
- sortLibs();
- for (i = 1; i <= maxGroupID; i++)
- if ((! gList[sGlist[i]].isLive) &&
- (gList[sGlist[i]].libC > 2) &&
- (ndbord[gList[sGlist[i]].lx][gList[sGlist[i]].ly] == -1))
- {
- spanGroup(gList[sGlist[i]].lx, gList[sGlist[i]].ly, &pList);
- for (j = 1; j <= pList.indx; j++)
- if (legal[pList.p[j].px][pList.p[j].py] &&
- (connectMap[pList.p[j].px][pList.p[j].py] > 0))
- if (safeMove(pList.p[j].px, pList.p[j].py))
- {
- *x = pList.p[j].px;
- *y = pList.p[j].py;
- return TRUE;
- }
- }
- return FALSE;
- } /* reduceHisLiberties */
-
-
- /*
- connects a group to the edge
- */
- short dropToEdge2(x, y)
- short *x, *y;
- { /* dropToEdge2 */
- short i;
- playReason = "dropToEdge2";
- for (i = 1; i <= maxPoint - 1; i++)
- {
- if (legal[i][0])
- {
- if ((ndbord[i][1] == 1) &&
- ((ndbord[i - 1][0] < 1) ||
- (groupIDs[i - 1][0] != groupIDs[i][1])) &&
- ((ndbord[i + 1][0] < 1) ||
- (groupIDs[i + 1][0] != groupIDs[i][1])) &&
- ((ndbord[i - 1][1] == -1) ||
- (ndbord[i + 1][1] == -1)))
- {
- *x = i;
- *y = 0;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if (legal[0][i])
- {
- if ((ndbord[1][i] == 1) &&
- ((ndbord[0][i - 1] < 1) ||
- (groupIDs[0][i - 1] != groupIDs[1][i])) &&
- ((ndbord[0][i + 1] < 1) ||
- (groupIDs[0][i + 1] != groupIDs[1][i])) &&
- ((ndbord[1][i - 1] == -1) ||
- (ndbord[1][i + 1] == -1)))
- {
- *x = 0;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if (legal[i][maxPoint])
- {
- if ((ndbord[i][maxPoint - 1] == 1) &&
- ((ndbord[i - 1][maxPoint] < 1) ||
- (groupIDs[i - 1][maxPoint] != groupIDs[i][maxPoint - 1])) &&
- ((ndbord[i + 1][maxPoint] < 1) ||
- (groupIDs[i + 1][maxPoint] != groupIDs[i][maxPoint - 1])) &&
- ((ndbord[i - 1][maxPoint - 1] == -1) ||
- (ndbord[i + 1][maxPoint - 1] == -1)))
- {
- *x = i;
- *y = maxPoint;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- if (legal[maxPoint][i])
- {
- if ((ndbord[maxPoint - 1][i] == 1) &&
- ((ndbord[maxPoint][i - 1] < 1) ||
- (groupIDs[maxPoint][i - 1] != groupIDs[maxPoint - 1][i])) &&
- ((ndbord[maxPoint][i + 1] < 1) ||
- (groupIDs[maxPoint][i + 1] != groupIDs[maxPoint - 1][i])) &&
- ((ndbord[maxPoint - 1][i - 1] == -1) ||
- (ndbord[maxPoint - 1][i + 1] == -1)))
- {
- *x = maxPoint;
- *y = i;
- if (safeMove(*x, *y))
- return TRUE;
- }
- }
- }
- return FALSE;
- } /* dropToEdge2 */
-
- SHAR_EOF
- fi
- if test -f 'goplayutils.c'
- then
- echo shar: "will not over-write existing file 'goplayutils.c'"
- else
- cat << \SHAR_EOF > 'goplayutils.c'
- /* The go player utilities */
- /* Ported from Pascal to C by Todd R. Johnson */
- /* From the original Pascal file:
- Copyright (c) 1983 by Three Rivers Computer Corp.
-
- Written: January 17, 1983 by Stoney Ballard
- */
-
- #include "goplayutils.h"
- #include "amigo.h"
- #include "go.h"
-
- extern struct bRec goboard[19][19];
-
- intBoard claim, extra, bord, ndbord, sGroups, threatBord,
- groupIDs, connectMap, protPoints;
- boolBoard groupSeen, legal;
- short maxGroupID;
- pointList pList, pList1, plist2, plist3, pPlist;
- intList nlcGroup, aList;
- sgRec sList[401];
- groupRec gList[maxGroup];
- short killFlag,
- numCapt,
- utilPlayLevel,
- treeLibLim;
- sType mySType;
- short showTrees;
- short sGlist[maxGroup+1];
- short depthLimit;
- intBoard markBoard;
- short marker;
-
- short adjInAtari, adj2Libs,
- intersectNum, spanNum, libMark;
- playRec playStack[1025];
- short playMark,
- newGID,
- tryLevel,
- grpMark,
- gMap[maxGroup];
- short dbStop, inGenState;
-
- pause()
- { /* pause */
- /* if (dbStop and ! inGenState)
- {
- while ! tabswitch do;
- repeat
- if (tabYellow)
- dbStop = false;
- until ! tabswitch;
- } */
- } /* pause */
-
- sstone(w, x, y, numb)
- short w, x, y, numb;
- { /* sstone */
- if (w == 1)
- placestone(mySType, x, y);
- else if (mySType == WHITE)
- placestone(BLACK, x, y);
- else
- placestone(WHITE, x, y);
- } /* sstone */
-
- rstone(x, y)
- short x, y;
- { /* rstone */
- removestone(x, y);
- } /* rstone */
-
- initBoolBoard(bb)
- boolBoard bb;
- { /* initBoolBoard */
- short i, j;
- #ifdef DEBUG
- printf( "initBoolBoard\n" );
- #endif
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- bb[i][j] = FALSE;
- } /* initBoolBoard */
-
- sortLibs()
- { /* sortLibs */
- short i, j, t;
- #ifdef DEBUG
- printf( "sortLibs\n" );
- #endif
- for (i = 1; i <= maxGroupID; i++)
- sGlist[i] = i;
- for (i = 1; i < maxGroupID; i++)
- for (j = i + 1; j <= maxGroupID; j++)
- if (gList[sGlist[i]].libC > gList[sGlist[j]].libC)
- {
- t = sGlist[i];
- sGlist[i] = sGlist[j];
- sGlist[j] = t;
- }
- } /* sortLibs */
-
- spanGroupspan(x, y, libs, lookFor)
- short x, y, lookFor;
- pointList *libs;
- { /* span */
- markBoard[x][y] = marker;
- if (bord[x][y] == 0)
- {
- libs->indx = libs->indx + 1;
- libs->p[libs->indx].px = x;
- libs->p[libs->indx].py = y;
- }
- else if (bord[x][y] == lookFor)
- {
- groupSeen[x][y] = TRUE;
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- spanGroupspan(x - 1, y, libs, lookFor);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- spanGroupspan(x, y - 1, libs, lookFor);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- spanGroupspan(x + 1, y, libs, lookFor);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- spanGroupspan(x, y + 1, libs, lookFor);
- }
- else if (gList[gMap[groupIDs[x][y]]].libC == 1)
- adjInAtari = TRUE;
- else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
- (! gList[gMap[groupIDs[x][y]]].isLive))
- adj2Libs = TRUE;
- } /* span */
-
- spanGroup(x, y, libs)
- short x, y;
- pointList *libs;
- { /* spanGroup */
- short lookFor;
- #ifdef DEBUG
- printf( "spanGroup\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- adjInAtari = FALSE;
- adj2Libs = FALSE;
- lookFor = bord[x][y];
- libs->indx = 0;
- spanGroupspan(x, y, libs, lookFor);
- } /* spanGroup */
-
- sSpanGroupspan(x, y, libs, lookFor)
- short x, y, lookFor;
- sPointList *libs;
- { /* span */
- markBoard[x][y] = marker;
- if (bord[x][y] == 0)
- {
- libs->indx += 1;
- if (libs->indx <= maxSPoint)
- {
- libs->p[libs->indx].px = x;
- libs->p[libs->indx].py = y;
- }
- }
- else if (bord[x][y] == lookFor)
- {
- groupSeen[x][y] = TRUE;
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- sSpanGroupspan(x - 1, y, libs, lookFor);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- sSpanGroupspan(x, y - 1, libs, lookFor);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- sSpanGroupspan(x + 1, y, libs, lookFor);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- sSpanGroupspan(x, y + 1, libs, lookFor);
- }
- else if (gList[gMap[groupIDs[x][y]]].libC == 1)
- adjInAtari = TRUE;
- else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
- (! gList[gMap[groupIDs[x][y]]].isLive))
- adj2Libs = TRUE;
- } /* span */
-
- sSpanGroup(x, y, libs)
- short x, y;
- sPointList *libs;
- { /* sSpanGroup */
- short lookFor;
- #ifdef DEBUG
- printf( "sSpanGroup\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- adjInAtari = FALSE;
- adj2Libs = FALSE;
- lookFor = bord[x][y];
- libs->indx = 0;
- sSpanGroupspan(x, y, libs, lookFor);
- } /* sSpanGroup */
-
- LAspan(x, y, me, him, iL)
- short x, y, me, him;
- intList *iL;
- { /* span */
- #ifdef DEBUG
- printf( "LAspan\n" );
- #endif
- markBoard[x][y] = marker;
- if (bord[x][y] == me)
- {
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- LAspan(x - 1, y, me, him, iL);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- LAspan(x + 1, y, me, him, iL);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- LAspan(x, y - 1, me, him, iL);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- LAspan(x, y + 1, me, him, iL);
- }
- else if (bord[x][y] == him)
- if (gList[gMap[groupIDs[x][y]]].groupMark != grpMark)
- {
- gList[gMap[groupIDs[x][y]]].groupMark = grpMark;
- iL->indx = iL->indx + 1;
- iL->v[iL->indx] = gMap[groupIDs[x][y]];
- }
- } /* span */
-
- listAdjacents(x, y, iL)
- short x, y;
- intList *iL;
- { /* listAdjacents */
- short me, him;
- #ifdef DEBUG
- printf( "listAdjacents\n" );
- #endif
- grpMark = grpMark + 1;
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- iL->indx = 0;
- me = bord[x][y];
- him = -me;
- LAspan(x, y, me , him, iL);
- } /* listAdjacents */
-
- LDspan(x, y, me, diags)
- short x, y, me;
- sPointList *diags;
- { /* span */
- #ifdef DEBUG
- printf( "LDspan\n" );
- #endif
- markBoard[x][y] = marker;
- if ((x > 0) && (y > 0) &&
- (bord[x - 1][y - 1] == 0) &&
- (bord[x][y - 1] != me) &&
- (bord[x - 1][y] != me) &&
- (markBoard[x - 1][y - 1] != marker))
- {
- markBoard[x - 1][y - 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x - 1;
- diags->p[diags->indx].py = y - 1;
- }
- }
- if ((x < maxPoint) && (y > 0) &&
- (bord[x + 1][y - 1] == 0) &&
- (bord[x][y - 1] != me) &&
- (bord[x + 1][y] != me) &&
- (markBoard[x + 1][y - 1] != marker))
- {
- markBoard[x + 1][y - 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x + 1;
- diags->p[diags->indx].py = y - 1;
- }
- }
- if ((x > 0) && (y < maxPoint) &&
- (bord[x - 1][y + 1] == 0) &&
- (bord[x][y + 1] != me) &&
- (bord[x - 1][y] != me) &&
- (markBoard[x - 1][y + 1] != marker))
- {
- markBoard[x - 1][y + 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x - 1;
- diags->p[diags->indx].py = y + 1;
- }
- }
- if ((x < maxPoint) && (y < maxPoint) &&
- (bord[x + 1][y + 1] == 0) &&
- (bord[x][y + 1] != me) &&
- (bord[x + 1][y] != me) &&
- (markBoard[x + 1][y + 1] != marker))
- {
- markBoard[x + 1][y + 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x + 1;
- diags->p[diags->indx].py = y + 1;
- }
- }
- if ((x > 0) && (bord[x - 1][y] == me) &&
- (markBoard[x - 1][y] != marker))
- LDspan(x - 1, y, me, diags);
- if ((x < maxPoint) && (bord[x + 1][y] == me) &&
- (markBoard[x + 1][y] != marker))
- LDspan(x + 1, y, me, diags);
- if ((y > 0) && (bord[x][y - 1] == me) &&
- (markBoard[x][y - 1] != marker))
- LDspan(x, y - 1, me, diags);
- if ((y < maxPoint) && (bord[x][y + 1] == me) &&
- (markBoard[x][y + 1] != marker))
- LDspan(x, y + 1, me , diags);
- } /* span */
-
- listDiags(x, y, diags)
- short x, y;
- sPointList *diags;
- { /* listDiags */
- short me;
- #ifdef DEBUG
- printf( "listDiags\n" );
- #endif
- me = bord[x][y];
- diags->indx = 0;
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- LDspan(x, y, me, diags);
- } /* listDiags */
-
- intersectPlist(p1, p2, pr)
- pointList *p1, *p2, *pr;
- { /* intersectPlist */
- short i, j, k;
- #ifdef DEBUG
- printf( "intersectPlist\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- pr->indx = 0;
- for (i = 1; i <= p1->indx; i++)
- markBoard[p1->p[i].px][p1->p[i].py] = marker;
- j = 0;
- for (i = 1; i <= p2->indx; i++)
- if (markBoard[p2->p[i].px][p2->p[i].py] == marker)
- {
- j = j + 1;
- pr->p[j] = p2->p[i];
- }
- pr->indx = j;
- } /* intersectPlist */
-
- initArray(ary)
- intBoard ary;
- { /* initArray */
- short i, j;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- ary[i][j] = 0;
- } /* initArray */
-
- initState()
- { /* initState */
- short i, j;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- {
- extra[i][j] = 0;
- claim[i][j] = 0;
- groupIDs[i][j] = 0;
- connectMap[i][j] = 0;
- protPoints[i][j] = 0;
- }
- } /* initState */
-
- copyArray( dest, src )
- intBoard dest, src;
- {
- short x, y;
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- dest[x][y] = src[x][y];
- }
-
- /*
- generates a one-point spread in the force field array (claim)
-
- the spread from a single point after four calls is:
-
- 1
- 2 2 2
- 2 4 6 4 2
- 2 4 8 10 8 4 2
- 1 2 6 10 62 10 6 2 1
- 2 4 8 10 8 4 2
- 2 4 6 4 2
- 2 2 2
- 1
-
- */
- stake()
- {
- short x, y;
- initArray( extra );
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- {
- extra[x][y] = extra[x][y] + claim[x][y];
- if (claim[x][y] > 0)
- {
- if (x > 0) extra[x-1][y] += 1;
- if (y > 0) extra[x][y-1] += 1;
- if (x < maxPoint) extra[x+1][y] += 1;
- if (y < maxPoint) extra[x][y+1] += 1;
- }
- else if (claim[x][y] < 0)
- {
- if (x > 0) extra[x-1][y] -= 1;
- if (y > 0) extra[x][y-1] -= 1;
- if (x < maxPoint) extra[x+1][y] -= 1;
- if (y < maxPoint) extra[x][y+1] -= 1;
- }
- }
- copyArray( claim, extra );
- } /* stake */
-
- /*
- sets up claim from the current board position
- */
- spread()
- {
- short x, y;
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- claim[x][y] = ndbord[x][y] * 50;
- stake();
- stake();
- stake();
- stake();
- } /* spread */
-
- /*
- gList is initialized with the size, loc, and libCount of each group
- groupIDs contains the serial numbers of the groups.
- */
- Resspan(x, y, gID, gSize, libCount, who)
- short x, y, gID, *gSize, *libCount, who;
- { /* span */
- if ((bord[x][y] == 0) &&
- (markBoard[x][y] != marker)) /* a liberty */
- {
- markBoard[x][y] = marker;
- *libCount = *libCount + 1;
- }
- else if ((bord[x][y] == who) &&
- (groupIDs[x][y] == 0))
- {
- groupIDs[x][y] = gID;
- *gSize = *gSize + 1;
- if (x > 0)
- Resspan(x - 1, y, gID, gSize, libCount, who);
- if (x < maxPoint)
- Resspan(x + 1, y, gID, gSize, libCount, who);
- if (y > 0)
- Resspan(x, y - 1, gID, gSize, libCount, who);
- if (y < maxPoint)
- Resspan(x, y + 1, gID, gSize, libCount, who);
- }
- } /* span */
-
- respreicen()
- { /* respreicen */
- short i, j, gID, libCount, gSize, who;
- gID = 0;
- #ifdef DEBUG
- printf( "respreicen\n" );
- #endif
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- groupIDs[i][j] = 0;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if ((bord[i][j] != 0) && /* a stone there */
- (groupIDs[i][j] == 0)) /* not seen yet */
- {
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- gID = gID + 1;
- libCount = 0;
- gSize = 0;
- who = bord[i][j];
- Resspan(i, j, gID, &gSize, &libCount, who); /* span the group, collecting info */
- gList[gID].groupMark = 0;
- gList[gID].atLevel = 0;
- gList[gID].isLive = FALSE; /* we don't know yet */
- gList[gID].isDead = FALSE;
- gList[gID].numEyes = -1;
- gList[gID].size = gSize;
- gList[gID].libC = libCount;
- gList[gID].lx = i;
- gList[gID].ly = j;
- gMap[gID] = gID; /* set up identity map */
- }
- maxGroupID = gID;
- newGID = gID;
- grpMark = 0;
- } /* respreicen */
-
- /*
- play z at [x, y].
- killFlag is set true if anything is killed.
- */
- killGroup(x, y, me, him)
- short x, y, me, him;
- { /* killGroup */
- #ifdef DEBUG
- printf( "killGroup\n" );
- #endif
- playMark = playMark + 1;
- /* record this kill */
- playStack[playMark].kind = rem;
- playStack[playMark].uval.rem.who = him;
- playStack[playMark].uval.rem.xl = x;
- playStack[playMark].uval.rem.yl = y;
- playStack[playMark].gID = groupIDs[x][y];
- playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum;
- if (showTrees)
- rstone(x, y);
- numCapt = numCapt + 1;
- bord[x][y] = 0;
- groupIDs[x][y] = 0;
- if (x > 0)
- {
- if (bord[x - 1][y] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
- }
- else if (bord[x - 1][y] == him)
- killGroup(x - 1, y, me , him);
- }
- if (x < maxPoint)
- {
- if (bord[x + 1][y] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
- }
- else if (bord[x + 1][y] == him)
- killGroup(x + 1, y, me, him);
- }
- if (y > 0)
- {
- if (bord[x][y - 1] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
- }
- else if (bord[x][y - 1] == him)
- killGroup(x, y - 1, me, him);
- }
- if (y < maxPoint)
- {
- if (bord[x][y + 1] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
- }
- else if (bord[x][y + 1] == him)
- killGroup(x, y + 1, me, him);
- }
- } /* killGroup */
-
- mergeGroup(sGID, myGID)
- short sGID, myGID;
- { /* mergeGroup */
- short i;
- #ifdef DEBUG
- printf( "mergeGroup\n" );
- #endif
- for (i = 1; i <= newGID; i++)
- if (gMap[i] == sGID)
- {
- playMark = playMark + 1;
- playStack[playMark].kind = reMap;
- playStack[playMark].gID = i;
- playStack[playMark].uval.reMap.oldGID = sGID;
- gMap[i] = myGID;
- }
- } /* mergeGroup */
-
- tryPlay(x, y, z)
- short x, y, z;
- { /* plei */
- short i, me, him, myGID;
- short isNew;
- #ifdef DEBUG
- printf( "tryPlay\n" );
- #endif
- me = z;
- him = -me;
- killFlag = FALSE; /* set true if something is killed */
- numCapt = 0;
- tryLevel = tryLevel + 1;
- isNew = FALSE;
- bord[x][y] = z; /* play the stone */
- if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */
- myGID = gMap[groupIDs[x - 1][y]];
- else if ((x < maxPoint) && (bord[x + 1][y] == me))
- myGID = gMap[groupIDs[x + 1][y]];
- else if ((y > 0) && (bord[x][y - 1] == me))
- myGID = gMap[groupIDs[x][y - 1]];
- else if ((y < maxPoint) && (bord[x][y + 1] == me))
- myGID = gMap[groupIDs[x][y + 1]];
- else /* nobody to connect to */
- {
- newGID = newGID + 1;
- isNew = TRUE;
- myGID = newGID;
- gList[myGID].groupMark = 0;
- gList[myGID].atLevel = tryLevel;
- gList[myGID].isLive = FALSE;
- gList[myGID].numEyes = -1;
- gList[myGID].size = -1;
- gList[myGID].lx = x;
- gList[myGID].ly = y;
- gMap[myGID] = myGID;
- }
- groupIDs[x][y] = myGID;
- playMark = playMark + 1;
- /* record this move */
- playStack[playMark].kind = add;
- playStack[playMark].uval.add.who = me;
- playStack[playMark].uval.add.xl = x;
- playStack[playMark].uval.add.yl = y;
- playStack[playMark].gID = myGID;
- playStack[playMark].uval.add.sNumber = 0;
- if (isNew)
- playStack[playMark].uval.add.nextGID = newGID - 1;
- else
- playStack[playMark].uval.add.nextGID = newGID;
- if (showTrees)
- sstone(me, x, y, 0);
- /* merge adjacent groups */
- if ((x > 0) && (bord[x - 1][y] == me) &&
- (gMap[groupIDs[x - 1][y]] != myGID))
- mergeGroup(gMap[groupIDs[x - 1][y]], myGID);
- if ((x < maxPoint) && (bord[x + 1][y] == me) &&
- (gMap[groupIDs[x + 1][y]] != myGID))
- mergeGroup(gMap[groupIDs[x + 1][y]], myGID);
- if ((y > 0) && (bord[x][y - 1] == me) &&
- (gMap[groupIDs[x][y - 1]] != myGID))
- mergeGroup(gMap[groupIDs[x][y - 1]], myGID);
- if ((y < maxPoint) && (bord[x][y + 1] == me) &&
- (gMap[groupIDs[x][y + 1]] != myGID))
- mergeGroup(gMap[groupIDs[x][y + 1]], myGID);
- /* kill opposing groups, listing affected groups */
- nlcGroup.indx = 1;
- nlcGroup.v[1] = myGID; /* init list to include me */
- if ((x > 0) && (bord[x - 1][y] == him) &&
- (gList[gMap[groupIDs[x - 1][y]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x - 1, y, me, him);
- }
- if ((x < maxPoint) && (bord[x + 1][y] == him) &&
- (gList[gMap[groupIDs[x + 1][y]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x + 1, y, me, him);
- }
- if ((y > 0) && (bord[x][y - 1] == him) &&
- (gList[gMap[groupIDs[x][y - 1]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x, y - 1, me, him);
- }
- if ((y < maxPoint) && (bord[x][y + 1] == him) &&
- (gList[gMap[groupIDs[x][y + 1]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x, y + 1, me, him);
- }
- /* list groups adjacent to me */
- if ((x > 0) && (bord[x - 1][y] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
- }
- if ((x < maxPoint) && (bord[x + 1][y] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
- }
- if ((y > 0) && (bord[x][y - 1] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
- }
- if ((y < maxPoint) && (bord[x][y + 1] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
- }
- /* fix liberty count for affected groups */
- grpMark = grpMark + 1;
- for (i = 1; i <= nlcGroup.indx; i++)
- if (gList[nlcGroup.v[i]].groupMark != grpMark)
- {
- if (gList[nlcGroup.v[i]].atLevel != tryLevel)
- {
- playMark = playMark + 1;
- playStack[playMark].kind = chLib;
- playStack[playMark].gID = nlcGroup.v[i];
- playStack[playMark].uval.chLib.oldLevel =
- gList[nlcGroup.v[i]].atLevel;
- playStack[playMark].uval.chLib.oldLC =
- gList[nlcGroup.v[i]].libC;
- }
- gList[nlcGroup.v[i]].groupMark = grpMark;
- gList[nlcGroup.v[i]].atLevel = tryLevel;
- spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist);
- gList[nlcGroup.v[i]].libC = pPlist.indx;
- }
- } /* plei */
-
- saveState()
- { /* saveState */
- playMark = 0;
- tryLevel = 0;
- newGID = maxGroupID;
- } /* saveState */
-
- /*
- undoes a move sequence back to uMark
- */
- undoTo(uMark)
- short uMark;
- { /* undoTo */
- short i, xl, yl;
- #ifdef DEBUG
- printf( "undoTo\n" );
- #endif
- for (i = playMark; i >= uMark + 1; i--)
- if (playStack[i].kind == rem)
- {
- xl = playStack[i].uval.rem.xl;
- yl = playStack[i].uval.rem.yl;
- bord[xl][yl] = playStack[i].uval.rem.who;
- groupIDs[xl][yl] = playStack[i].gID;
- if (showTrees)
- sstone(playStack[i].uval.rem.who, xl, yl,
- playStack[i].uval.rem.sNumber);
- }
- else if (playStack[i].kind == add)
- {
- xl = playStack[i].uval.add.xl;
- yl = playStack[i].uval.add.yl;
- bord[xl][yl] = 0;
- groupIDs[xl][yl] = 0;
- tryLevel = tryLevel - 1;
- newGID = playStack[i].uval.add.nextGID;
- if (showTrees)
- rstone(xl, yl);
- }
- else if (playStack[i].kind == reMap)
- gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID;
- else /* change libs of group - gID is pre-mapped */
- {
- gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC;
- gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel;
- }
- playMark = uMark;
- } /* undoTo */
-
- /*
- restores the state of the world after trying a move sequence
- */
- restoreState()
- { /* restoreState */
- #ifdef DEBUG
- printf( "restoreState\n" );
- #endif
- if (playMark > 0)
- {
- undoTo(0);
- playMark = 0;
- tryLevel = 0;
- }
- } /* restoreState */
-
- /* exception bpt; */
-
-
- /*
- returns true if (the group (at gx, gy) is saveable.
- if so, returns the point to play at in savex, savey
- */
- short saveable(gx, gy, savex, savey)
- short gx, gy, *savex, *savey;
- { /* saveable */
- short me, him, gx1, gx2, i, j, smark, mark2, tl, result;
- char sChar;
- sPointList dList;
- point tp;
- short libList[maxSPoint+1];
- #ifdef DEBUG
- printf( "saveable\n" );
- #endif
- dbStop = TRUE;
- me = bord[gx][gy];
- him = -me;
- if (me == 1)
- sChar = '|';
- else
- sChar = '>';
- /* write(sChar); */
- spanGroup(gx, gy, &plist3); /* find my liberties */
- if (adjInAtari) /* one of my options is to kill */
- {
- listAdjacents(gx, gy, &aList);
- for (i = 1; i <= aList.indx; i++)
- if (gList[aList.v[i]].libC == 1)
- {
- spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly,
- &pList1); /* find it's liberty */
- plist3.indx = plist3.indx + 1;
- plist3.p[plist3.indx].px = pList1.p[1].px;
- plist3.p[plist3.indx].py = pList1.p[1].py;
- }
- }
- for (i = 1; i <= maxSPoint; i++)
- libList[i] = -1;
- if ((utilPlayLevel > 4) &&
- (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */
- {
- listDiags(gx, gy, &dList);
- j = 0;
- i = plist3.indx;
- while ((j < dList.indx) &&
- (i < maxSPoint))
- {
- j = j + 1;
- i = i + 1;
- libList[i] = 100;
- plist3.p[i].px = dList.p[j].px;
- plist3.p[i].py = dList.p[j].py;
- }
- plist3.indx = i;
- }
- if (plist3.indx > 1) /* sort by decreasing lib count */
- {
- for (i = 1; i <= plist3.indx; i++)
- if (libList[i] != 100)
- {
- mark2 = playMark;
- tryPlay(plist3.p[i].px, plist3.p[i].py, me);
- libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
- if (libList[i] > treeLibLim) /* i'm safe */
- {
- *savex = plist3.p[i].px;
- *savey = plist3.p[i].py;
- result = TRUE;
- goto one;
- }
- undoTo(mark2);
- }
- for (i = 1; i <= plist3.indx - 1; i++)
- for (j = i + 1; j <= plist3.indx; j++)
- if (libList[i] < libList[j])
- {
- tl = libList[i];
- libList[i] = libList[j];
- libList[j] = tl;
- tp = plist3.p[i];
- plist3.p[i] = plist3.p[j];
- plist3.p[j] = tp;
- }
- }
- for (i = 1; i <= plist3.indx; i++)
- {
- *savex = plist3.p[i].px;
- *savey = plist3.p[i].py;
- if (legal[*savex][*savey])
- {
- smark = playMark;
- tryPlay(*savex, *savey, me);
- pause();
- if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1)
- if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
- {
- restoreState();
- /* sClearChar(sChar, rXor); */
- return TRUE;
- }
- else if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
- if (! killable(gx, gy, &gx1, &gx2))
- {
- restoreState();
- /* sClearChar(sChar, rXor); */
- return TRUE;
- }
- undoTo(smark);
- }
- }
- result = FALSE;
- one:
- restoreState();
- /* sClearChar(sChar, rXor); */
- return result;
- } /* saveable */
-
- /*
- marks unsavable groups as dead
- */
- markDead()
- { /* markDead */
- short i, j, gx, gy, result;
- #ifdef DEBUG
- printf( "markDead\n" );
- #endif
- for (i = 1; i <= maxGroupID; i++)
- if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
- result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy);
- else
- result = FALSE;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (bord[i][j] == 0)
- ndbord[i][j] = 0;
- else if (gList[groupIDs[i][j]].isDead)
- ndbord[i][j] = 0;
- else
- ndbord[i][j] = bord[i][j];
- } /* markDead */
-
- /*
- marks groups with two eyes as live
- */
- MLspan(x, y, saw1, sawm1, size, sMark)
- short x, y, *saw1, *sawm1, *size, sMark;
- { /* span */
- if (ndbord[x][y] == 1)
- *saw1 = TRUE;
- else if (ndbord[x][y] == -1)
- *sawm1 = TRUE;
- else if (sGroups[x][y] == 0)
- {
- sGroups[x][y] = sMark;
- *size = *size + 1;
- if (x > 0)
- MLspan(x - 1, y, saw1, sawm1, size, sMark);
- if (x < maxPoint)
- MLspan(x + 1, y, saw1, sawm1, size, sMark);
- if (y > 0)
- MLspan(x, y - 1, saw1, sawm1, size, sMark);
- if (y < maxPoint)
- MLspan(x, y + 1, saw1, sawm1, size, sMark);
- }
- } /* span */
-
- short CLspan(x, y, numEyes, who)
- short x, y, *numEyes, who;
- { /* span */
- markBoard[x][y] = marker;
- if (ndbord[x][y] == 0)
- {
- if ((sList[sGroups[x][y]].sm != marker) &&
- (sList[sGroups[x][y]].w == who))
- {
- sList[sGroups[x][y]].sm = marker;
- if (sList[sGroups[x][y]].s > 6)
- return TRUE;
- *numEyes = *numEyes + 1;
- if (*numEyes > 1)
- return TRUE;
- }
- }
- else if (bord[x][y] == who)
- {
- if ((x > 0) &&
- (markBoard[x - 1][y] != marker))
- if (CLspan(x - 1, y, numEyes, who)) return TRUE;
- if ((x < maxPoint) &&
- (markBoard[x + 1][y] != marker))
- if (CLspan(x + 1, y, numEyes, who)) return TRUE;
- if ((y > 0) &&
- (markBoard[x][y - 1] != marker))
- if (CLspan(x, y - 1, numEyes, who)) return TRUE;
- if ((y < maxPoint) &&
- (markBoard[x][y + 1] != marker))
- if (CLspan(x, y + 1, numEyes, who)) return TRUE;
- }
- return FALSE;
- } /* span */
-
- short checkLive(x, y)
- short x, y;
- { /* checkLive */
- short numEyes, who;
- #ifdef DEBUG
- printf( "checkLive\n" );
- #endif
- numEyes = 0;
- who = bord[x][y];
- marker = marker + 1;
- return CLspan(x, y, &numEyes, who);
- } /* checkLive */
-
- markLive()
- { /* markLive */
- short i, j, size, sMark = 0;
- short saw1, sawm1;
- #ifdef DEBUG
- printf( "markLive\n" );
- #endif
- initArray(sGroups);
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if ((sGroups[i][j] == 0) &&
- (ndbord[i][j] == 0))
- {
- size = 0;
- sMark = sMark + 1;
- sawm1 = FALSE;
- saw1 = FALSE;
- MLspan(i, j, &saw1, &sawm1, &size, sMark);
- sList[sMark].s = size;
- sList[sMark].sm = 0;
- if (sawm1)
- if (saw1)
- sList[sMark].w = 0;
- else
- sList[sMark].w = -1;
- else if (saw1)
- sList[sMark].w = 1;
- else
- sList[sMark].w = 0;
- }
- for (i = 1; i <= maxGroupID; i++)
- if (! gList[i].isDead)
- gList[i].isLive = checkLive(gList[i].lx, gList[i].ly);
- } /* markLive */
-
- /*
- generates the connection map and the protected point map.
- */
- genConnects()
- { /* genConnects */
- short x, y, numStones;
- #ifdef DEBUG
- printf( "genConnects\n" );
- #endif
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- {
- connectMap[x][y] = 0;
- protPoints[x][y] = 0;
- }
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- if (bord[x][y] == 1) /* map connections to this stone */
- {
- if (x > 0) /* direct connection */
- connectMap[x - 1][y] += 1;
- if (x < maxPoint)
- connectMap[x + 1][y] += 1;
- if (y > 0)
- connectMap[x][y - 1] += 1;
- if (y < maxPoint)
- connectMap[x][y + 1] += 1;
- if ((x > 0) && (y > 0) && /* diagonal connection */
- (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0))
- connectMap[x - 1][y - 1] += 1;
- if ((x < maxPoint) && (y > 0) &&
- (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0))
- connectMap[x + 1][y - 1] += 1;
- if ((x < maxPoint) && (y < maxPoint) &&
- (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0))
- connectMap[x + 1][y + 1] += 1;
- if ((x > 0) && (y < maxPoint) &&
- (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0))
- connectMap[x - 1][y + 1] += 1;
- if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */
- connectMap[x - 2][y] += 1;
- if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3))
- connectMap[x + 2][y] += 1;
- if ((y > 1) && (claim[x][y - 1] > 3))
- connectMap[x][y - 2] += 1;
- if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3))
- connectMap[x][y + 2] += 1;
- if ((x > 1) && (y > 0) && /* knight's move */
- (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3))
- connectMap[x - 2][y - 1] += 1;
- if ((x > 0) && (y > 1) &&
- (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3))
- connectMap[x - 1][y - 2] += 1;
- if ((x < (maxPoint - 1)) && (y > 0) &&
- (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3))
- connectMap[x + 2][y - 1] += 1;
- if ((x < maxPoint) && (y > 1) &&
- (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3))
- connectMap[x + 1][y - 2] += 1;
- if ((x > 1) && (y < maxPoint) &&
- (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3))
- connectMap[x - 2][y + 1] += 1;
- if ((x > 0) && (y < (maxPoint - 1)) &&
- (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3))
- connectMap[x - 1][y + 2] += 1;
- if ((x < (maxPoint - 1)) && (y < maxPoint) &&
- (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3))
- connectMap[x + 2][y + 1] += 1;
- if ((x < maxPoint) && (y < (maxPoint - 1)) &&
- (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3))
- connectMap[x + 1][y + 2] += 1;
- }
- else if (bord[x][y] == 0) /* see if protected point */
- {
- numStones = 0;
- if (x == 0)
- numStones = numStones + 1;
- if (y == 0)
- numStones = numStones + 1;
- if (x == maxPoint)
- numStones = numStones + 1;
- if (y == maxPoint)
- numStones = numStones + 1;
- if ((x > 0) && (bord[x - 1][y] == 1))
- numStones = numStones + 1;
- if ((y > 0) && (bord[x][y - 1] == 1))
- numStones = numStones + 1;
- if ((x < maxPoint) && (bord[x + 1][y] == 1))
- numStones = numStones + 1;
- if ((y < maxPoint) && (bord[x][y + 1] == 1))
- numStones = numStones + 1;
- if (numStones == 4)
- protPoints[x][y] = 1;
- else if (numStones == 3)
- {
- if ((x > 0) &&
- ((bord[x - 1][y] == 0) ||
- ((bord[x - 1][y] == -1) &&
- (gList[groupIDs[x - 1][y]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((x < maxPoint) &&
- ((bord[x + 1][y] == 0) ||
- ((bord[x + 1][y] == -1) &&
- (gList[groupIDs[x + 1][y]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((y > 0) &&
- ((bord[x][y - 1] == 0) ||
- ((bord[x][y - 1] == -1) &&
- (gList[groupIDs[x][y - 1]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((y < maxPoint) &&
- ((bord[x][y + 1] == 0) ||
- ((bord[x][y + 1] == -1) &&
- (gList[groupIDs[x][y + 1]].libC == 1))))
- protPoints[x][y] = 1;
- }
- }
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- if (bord[x][y] != 0)
- {
- connectMap[x][y] = 0;
- protPoints[x][y] = 0;
- }
- } /* genConnects */
-
- /*
- generates the whole state of the game.
- */
- genState()
- { /* genState */
- #ifdef DEBUG
- printf( "genState\n" );
- #endif
- inGenState = TRUE;
- respreicen();
- markDead();
- markLive();
- spread();
- genConnects();
- #ifdef DEBUG
- /* printBoard( claim, "claim" ); */
- /* printBoard( bord, "bord" ); */
- /* printBoard( ndbord, "ndbord" );
- printBoard( sGroups, "sGroups" );
- printBoard( groupIDs, "groupIDs" );
- printBoard( connectMap, "connectMap" );
- printBoard( protPoints, "protPoints" ); */
- #endif
- inGenState = FALSE;
- } /* genState */
-
- /*
- generates a value for the [x, y] location that appears to get larger
- for points that are saddle points in the influence graph (klein)
- */
- short tencen(x, y)
- short x, y;
- { /* tencen */
- short a, b, c, d, w, z;
- #ifdef DEBUG
- printf( "tencen\n" );
- #endif
- if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */
- {
- return 50;
- }
- w = claim[x][y]; /* w <= -1 */
- a = iNil;
- if (x > 0)
- if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */
- a = claim[x - 1][y] - w; /* score is sum of his influence on central */
- b = iNil; /* point and my influence on this neighbor */
- if (y > 0)
- if (claim[x][y - 1] > -1)
- b = claim[x][y - 1] - w;
- c = iNil;
- if (x < maxPoint)
- if (claim[x + 1][y] > -1)
- c = claim[x + 1][y] - w;
- d = iNil;
- if (y < maxPoint)
- if (claim[x][y + 1] > -1)
- d = claim[x][y + 1] - w;
- z = a; /* z = max(a, b, c, d) */
- if (z != iNil)
- {
- if ((b != iNil) &&
- (b > z))
- z = b;
- }
- else
- z = b;
- if (z != iNil)
- {
- if ((c != iNil) &&
- (c > z))
- z = c;
- }
- else
- z = c;
- if (z != iNil)
- {
- if ((d != iNil) &&
- (d > z))
- z = d;
- }
- else
- z = d;
- if ((z != iNil) &&
- ((x == 0) ||
- (y == 0) ||
- (x == maxPoint) ||
- (y == maxPoint)))
- z = z * 2; /* double z if (on the edge of the board ?? */
- if (z != iNil)
- return z;
- else
- return 50;
- } /* tencen */
-
- initGPUtils()
- { /* initGPUtils */
- #ifdef DEBUG
- printf( "initGPUtils\n" );
- #endif
- initArray(markBoard);
- initState();
- marker = 0;
- playMark = 0;
- gList[0].isLive = FALSE;
- gList[0].isDead = FALSE;
- gList[0].libC = 0;
- gList[0].size = 0;
- gList[0].numEyes = 0;
- gList[0].lx = -1;
- gList[0].ly = -1;
- gMap[0] = 0;
- dbStop = FALSE;
- inGenState = FALSE;
- } /* initGPUtils */
-
- SHAR_EOF
- fi
- if test -f 'goplayutils.h'
- then
- echo shar: "will not over-write existing file 'goplayutils.h'"
- else
- cat << \SHAR_EOF > 'goplayutils.h'
- #define iNil 32767 /* a distinguished value like nil */
- #define maxGroup 512
- #define maxSPoint 16
- #define tryLimit 300
-
- typedef short intBoard[19][19]; /* these were -2 to maxPoint + 2 */
-
- typedef short boolBoard[19][19];
-
- typedef struct
- {
- short px, py;
- } point;
-
- typedef struct
- {
- point p[401];
- short indx;
- } pointList;
-
- typedef struct
- {
- point p[maxSPoint+1];
- short indx;
- } sPointList;
-
- typedef struct
- {
- short indx,
- v[401];
- } intList;
-
- typedef struct { short w, s, sm; } sgRec;
-
- typedef struct
- {
- short groupMark,
- atLevel,
- isLive,
- isDead,
- libC,
- numEyes,
- size,
- lx, ly;
- } groupRec;
-
- typedef enum {rem, add, chLib, reMap} playType;
-
- typedef struct { short who, xl, yl, nextGID, sNumber; } remAddRec;
- typedef struct { short oldLC, oldLevel; } chLibRec;
- typedef struct { short oldGID; } reMapRec;
- typedef struct
- {
- short gID;
- playType kind;
- union {
- remAddRec rem, add;
- chLibRec chLib;
- reMapRec reMap;
- } uval;
- } playRec;
-
- SHAR_EOF
- fi
- if test -f 'graystone.bm'
- then
- echo shar: "will not over-write existing file 'graystone.bm'"
- else
- cat << \SHAR_EOF > 'graystone.bm'
- #define graystone_width 16
- #define graystone_height 16
- #define graystone_x_hot 7
- #define graystone_y_hot 8
- static char graystone_bits[] = {
- 0xc0, 0x03, 0xb0, 0x0e, 0x58, 0x15, 0xac, 0x2a, 0x56, 0x55, 0xaa, 0x6a,
- 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xba, 0x56, 0x5d, 0xaa, 0x6e,
- 0x54, 0x37, 0xa8, 0x1a, 0x70, 0x0d, 0xc0, 0x03};
- SHAR_EOF
- fi
- if test -f 'killable.c'
- then
- echo shar: "will not over-write existing file 'killable.c'"
- else
- cat << \SHAR_EOF > 'killable.c'
- /* By Stoney Ballard */
- /* Ported from Pascal to C by Todd R. Johnson */
-
- #include "go.h"
- #include "amigo.h"
- #include "goplayutils.h"
-
- extern intBoard bord, groupIDs;
- extern boolBoard legal;
- extern groupRec gList[maxGroup];
- extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim,
- utilPlayLevel, killFlag, depthLimit, dbStop, showTrees;
- extern pointList plist2;
-
- /*
- returns true if the group (at x, y) is killable.
- if so, returns the point to play at in killx, killy.
- */
-
- short me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2;
- char sChar;
- sPointList lList, dList;
- point tp;
- short libList[maxSPoint+1];
- short esc;
-
- short mtNbrs(x, y)
- short x, y;
- { /* mtNbrs */
- short n = 0;
- if ((x > 0) && (bord[x - 1][y] == 0))
- n = n + 1;
- if ((x < maxPoint) && (bord[x + 1][y] == 0))
- n = n + 1;
- if ((y > 0) && (bord[x][y - 1] == 0))
- n = n + 1;
- if ((y < maxPoint) && (bord[x][y + 1] == 0))
- n = n + 1;
- return n;
- } /* mtNbrs */
-
- short killTree(tx, ty, gx, gy, escape, tkMark)
- short tx, ty, gx, gy, *escape, tkMark;
- { /* killTree */
- short curMark, mark2, mark3, i, j, k, tl, dStart, result;
- sPointList lList1, lList2;
- short libList[maxSPoint+1];
- point tp;
- short esc = FALSE;
- tryCount = tryCount + 1;
- if (tryCount > tryLimit)
- {
- undoTo(tkMark);
- /* for (i = 1; i <= depth - 1; i++)
- {
- sClearChar(sChar, rXor);
- } */
- depth = 1;
- return FALSE;
- }
- /* write(sChar); */
- depth = depth + 1;
- curMark = playMark;
- tryPlay(tx, ty, me); /* try my move */
- pause();
- if (gList[gMap[groupIDs[tx][ty]]].libC == 0) /* I'm dead */
- {
- result = FALSE;
- goto one;
- }
- else if (killFlag) /* I killed something of his */
- {
- result = TRUE;
- goto one;
- }
- else if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) /* safe */
- {
- result = FALSE;
- goto one;
- }
- else
- {
- sSpanGroup(gx, gy, &lList1); /* find his liberties */
- if (gList[gMap[groupIDs[tx][ty]]].libC == 1) /* he can kill me */
- {
- if (lList1.indx < maxSPoint) /* add that option to his list */
- {
- lList1.indx = lList1.indx + 1;
- spanGroup(tx, ty, &plist2); /* find my liberty */
- lList1.p[lList1.indx].px = plist2.p[1].px;
- lList1.p[lList1.indx].py = plist2.p[1].py;
- }
- else
- {
- result = FALSE;
- goto one;
- }
- }
- for (i = 1; i <= maxSPoint; i++) /* init liblist so diags can be marked */
- libList[i] = -1;
- if ((utilPlayLevel > 4) &&
- (lList1.indx > 1) &&
- (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* try diags */
- {
- listDiags(gx, gy, &dList);
- j = 0;
- i = lList1.indx;
- while ((j < dList.indx) &&
- (i < maxSPoint))
- {
- j = j + 1;
- i = i + 1;
- libList[i] = 0; /* mark this as a diag */
- lList1.p[i].px = dList.p[j].px;
- lList1.p[i].py = dList.p[j].py;
- }
- lList1.indx = i;
- }
- if (lList1.indx > 1) /* sort by decreasing lib count */
- {
- for (i = 1; i <= lList1.indx; i++)
- if (libList[i] != 0) /* diags are tried last */
- {
- mark2 = playMark;
- tryPlay(lList1.p[i].px, lList1.p[i].py, him);
- libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
- if ((libList[i] > treeLibLim) ||
- ((libList[i] > (depthLimit - depth)) &&
- (libList[i] > 2)))
- {
- *escape = TRUE;
- result = FALSE;
- goto one;
- }
- undoTo(mark2);
- }
- for (i = 1; i <= lList1.indx - 1; i++)
- for (j = i + 1; j <= lList1.indx; j++)
- if (libList[i] < libList[j])
- {
- tl = libList[i];
- libList[i] = libList[j];
- libList[j] = tl;
- tp = lList1.p[i];
- lList1.p[i] = lList1.p[j];
- lList1.p[j] = tp;
- }
- }
- for (i = 1; i <= lList1.indx + 1; i++) /* try his responses */
- {
- mark2 = playMark;
- if (i <= lList1.indx) /* try his move */
- {
- tryPlay(lList1.p[i].px, lList1.p[i].py, him); /* play his response */
- pause();
- if (gList[gMap[groupIDs[lList1.p[i].px]
- [lList1.p[i].py]]].libC < 2)
- goto two; /* a bogus move */
- }
- else if (gList[gMap[groupIDs[gx][gy]]].libC <= 1)
- {
- result = TRUE;
- goto one;
- }
- if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
- {
- *escape = TRUE;
- result = FALSE;
- goto one;
- }
- if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
- { /* look at my responses */
- sSpanGroup(gx, gy, &lList2); /* list his liberties */
- dStart = lList2.indx + 1;
- if (adjInAtari) /* he wins */
- {
- result = FALSE;
- goto one;
- }
- if ((lList2.indx > 2) && adj2Libs) /* he wins */
- {
- result = FALSE;
- goto one;
- }
- for (k = 1; k <= maxSPoint; k++)
- libList[k] = -1;
- if (utilPlayLevel > 4) /* account for diagonal moves */
- {
- listDiags(gx, gy, &dList);
- j = 0;
- k = lList2.indx;
- while ((j < dList.indx) &&
- (k < maxSPoint))
- {
- j = j + 1;
- k = k + 1;
- libList[k] = 100;
- lList2.p[k].px = dList.p[j].px;
- lList2.p[k].py = dList.p[j].py;
- }
- lList2.indx = k;
- }
- if (lList2.indx > 1) /* sort by increasing lib count */
- {
- for (k = 1; k <= lList2.indx; k++)
- if (libList[k] != 100) /* diags go last */
- {
- mark3 = playMark;
- tryPlay(lList2.p[k].px, lList2.p[k].py, me);
- libList[k] = gList[gMap[groupIDs[gx][gy]]].libC;
- undoTo(mark3);
- }
- for (k = 1; k <= lList2.indx - 1; k++)
- for (j = k + 1; j <= lList2.indx; j++)
- if (libList[k] > libList[j])
- {
- tl = libList[k];
- libList[k] = libList[j];
- libList[j] = tl;
- tp = lList2.p[k];
- lList2.p[k] = lList2.p[j];
- lList2.p[j] = tp;
- }
- else if ((libList[k] == libList[j]) &&
- (libList[k] == 1))
- if (mtNbrs(lList2.p[k].px, lList2.p[k].py) <
- mtNbrs(lList2.p[j].px, lList2.p[j].py))
- {
- tl = libList[k];
- libList[k] = libList[j];
- libList[j] = tl;
- tp = lList2.p[k];
- lList2.p[k] = lList2.p[j];
- lList2.p[j] = tp;
- }
- }
- for (j = 1; j <= lList2.indx; j++)
- {
- if (killTree(lList2.p[j].px, lList2.p[j].py, gx,
- gy, &esc, tkMark))
- goto two; /* this kills him */
- if (esc && (j >= dStart))
- {
- result = FALSE;
- goto one; /* don't bother with more diags if escapes */
- }
- }
- result = FALSE; /* none of my responses kills him */
- goto one;
- }
- two:
- undoTo(mark2);
- }
- result = TRUE; /* none of his responses saves him */
- }
- one:
- undoTo(curMark);
- /* sClearChar(sChar, rXor); */
- depth = depth - 1;
- return result;
- } /* killTree */
-
- short tKillTree(tx, ty, gx, gy)
- short tx, ty, gx, gy;
- { /* tKillTree */
- short tkMark, escape;
- tryCount = 0;
- tkMark = playMark;
- return killTree(tx, ty, gx, gy, &escape, tkMark);
- } /* tKillTree */
-
- short killable(gx, gy, killx, killy)
- short gx, gy, *killx, *killy;
- { /* killable */
- #ifdef DEBUG
- printf( "killable\n" );
- showTrees = TRUE;
- #endif
- dbStop = TRUE;
- him = bord[gx][gy]; /* find out who I am */
- me = -him;
- /* if (me == 1)
- sChar = '>';
- else
- sChar = '|'; */
- /* write(sChar); */
- depth = 1;
- topMark = playMark;
- sSpanGroup(gx, gy, &lList); /* find his liberties */
- if (lList.indx == 1)
- {
- *killx = lList.p[1].px;
- *killy = lList.p[1].py;
- return TRUE;
- }
- else if (lList.indx > treeLibLim)
- return FALSE;
- else if (adjInAtari)
- return FALSE;
- else if ((lList.indx > 2) && adj2Libs)
- return FALSE;
- else
- {
- for (i = 1; i <= maxSPoint; i++)
- libList[i] = -1;
- if (utilPlayLevel > 4) /* account for diagonal moves */
- {
- listDiags(gx, gy, &dList);
- j = 0;
- i = lList.indx;
- while ((j < dList.indx) &&
- (i < maxSPoint))
- {
- j = j + 1;
- i = i + 1;
- libList[i] = 100;
- lList.p[i].px = dList.p[j].px;
- lList.p[i].py = dList.p[j].py;
- }
- lList.indx = i;
- }
- if (lList.indx > 1) /* sort by increasing lib count */
- {
- for (i = 1; i <= lList.indx; i++)
- if (libList[i] != 100) /* diags go last */
- {
- mark2 = playMark;
- tryPlay(lList.p[i].px, lList.p[i].py, me);
- libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
- undoTo(mark2);
- }
- for (i = 1; i <= lList.indx - 1; i++)
- for (j = i + 1; j <= lList.indx; j++)
- if (libList[i] > libList[j])
- {
- tl = libList[i];
- libList[i] = libList[j];
- libList[j] = tl;
- tp = lList.p[i];
- lList.p[i] = lList.p[j];
- lList.p[j] = tp;
- }
- else if ((libList[i] == libList[j]) &&
- (libList[i] == 1))
- if (mtNbrs(lList.p[i].px, lList.p[i].py) <
- mtNbrs(lList.p[j].px, lList.p[j].py))
- {
- tl = libList[i];
- libList[i] = libList[j];
- libList[j] = tl;
- tp = lList.p[i];
- lList.p[i] = lList.p[j];
- lList.p[j] = tp;
- }
- }
- for (i = 1; i <= lList.indx; i++)
- {
- if (legal[lList.p[i].px, lList.p[i].py])
- {
- *killx = lList.p[i].px;
- *killy = lList.p[i].py;
- if (tKillTree(*killx, *killy, gx, gy))
- {
- /* sClearChar(sChar, rXor); */
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- /* sClearChar(sChar, rXor); */
- } /* killable */
-
- SHAR_EOF
- fi
- if test -f 'main.c'
- then
- echo shar: "will not over-write existing file 'main.c'"
- else
- cat << \SHAR_EOF > 'main.c'
- /*=========================================================================
- === ===
- === FILE main.c ===
- === ===
- === CONTENTS Main file for xamigo. ===
- === ===
- === PART OF xamigo ===
- === ===
- === COPYRIGHT Copyright (C) 1992 by Neil Bowers ===
- === ===
- =========================================================================*/
-
- #include <stdio.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Command.h>
- #include <X11/Xaw/AsciiText.h>
- #include <X11/Xaw/Box.h>
- #include <X11/Shell.h>
- #include "check16.xbm"
- #include "Goban.h"
- #include "xamigo.h"
- #include "amigo.h"
-
- Pixmap checkmark;
-
-
- char *stat_widget_names[] =
- {
- "playerLabel","scoreLabel","playerScore","lastMoveLabel","lastMove"
- };
-
- Widget black_stat_widgets[5];
- Widget white_stat_widgets[5];
- Widget toplevel,form,box;
- Widget goban,stats_popup,message;
- int current_handicap, new_handicap;
- int current_level, new_level;
- int ingame,counting;
- short humanColor, amigoColor;
- short new_color;
- short human_passed,amigo_passed;
- short amigo_last_x,amigo_last_y,
- human_last_x,human_last_y;
-
- extern short playLevel;
- extern short showTrees,showMoveReason,groupInfo;
- extern char *playReason;
-
- extern MenuItem game_items[],level_items[],handicap_items[],level_items[];
-
-
- XtActionsRec actions[] =
- {
- {"inputStone", InputStone},
- {"pass", PassMove}
- };
-
-
- /*--------------------------------------------------------
- -- main() --
- --------------------------------------------------------*/
- void
- main(argc, argv)
- unsigned int argc;
- char *argv[];
- {
- XtAppContext app_con;
- int i;
-
-
- toplevel = XtAppInitialize(&app_con, "Xamigo", NULL, 0,
- &argc, argv, NULL, NULL, 0);
-
- form = XtCreateManagedWidget("form", formWidgetClass, toplevel,
- NULL,0);
-
- box = XtCreateManagedWidget("buttonBox", boxWidgetClass, form,
- NULL,0);
-
-
- /*-- create the menus --*/
-
- CreateAmigoMenus(box);
-
- goban = XtVaCreateManagedWidget("goban",gobanWidgetClass,form,
- XtNsensitive, TRUE,
- XtNcursor, GbCGrayStone,
- 0);
-
- checkmark = XCreateBitmapFromData(XtDisplay(toplevel),
- RootWindowOfScreen(XtScreen(toplevel)),
- check16_bits, check16_width, check16_height);
-
- XtAppAddActions(app_con, actions, XtNumber(actions));
-
- ingame = counting = 0;
- new_handicap = current_handicap = 0;
- new_level = playLevel = 7;
- humanColor = WHITE;
- new_color = amigoColor = BLACK;
- XtVaSetValues(game_items[4].widget,XtNleftBitmap,checkmark,0);
- XtVaSetValues(level_items[6].widget,XtNleftBitmap,checkmark,0);
- XtVaSetValues(handicap_items[0].widget,XtNleftBitmap,checkmark,0);
-
- CreateStatsPopup();
-
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app_con);
- }
-
-
- /*----------------------------------------------------------------
- -- NewGameProc() --
- -- Handler routine for New Game entry on "Game" menu. --
- -- Clear board, initialise AmiGo, and start a new game. --
- ----------------------------------------------------------------*/
- void
- NewGameProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- ingame = 0;
- current_handicap = new_handicap;
- playLevel = new_level;
- human_passed = amigo_passed = FALSE;
-
- amigo_last_x = amigo_last_y = human_last_x = human_last_y = 0;
- amigoColor = new_color;
- humanColor = (amigoColor==BLACK?WHITE:BLACK);
- XtVaSetValues(goban,
- XtNcursor,(humanColor==BLACK ? GbCBlackStone: GbCWhiteStone),
- NULL);
-
- /*-- clear goban *before* calling goRestart() --*/
- GbClearBoard(goban);
- goRestart(current_handicap);
-
- XtVaSetValues(black_stat_widgets[4],XtNlabel," ",0);
- XtVaSetValues(white_stat_widgets[4],XtNlabel," ",0);
- XtVaSetValues(message,XtNstring,"",0);
-
- ingame = 1;
-
- if ((amigoColor == BLACK && current_handicap == 0) ||
- (amigoColor == WHITE && current_handicap > 0))
- AmigoMove();
- }
-
- /*----------------------------------------------------------------
- -- QuitProc() --
- -- Handler routine for the Quit item of the Game menu. --
- -- This should perhaps do a bit more. Eg, if there is a --
- -- game in progress, request confirmation. --
- ----------------------------------------------------------------*/
- void
- QuitProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- exit(0);
- }
-
- /*----------------------------------------------------------------
- -- LevelProc() --
- -- Handler routine for "Level" menu. --
- ----------------------------------------------------------------*/
- void
- LevelProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- Widget old;
- int item_num = (int) call_data;
-
- if (item_num == new_level - 1)
- return;
-
- old = level_items[new_level-1].widget;
- XtVaSetValues(old,XtNleftBitmap,None,0);
-
- new_level = item_num + 1;
- XtVaSetValues(widget,XtNleftBitmap,checkmark,0);
- }
-
- /*----------------------------------------------------------------
- -- OptionProc() --
- -- Handler routine for `option' entries on the "Game" menu --
- ----------------------------------------------------------------*/
- void
- OptionProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- int item_num = (int) call_data;
- short setting;
-
- if (item_num < 5)
- {
- XtVaSetValues(game_items[3].widget,XtNleftBitmap,None,0);
- XtVaSetValues(game_items[4].widget,XtNleftBitmap,None,0);
- new_color = (item_num==3?WHITE:BLACK);
- XtVaSetValues(widget,XtNleftBitmap,checkmark,0);
- return;
- }
- switch (item_num)
- {
- case 6: /* Move Reason */
- setting = (showMoveReason = ! showMoveReason);
- break;
-
- case 7: /* show lookahead */
- setting = (showTrees = ! showTrees);
- }
- XtVaSetValues(widget,XtNleftBitmap,(setting?checkmark:None),0);
- }
-
- /*----------------------------------------------------------------
- -- HandicapProc() --
- -- Handler routine for the "Move" menu. --
- ----------------------------------------------------------------*/
- void
- MoveProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- short x,y;
- char mv[8];
-
- if (!ingame && !counting)
- {
- XtVaSetValues(message,XtNstring,"Game not in progess.",0);
- XBell(XtDisplay(goban),0);
- return;
- }
- switch((int)call_data)
- {
- case 0: /* pass */
- HumanPassMove();
- break;
-
- case 1: /* resign */
- intrMoveReport(humanColor,"resign","");
- XtVaSetValues(message,XtNstring,"Game over.",0);
- XtVaSetValues(goban,XtNcursor,GbCGrayStone,NULL);
- counting = 0;
- ingame = 0;
- break;
- }
- }
-
- /*----------------------------------------------------------------
- -- HandicapProc() --
- -- Handler routine for the "Handicap" menu. --
- ----------------------------------------------------------------*/
- void
- HandicapProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- Widget old;
- int item_num = (int) call_data;
- int newh;
-
- newh = (item_num==0?0:item_num + 1);
- if (newh == new_handicap)
- return;
-
- old = handicap_items[(new_handicap?new_handicap-1:0)].widget;
- XtVaSetValues(old,XtNleftBitmap,None,0);
-
- new_handicap = newh;
- XtVaSetValues(widget,XtNleftBitmap,checkmark,0);
- }
-
- /*----------------------------------------------------------------
- -- PopupStatsProc() --
- -- Popup the stats window. Simple bit of code which tries --
- -- to put the popup in a sensible position. Only handles --
- -- one case right now. --
- ----------------------------------------------------------------*/
- void
- PopupStatsProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- Dimension width,height,twidth,theight;
- Position x,y,tx,ty;
-
-
- XtVaGetValues(stats_popup,
- XtNx,&x,
- XtNy,&y,
- XtNwidth,&width,
- XtNheight,&height,
- 0);
- XtVaGetValues(toplevel,
- XtNx,&tx,
- XtNy,&ty,
- XtNwidth,&twidth,
- XtNheight,&theight,
- 0);
- if (ty > height+40)
- XtVaSetValues(stats_popup,
- XtNx,tx,
- XtNy,ty-height-40,
- 0);
- XtPopup(stats_popup,XtGrabNone);
- }
-
- /*----------------------------------------------------------------
- -- StatDoneProc() --
- -- Callback routine for the "Done" button on the Stats --
- -- popup window. Pop down the stats window. --
- ----------------------------------------------------------------*/
- void
- StatDoneProc(widget,call_data,closure)
- Widget widget;
- XtPointer closure;
- XtPointer call_data;
- {
- XtPopdown(stats_popup);
- }
-
- /*----------------------------------------------------------------
- -- CreateStatsPopup() --
- -- Create the stats popup window, which displays captured --
- -- stone count, last move, any messages from AmiGo, and --
- -- the final score. --
- ----------------------------------------------------------------*/
- CreateStatsPopup()
- {
- Widget statform,form,done;
- char *getenv(), *username;
- Dimension width;
- int i;
-
- stats_popup = XtCreatePopupShell("statsPopup",
- transientShellWidgetClass,toplevel,NULL,0);
-
- username = getenv("USER");
- statform = XtCreateManagedWidget("statForm", formWidgetClass,
- stats_popup, NULL,0);
-
- form = XtCreateManagedWidget("blackStatForm",formWidgetClass,statform,
- NULL,0);
-
- for (i=0;i<5;i++)
- black_stat_widgets[i] = XtCreateManagedWidget(
- stat_widget_names[i],labelWidgetClass,
- form,NULL,0);
-
- form = XtCreateManagedWidget("whiteStatForm",formWidgetClass,statform,
- NULL,0);
-
- for (i=0;i<5;i++)
- white_stat_widgets[i] = XtCreateManagedWidget(
- stat_widget_names[i],labelWidgetClass,
- form,NULL,0);
-
- message = XtCreateManagedWidget("messageWindow",asciiTextWidgetClass,
- statform,NULL,0);
-
- done = XtCreateManagedWidget("statDone",commandWidgetClass,statform,
- NULL,0);
-
- XtAddCallback(done,XtNcallback,StatDoneProc,NULL);
-
- XtRealizeWidget(stats_popup);
- }
-
- /*----------------------------------------------------------------
- -- HumanPassMove() --
- -- Called when (human) player passes: check for end of --
- -- game. Should we pass a stone to the opponent? --
- -- Generate a move for computer player. --
- ----------------------------------------------------------------*/
- void
- HumanPassMove()
- {
- if (!ingame)
- {
- if (counting)
- {
- CountUp();
- counting=0;
- }
- return;
- }
- intrMoveReport(humanColor,"pass ","");
- human_passed = TRUE;
- CheckBothPassed();
- if (ingame)
- AmigoMove();
- }
-
- /*----------------------------------------------------------------
- -- AmigoMove() --
- -- Generate a move for the computer player. Update --
- -- message window, mark stone placed. If we passed, check --
- -- to see if game is over. --
- ----------------------------------------------------------------*/
- AmigoMove()
- {
- short x,y;
- char mv[8];
-
-
- XtVaSetValues(message,XtNstring,"I'm thinking...",0);
- UpdateWidget(message);
- if (genMove(amigoColor,&x,&y))
- {
- sprintf(mv,"%c%d%s",(x<8?x+'A':x+'B'),y+1,(y<9?" ":" "));
- GoPlaceStone(amigoColor,x,y);
- if (amigo_last_x != 0)
- GbSetMark(goban,amigo_last_x,amigo_last_y,0,0);
- amigo_last_x = x+1;
- amigo_last_y = y+1;
- GbSetMark(goban,amigo_last_x,amigo_last_y,0,GbMDiamondMark);
- intrMoveReport(amigoColor,mv,playReason);
- amigo_passed = FALSE;
- }
- else
- {
- intrMoveReport(amigoColor,"pass ","");
- amigo_passed = TRUE;
- CheckBothPassed();
- }
- }
-
- /*----------------------------------------------------------------
- -- CheckBothPassed() --
- -- Check to see whether the last two moves were both PASS. --
- -- If so, go into `remove dead stone' mode. --
- ----------------------------------------------------------------*/
- CheckBothPassed()
- {
- if (human_passed && amigo_passed)
- {
- XtVaSetValues(message,XtNstring,
- "Click on dead groups. When all dead groups are removed, select \"pass\" from the Move menu.",0);
- XtVaSetValues(goban,XtNcursor,GbCGrayStone,NULL);
- ingame = 0;
- counting = 1;
- }
- }
-
-
- /*----------------------------------------------------------------
- -- PassMove() --
- -- Action proc for the 'p' keyboard command (pass). --
- ----------------------------------------------------------------*/
- void
- PassMove(widget,event)
- Widget widget;
- XKeyEvent *event;
- {
- HumanPassMove();
- }
-
- /*----------------------------------------------------------------
- -- InputStone() --
- -- Mouse button press handler for Goban widget. --
- ----------------------------------------------------------------*/
- void
- InputStone(widget,event)
- Widget widget;
- XButtonEvent *event;
- {
- char mv[8];
- Position x = event->x;
- Position y = event->y;
-
-
- if (GbGetStoneFromPosition(widget, &x, &y) != TRUE)
- return;
-
- x--;
- y--;
- sprintf(mv,"%c%d%s",(x<8?x+'A':x+'B'),y+1,(y<9?" ":" "));
-
- if (!ingame && counting)
- {
- DeleteGroupFromStone(x,y);
- return;
- }
-
- if (!ingame && !counting)
- return;
-
- if (!GoPlaceStone(humanColor,x,y))
- return;
-
- if (human_last_x != 0)
- GbSetMark(goban,human_last_x,human_last_y,0,0);
- human_last_x = x+1;
- human_last_y = y+1;
- GbSetMark(goban,human_last_x,human_last_y,0,GbMDiamondMark);
-
- intrMoveReport(humanColor,mv,"");
- human_passed = FALSE;
-
- AmigoMove();
- }
- SHAR_EOF
- fi
- if test -f 'menus.c'
- then
- echo shar: "will not over-write existing file 'menus.c'"
- else
- cat << \SHAR_EOF > 'menus.c'
- /*=========================================================================
- === ===
- === FILE menus.c ===
- === ===
- === CONTENTS Definitions and routines for creating menus. ===
- === ===
- === PART OF xamigo ===
- === ===
- === COPYRIGHT Copyright (C) 1992 by Neil Bowers ===
- === ===
- =========================================================================*/
-
- #include <stdio.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/MenuButton.h>
- #include <X11/Xaw/SimpleMenu.h>
- #include <X11/Xaw/Sme.h>
- #include <X11/Xaw/SmeBSB.h>
- #include <X11/Xaw/SmeLine.h>
- #include "xamigo.h"
-
-
- MenuItem game_items[] =
- {
- {"newGame", NewGameProc, NULL},
- {"stats", PopupStatsProc, NULL},
- {"line", NULL, NULL},
- {"aWhite", OptionProc, NULL},
- {"aBlack", OptionProc, NULL},
- {"line", NULL, NULL},
- {"reason", OptionProc, NULL},
- {"lookahead", OptionProc, NULL},
- {"line", NULL, NULL},
- {"quit", QuitProc, NULL}
- };
-
- MenuItem move_items[] =
- {
- {"pass", MoveProc, NULL},
- {"resign", MoveProc, NULL}
- };
-
- MenuItem level_items[] =
- {
- {"level1", LevelProc, NULL},
- {"level2", LevelProc, NULL},
- {"level3", LevelProc, NULL},
- {"level4", LevelProc, NULL},
- {"level5", LevelProc, NULL},
- {"level6", LevelProc, NULL},
- {"level7", LevelProc, NULL}
- };
-
- MenuItem handicap_items[] =
- {
- {"handicap0", HandicapProc, NULL},
- {"handicap2", HandicapProc, NULL},
- {"handicap3", HandicapProc, NULL},
- {"handicap4", HandicapProc, NULL},
- {"handicap5", HandicapProc, NULL},
- {"handicap6", HandicapProc, NULL},
- {"handicap7", HandicapProc, NULL},
- {"handicap8", HandicapProc, NULL},
- {"handicap9", HandicapProc, NULL}
- };
-
-
- Menu menus[] =
- {
- {"gameMenu", "gameButton",
- game_items, XtNumber(game_items), NULL},
-
- {"moveMenu", "moveButton",
- move_items, XtNumber(move_items), NULL},
-
- {"levelMenu", "levelButton",
- level_items, XtNumber(level_items), NULL},
-
- {"handicapMenu", "handicapButton",
- handicap_items, XtNumber(handicap_items), NULL}
- };
-
-
- void
- CreateAmigoMenus(widget)
- Widget widget;
- {
- CreateMenuStrip(widget,menus,XtNumber(menus));
- }
-
-
- void
- CreateMenuStrip(container,mdef,num)
- Widget container;
- Menu *mdef;
- int num;
- {
- while (num--)
- {
- mdef->menu_button = CreateMenu(container,
- mdef->menu_name,
- mdef->button_name,
- mdef->items,
- mdef->num_items);
- mdef++;
- }
- }
-
-
- Widget
- CreateMenu(parent,menu_name,button_name,menu_items,nitems)
- Widget parent;
- char *menu_name;
- char *button_name;
- MenuItem menu_items[];
- int nitems;
- {
- Widget button, menu, item;
- int i;
-
-
- button = XtVaCreateManagedWidget(button_name,
- menuButtonWidgetClass, parent,
- XtNmenuName, menu_name,
- 0);
-
- menu = XtCreatePopupShell(menu_name, simpleMenuWidgetClass, button,
- NULL, 0);
-
- for (i=0;i<nitems;i++)
- {
- if (!strcmp(menu_items[i].item_name,"line"))
- menu_items[i].widget = XtVaCreateManagedWidget(
- menu_items[i].item_name,
- smeLineObjectClass,menu, 0);
- else
- {
- menu_items[i].widget = XtVaCreateManagedWidget(
- menu_items[i].item_name,
- smeBSBObjectClass,menu,
- 0);
-
- XtAddCallback(menu_items[i].widget,
- XtNcallback, menu_items[i].callback,
- (XtPointer)i);
- }
- }
-
- return button;
- }
- SHAR_EOF
- fi
- if test -f 'stonemask.bm'
- then
- echo shar: "will not over-write existing file 'stonemask.bm'"
- else
- cat << \SHAR_EOF > 'stonemask.bm'
- #define stonemask_width 16
- #define stonemask_height 16
- #define stonemask_x_hot 7
- #define stonemask_y_hot 8
- static char stonemask_bits[] = {
- 0xc0, 0x03, 0xf0, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xfe, 0x7f,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x7f,
- 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, 0xc0, 0x03};
- SHAR_EOF
- fi
- if test -f 'whitestone.bm'
- then
- echo shar: "will not over-write existing file 'whitestone.bm'"
- else
- cat << \SHAR_EOF > 'whitestone.bm'
- #define whitestone_width 16
- #define whitestone_height 16
- #define whitestone_x_hot 7
- #define whitestone_y_hot 8
- static char whitestone_bits[] = {
- 0xc0, 0x03, 0x30, 0x0c, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40,
- 0x01, 0x80, 0x01, 0x80, 0x01, 0x90, 0x01, 0x90, 0x02, 0x48, 0x02, 0x44,
- 0x04, 0x23, 0x08, 0x10, 0x30, 0x0c, 0xc0, 0x03};
- SHAR_EOF
- fi
- if test -f 'xamigo.h'
- then
- echo shar: "will not over-write existing file 'xamigo.h'"
- else
- cat << \SHAR_EOF > 'xamigo.h'
- /*=========================================================================
- === ===
- === FILE xamigo.h ===
- === ===
- === CONTENTS Definitions for xamigo. ===
- === ===
- === PART OF xamigo ===
- === ===
- === AUTHOR Neil Bowers, University of Leeds ===
- === ===
- === DATE 12th July 1992 ===
- === ===
- =========================================================================*/
-
- #ifndef __xamigo_h
- #define __xamigo_h
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
-
- #ifdef __STDC__
- #define PROTO(fp) fp
- #else
- #define PROTO(fp) ()
- #endif
-
-
- typedef struct _MenuItem
- {
- char *item_name;
- void (*callback)();
- Widget widget;
- } MenuItem;
-
-
- typedef struct _Menu
- {
- char *menu_name;
- char *button_name;
- MenuItem *items;
- int num_items;
- Widget menu_button;
- } Menu;
-
-
- /*----------------------------------------------------------------
- -- Function Prototypes --
- ----------------------------------------------------------------*/
-
- void NewGameProc PROTO((Widget,XtPointer,XtPointer));
- void QuitProc PROTO((Widget,XtPointer,XtPointer));
- void LevelProc PROTO((Widget,XtPointer,XtPointer));
- void OptionProc PROTO((Widget,XtPointer,XtPointer));
- void MoveProc PROTO((Widget,XtPointer,XtPointer));
- void HandicapProc PROTO((Widget,XtPointer,XtPointer));
- void PopupStatsProc PROTO((Widget,XtPointer,XtPointer));
- void StatDoneProc PROTO((Widget,XtPointer,XtPointer));
- Widget CreateMenu PROTO((Widget,char *,char *,MenuItem,int));
- void CreateMenuStrip PROTO((Widget,Menu *,int));
- void CreateAmigoMenus PROTO((Widget));
- void InputStone PROTO((Widget,XButtonEvent));
- void PassMove PROTO((Widget,XKeyEvent));
- void HumanPassMove PROTO(());
-
-
- #endif
- SHAR_EOF
- fi
- if test -f 'xamigo.man'
- then
- echo shar: "will not over-write existing file 'xamigo.man'"
- else
- cat << \SHAR_EOF > 'xamigo.man'
- .\" Man page for xamigo, by Neil Bowers
- .TH Xamigo 1.0 "August 12 1992"
- .SH NAME
- \fIXamigo\fR \- An X interface to "AmiGo" --- A Go playing program
- .SH SYNOPSIS
- .B xamigo
- [-\fItoolkit_options\fP]
- .SH DESCRIPTION
- .I Xamigo
- is a simple interface to the
- .I AmiGo
- Go playing program,
- originally written for the Amiga computer.
- The Go player was written by Stoney Ballard,
- with additional code by Todd R. Johnson.
- Xamigo is at best a beta release,
- please send any suggestions for improvements to the author (see below).
-
- When you invoke xamigo,
- a window will appear which contains a goban with a row
- of menu buttons across the top.
- There are four menus, which are described in the following sections.
-
- .SH "GAME MENU"
-
- The Project menu contains entries which give control over xamigo,
- rather than the wally code, or the goban.
- The menu items are as follows:
- .TP 8
- .BI "New Game"
- clears the goban and starts a new game,
- using the level and handicap selected on the appropriate menus.
- .TP 8
- .BI "Game Stats"
- pops up a window which presents game details for the players ---
- last move and stones captured --- and a text window used to display
- messages from xamigo, such as the final score when the game is over.
- The Game Stats window has a
- .BI Done
- button which will pop down the window.
- .TP 8
- .BI "Amigo Plays White"
- .TP 8
- .BI "Amigo Plays Black"
- hopefully obvious. One (and only one) of these items should be checked,
- signifying which color the computer will take in the next game.
- .TP 8
- .BI "Move Reason"
- if this item is checked, then whenever the computer player makes a move,
- the reasoning behind the move will be displayed in the message area
- of the stats window.
- .TP 8
- .BI "Show Lookahead"
- If checked, then xamigo will display each move which it is considering.
- Fun to look at the first time,
- but slows down the play.
- .TP 8
- .BI "Quit"
- guess what this does.
-
- .SH "MOVES MENU"
- The Moves menu contains items related to moves once the game is in play.
- .TP 8
- .BI "Pass"
- pass this move.
- When both players pass, you can then remove dead groups by clicking on stones.
- Once all dead groups have been removed, selecting Pass again will
- result in the final score being displayed in the message window
- (which is part of the Game Stats popup window).
- The `p' key can be used as a short-cut for pass.
- .TP 8
- .BI "Resign"
- resign the current game.
- .LP
- Other commands which could be added in the future include `undo',
- `make my move for me', etc.
-
- .SH "LEVEL MENU"
- Select the level at which xamigo should play, between 1 and 7,
- with 7 the highest.
-
- .SH "HANDICAP MENU"
-
- The Handicap
- menu is used to set the handicap for the next game.
-
- .SH OPTIONS
- \fIXamigo\fP accepts the standard X Toolkit command line options.
- One day there might be some xamigo options, who knows?
-
- .SH RESOURCES
- \fIXamigo\fP accepts the standard X Toolkit resource names and classes.
- See OPTIONS above.
-
- .SH BUGS
- Plenty no doubt. Please let me know if you find any.
-
- .SH COPYRIGHT
- The Goban widget is copyright (c) 1992 by Antoine Dumesnil de Maricourt.
-
- The xamigo specific code is copyright (c) 1992 by Neil Bowers.
- Feel free to distribute xamigo and use any code,
- provided you give due credit to the respective authors.
-
- .SH AUTHOR
- .nf
- Go player: Stoney Ballard
- .fi
-
- .nf
- Goban Widget: Antoine Dumesnil de Maricourt
- Email: dumesnil@etca.fr
- .fi
-
- .nf
- Xamigo: Neil Bowers
- School of Computer Studies
- University of Leeds.
- Email: neilb@scs.leeds.ac.uk
- .fi
-
- SHAR_EOF
- fi
- if test -f 'xinterface.c'
- then
- echo shar: "will not over-write existing file 'xinterface.c'"
- else
- cat << \SHAR_EOF > 'xinterface.c'
- /* AmiGo Interface. Started 4/7/88 by Todd R. Johnson */
- /* 8/8/89 Cleaned up for first release */
- /* Version 1.0 */
- /* Public Domain */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include "Goban.h"
- #include <stdio.h>
-
- #include "amigo.h"
-
- extern Widget goban;
- extern Widget black_stat_widgets[5];
- extern Widget white_stat_widgets[5];
- extern Widget message;
-
-
- extern short showTrees, playLevel, showMoveReason, groupInfo;
-
-
- /* Print a stone of color at x, y intersection */
- void
- placestone(color, x, y)
- enum bVal color;
- short x, y;
- {
- GbSetPoint(goban,++x,++y,(color==BLACK ? GbBlackStone : GbWhiteStone));
- UpdateWidget(goban);
- }
-
- /* Remove a stone from an intersection */
- void
- removestone(x, y)
- short x, y;
- {
- GbSetPoint(goban,++x,++y,GbEmptyPoint);
- UpdateWidget(goban);
- }
-
- /* Report on a move */
- void
- intrMoveReport(color, coord, reason)
- enum bVal color;
- char *coord;
- char *reason;
- {
- XtVaSetValues(message, XtNstring,"", NULL);
-
- XtVaSetValues((color == BLACK ? black_stat_widgets[4] :
- white_stat_widgets[4]),XtNlabel,coord,0);
-
- XtVaSetValues(message,XtNstring, (showMoveReason ? reason : ""), NULL);
- }
-
- void
- intrPrisonerReport(blackcnt, whitecnt)
- short blackcnt;
- short whitecnt;
- {
- char val[5];
-
- sprintf(val,"%d",blackcnt);
- XtVaSetValues(white_stat_widgets[2],XtNlabel,val,0);
- sprintf(val,"%d",whitecnt);
- XtVaSetValues(black_stat_widgets[2],XtNlabel,val,0);
- }
-
- #if 0
- void intrCredits()
- {
- intrPuts( "Player by Stoney Ballard" ); intrPutLn();
- intrPuts( "C port and interface"); intrPutLn();
- intrPuts( "by Todd R. Johnson"); intrPutLn();
- intrPutLn();
- intrPuts( "Use menus to set options." ); intrPutLn();
- intrPuts( "Select the Play menu" ); intrPutLn();
- intrPuts( "item to begin play." );
- }
- #endif
-
- UpdateWidget(widget)
- Widget widget;
- {
- XEvent event;
-
-
- while (XCheckTypedWindowEvent(XtDisplay(widget),XtWindow(widget),
- Expose,&event))
- XtDispatchEvent(&event);
- }
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
-