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

落子比较简单,只需要根据鼠标在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:
  1. namespace FivePiece {   
  2.     /// <summary>   
  3.     /// 棋子   
  4.     /// </summary>   
  5.     class Piece {   
  6.         public static int Side = 28;//边长   
  7.         public Color Color;         //棋子颜色   
  8.         public int X;   
  9.         public int Y;   
  10.     }   
  11. }  

 棋盘类:
 

Code:
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Text;   
  4. using System.Windows.Forms;   
  5. using System.Drawing;   
  6.   
  7. namespace FivePiece {   
  8.     /// <summary>   
  9.     /// 棋盘   
  10.     /// </summary>   
  11.     class ChessBoard {   
  12.   
  13.         public int Lines = 19;      //线条书   
  14.         public int LineSpace = 30;  //线间距   
  15.         public int Margin = 30 / 2; //边距(线间距/2)   
  16.         public PictureBox PicCtrl;  //棋盘容器控件   
  17.   
  18.         /// <summary>   
  19.         /// 绘制棋盘   
  20.         /// </summary>   
  21.         public void DrawBoard() {   
  22.             Bitmap bmp = new Bitmap(PicCtrl.Width, PicCtrl.Height);   
  23.             Graphics g = Graphics.FromImage(bmp);   
  24.   
  25.             //绘制背景颜色   
  26.             SolidBrush brush = new SolidBrush(Color.Gold);   
  27.             g.FillRectangle(brush, Margin, Margin,   
  28.                 (Lines - 1) * LineSpace, (Lines - 1) * LineSpace);   
  29.   
  30.             Pen linePen = new Pen(Color.Black, 1);//画线笔   
  31.             //Lines条横线   
  32.             for(int i = 0; i < Lines; i++) {   
  33.                 Point start = new Point(Margin, i * LineSpace + Margin);   
  34.                 Point end = new Point(start.X+(Lines-1)*LineSpace, start.Y);   
  35.                 g.DrawLine(linePen, start, end);   
  36.             }   
  37.             //Lines条竖线   
  38.             for(int i = 0; i < Lines; i++) {   
  39.                 Point start = new Point(i * LineSpace + Margin, Margin);   
  40.                 Point end = new Point(start.X, start.Y + (Lines - 1) * LineSpace);   
  41.                 g.DrawLine(linePen, start, end);   
  42.             }   
  43.   
  44.             PicCtrl.BackgroundImage = bmp;   
  45.         }   
  46.   
  47.         /// <summary>   
  48.         /// 绘制棋子   
  49.         /// </summary>   
  50.         /// <param name="c">棋子颜色</param>   
  51.         /// <param name="x">x轴线坐标</param>   
  52.         /// <param name="y">y轴线坐标</param>   
  53.         public void DrawPiece(Color c, int x, int y) {   
  54.             Bitmap bmp = new Bitmap(PicCtrl.BackgroundImage);   
  55.             Graphics g = Graphics.FromImage(bmp);   
  56.   
  57.             Rectangle rect = new Rectangle(   
  58.                 x * LineSpace + Margin - Piece.Side / 2,   
  59.                 y * LineSpace + Margin - Piece.Side / 2,   
  60.                 Piece.Side, Piece.Side);   
  61.             SolidBrush brush = new SolidBrush(c);   
  62.             g.FillEllipse(brush, rect);   
  63.   
  64.             PicCtrl.BackgroundImage = bmp;   
  65.         }   
  66.            
  67.         /// <summary>   
  68.         /// 重绘   
  69.         /// </summary>   
  70.         /// <param name="step"></param>   
  71.         public void Redraw(Piece[] step) {   
  72.             DrawBoard();   
  73.   
  74.             foreach(Piece p in step) {   
  75.                 if(p != null) {   
  76.                     DrawPiece(p.Color, p.X, p.Y);   
  77.                 }   
  78.             }   
  79.         }   
  80.     }   
  81. }   

游戏类:
 

