落子比较简单,只需要根据鼠标在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;
还要解决的问题是,已有子上点击一下,又在此处落子了,覆盖问题!
解决方法:用一个二维数组标识落子情况,落子前检查该标识是否可以落子
最后是悔棋的方案,只要用一个集合记录所有落子情况即可。
棋子类:
- namespaceFivePiece{
- ///<summary>
- ///棋子
- ///</summary>
- classPiece{
- publicstaticintSide=28;//边长
- publicColorColor;//棋子颜色
- publicintX;
- publicintY;
- }
- }
棋盘类:
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Text;
- usingSystem.Windows.Forms;
- usingSystem.Drawing;
- namespaceFivePiece{
- ///<summary>
- ///棋盘
- ///</summary>
- classChessBoard{
- publicintLines=19;//线条书
- publicintLineSpace=30;//线间距
- publicintMargin=30/2;//边距(线间距/2)
- publicPictureBoxPicCtrl;//棋盘容器控件
- ///<summary>
- ///绘制棋盘
- ///</summary>
- publicvoidDrawBoard(){
- Bitmapbmp=newBitmap(PicCtrl.Width,PicCtrl.Height);
- Graphicsg=Graphics.FromImage(bmp);
- //绘制背景颜色
- SolidBrushbrush=newSolidBrush(Color.Gold);
- g.FillRectangle(brush,Margin,Margin,
- (Lines-1)*LineSpace,(Lines-1)*LineSpace);
- PenlinePen=newPen(Color.Black,1);//画线笔
- //Lines条横线
- for(inti=0;i<Lines;i++){
- Pointstart=newPoint(Margin,i*LineSpace+Margin);
- Pointend=newPoint(start.X+(Lines-1)*LineSpace,start.Y);
- g.DrawLine(linePen,start,end);
- }
- //Lines条竖线
- for(inti=0;i<Lines;i++){
- Pointstart=newPoint(i*LineSpace+Margin,Margin);
- Pointend=newPoint(start.X,start.Y+(Lines-1)*LineSpace);
- g.DrawLine(linePen,start,end);
- }
- PicCtrl.BackgroundImage=bmp;
- }
- ///<summary>
- ///绘制棋子
- ///</summary>
- ///<paramname="c">棋子颜色</param>
- ///<paramname="x">x轴线坐标</param>
- ///<paramname="y">y轴线坐标</param>
- publicvoidDrawPiece(Colorc,intx,inty){
- Bitmapbmp=newBitmap(PicCtrl.BackgroundImage);
- Graphicsg=Graphics.FromImage(bmp);
- Rectanglerect=newRectangle(
- x*LineSpace+Margin-Piece.Side/2,
- y*LineSpace+Margin-Piece.Side/2,
- Piece.Side,Piece.Side);
- SolidBrushbrush=newSolidBrush(c);
- g.FillEllipse(brush,rect);
- PicCtrl.BackgroundImage=bmp;
- }
- ///<summary>
- ///重绘
- ///</summary>
- ///<paramname="step"></param>
- publicvoidRedraw(Piece[]step){
- DrawBoard();
- foreach(Piecepinstep){
- if(p!=null){
- DrawPiece(p.Color,p.X,p.Y);
- }
- }
- }
- }
- }
游戏类:
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Text;
- usingSystem.Drawing;
- namespaceFivePiece{
- ///<summary>
- ///游戏类
- ///</summary>
- classGame{
- //棋盘
- publicChessBoardChessBoard=newChessBoard();
- //下一个落子颜色
- publicColorNextColor=Color.White;
- //落子步骤
- publicPiece[]Steps;
- //步骤数
- publicintStepCount;
- //游戏是否结束
- publicboolGameOver=false;
- //落子标记
- int[,]pieces;
- //构造方法
- publicGame(){
- pieces=newint[ChessBoard.Lines,ChessBoard.Lines];
- Steps=newPiece[ChessBoard.Lines*ChessBoard.Lines];
- }
- ///<summary>
- ///落子
- ///</summary>
- ///<paramname="mLocation">鼠标位置</param>
- publicvoidDownPiece(PointmLocation){
- intx=(mLocation.X-ChessBoard.Margin+ChessBoard.LineSpace/2)/ChessBoard.LineSpace;
- inty=(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]=newPiece();
- 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>
- publicvoidRegretPiece(){
- 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>
- ///<paramname="p"></param>
- ///<returns></returns>
- privateboolIsWin(Piecep){
- intx=p.X;
- inty=p.Y;
- boolwin=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);//左上斜
- returnwin;
- }
- privateboolIsFive(intx,inty,intoffsetX,intoffsetY,Colorc){
- intcount=1;
- intsearchX=x+offsetX;
- intsearchY=y+offsetY;
- boolstop=false;
- while(searchX>=0&&searchX<ChessBoard.Lines&&
- searchY>=0&&searchY<ChessBoard.Lines&&
- !stop){
- intintColor=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){
- intintColor=c==Color.White?1:2;
- if(pieces[searchX,searchY]==intColor){
- count++;
- searchX-=offsetX;
- searchY-=offsetY;
- }else{
- stop=true;
- }
- }
- returncount==5;
- }
- }
- }