看看别人的程序:C# ---五子棋游戏

来源:互联网 发布:淘宝支付限额怎么使用 编辑:程序博客网 时间:2024/05/17 05:54

C# 实现编写了五子棋游戏

字体变小 字体变大

今天我使用 C# 实现编写了五子棋游戏。该游戏代码中我作了详细的注释,希望对大家有所帮助。

本游戏主要由 几个类 和 一个主窗口组成。

using System.Reflection;
using System.Runtime.CompilerServices;

//
// 有关程序集的常规信息是通过下列
// 属性集控制的。更改这些属性值可修改与程序集
// 关联的信息。
//
[assembly: AssemblyTitle("FiveStones")]
[assembly: AssemblyDescription("这是一个用C#编写的五子棋程序。")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("二十四画生")]
[assembly: AssemblyProduct("C#版五子棋")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

//
// 程序集的版本信息由下列 4 个值组成:
//
//      主版本
//      次版本 
//      内部版本号
//      修订号
//
// 您可以指定所有这些值,也可以使用“修订号”和“内部版本号”的默认值,方法是按
// 如下所示使用 '*':

[assembly: AssemblyVersion("1.0.1")]

//
// 要对程序集进行签名,必须指定要使用的密钥。有关程序集签名的更多信息,请参考 
// Microsoft .NET Framework 文档。
//
// 使用下面的属性控制用于签名的密钥。
//
// 注意:
//   (*) 如果未指定密钥,则程序集不会被签名。
//   (*) KeyName 是指已经安装在计算机上的
//      加密服务提供程序(CSP)中的密钥。KeyFile 是指包含
//       密钥的文件。
//   (*) 如果 KeyFile 和 KeyName 值都已指定,则 
//       发生下列处理:
//       (1) 如果在 CSP 中可以找到 KeyName,则使用该密钥。
//       (2) 如果 KeyName 不存在而 KeyFile 存在,则 
//           KeyFile 中的密钥安装到 CSP 中并且使用该密钥。
//   (*) 要创建 KeyFile,可以使用 sn.exe(强名称)实用工具。
//       在指定 KeyFile 时,KeyFile 的位置应该相对于
//       项目输出目录,即
//       %Project Directory%/obj/<configuration>。例如,如果 KeyFile 位于
//       该项目目录,应将 AssemblyKeyFile 
//       属性指定为 [assembly: AssemblyKeyFile("..//..//mykey.snk")]
//   (*) “延迟签名”是一个高级选项 - 有关它的更多信息,请参阅 Microsoft .NET Framework
//       文档。
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

using System;

namespace FiveStones
{
 /// <summary>
 /// Computer 的摘要说明。
 /// 电脑类。计算电脑下棋的位置
 /// </summary>
 public class Computer
 {
  private bool mflag; //区别电脑是下黑棋还是下白棋
  private int x;  //电脑下子的位置
  private int y;  //电脑下子的位置

  public Computer(bool flag)
  {
   mflag = flag;
  }

  public int X
  {
   get
   {
    return x;
   }
  }

  public int Y
  {
   get
   {
    return y;
   }
  }


  /// <summary>
  /// 电脑下棋
  /// </summary>
  /// <param name="arrchessboard"></param>
  public void Down(int[,] arrchessboard)
  {
   //权值数组
   int [,] qz = new int[15,15];
   //基本思路:先计算每个点的权值,在权值最高的位置下棋
   for (int i=0;i<15;i++)
   {
    for(int j=0;j<15;j++)
    {
     if (arrchessboard[i,j] < 2)
     {
      qz[i,j] = -1;  //当已有子时标注为-1
     }
     else
     {
      qz[i,j] = Check(i,j,arrchessboard);
     }
    }
   }

   //找出权值最大的点
   MaxQZ(qz);


   //先不考虑智能问题,只管下棋的地方无子
   //Random r = new Random();
   //x = r.Next(0,14);
   //y = r.Next(0,14);

  }

  /// <summary>
  /// 找出权值最大点
  /// </summary>
  /// <param name="qz"></param>
  private void MaxQZ(int [,] qz)
  {
   int max = 0;
   for (int i=0;i<15;i++)
   {
    for(int j=0;j<15;j++)
    {
     if (qz[i,j]>max)
     {
      x = i;
      y = j;
      max = qz[i,j];
     }
    }
   }
  }

  /// <summary>
  /// 检查m,n点的权值
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns></returns>
  private int Check(int m, int n, int[,] arrchessboard)
  {
   int qz = 0;
   //找自己的取胜点(1000)
   int w1 = 100000;
   //找对手的取胜点(80)
   int w2 = 50000;
   //找自己的三个相连的点(60)
   int w3 = 10000;
   //找对手的三个相连的点(40)
   int w4 = 5000;
   //找自己的两个相连的点(20)
   int w5 = 1000;
   //找对手的两个相连的点(10)
   int w6 = 500;
   //找自己的相连的点(5)
   int w7 = 100;
   //找对方的相连的点(5)
   int w8 = 50;
   //找自己的失败点
   int w9 = -1000000;

   int[] arrf = new int[4];
   //如果该位置下我方的子
   if (mflag)
   {
    //我方黑子
    arrchessboard[m,n] = 0;
   }
   else
   {
    //我方白子
    arrchessboard[m,n] = 1;
   }
   arrf[0] = Rule.Xnum(m,n,arrchessboard);
   arrf[1] = Rule.Ynum(m,n,arrchessboard);
   arrf[2] = Rule.YXnum(m,n,arrchessboard);
   arrf[3] = Rule.XYnum(m,n,arrchessboard);
   //中心点权值加1
   if (m==7 && n==7){qz+=1;}

   for (int i=0;i<4;i++)
   {
    if (Math.Abs(arrf[i]) == 5)
    {
     qz += w1;
    }
    if (arrf[i] == 4)
    {
     qz += w3;
    }
    if (arrf[i] == 3)
    {
     qz += w5;
    }
    if (arrf[i] == 2)
    {
     qz += w7;
    }
    //如果我方为黑棋,还要检查失败点
    if (mflag)
    {
     if (Rule.IsFail(arrf, arrchessboard[m,n])>0)
     {
      qz += w9;
     }
    }
   }
   //如果该位置下对方的子
   if (mflag)
   {
    //对方白子
    arrchessboard[m,n] = 1;
   }
   else
   {
    //对方黑子
    arrchessboard[m,n] = 0;
   }
   arrf[0] = Rule.Xnum(m,n,arrchessboard);
   arrf[1] = Rule.Ynum(m,n,arrchessboard);
   arrf[2] = Rule.YXnum(m,n,arrchessboard);
   arrf[3] = Rule.XYnum(m,n,arrchessboard);

   for (int i=0;i<4;i++)
   {
    if (Math.Abs(arrf[i]) == 5)
    {
     qz += w2;
    }
    if (arrf[i] == 4)
    {
     qz += w4;
    }
    if (arrf[i] == 3)
    {
     qz += w6;
    }
    if (arrf[i] == 2)
    {
     qz += w8;
    }
   }
   //数组好像是引用传递,探测完后恢复到默认值
   arrchessboard[m,n] = 2;
   return qz;
  }
 }
}
using System;

namespace FiveStones
{
 /// <summary>
 /// Rule 的摘要说明。
 /// 游戏规则类
 /// </summary>
 public class Rule
 {
  
  /// <summary>
  /// 判断下棋位置是否有子
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns></returns>
  public static bool IsExist(int m, int n, int[,] arrchessboard)
  {
   if (arrchessboard[m,n] < 2)
   {
    return true;
   }
   else
   {
    return false;
   }
  }

  /// <summary>
  /// 返回结果(1:双三禁手失败/2:双四禁手失败/3:长连禁手失败/4:胜利/5:平局/6:继续)
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns></returns>
  public static int Result(int m, int n, int[,] arrchessboard)
  {
   //m,n点四个方向的连子数,依次正东正西,正南正北方,西北东南,西南东北
   int[] arrf = new int[4];
   arrf[0] = Xnum(m,n,arrchessboard);
   arrf[1] = Ynum(m,n,arrchessboard);
   arrf[2] = YXnum(m,n,arrchessboard);
   arrf[3] = XYnum(m,n,arrchessboard);

   //测试
   //return Ynum(m,n,arrchessboard);

   //检查是否失败
   if (IsFail(arrf, arrchessboard[m,n]) > 0)
   {
    return IsFail(arrf, arrchessboard[m,n]);
   }
   else
   {
    //检查是否胜利
    if (IsWin(arrf))
    {
     return 4;
    }
    else
    {
     //检查是否平局
     if (IsTie(arrchessboard))
     {
      return 5;
     }
     else
     {
      return 6;
     }
    }
   }
  }

  #region  检查是否失败,是否胜利,是否平局
  
  /// <summary>
  /// 是否失败(0:没有失败/1:双三禁手/2:双四禁手/3:长连禁手)
  /// </summary>
  /// <param name="arr"></param>
  /// <param name="stoneflag">是黑棋还是白棋</param>
  /// <returns>没有失败:0/双三禁手:1/双四禁手:2/长连禁手:3</returns>
  public static int IsFail(int[] arr, int stoneflag)
  {
   if (stoneflag == 1)
   {
    //如果是白棋不验证因为白棋无禁手
    return 0;
   }
   else
   {
    //验证双三禁手(该处的双三因该是活的双三吧)
    int num = 0;  //活的3子相连的个数
    for (int i=0;i<4;i++)
    {
     if (arr[i] == 3)
     {
      num++;
     }
    }
    if (num > 1)
    {
     return 1;
    }
    //验证双四禁手(该处的双四因该是活的双四吧)
    num = 0;  //活的4子相连的个数
    for (int i=0;i<4;i++)
    {
     if (arr[i] == 4)
     {
      num++;
     }
    }
    if (num > 1)
    {
     return 2;
    }
    //验证长连禁手
    for (int i=0;i<4;i++)
    {
     if (Math.Abs(arr[i]) > 5)
     {
      return 3;
     }
    }
    return 0;
   }
  }

  /// <summary>
  /// 是否胜利
  /// </summary>
  /// <param name="arr"></param>
  /// <returns>胜利:true</returns>
  private static bool IsWin(int[] arr)
  {
   for (int i=0;i<4;i++)
   {
    if (Math.Abs(arr[i]) == 5)
    {
     return true;
    }
   }
   return false;
  }

  
  /// <summary>
  /// 是否平局
  /// </summary>
  /// <param name="arrchessboard"></param>
  /// <returns>平局:true</returns>
  private static bool IsTie(int[,] arrchessboard)
  {
   //当所有位置都有子时为平局
   for (int i=0;i<15;i++)
   {
    for (int j=0;j<15;j++)
    {
     if (arrchessboard[i,j] == 2)
      return false;
    }
   }
   return true;
  }

  #endregion

  #region 从四个方向检测,连子个数

  /// <summary>
  /// 正东正西检测与m,n点棋子相同的棋子个数
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns>如果返回负值则表示改方向在无子可下</returns>
  public static int Xnum(int m, int n, int[,] arrchessboard)
  {
   //检查是否无子可下(当flag=2时表示无子可下)
   int flag = 0;
   //连子个数
   int num = 1;

   //正东方向检查(x+)
   int i = m+1;
   //不超出棋格
   while(i < 15)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,n] == arrchessboard[m,n])
    {
     num++;
     i++;
    }
    else
    {
     break;
    }
   }
   //正东方向超出棋格
   if (i==15)
   {
    flag++;
   }
   else
   {
    //正东方向有别的子不可在下
    if(arrchessboard[i,n] != 2)
    {
     flag++;
    }
   }

   //正西方向检查(x-)
            i = m-1;
   while(i >= 0)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,n] == arrchessboard[m,n])
    {
     num++;
     i--;
    }
    else
    {
     break;
    }
   }
   //正西方向超出棋格
   if (i == -1)
   {
    flag++;
   }
   else
   {
    //正西方向有别的子不可在下
    if(arrchessboard[i,n] != 2)
    {
     flag++;
    }
   }


   if (flag == 2)
   {
    return -num;
   }
   else
   {
    if (flag == 1 && num == 3 )
    {
     //连子数为3时有一边不能下就不是活三
     return -num;
    }
    else
    {
     return num;
    }
   }
  }

  /// <summary>
  /// 正南正北方向检测
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns>如果返回负值则表示改方向在无子可下</returns>
  public static int Ynum(int m, int n, int[,] arrchessboard)
  {
   //检查是否无子可下(当flag=2时表示无子可下)
   int flag = 0;
   //连子个数
   int num = 1;
   //正南方向检查(y+)
   int i = n+1;
   while(i<15)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[m,i] == arrchessboard[m,n])
    {
     num++;
     i++;
    }
    else
    {
     break;
    }
   }
   //正南方向超出棋格
   if (i==15)
   {
    flag++;
   }
   else
   {
    //正南方向有别的子不可在下
    if(arrchessboard[m,i] != 2)
    {
     flag++;
    }
   }

   //正北方向检查(y-)
   i = n-1;
   while(i >= 0)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[m,i] == arrchessboard[m,n])
    {
     num++;
     i--;
    }
    else
    {
     break;
    }
   }
   //正北方向超出棋格
   if (i == -1)
   {
    flag++;
   }
   else
   {
    //正北方向有别的子不可在下
    if(arrchessboard[m,i] != 2)
    {
     flag++;
    }
   }

   if (flag == 2)
   {
    return -num;
   }
   else
   {
    if (flag == 1 && num == 3 )
    {
     //连子数为3时有一边不能下就不是活三
     return -num;
    }
    else
    {
     return num;
    }
   }
  }

  /// <summary>
  /// 西北东南方向检查
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns>如果返回负值则表示改方向在无子可下</returns>
  public static int YXnum(int m, int n, int[,] arrchessboard)
  {
   //检查是否无子可下(当flag=2时表示无子可下)
   int flag = 0;
   //连子个数
   int num = 1;
   
   //东南方向(x+,y+)
   int i = m+1;
   int j = n+1;
   //不超出棋格
   while(i < 15 && j < 15)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,j] == arrchessboard[m,n])
    {
     num++;
     i++;
     j++;
    }
    else
    {
     break;
    }
   }
   //东南方向超出棋格
   if (i==15 || j==15)
   {
    flag++;
   }
   else
   {
    //东南方向有别的子不可在下
    if(arrchessboard[i,j] != 2)
    {
     flag++;
    }
   }

   //西北方向(x-,y-)
   i = m-1;
   j = n-1;
   //不超出棋格
   while(i >= 0 && j >= 0)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,j] == arrchessboard[m,n])
    {
     num++;
     i--;
     j--;
    }
    else
    {
     break;
    }
   }
   //西北方向超出棋格
   if (i == -1 || j == -1)
   {
    flag++;
   }
   else
   {
    //西北方向有别的子不可在下
    if(arrchessboard[i,j] != 2)
    {
     flag++;
    }
   }

   if (flag == 2)
   {
    return -num;
   }
   else
   {
    if (flag == 1 && num == 3 )
    {
     //连子数为3时有一边不能下就不是活三
     return -num;
    }
    else
    {
     return num;
    }
   }
  }

  /// <summary>
  /// 西南东北方向检查
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="arrchessboard"></param>
  /// <returns>如果返回负值则表示改方向在无子可下</returns>
  public static int XYnum(int m, int n, int[,] arrchessboard)
  {
   //检查是否无子可下(当flag=2时表示无子可下)
   int flag = 0;
   //连子个数
   int num = 1;

   //西南方向(x-,y+)
   int i = m-1;
   int j = n+1;
   //不超出棋格
   while(i >= 0 && j < 15)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,j] == arrchessboard[m,n])
    {
     num++;
     i--;
     j++;
    }
    else
    {
     break;
    }
   }
   //西南方向超出棋格
   if (i == -1 || j == 15)
   {
    flag++;
   }
   else
   {
    //西南方向有别的子不可在下
    if(arrchessboard[i,j] != 2)
    {
     flag++;
    }
   }

   //东北方向(x+,y-)
   i = m+1;
   j = n-1;
   //不超出棋格
   while(i < 15 && j >= 0)
   {
    //前方的棋子与m,n点不同时跳出循环
    if (arrchessboard[i,j] == arrchessboard[m,n])
    {
     num++;
     i++;
     j--;
    }
    else
    {
     break;
    }
   }
   //东北方向超出棋格
   if (i == 15 || j == -1)
   {
    flag++;
   }
   else
   {
    //东北方向有别的子不可在下
    if(arrchessboard[i,j] != 2)
    {
     flag++;
    }
   }

   if (flag == 2)
   {
    return -num;
   }
   else
   {
    if (flag == 1 && num == 3 )
    {
     //连子数为3时有一边不能下就不是活三
     return -num;
    }
    else
    {
     return num;
    }
   }
  }

  #endregion
 }
}
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;

namespace FiveStones
{
 /// <summary>
 /// Chessboard 的摘要说明。
 /// 棋盘类
 /// </summary>
 public class Chessboard
 {
  //arrchessboard为棋盘情况数组,arrchessboard[i,j]=2表示此处无子,arrchessboard[i,j]=0表示此处为黑子,arrchessboard[i,j]=1表示此处为白子
  private int[,] arrchessboard = new int [15,15];
        //绘制的对象
  private Graphics mg;
  //棋子对象
  private Stone stone;
  //电脑对象
  private Computer computer;
  //判断当前棋子是黑(true)是白(false)
  private bool stoneflag = true;
  //判断先手玩家(是电脑(true)还是人(false),先手下黑棋)
  private bool mplayfirstflag;
  //历史记录堆栈
  private Stack mStarckHistory = new Stack();

  /// <summary>
  /// 历史记录属性
  /// </summary>
  public Stack StarckHistory
  {
   get
   {
    return mStarckHistory;
   }
  }

 

  /// <summary>
  /// 构造函数
  /// </summary>
  /// <param name="g">绘制的对象</param>
  public Chessboard(Graphics g)
  {
   mg = g;
   Initialization();
  }

  /// <summary>
  /// 画棋盘
  /// </summary>
  public void Draw()
  {
   //读取棋盘图像
   //从资源中获取
   System.Reflection.Assembly thisExe;
   thisExe = System.Reflection.Assembly.GetExecutingAssembly();
   System.IO.Stream file = thisExe.GetManifestResourceStream("FiveStones.chessboard.gif");
   Image imgChessboard = System.Drawing.Image.FromStream(file);  //棋盘图片 大小600*600像素
   file.Close();
   //从文件获取
   //Image imgChessboard = System.Drawing.Image.FromFile("chessboard.gif");  //棋盘图片 大小600*600像素

   mg.DrawImage(imgChessboard,0,0,imgChessboard.Width,imgChessboard.Height);
   //绘制棋子
   for (int i=0;i<15;i++)
   {
    for(int j=0;j<15;j++)
    {
     if (arrchessboard[i,j] == 0)
     {
      stone.DrawStone(i,j,true,-1,-1);
     }
     if (arrchessboard[i,j] == 1)
     {
      stone.DrawStone(i,j,false,-1,-1);
     }
    }
   }
  }


