您的位置:首页 > 其它

五子棋游戏-2(落子与悔棋)

2009-09-01 17:15 218 查看
落子比较简单,只需要根据鼠标在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;

还要解决的问题是,已有子上点击一下,又在此处落子了,覆盖问题!

解决方法:用一个二维数组标识落子情况,落子前检查该标识是否可以落子

最后是悔棋的方案,只要用一个集合记录所有落子情况即可。

棋子类:

Code:

namespace FivePiece {

/// <summary>

/// 棋子

/// </summary>

class Piece {

public static int Side = 28;//边长

public Color Color; //棋子颜色

public int X;

public int Y;

}

}

棋盘类:



Code:

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);

}

}

}

}

}

游戏类:



Code:

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;

}

}

}

视频内容请见http://www.itcast.net/course/detail/1989

<<如果您想和我交流,请点击和我成为好友>>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: