五子棋游戏-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
<<如果您想和我交流,请点击和我成为好友>>
但是你会发现:为什么鼠标落在左下角的时候会点到左边的位置上去?而应该是如果落在棋子的范围内任意一点的话都应该落在一个点上。
解决方法:在当前鼠标位置+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
<<如果您想和我交流,请点击和我成为好友>>
相关文章推荐
- MATLAB五子棋游戏(双人对战,可悔棋)
- Java实现两人五子棋游戏(四) 落子动作的实现
- android游戏开发之我的小小游戏1——五子棋游戏3之悔棋与重新开始
- Java实现一个简单的两人五子棋游戏(四) 落子动作的实现
- 五子棋游戏-3(判断五子连心)
- Flex 联机游戏开发 - 五子棋游戏:(一)游戏核心
- 十四步实现拥有强大AI的五子棋游戏
- android游戏开发之我的小小游戏1——五子棋游戏5之蓝牙对战
- 五子棋游戏中判断胜负的C++源代码
- html5 canvas 五子棋游戏
- 关于AS3.0 五子棋悔棋功能和五子棋复盘功能的实现
- 单步commit悔棋 ----- git commit --amend
- C++ 简易的五子棋游戏 初学者
- 自定义View实现五子棋游戏
- Java实现一个简单的两人五子棋游戏(五) 判断是否有一方胜出
- C++实现五子棋游戏
- 五子棋 (用C语言编写五子棋游戏)
- 我的第一次h5 五子棋游戏作品
- Android实现五子棋游戏(二) 人机对战实现
- 关于原生js实现五子棋游戏