  /// <summary>
  /// 下棋
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  private void DownStone(int m,int n)
  {
   int lm = -1,ln = -1;  //上一落子点

   if (mStarckHistory.Count > 0)
   {
    //分解上一落子点
    string lstr = mStarckHistory.Peek().ToString().Replace("黑:","").Replace("白:","");
    string[] arr = lstr.Split(',');
    lm = Convert.ToInt32(arr[0]);
    ln = Convert.ToInt32(arr[1]);
   }
   stone.DrawStone(m,n,stoneflag,lm,ln);
   //记录情况
   if (stoneflag)
   {
    arrchessboard[m,n] = 0;
   }
   else
   {
    arrchessboard[m,n] = 1;
   }
   //记录历史记录
   if (stoneflag)
   {
    mStarckHistory.Push("黑:"+m.ToString()+","+n.ToString());
   }
   else
   {
    mStarckHistory.Push("白:"+m.ToString()+","+n.ToString());
   }
   //判断结果
   if (Rule.Result(m,n,arrchessboard) < 6)
   {
    switch(Rule.Result(m,n,arrchessboard))
    {
     case 1:
      MessageBox.Show("黑棋双三禁手失败!");
      break;
     case 2:
      MessageBox.Show("黑棋双四禁手失败!");
      break;
     case 3:
      MessageBox.Show("黑棋长连禁手失败!");
      break;
     case 4:
      if (stoneflag)
      {
       MessageBox.Show("黑棋胜利!");
      }
      else
      {
       MessageBox.Show("白棋胜利!");
      }
      break;
     case 5:
      MessageBox.Show("平局!");
      break;
    }
    //重新开始!
    Start();
   }
   else
   {
    //交换当前棋子颜色
    stoneflag = !stoneflag;
   }
   //测试
   //MessageBox.Show(Rule.Result(m,n,arrchessboard).ToString());
  }

