由于不是五手两打开局,所以执黑必胜,所以推荐执白

而且禁手只考虑了长连

五子棋理论上已经证明过如果没有任何规则,执黑先行的人如果每一步都应对得正确的话,是必胜的,也就是说,执黑因为有先手优势,每一步都有必胜的落子点,白棋不管怎么应对,结果都是很输的,所以为了抵消执黑的优势,在国际五子棋比赛里才规定了五手两打(上面打错了)和禁手的规则, 

所谓的五手两打就是执黑和执白各走了二步后执黑连下两子让执白选择一个,去掉一个,然后继续, 

还有三手交换,执黑和执白各走了一步后,执黑再走一步,如果执白这时发现开局对自己不利,可以要求互换,也就是执黑变执白,执白变执黑, 

禁手就是不能下的点,连六、连七等都叫长连,比如执黑,也就是说下了这个子后,棋盘上连续的黑子超过了5个,那就不能下这点,三三禁手就是下了这点后棋盘上出现了两个(或更多)的活三(活三就是连续3个而且两头都是空格),四四禁手一样,就是连续4个子(不一定要两头都是空格)的情况出现了2个或以上 

禁手对执白同样成立, 

比赛可以规定有禁手和无禁手两种比赛规则 

比如三三禁手: 
         口 
口黑黑X 口 
         黑 
         黑 
         口 

X处不能下

