单机五子棋
//必须在ImageList控件里加入空白棋子的两幅高和宽都为20的图片.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication2
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem7;
private System.ComponentModel.IContainer components;
private const int None = -1;//没有棋子
private const int White = 0;//代表白棋
private const int Black = 1;//代表黑棋
private int[,] checkerBoard = new int[15, 15];//棋盘(用来保存每一个棋子)
private int nextPlayer;//下一个选手
private int Player
{
get
{
return nextPlayer;
}
set
{
nextPlayer = value;
ReDrawNextPlayerMark();
}
}
private System.Windows.Forms.MenuItem menuItem8;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.MenuItem menuItem10;//下一次该黑棋还是白棋下
private Stack History;//下棋的历史记录
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
// checkerBoard = new int [15,15];
History = new Stack();
Player = White;//默认设置为白棋先下
Reset();
}
///
/// Clean up any resources being used.
///
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.menuItem8 = new System.Windows.Forms.MenuItem();
this.menuItem9 = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.menuItem6 = new System.Windows.Forms.MenuItem();
this.menuItem7 = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem10 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.SuspendLayout();
//
// menuItem8
//
this.menuItem8.Index = 3;
this.menuItem8.Shortcut = System.Windows.Forms.Shortcut.AltBksp;
this.menuItem8.Text = "悔一步棋 (&H)";
this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
//
// menuItem9
//
this.menuItem9.Index = 1;
this.menuItem9.Text = "-";
//
// menuItem4
//
this.menuItem4.Index = 1;
this.menuItem4.Text = "关于… (&A)";
this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click_1);
//
// menuItem5
//
this.menuItem5.Index = 0;
this.menuItem5.Shortcut = System.Windows.Forms.Shortcut.CtrlN;
this.menuItem5.Text = "重新开始 (&N)";
this.menuItem5.Click += new System.EventHandler(this.menuItem5_Click);
//
// menuItem6
//
this.menuItem6.Index = 5;
this.menuItem6.Shortcut = System.Windows.Forms.Shortcut.CtrlX;
this.menuItem6.Text = "退出 (&X)";
this.menuItem6.Click += new System.EventHandler(this.menuItem6_Click);
//
// menuItem7
//
this.menuItem7.Index = 4;
this.menuItem7.Text = "-";
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem5,
this.menuItem9,
this.menuItem10,
this.menuItem8,
this.menuItem7,
this.menuItem6});
this.menuItem1.Text = "系统 (&S)";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
this.menuItem1.Popup += new System.EventHandler(this.menuItem1_Popup);
//
// menuItem10
//
this.menuItem10.Index = 2;
this.menuItem10.Text = "黑棋先下 (&B)";
this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.MdiList = true;
this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem3,
this.menuItem4});
this.menuItem2.Text = "帮助 (&H)";
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
//
// menuItem3
//
this.menuItem3.Index = 0;
this.menuItem3.Shortcut = System.Windows.Forms.Shortcut.F1;
this.menuItem3.Text = "使用方法";
this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click_1);
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem2});
//
// imageList1
//
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
this.imageList1.Images.SetKeyName(0, "White.bmp");
this.imageList1.Images.SetKeyName(1, "Black.bmp");
this.imageList1.Images.SetKeyName(2, "None.bmp");
//
// Form1
//
this.AccessibleDescription = "";
this.AllowDrop = true;
this.ClientSize = new System.Drawing.Size(325, 333);
this.Cursor = System.Windows.Forms.Cursors.Hand;
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.ImeMode = System.Windows.Forms.ImeMode.Off;
this.MaximizeBox = false;
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "五子棋";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void menuItem4_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void menuItem3_Click(object sender, System.EventArgs e)
{
}
private void Form1_Load(object sender, System.EventArgs e)
{
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
}
private void menuItem4_Click_1(object sender, System.EventArgs e)
{
//(new About()).ShowDialog();
}
private void menuItem2_Click(object sender, System.EventArgs e)
{
}
private void menuItem3_Click_1(object sender, System.EventArgs e)
{
//new Help().ShowDialog();
}
private void menuItem6_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void menuItem5_Click(object sender, System.EventArgs e)
{
if (History.Count > 0) this.Reset();
}
private void menuItem8_Click(object sender, System.EventArgs e)
{
Penitence();
}
//重载重画函数
protected override void OnPaint(PaintEventArgs e)
{
System.Drawing.Graphics g = this.CreateGraphics();
for (int x = 0; x < 15; x++)
{
for (int y = 0; y < 15; y++)
{
if (checkerBoard[y, x] != None) DrawChess(new Point(x, y), checkerBoard[y, x]);
}
}
ReDrawNextPlayerMark();
base.OnPaint(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
this.Text = "五子棋 " + "X=" + e.X.ToString() + " Y=" + e.Y.ToString();
}
//重载鼠标按下事件
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
base.OnMouseDown(e);
switch (e.Button)
{
//take left button down
case MouseButtons.Left:
if ((History.Count == 0) && (2 < e.X) && (e.X < 22) && (309 < e.Y) && (e.Y < 329))
Player = (Player == White) ? Black : White;
else AddChess(MToA(new Point(e.X, e.Y)));
break;
//take right button down
case MouseButtons.Right:
// OnRButtonDown(new Point(e.X,e.Y));
break;
}
}
//把鼠标坐标转换成棋盘坐标
private Point MToA(Point p)
{
return new Point((p.X - 10) / 20, (p.Y - 6) / 20);
}
//开始新的棋局,所有数据复位并重画棋盘
private void Reset()
{
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
checkerBoard[i, j] = None;
}
}
History.Clear();//清空历史记录
DrawCheckerBoard();//重画棋盘
}
//重画棋盘
private void DrawCheckerBoard()
{
this.BackColor = System.Drawing.SystemColors.Desktop;
this.BackColor = System.Drawing.SystemColors.Control;
}
//重画下一个选手的标志棋子
private void ReDrawNextPlayerMark()
{
System.Drawing.Graphics g = this.CreateGraphics();
imageList1.Draw(g, 2, 309, 20, 20, Player);
}
//在棋盘上画一个棋子
private void DrawChess(Point pCoordinates, int iPlayer)
{
System.Drawing.Graphics g = this.CreateGraphics();
imageList1.Draw(g, 10 + pCoordinates.X * 20, 6 + pCoordinates.Y * 20, 20, 20, iPlayer);
}
//在指定的棋盘坐标位置添加一个棋子
private void AddChess(Point p)
{
//判断是否超出边界
if ((p.X < 0 || p.X > 14) || (p.Y < 0 || p.Y > 14)) return;
//判断该位置有无棋子
if (checkerBoard[p.Y, p.X] != None) return;//如果已经有了棋子则退出(这颗棋不能下)
DrawChess(p, Player);
if (Player == White)//该白棋下
{
checkerBoard[p.Y, p.X] = White;
Player = Black;
}
else
{
checkerBoard[p.Y, p.X] = Black;
Player = White;
}
History.Push(new Point(p.X, p.Y));//添加历史记录
CheckGameResult(p);
}
//检查游戏结果
/*
* 算法:
* 由于根据游戏规则,只有先放成 5 个相连的棋子的一方或剩,
* 所以只要以刚刚下过的那个棋子为中心,检查有没有 5 个相连的同颜色棋子就好了。
*/
private void CheckGameResult(Point sourcePoint)
{
int x, y;
int LastPlayer = (Player == White) ? Black : White;
int n;
//检查行
n = 1;
y = sourcePoint.Y;
for (x = sourcePoint.X - 1; x >= 0; x--)
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
for (x = sourcePoint.X + 1; x < 15; x++)
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
if (n >= 5)
{
Win(LastPlayer);
return;
}
//检查列
n = 1;
x = sourcePoint.X;
for (y = sourcePoint.Y - 1; y >= 0; y--)
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
for (y = sourcePoint.Y + 1; y < 15; y++)
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
if (n >= 5)
{
Win(LastPlayer);
return;
}
//检查左斜线
n = 1;
for (x = sourcePoint.X + 1, y = sourcePoint.Y - 1; x < 15 && y >= 0; x++, y--)//检查左斜线的上半截
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
for (x = sourcePoint.X - 1, y = sourcePoint.Y + 1; x >= 0 && y < 15; x--, y++)//检查左斜线的下半截
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
if (n >= 5)
{
Win(LastPlayer);
return;
}
//检查右斜线
n = 1;
for (x = sourcePoint.X - 1, y = sourcePoint.Y - 1; x >= 0 && y >= 0; x--, y--)//检查右斜线的上半截
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
for (x = sourcePoint.X + 1, y = sourcePoint.Y + 1; x < 15 && y < 15; x++, y++)//检查右斜线的下半截
{
if (checkerBoard[y, x] == LastPlayer) n++;
else break;
}
if (n >= 5)
{
Win(LastPlayer);
return;
}
//棋盘满棋,平手
if (History.Count >= 225)
{
Win(None);
return;
}
}
//显示指定选手的获胜信息
private void Win(int NPlayer)
{
switch (NPlayer)
{
case None:
MessageBox.Show("本局平手!", "恭喜!");
break;
case White:
MessageBox.Show("本局 白棋 获胜 !", "恭喜!");
break;
case Black:
MessageBox.Show("本局 黑棋 获胜 !", "恭喜!");
break;
}
Reset();
}
//悔棋 1 步
private void Penitence()
{
if (History.Count > 0)
{
Point p = (Point)History.Pop();
checkerBoard[p.Y, p.X] = None;
nextPlayer = (Player == White) ? Black : White;
DrawCheckerBoard();
}
}
private void menuItem10_Click(object sender, System.EventArgs e)
{
Player = (Player == White) ? Black : White;
}
private void menuItem1_Popup(object sender, System.EventArgs e)
{
if (History.Count == 0)
{
menuItem10.Visible = true;
menuItem10.Text = (Player == White) ? "黑棋先下 (&B)" : "白棋先下 (&W)";
}
else menuItem10.Visible = false;
}
private ImageList imageList1;
}
}