  /// <summary>
  /// 人下棋
  /// </summary>
  /// <param name="x"></param>
  /// <param name="y"></param>
  public void PersonDownStone(int x,int y)
  {
   if (x < 600 && y < 600)
   {
    //取下棋点
    int m = (int)Math.Floor((double)x/40);
    int n = (int)Math.Floor((double)y/40);
    if (!Rule.IsExist(m,n,arrchessboard))
    {
     DownStone(m,n);
     ComputerDownStone();
    }
   }

  }
  
  /// <summary>
  /// 电脑下棋
  /// </summary>
  private void ComputerDownStone()
  {
   int m,n,count=0;
   do
   {
    computer.Down(arrchessboard);
    m = computer.X;
    n = computer.Y;
    count++;
    if (count > 100)
    {
     MessageBox.Show("异常!");
     Start();
     return;
    }
   }
   while(Rule.IsExist(m,n,arrchessboard));
   
   DownStone(m,n);
  }

 
  /// <summary>
  /// 开始(是电脑(true)还是人(false))
  /// </summary>
  /// <param name="playfirstflag">判断先手玩家(是电脑(true)还是人(false),先手下黑棋)</param>
  public void Start(bool playfirstflag)
  {
   mplayfirstflag = playfirstflag;
   Start();
  }

