简单五子棋算法

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

    而且禁手只考虑了长连

     

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

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

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

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

    禁手对执白同样成立, 

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

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

    X处不能下


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值