home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / Games / NeXTGo / Source / matchpat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1977-12-27  |  5.3 KB  |  208 lines

  1. /*
  2.   GNU GO - the game of Go (Wei-Chi)
  3.   Version 1.1   last revised 3-1-89
  4.   Copyright (C) Free Software Foundation, Inc.
  5.   written by Man L. Li
  6.   modified by Wayne Iba
  7.   documented by Bob Webber
  8.   NeXT version by John Neil
  9.   */
  10. /*
  11.   This program is free software; you can redistribute it and/or modify
  12.   it under the terms of the GNU General Public License as published by
  13.   the Free Software Foundation - version 1.
  14.   
  15.   This program is distributed in the hope that it will be useful,
  16.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.   GNU General Public License in file COPYING for more details.
  19.   
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.   
  24.   Please report any bug/fix, modification, suggestion to
  25.   
  26.   mail address:   Man L. Li
  27.   Dept. of Computer Science
  28.   University of Houston
  29.   4800 Calhoun Road
  30.   Houston, TX 77004
  31.   
  32.   e-mail address: manli@cs.uh.edu         (Internet)
  33.   coscgbn@uhvax1.bitnet   (BITNET)
  34.   70070,404               (CompuServe)
  35.  
  36. For the NeXT version, please report any bug/fix, modification, suggestion to
  37.  
  38. mail address:   John Neil
  39.                 Mathematics Department
  40.                 Portland State University
  41.                 PO Box 751
  42.                 Portland, OR  97207
  43.  
  44. e-mail address: neil@math.mth.pdx.edu  (Internet)
  45.                 neil@psuorvm.bitnet    (BITNET)
  46.   */
  47.  
  48. #define EMPTY 0
  49. #define MAXPC 16
  50. #define abs(x) ((x) < 0 ? -(x) : (x))
  51. #define line(x) (abs(x - 9))
  52.  
  53. extern unsigned char p[19][19];
  54. extern int currentStone, opposingStone, MAXX, MAXY;
  55. extern int lib;
  56. extern void countlib(int,int,int);
  57.  
  58. int matchpat(int m, int n, int *i, int *j, int *val)
  59.      /* match pattern and get next move */
  60. {
  61.   struct patval {int x, y, att;}; /* pattern x, y coor and attribute */
  62.   /* att = 0 - empty, 1 - your piece, 2 - my piece, 3 - my next move */
  63.   /* 4 - empty on edge, 5 - your piece on edge, 6 - my piece on edge */
  64.   struct pattern {
  65.     struct patval patn[MAXPC];   /* pattern */
  66.     /* number of pieces in pattern, no. of transformation, pattern value */
  67.     int patlen, trfno, patwt;
  68.   };
  69.   
  70. #include "patterns.h"
  71.   
  72.   /* transformation matrice */
  73.   static int trf [8][2][2] = {
  74.     {{1, 0}, {0, 1}}, /* linear transfomation matrix */
  75.     {{1, 0}, {0, -1}},  /* invert */
  76.     {{0, 1}, {-1, 0}},  /* rotate 90 */
  77.     {{0, -1}, {-1, 0}},    /* rotate 90 and invert */
  78.     {{-1, 0}, {0, 1}},  /* flip left */
  79.     {{-1, 0}, {0, -1}},    /* flip left and invert */
  80.     {{0, 1}, {1, 0}},  /* rotate 90 and flip left */
  81.     {{0, -1}, {1, 0}}  /* rotate 90, flip left and invert */
  82.   };
  83.   int k, my, nx, l, r, cont;
  84.   int ti, tj, tval;
  85.   
  86.   *i = -1;   *j = -1;   *val = -1;
  87.   for (r = 0; r < PATNO; r++)
  88.     /* try each pattern */
  89.     for (l = 0; l < pat[r].trfno; l++)
  90.       /* try each orientation transformation */
  91.       {
  92.     k = 0;  cont = 1;
  93.     while ((k != pat[r].patlen) && cont)
  94.       /* match each point */
  95.       {
  96.         /* transform pattern real coordinate */
  97.         nx = n + trf[l][0][0] * pat[r].patn[k].x
  98.           + trf[l][0][1] * pat[r].patn[k].y;
  99.         my = m + trf[l][1][0] * pat[r].patn[k].x
  100.           + trf[l][1][1] * pat[r].patn[k].y;
  101.         
  102.         /* outside the board */
  103.         if ((my < 0) || ( my > MAXY - 1) || (nx < 0) || (nx > MAXX - 1))
  104.           {
  105.         cont = 0;
  106.         break;
  107.           }
  108.         switch (pat[r].patn[k].att) {
  109.         case 0 : if (p[my][nx] == EMPTY)    /* open */
  110.           break;
  111.         else
  112.           {
  113.         cont = 0;
  114.         break;
  115.           }
  116.         case 1 : if (p[my][nx] == opposingStone)  /* your piece */
  117.           break;
  118.         else
  119.           {
  120.         cont = 0;
  121.         break;
  122.           }
  123.         case 2 : if (p[my][nx] == currentStone)  /* my piece */
  124.           break;
  125.         else
  126.           {
  127.         cont = 0;
  128.         break;
  129.           }
  130.         case 3 : if (p[my][nx] == EMPTY)    /* open for new move */
  131.           {
  132.         lib = 0;
  133.         countlib(my, nx, currentStone);    /* check liberty */
  134.         if (lib > 1)  /* move o.k. */
  135.           {
  136.             ti = my;
  137.             tj = nx;
  138.             break;
  139.           }
  140.         else
  141.           {
  142.             cont = 0;
  143.             break;
  144.           }
  145.           }
  146.         else
  147.           {
  148.         cont = 0;
  149.         break;
  150.           }
  151.         case 4 : if ((p[my][nx] == EMPTY)  /* open on edge */
  152.              && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
  153.           break;
  154.         else
  155.           {
  156.         cont = 0;
  157.         break;
  158.           }
  159.         case 5 : if ((p[my][nx] == opposingStone)  /* your piece on edge */
  160.              && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
  161.           break;
  162.         else
  163.           {
  164.         cont = 0;
  165.         break;
  166.           }
  167.         case 6 : if ((p[my][nx] == currentStone)  /* my piece on edge */
  168.              && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
  169.           break;
  170.         else
  171.           {
  172.         cont = 0;
  173.         break;
  174.           }
  175.         }
  176.         ++k;
  177.       }
  178.     if (cont)   /* match pattern */
  179.       {
  180.         tval = pat[r].patwt;
  181.         if ((r >= 8) && (r <= 13))    /* patterns for expand region */
  182.           {
  183.         if (line(ti) > 7)  /* penalty on line 1, 2 */
  184.           tval--;
  185.         else
  186.           if ((line(ti) == 6) || (line(ti) == 7))
  187.             tval++;    /* reward on line 3, 4 */
  188.         
  189.         if (line(tj) > 7)  /* penalty on line 1, 2 */
  190.           tval--;
  191.         else
  192.           if ((line(tj) == 6) || (line(tj) == 7))
  193.             tval++;    /* reward on line 3, 4 */
  194.           }
  195.         if (tval > *val)
  196.           {
  197.         *val = tval;
  198.         *i = ti;
  199.         *j = tj;
  200.           }
  201.       }
  202.       }
  203.   if (*val > 0)    /* pattern matched */
  204.     return 1;
  205.   else  /* match failed */
  206.     return 0;
  207. }  /* end matchpat */
  208.