Code:
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Text;   
  4. using System.Drawing;   
  5.   
  6. namespace FivePiece {   
  7.     /// <summary>   
  8.     /// 游戏类   
  9.     /// </summary>   
  10.     class Game {   
  11.         //棋盘   
  12.         public ChessBoard ChessBoard = new ChessBoard();   
  13.         //下一个落子颜色   
  14.         public Color NextColor = Color.White;   
  15.         //落子步骤   
  16.         public Piece[] Steps;   
  17.         //步骤数   
  18.         public int StepCount;   
  19.         //游戏是否结束   
  20.         public bool GameOver = false;   
  21.         //落子标记   
  22.         int[,] pieces;   
  23.   
  24.            
  25.   
  26.         //构造方法   
  27.         public Game() {   
  28.             pieces = new int[ChessBoard.Lines, ChessBoard.Lines];   
  29.             Steps = new Piece[ChessBoard.Lines * ChessBoard.Lines];   
  30.         }   
  31.   
  32.         /// <summary>   
  33.         /// 落子   
  34.         /// </summary>   
  35.         /// <param name="mLocation">鼠标位置</param>   
  36.         public void DownPiece(Point mLocation) {   
  37.             int x = (mLocation.X - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;   
  38.             int y = (mLocation.Y - ChessBoard.Margin + ChessBoard.LineSpace / 2) / ChessBoard.LineSpace;   
  39.   
  40.             //判断此处是否可以落子   
  41.             if(pieces[x, y] == 0) {   
  42.                 ChessBoard.DrawPiece(NextColor, x, y);   
  43.                 pieces[x, y] = NextColor == Color.White ? 1 : 2;   
  44.                    
  45.   
  46.                 Steps[StepCount] = new Piece();   
  47.                 Steps[StepCount].X = x;   
  48.                 Steps[StepCount].Y = y;   
  49.                 Steps[StepCount].Color = NextColor;   
  50.                    
  51.                    
  52.                 NextColor = NextColor == Color.White ? Color.Black : Color.White;   
  53.                 //判断是否胜利   
  54.                 if(IsWin(Steps[StepCount])) {   
  55.                     GameOver = true;   
  56.                 }   
  57.                 StepCount++;   
  58.             }   
  59.         }   
  60.            
  61.         /// <summary>   
  62.         /// 悔棋   
  63.         /// </summary>   
  64.         public void RegretPiece() {   
  65.             if(StepCount == 0) return;   
  66.   
  67.             //落子标识设为0   
  68.             pieces[Steps[StepCount - 1].X, Steps[StepCount - 1].Y] = 0;   
  69.             //改变当前颜色   
  70.             NextColor = NextColor == Color.White ? Color.Black : Color.White;   
  71.   
  72.             Steps[StepCount - 1] = null;   
  73.             StepCount--;   
  74.   
  75.             ChessBoard.Redraw(Steps);   
  76.         }   
  77.            
  78.         /// <summary>   
  79.         /// 判断是否五子连心   
  80.         /// </summary>   
  81.         /// <param name="p"></param>   
  82.         /// <returns></returns>   
  83.         private bool IsWin(Piece p) {   
  84.             int x = p.X;   
  85.             int y = p.Y;   
  86.             bool win = IsFive(x, y, 0, 1, p.Color); //纵向   
  87.             win |= IsFive(x, y, 1, 1, p.Color);     //右下斜   
  88.             win |= IsFive(x, y, 1, 0, p.Color);     //横向   
  89.             win |= IsFive(x, y, 1, -1, p.Color);    //左上斜   
  90.             return win;   
  91.         }   
  92.   
  93.         private bool IsFive(int x, int y, int offsetX, int offsetY, Color c) {   
  94.             int count = 1;   
  95.             int searchX = x + offsetX;   
  96.             int searchY = y + offsetY;   
  97.             bool stop = false;   
  98.             while(searchX >= 0 && searchX < ChessBoard.Lines &&   
  99.                 searchY >= 0 && searchY < ChessBoard.Lines &&   
  100.                 !stop) {   
  101.                 int intColor = c == Color.White ? 1 : 2;   
  102.                 if(pieces[searchX, searchY] == intColor) {   
  103.                     count++;   
  104.                     searchX += offsetX;   
  105.                     searchY += offsetY;   
  106.                 } else {   
  107.                     stop = true;   
  108.                 }   
  109.             }   
  110.             stop = false;   
  111.             searchX = x - offsetX;   
  112.             searchY = y - offsetY;   
  113.             while(searchX >= 0 && searchX < ChessBoard.Lines &&   
  114.                 searchY >= 0 && searchY < ChessBoard.Lines &&   
  115.                 !stop) {   
  116.                 int intColor = c == Color.White ? 1 : 2;   
  117.                 if(pieces[searchX, searchY] == intColor) {   
  118.                     count++;   
  119.                     searchX -= offsetX;   
  120.                     searchY -= offsetY;   
  121.                 } else {   
  122.                     stop = true;   
  123.                 }   
  124.             }   
  125.             return count == 5;   
  126.         }   
  127.     }   
  128. }   

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

<<如果您想和我交流,请点击和我成为好友>>

题目:五子棋对弈 对弈规则如下: 主要功能是实现两人之间的对弈,在画好的棋盘上,两个玩家轮流选择自己的落子坐标,然后由五子棋系统自动识别判断游戏的进展,知道一方的五子连成一条线或者棋盘已经无法落子游戏结束。 选定五子棋的棋盘大小为19*19,玩家可以在这个棋盘上选择落子坐标位置,通过在棋盘上显示不同的符号来代替不同玩家所下的棋子,“o”代表A玩家,“*”代表B玩家。玩家每次落子之后游戏系统都会对落子位置进行检查,如果落子坐标输入有错应提示错误,并要求玩家继续输入。 当出现同一玩家五子连成一线时,无论是行、列或是对角线的五子连线,都表示玩家游戏胜利,退出游戏 任务:编程实现以下功能 1. 欢迎主界面 提示玩家选择游戏开始,结束,设置悔棋次数等。 2. 绘制棋盘 该模块要求的功能是实现棋盘的显示及棋子的显示,,“o”代表A玩家,“*”代表B玩家。在每次下棋后要对棋盘进行刷新,将棋盘的状态变化为当前最新状态,然后等待另一个玩家下棋。 3. 玩家交替下棋 玩家能在棋盘上下棋,玩家每次选择好下棋的行和列坐标,并在该位置落子。 要求:a.提示当前玩家输入落子坐标 b.能判断用户输入的坐标是否正确(坐标超出范围或该处已有棋子) 4. 悔棋功能 玩家选择悔棋后刷新棋盘,删除前一次的落子悔棋次数有限制。 5. 输赢判断 判断输赢模块的作用是每次玩家落子后判断是否已分出胜负,如果是,则返回胜利者相关信息。 6. 设计丰富的用户界面,方便用户操作 设计要求: ① 根据以上功能需求,自己定义合适的数据结构,并说明原因; ② 每个功能能提供友好的用户界面,方便用户操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值