落子比较简单,只需要根据鼠标在PictureBox上的位置做一定的处理,就能判断该子落在第几行第几列的交叉点上。
但是你会发现:为什么鼠标落在左下角的时候会点到左边的位置上去?而应该是如果落在棋子的范围内任意一点的话都应该落在一个点上。
解决方法:在当前鼠标位置+LineSpace 的一半距离然后整除,判断是否在位置里面。
int x = (mLocation.X - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;
int y = (mLocation.Y - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;
落子后要更改下一个子的颜色
Public color nextcolor=color.white;
Chessboard.drawpiece(nextcolor,x,y);
Nextcolor=nextcolor==color.white?color.black:color.white;
还要解决的问题是,已有子上点击一下,又在此处落子了,覆盖问题!
解决方法:用一个二维数组标识落子情况,落子前检查该标识是否可以落子
最后是悔棋的方案,只要用一个集合记录所有落子情况即可。
棋子类:
- namespace FivePiece {
- /// <summary>
- /// 棋子
- /// </summary>
- class Piece {
- public static int Side = 28;//边长
- public Color Color; //棋子颜色
- public int X;
- public int Y;
- }
- }
棋盘类:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Windows.Forms;
- using System.Drawing;
- namespace FivePiece {
- /// <summary>
- /// 棋盘
- /// </summary>
- class ChessBoard {
- public int Lines = 19; //线条书
- public int LineSpace = 30; //线间距
- public int Margin = 30 / 2; //边距(线间距/2)
- public PictureBox PicCtrl; //棋盘容器控件
- /// <summary>
- /// 绘制棋盘
- /// </summary>
- public void DrawBoard() {
- Bitmap bmp = new Bitmap(PicCtrl.Width, PicCtrl.Height);
- Graphics g = Graphics.FromImage(bmp);
- //绘制背景颜色
- SolidBrush brush = new SolidBrush(Color.Gold);
- g.FillRectangle(brush, Margin, Margin,
- (Lines - 1) * LineSpace, (Lines - 1) * LineSpace);
- Pen linePen = new Pen(Color.Black, 1);//画线笔
- //Lines条横线
- for(int i = 0; i < Lines; i++) {
- Point start = new Point(Margin, i * LineSpace + Margin);
- Point end = new Point(start.X+(Lines-1)*LineSpace, start.Y);
- g.DrawLine(linePen, start, end);
- }
- //Lines条竖线
- for(int i = 0; i < Lines; i++) {
- Point start = new Point(i * LineSpace + Margin, Margin);
- Point end = new Point(start.X, start.Y + (Lines - 1) * LineSpace);
- g.DrawLine(linePen, start, end);
- }
- PicCtrl.BackgroundImage = bmp;
- }
- /// <summary>
- /// 绘制棋子
- /// </summary>
- /// <param name="c">棋子颜色</param>
- /// <param name="x">x轴线坐标</param>
- /// <param name="y">y轴线坐标</param>
- public void DrawPiece(Color c, int x, int y) {
- Bitmap bmp = new Bitmap(PicCtrl.BackgroundImage);
- Graphics g = Graphics.FromImage(bmp);
- Rectangle rect = new Rectangle(
- x * LineSpace + Margin - Piece.Side / 2,
- y * LineSpace + Margin - Piece.Side / 2,
- Piece.Side, Piece.Side);
- SolidBrush brush = new SolidBrush(c);
- g.FillEllipse(brush, rect);
- PicCtrl.BackgroundImage = bmp;
- }
- /// <summary>
- /// 重绘
- /// </summary>
- /// <param name="step"></param>
- public void Redraw(Piece[] step) {
- DrawBoard();
- foreach(Piece p in step) {
- if(p != null) {
- DrawPiece(p.Color, p.X, p.Y);
- }
- }
- }
- }
- }
游戏类:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Drawing;
- namespace FivePiece {
- /// <summary>
- /// 游戏类
- /// </summary>
- class Game {
- //棋盘
- public ChessBoard ChessBoard = new ChessBoard();
- //下一个落子颜色
- public Color NextColor = Color.White;
- //落子步骤
- public Piece[] Steps;
- //步骤数
- public int StepCount;
- //游戏是否结束
- public bool GameOver = false;
- //落子标记
- int[,] pieces;
- //构造方法
- public Game() {
- pieces = new int[ChessBoard.Lines, ChessBoard.Lines];
- Steps = new Piece[ChessBoard.Lines * ChessBoard.Lines];
- }
- /// <summary>
- /// 落子
- /// </summary>
- /// <param name="mLocation">鼠标位置</param>
- public void DownPiece(Point mLocation) {
- int x = (mLocation.X - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;
- int y = (mLocation.Y - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;
- //判断此处是否可以落子
- if(pieces[x, y] == 0) {
- ChessBoard.DrawPiece(NextColor, x, y);
- pieces[x, y] = NextColor == Color.White ? 1 : 2;
- Steps[StepCount] = new Piece();
- Steps[StepCount].X = x;
- Steps[StepCount].Y = y;
- Steps[StepCount].Color = NextColor;
- NextColor = NextColor == Color.White ? Color.Black : Color.White;
- //判断是否胜利
- if(IsWin(Steps[StepCount])) {
- GameOver = true;
- }
- StepCount++;
- }
- }
- /// <summary>
- /// 悔棋
- /// </summary>
- public void RegretPiece() {
- if(StepCount == 0) return;
- //落子标识设为0
- pieces[Steps[StepCount - 1].X, Steps[StepCount - 1].Y] = 0;
- //改变当前颜色
- NextColor = NextColor == Color.White ? Color.Black : Color.White;
- Steps[StepCount - 1] = null;
- StepCount--;
- ChessBoard.Redraw(Steps);
- }
- /// <summary>
- /// 判断是否五子连心
- /// </summary>
- /// <param name="p"></param>
- /// <returns></returns>
- private bool IsWin(Piece p) {
- int x = p.X;
- int y = p.Y;
- bool win = IsFive(x, y, 0, 1, p.Color); //纵向
- win |= IsFive(x, y, 1, 1, p.Color); //右下斜
- win |= IsFive(x, y, 1, 0, p.Color); //横向
- win |= IsFive(x, y, 1, -1, p.Color); //左上斜
- return win;
- }
- private bool IsFive(int x, int y, int offsetX, int offsetY, Color c) {
- int count = 1;
- int searchX = x + offsetX;
- int searchY = y + offsetY;
- bool stop = false;
- while(searchX >= 0 && searchX < ChessBoard.Lines &&
- searchY >= 0 && searchY < ChessBoard.Lines &&
- !stop) {
- int intColor = c == Color.White ? 1 : 2;
- if(pieces[searchX, searchY] == intColor) {
- count++;
- searchX += offsetX;
- searchY += offsetY;
- } else {
- stop = true;
- }
- }
- stop = false;
- searchX = x - offsetX;
- searchY = y - offsetY;
- while(searchX >= 0 && searchX < ChessBoard.Lines &&
- searchY >= 0 && searchY < ChessBoard.Lines &&
- !stop) {
- int intColor = c == Color.White ? 1 : 2;
- if(pieces[searchX, searchY] == intColor) {
- count++;
- searchX -= offsetX;
- searchY -= offsetY;
- } else {
- stop = true;
- }
- }
- return count == 5;
- }
- }
- }