  /// <summary>
  /// 开始
  /// </summary>
  private void Start()
  {
   Initialization();
   //构造电脑对象
   computer = new Computer(mplayfirstflag);
   //画棋盘
   Draw();
   if (mplayfirstflag)
   {
    ComputerDownStone();
   }
  }

  /// <summary>
  /// 初始化
  /// </summary>
  private void Initialization()
  {
   //置当前要走的棋为黑棋(黑棋先走)
   stoneflag = true;
   //把棋盘所有位置置为空(未下子)
   for(int i=0;i<15;i++)
   {
    for(int j=0;j<15;j++)
    {
     arrchessboard[i,j] = 2; 
    }
   }
   //清空历史记录堆栈
   mStarckHistory.Clear();
   //构造棋子对象
   stone = new Stone(mg);
  }
 }
}
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace FiveStones
{
 /// <summary>
 /// Form1 的摘要说明。
 /// </summary>
 public class frmMain : System.Windows.Forms.Form
    {
        private IContainer components;
  private System.Windows.Forms.MenuItem menuItem1;
  private System.Windows.Forms.MenuItem menuItem2;
  private System.Windows.Forms.MenuItem menuItem4;
  private System.Windows.Forms.MenuItem menuItem7;
  private System.Windows.Forms.MenuItem menuItem10;
  private System.Windows.Forms.MainMenu mainMenu;
  private System.Windows.Forms.MenuItem mnuClose;
  private System.Windows.Forms.MenuItem mnuNew;
  private System.Windows.Forms.MenuItem mnuComputerFirst;
  private System.Windows.Forms.MenuItem mnuPersonFirst;
  private System.Windows.Forms.GroupBox groupBox1;
  private System.Windows.Forms.GroupBox groupBox2;
  private System.Windows.Forms.PictureBox pictureBox1;
  private System.Windows.Forms.PictureBox pictureBox2;
  private System.Windows.Forms.Label lblBlackPlayer;
  private System.Windows.Forms.Label lblWhitePlayer;
  private System.Windows.Forms.ListBox lstHistory;
  private System.Windows.Forms.GroupBox groupBox3;
  private System.Windows.Forms.Label lblXY;
  private System.Windows.Forms.MenuItem mnuAbout;
  private System.Windows.Forms.MenuItem mnuHelp;
  //定义棋盘类
  private Chessboard chessboard;

  public frmMain()
  {
   //
   // Windows 窗体设计器支持所必需的
   //
   InitializeComponent();

   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //

   //构造棋盘类
   System.Drawing.Graphics g = this.CreateGraphics();
   chessboard = new Chessboard(g);
  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain));
            this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.mnuNew = new System.Windows.Forms.MenuItem();
            this.menuItem7 = new System.Windows.Forms.MenuItem();
            this.mnuPersonFirst = new System.Windows.Forms.MenuItem();
            this.mnuComputerFirst = new System.Windows.Forms.MenuItem();
            this.menuItem10 = new System.Windows.Forms.MenuItem();
            this.mnuClose = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.mnuHelp = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.mnuAbout = new System.Windows.Forms.MenuItem();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.lstHistory = new System.Windows.Forms.ListBox();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.lblWhitePlayer = new System.Windows.Forms.Label();
            this.pictureBox2 = new System.Windows.Forms.PictureBox();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.lblBlackPlayer = new System.Windows.Forms.Label();
            this.groupBox3 = new System.Windows.Forms.GroupBox();
            this.lblXY = new System.Windows.Forms.Label();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.groupBox3.SuspendLayout();
            this.SuspendLayout();
            //
            // mainMenu
            //
            this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem1,
            this.menuItem2});
            //
            // menuItem1
            //
            this.menuItem1.Index = 0;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuNew,
            this.menuItem7,
            this.mnuPersonFirst,
            this.mnuComputerFirst,
            this.menuItem10,
            this.mnuClose});
            this.menuItem1.Text = "游戏(&G)";
            //
            // mnuNew
            //
            this.mnuNew.Index = 0;
            this.mnuNew.Shortcut = System.Windows.Forms.Shortcut.F2;
            this.mnuNew.Text = "开始";
            this.mnuNew.Click += new System.EventHandler(this.mnuNew_Click);
            //
            // menuItem7
            //
            this.menuItem7.Index = 1;
            this.menuItem7.Text = "-";
            //
            // mnuPersonFirst
            //
            this.mnuPersonFirst.Checked = true;
            this.mnuPersonFirst.Index = 2;
            this.mnuPersonFirst.Text = "玩家先";
            this.mnuPersonFirst.Click += new System.EventHandler(this.mnuPersonFirst_Click);
            //
            // mnuComputerFirst
            //
            this.mnuComputerFirst.Index = 3;
            this.mnuComputerFirst.Text = "电脑先";
            this.mnuComputerFirst.Click += new System.EventHandler(this.mnuComputerFirst_Click);
            //
            // menuItem10
            //
            this.menuItem10.Index = 4;
            this.menuItem10.Text = "-";
            //
            // mnuClose
            //
            this.mnuClose.Index = 5;
            this.mnuClose.Text = "关闭(&X)";
            this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
            //
            // menuItem2
            //
            this.menuItem2.Index = 1;
            this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuHelp,
            this.menuItem4,
            this.mnuAbout});
            this.menuItem2.Text = "帮助(&H)";
            //
            // mnuHelp
            //
            this.mnuHelp.Index = 0;
            this.mnuHelp.Shortcut = System.Windows.Forms.Shortcut.F1;
            this.mnuHelp.Text = "帮助";
            this.mnuHelp.Click += new System.EventHandler(this.mnuHelp_Click);
            //
            // menuItem4
            //
            this.menuItem4.Index = 1;
            this.menuItem4.Text = "-";
            //
            // mnuAbout
            //
            this.mnuAbout.Index = 2;
            this.mnuAbout.Text = "关于(&A)";
            this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
            //
            // groupBox1
            //
            this.groupBox1.Controls.Add(this.lstHistory);
            this.groupBox1.Location = new System.Drawing.Point(616, 8);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(160, 300);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "历史记录";
            //
            // lstHistory
            //
            this.lstHistory.ItemHeight = 12;
            this.lstHistory.Location = new System.Drawing.Point(20, 22);
            this.lstHistory.Name = "lstHistory";
            this.lstHistory.Size = new System.Drawing.Size(120, 256);
            this.lstHistory.TabIndex = 0;
            //
            // groupBox2
            //
            this.groupBox2.Controls.Add(this.lblWhitePlayer);
            this.groupBox2.Controls.Add(this.pictureBox2);
            this.groupBox2.Controls.Add(this.pictureBox1);
            this.groupBox2.Controls.Add(this.lblBlackPlayer);
            this.groupBox2.Location = new System.Drawing.Point(616, 336);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(160, 144);
            this.groupBox2.TabIndex = 1;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "玩家信息";
            //
            // lblWhitePlayer
            //
            this.lblWhitePlayer.Font = new System.Drawing.Font("楷体_GB2312", 15F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.lblWhitePlayer.ForeColor = System.Drawing.Color.Blue;
            this.lblWhitePlayer.Location = new System.Drawing.Point(56, 80);
            this.lblWhitePlayer.Name = "lblWhitePlayer";
            this.lblWhitePlayer.Size = new System.Drawing.Size(90, 40);
            this.lblWhitePlayer.TabIndex = 3;
            this.lblWhitePlayer.Text = "电脑";
            this.lblWhitePlayer.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            //
            // pictureBox2
            //
            this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
            this.pictureBox2.Location = new System.Drawing.Point(8, 80);
            this.pictureBox2.Name = "pictureBox2";
            this.pictureBox2.Size = new System.Drawing.Size(40, 40);
            this.pictureBox2.TabIndex = 1;
            this.pictureBox2.TabStop = false;
            //
            // pictureBox1
            //
            this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
            this.pictureBox1.Location = new System.Drawing.Point(8, 24);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(40, 40);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            //
            // lblBlackPlayer
            //
            this.lblBlackPlayer.Font = new System.Drawing.Font("楷体_GB2312", 15F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.lblBlackPlayer.ForeColor = System.Drawing.Color.Red;
            this.lblBlackPlayer.Location = new System.Drawing.Point(56, 24);
            this.lblBlackPlayer.Name = "lblBlackPlayer";
            this.lblBlackPlayer.Size = new System.Drawing.Size(90, 40);
            this.lblBlackPlayer.TabIndex = 2;
            this.lblBlackPlayer.Text = "玩家";
            this.lblBlackPlayer.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            //
            // groupBox3
            //
            this.groupBox3.Controls.Add(this.lblXY);
            this.groupBox3.Location = new System.Drawing.Point(616, 504);
            this.groupBox3.Name = "groupBox3";
            this.groupBox3.Size = new System.Drawing.Size(160, 80);
            this.groupBox3.TabIndex = 2;
            this.groupBox3.TabStop = false;
            this.groupBox3.Text = "落子点";
            //
            // lblXY
            //
            this.lblXY.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.lblXY.ForeColor = System.Drawing.Color.Red;
            this.lblXY.Location = new System.Drawing.Point(20, 29);
            this.lblXY.Name = "lblXY";
            this.lblXY.Size = new System.Drawing.Size(120, 23);
            this.lblXY.TabIndex = 0;
            this.lblXY.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            //
            // frmMain
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(792, 595);
            this.Controls.Add(this.groupBox3);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MaximumSize = new System.Drawing.Size(800, 650);
            this.Menu = this.mainMenu;
            this.MinimumSize = new System.Drawing.Size(800, 650);
            this.Name = "frmMain";
            this.Text = "盛光五子赢天下";
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.frmMain_Paint);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.frmMain_MouseMove);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.frmMain_MouseDown);
            this.Load += new System.EventHandler(this.frmMain_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.groupBox3.ResumeLayout(false);
            this.ResumeLayout(false);

  }
  #endregion

  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main()
  {
   Application.Run(new frmMain());
  }


  private void frmMain_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
  {
   //绘制棋盘内容
   chessboard.Draw();
  }

  private void frmMain_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
  {
   //人下棋子
   chessboard.PersonDownStone(e.X,e.Y);
   //显示历史记录
   Array arr = chessboard.StarckHistory.ToArray();
   lstHistory.DataSource = arr;
  }


  private void frmMain_Load(object sender, System.EventArgs e)
  {
   //初始载入默认玩家先
   chessboard.Start(false);
  }

  //显示落子点的位置
  private void frmMain_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
  {
   if (e.X < 600 && e.Y < 600)
   {
    //取下棋点
    int m = (int)Math.Floor((double)e.X/40);
                int n = (int)Math.Floor((double)e.Y / 40);
    lblXY.Text = "X:"+m.ToString()+"  Y:"+n.ToString();
   }
  }

  #region 游戏菜单操作
  //开始
  private void mnuNew_Click(object sender, System.EventArgs e)
  {
   //显示历史记录
   ArrayList arr = new ArrayList();
   lstHistory.DataSource = arr;

   if (mnuPersonFirst.Checked)
   {
    chessboard.Start(false);
   }
   else
   {
    chessboard.Start(true);
   }
  }

  //玩家先
  private void mnuPersonFirst_Click(object sender, System.EventArgs e)
  {
   //清空历史记录
   ArrayList arrl = new ArrayList();
   lstHistory.DataSource = arrl;

   mnuPersonFirst.Checked = true;
   mnuComputerFirst.Checked = false;
   lblBlackPlayer.Text = "玩家";
   lblWhitePlayer.Text = "电脑";
   chessboard.Start(false);
  }

  //电脑先
  private void mnuComputerFirst_Click(object sender, System.EventArgs e)
  {
   //清空历史记录
   ArrayList arrl = new ArrayList();
   lstHistory.DataSource = arrl;

   mnuPersonFirst.Checked = false;
   mnuComputerFirst.Checked = true;
   lblBlackPlayer.Text = "电脑";
   lblWhitePlayer.Text = "玩家";
   chessboard.Start(true);

   //显示历史记录
   Array arr = chessboard.StarckHistory.ToArray();
   lstHistory.DataSource = arr;
  }

  //关闭
  private void mnuClose_Click(object sender, System.EventArgs e)
  {
   this.Close();
  }
  #endregion

  #region 帮助菜单操作
  //帮助
  private void mnuHelp_Click(object sender, System.EventArgs e)
  {
   try
   {
    System.Diagnostics.Process.Start("help.chm");
   }
   catch
   {
    MessageBox.Show("未找到帮助文件!");
   }
  }

  //关于
  private void mnuAbout_Click(object sender, System.EventArgs e)
  {
   frmAbout frmabout = new frmAbout();
   frmabout.Show();
  }
  #endregion
 }
}
using System;
using System.Collections;
using System.Drawing;