源代码及Demo下载

 http://download.csdn.net/source/1896609

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8.   
  9. namespace wzq  
  10. {  
  11.     /// <summary>  
  12.     /// Made by Wartim 1.0  
  13.     /// </summary>  
  14.     public partial class Form1 : Form  
  15.     {  
  16.         const int BORDER_LINES = 5; // >=5  
  17.         const int DESK_LINES = 15;  
  18.         const int TOTAL_LINES = DESK_LINES + BORDER_LINES * 2;  
  19.         static int[,] Desk = new int[TOTAL_LINES, TOTAL_LINES];  
  20.         static int SPACE = 0;  
  21.         static int PLAYER = 1;  
  22.         static int CPU  
  23.         {  
  24.             get  
  25.             {  
  26.                 return 3 - PLAYER;  
  27.             }  
  28.         }  
  29.         static int BORDER = 3;  
  30.         PictureBox PB = new PictureBox();  
  31.   
  32.         public Form1()  
  33.         {  
  34.             InitializeComponent();  
  35.   
  36.             PB.Parent = this;  
  37.             PB.Dock = DockStyle.Fill;  
  38.             PB.MouseClick += new MouseEventHandler(PB_MouseClick);  
  39.   
  40.             this.MaximizeBox = false;  
  41.             this.ClientSize = new Size(TOTAL_LINES * 10, TOTAL_LINES * 10);  
  42.             this.FormBorderStyle = FormBorderStyle.FixedSingle;  
  43.             this.StartPosition = FormStartPosition.CenterScreen;   
  44.   
  45.             Start();  
  46.         }  
  47.   
  48.         void Start()  
  49.         {  
  50.             for (int i = 0; i < TOTAL_LINES; i++)  
  51.                 for (int j = 0; j < TOTAL_LINES; j++)  
  52.                     if (i >= BORDER_LINES && i < BORDER_LINES + DESK_LINES  
  53.                         && j >= BORDER_LINES && j < BORDER_LINES + DESK_LINES)  
  54.                         Desk[i, j] = SPACE;  
  55.                     else  
  56.                         Desk[i, j] = BORDER;  
  57.             Draw();  
  58.   
  59.             if (MessageBox.Show("执黑?""开局", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk) == DialogResult.Yes)  
  60.                 PLAYER = 1;  
  61.             else  
  62.             {  
  63.                 Random R = new Random();  
  64.   
  65.                 PLAYER = 2;  
  66.                 Desk[BORDER_LINES + DESK_LINES / 3 + R.Next(DESK_LINES / 3),  
  67.                     BORDER_LINES + DESK_LINES / 3 + R.Next(DESK_LINES / 3)] = CPU;  
  68.                 Draw();  
  69.             }  
  70.         }  
  71.   
  72.         void PB_MouseClick(object sender, MouseEventArgs e)  
  73.         {  
  74.             int X = e.X / 10;  
  75.             int Y = e.Y / 10;  
  76.   
  77.             if (X >= BORDER_LINES && X <= BORDER_LINES + DESK_LINES - 1  
  78.                 && Y >= BORDER_LINES && Y <= BORDER_LINES + DESK_LINES - 1)  
  79.             {  
  80.                 if (Desk[X, Y] != SPACE)  
  81.                     return;  
  82.   
  83.                 Desk[X, Y] = PLAYER;  
  84.                 for (int k = 0; k < 8; k++)  
  85.                 {  
  86.                     int Count = LineLength(GetCheckString(X, Y, k).Replace('X''P'), 'P');  
  87.                     if (Count > 5)  
  88.                     {  
  89.                         Desk[X, Y] = SPACE;  
  90.                         MessageBox.Show("禁手!");  
  91.                         return;  
  92.                     }  
  93.                     if (Count == 5)  
  94.                     {  
  95.                         Draw();  
  96.                         MessageBox.Show("你赢了");  
  97.                         Start();  
  98.                         return;  
  99.                     }  
  100.                 }  
  101.                 Draw();  
  102.   
  103.                 Compute();  
  104.             }  
  105.         }  
  106.   
  107.         void Draw()  
  108.         {  
  109.             if (PB.Image != null)  
  110.                 PB.Image.Dispose();  
  111.             Bitmap Bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);  
  112.             using (Graphics G = Graphics.FromImage(Bmp))  
  113.             {  
  114.                 G.Clear(Color.LightGreen);  
  115.   
  116.                 for (int i = 0; i < TOTAL_LINES; i++)  
  117.                     for (int j = 0; j < TOTAL_LINES; j++)  
  118.                         if (Desk[i, j] == SPACE )  
  119.                         {  
  120.                             G.DrawLine(Pens.Gray, i * 10, j * 10 + 5, i * 10 + 10, j * 10 + 5);  
  121.                             G.DrawLine(Pens.Gray, i * 10 + 5, j * 10, i * 10 + 5, j * 10 + 10);  
  122.                         }  
  123.                         else if (Desk[i, j] != BORDER)  
  124.                         {  
  125.                             Color FillColor = Desk[i, j] == 1 ? Color.Black  : Color.White ;  
  126.   
  127.                             G.FillPie(new SolidBrush(FillColor), new Rectangle(i * 10, j * 10, 10, 10),0,360);  
  128.                         }  
  129.   
  130.                 PB.Image = Bmp;  
  131.             }  
  132.         }  
  133.   
  134.         void Compute()  
  135.         {  
  136.             double Max = 0;  
  137.             int X = 0;  
  138.             int Y = 0;  
  139.             for (int i = BORDER_LINES; i <= BORDER_LINES + DESK_LINES - 1; i++)  
  140.                 for (int j = BORDER_LINES; j <= BORDER_LINES + DESK_LINES - 1; j++)  
  141.                     if (Desk[i, j] == SPACE)  
  142.                     {  
  143.                         double Sum = 0;  
  144.                         for (int k = 0; k < 8; k++)  
  145.                         {  
  146.                             Desk[i, j] = CPU;  
  147.                             if (LineLength(GetCheckString(i, j, k).Replace('X''C'), 'C') == 5)  
  148.                             {  
  149.                                 Draw();  
  150.                                 MessageBox.Show("你输了!");  
  151.                                 Start();  
  152.                                 return;  
  153.                             }  
  154.                             Desk[i, j] = SPACE;  
  155.   
  156.                             Sum += GetSource(GetCheckString(i, j, k));  
  157.                         }  
  158.                         if (Sum > Max)  
  159.                         {  
  160.                             Max = Sum;  
  161.                             X = i;  
  162.                             Y = j;  
  163.                         }  
  164.                     }  
  165.   
  166.             Desk[X, Y] = CPU;  
  167.             Draw();  
  168.         }  
  169.   
  170.         String GetCheckString(int i, int j, int Direct)  
  171.         {  
  172.             int StartX = 0;  
  173.             int StartY = 0;  
  174.             if (Direct == 0 || Direct == 4)  
  175.                 StartX = 0;  
  176.             else if (Direct == 1 || Direct == 2 || Direct == 3)  
  177.                 StartX = 5;  
  178.             else  
  179.                 StartX = -5;  
  180.             if (Direct == 2 || Direct == 6)  
  181.                 StartY = 0;  
  182.             else if (Direct == 3 || Direct == 4 || Direct == 5)  
  183.                 StartY = 5;  
  184.             else  
  185.                 StartY = -5;  
  186.   
  187.             int XStep = -Math.Sign(StartX);  
  188.             int YStep = -Math.Sign(StartY);  
  189.             String S = String.Empty;  
  190.             int X = i + StartX;  
  191.             int Y = j + StartY;  
  192.   
  193.             for (int k = 0; k < 10 + 1; k++, X += XStep, Y += YStep)  
  194.                 if (X == i && Y == j)  
  195.                     S += "X";  
  196.                 else if (Desk[X, Y] != 3)  
  197.                     S += Desk[X, Y].ToString();  
  198.               
  199.             return S.Replace((Char)(PLAYER + '0'), 'P').Replace((Char)(CPU + '0'), 'C');  
  200.         }  
  201.   
  202.         double GetSource(String CheckString)  
  203.         {  
  204.             double Source = 0;  
  205.             String[][] CheckArea =  
  206.             {  
  207.                 new String[]  
  208.                 {  
  209.                     "XPPPP","PXPPP","PPXPP","PPPXP","PPPPX" // 玩家 连5  
  210.                 },  
  211.                 new String[]  
  212.                 {  
  213.                     "0XCCC0","0CXCC0","0CCXC0","0CCCX0"// 连4全连通  
  214.                 },  
  215.                 new String[]  
  216.                 {  
  217.                     "0XPPP0","0PXPP0","0PPXP0","0PPPX0"// 玩家 连4全连通  
  218.                 },  
  219.                 new String[]  
  220.                 {  
  221.                     "XCCC0","CXCC0","CCXC0","CCCX0" // 连4半连通  
  222.                 },  
  223.                 new String[]  
  224.                 {  
  225.                     "XPPP0","PXPP0","PPXP0","PPPX0" // 玩家 连4半连通  
  226.                 },  
  227.                 new String[]  
  228.                 {  
  229.                     "X0CCC","C0XCC","C0CXC","C0CCX"// 连4  
  230.                     "XC0CC","CX0CC","CC0XC","CC0CX",  
  231.                     "XCC0C","CXC0C","CCX0C","CCC0X",  
  232.                 },  
  233.                 new String[]  
  234.                 {  
  235.                     "X0PPP","P0XPP","P0PXP","P0PPX"// 玩家 连4  
  236.                     "XP0PP","PX0PP","PP0XP","PP0PX",  
  237.                     "XPP0P","PXP0P","PPX0P","PPP0X",  
  238.                 },  
  239.                 new String[]  
  240.                 {  
  241.                     "0XCC0","0CXC0","0CCX0"  // 连3全连通  
  242.                 },  
  243.                 new String[]  
  244.                 {  
  245.                     "0XPP0","0PXP0","0PPX0"  // 玩家 连3全连通  
  246.                 },  
  247.                 new String[]  
  248.                 {  
  249.                     "0X0CC0","0CX0C0","0C0XC0","0CC0X0" // 连3  
  250.                 },  
  251.                 new String[]  
  252.                 {  
  253.                     "0X0PP0","0PX0P0","0P0XP0","0PP0X0" // 玩家 连3  
  254.                 },  
  255.                 new String[]  
  256.                 {  
  257.                     "0XC0","0CX0" // 连2全连通  
  258.                 },  
  259.                 new String[]  
  260.                 {  
  261.                     "0XP0","0PX0" // 玩家 连2全连通  
  262.                 },  
  263.                 new String[]  
  264.                 {  
  265.                     "0X0P0","0P0X0" // 连2  
  266.                 },  
  267.                 new String[]  
  268.                 {  
  269.                     "0X0C0","0C0X0" // 玩家 连2  
  270.                 }  
  271.             };  
  272.             int CPUCount = LineLength(CheckString.Replace('X''C'), 'C');  
  273.             int PLAYERCount = LineLength(CheckString, 'P');  
  274.   
  275.             if (CPUCount > 5 || PLAYERCount > 5)  
  276.                 return -1;  
  277.             else if (CPUCount == 5)  
  278.                 return GetN(CheckArea.GetUpperBound(0) + 1) + 1;  
  279.             else if (PLAYERCount == 5)  
  280.                 return GetN(CheckArea.GetUpperBound(0) + 1);  
  281.             else  
  282.             {  
  283.                 for (int i = 0; i <= CheckArea.GetUpperBound(0); i++)  
  284.                     foreach (String S in CheckArea[i])  
  285.                         if (CheckString.IndexOf(S) > 0)  
  286.                         {  
  287.                             Source += GetN(CheckArea.GetUpperBound(0) - i);  
  288.                             break;  
  289.                         }  
  290.             }  
  291.             for (int i = 0; i < CheckString.Length; i++)  
  292.             {  
  293.                 int LineChar = CheckString[i];  
  294.                 Source += LineChar == 'C' ? 3 : LineChar == 'P' ? 2 : LineChar == '0' ? 1 : 0;  
  295.             }  
  296.             Source += CPUCount * 2 + PLAYERCount;  
  297.             return Source;  
  298.         }  
  299.   
  300.         double GetN(int M)  
  301.         {  
  302.             if (M == 0)  
  303.                 return 1000;  
  304.             else  
  305.                 return GetN(M - 1) * 8 + 1;  
  306.         }  
  307.   
  308.         int LineLength(String CheckString, Char LineChar)  
  309.         {  
  310.             int Max = 0;  
  311.             int Count = 0;  
  312.             for (int i = 0; i < CheckString.Length; i++)  
  313.                 if (CheckString[i] == LineChar)  
  314.                     Count++;  
  315.                 else  
  316.                 {  
  317.                     if (Count > Max)  
  318.                         Max = Count;  
  319.                     Count = 0;  
  320.                 }  
  321.             if (Count > Max)  
  322.                 Max = Count;  
  323.             return Max;  
  324.         }  
  325.     }  
  326. }  

原文 http://blog.csdn.net/wartim/archive/2009/12/12/4993364.aspx



dm520