namespace FiveStones
{
 /// <summary>
 /// Stone(棋子类) 的摘要说明。
 /// 提供棋子相关的属性,方法,事件
 /// </summary>
 public class Stone
 {
  private Graphics mg;
  //从文件获取
  private Image imgBlackStone;  //黑子图片
  private Image imgWhiteStone;  //白子图片
  private Image imgRedTriangle; //红三角(用于标识最后一子)

  public Stone(Graphics g)
  {
   //读取黑子,白子图片
   //从资源中获取
   System.Reflection.Assembly thisExe;
   thisExe = System.Reflection.Assembly.GetExecutingAssembly();
   System.IO.Stream wfile = thisExe.GetManifestResourceStream("FiveStones.whitestone.gif");
   System.IO.Stream bfile = thisExe.GetManifestResourceStream("FiveStones.blackstone.gif");
   System.IO.Stream rfile = thisExe.GetManifestResourceStream("FiveStones.redtriangle.gif");
   imgBlackStone = System.Drawing.Image.FromStream(bfile);
   imgWhiteStone = System.Drawing.Image.FromStream(wfile);
   imgRedTriangle = System.Drawing.Image.FromStream(rfile);
   bfile.Close();
   wfile.Close();
   //从文件获取
   //imgBlackStone = System.Drawing.Image.FromFile("blackstone.gif");  //黑子图片
   //imgWhiteStone = System.Drawing.Image.FromFile("whitestone.gif");  //白子图片
   mg = g;
  }


  /// <summary>
  /// 绘制棋子
  /// </summary>
  /// <param name="m"></param>
  /// <param name="n"></param>
  /// <param name="flag">判断是黑棋(true)还是白棋(false)</param>
  public void DrawStone(int m,int n,bool flag,int lm,int ln)
  {
   if (flag)
   {
    //覆盖上一子的标识
    mg.DrawImage(imgWhiteStone,lm*40,ln*40,imgWhiteStone.Width,imgWhiteStone.Height);
    //写当前子
    mg.DrawImage(imgBlackStone,m*40,n*40,imgBlackStone.Width,imgBlackStone.Height);
    mg.DrawImage(imgRedTriangle,m*40,n*40);
   }
   else
   {
    //覆盖上一子的标识
    mg.DrawImage(imgBlackStone,lm*40,ln*40,imgWhiteStone.Width,imgWhiteStone.Height);
    //写当前子
    mg.DrawImage(imgWhiteStone,m*40,n*40,imgBlackStone.Width,imgBlackStone.Height);
    mg.DrawImage(imgRedTriangle,m*40,n*40);
   }
  }
 }
}

 
原创粉丝点击