如何在国际象棋游戏中实现棋子移动?

3
我正在学习使用windows forms C#制作一个小型的国际象棋游戏,该游戏只包含双方的兵。我已经画好了棋盘并将棋子组织到了相应位置,但是我不知道如何开始通过点击鼠标来实现移动棋子到目标位置。
参考黑色兵为"piece",白色兵为"pieceW"。
以下是我的棋盘代码。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace AIchess
    {
        public partial class Form1 : Form
        {
            static System.Drawing.Bitmap piece = AIchess.Properties.Resources.piece;
            ChessPiece Piece = new ChessPiece(piece, ChessColor.Black);

            static System.Drawing.Bitmap pieceW = AIchess.Properties.Resources.pieceW;
            ChessPiece PieceW = new ChessPiece(pieceW, ChessColor.White);

            Square[,] square = new Square[8, 8];
            public Form1()
            {
                InitializeComponent();
                int i, j;

                for (i = 0; i < 8; i++)
                {
                    for (j = 0; j < 8; j++)
                    {
                        this.square[i, j] = new Square();
                        this.square[i, j].BackColor = System.Drawing.SystemColors.ActiveCaption;
                        this.square[i, j].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                        this.square[i, j].Location = new System.Drawing.Point(57 + i * 60, 109 + j * 60);
                        this.square[i, j].Name = i.ToString()+j.ToString();
                        this.square[i, j].Size = new System.Drawing.Size(60, 60);
                        this.square[i, j].TabIndex = 2;
                        this.square[i, j].TabStop = false;
                        this.Controls.Add(this.square[i, j]);

                        if (j == 1)
                        {
                            this.square[i, j].Image = piece;
                            this.square[i, j].AllocatedBy = "black";
                        }
                        if (j == 6)
                        {
                            this.square[i, j].Image = pieceW;
                            this.square[i, j].AllocatedBy = "white";
                        }

                        if (((i+j) % 2) ==0)
                            this.square[i, j].BackColor = Color.RoyalBlue;
                        else
                            this.square[i, j].BackColor = Color.LightBlue;
                    } 
                }
            }
        }



 public enum ChessColor
    {
        White,
        Black,

    };

    class ChessPiece
    {
        private Image DisplayedImage;
        private ChessColor DisplayedColor;
        private Point CurrentSquare;
        public ChessPiece(Image image, ChessColor color)
        {
            DisplayedImage = image;
            DisplayedColor = color;
        }
    }
        class Square:PictureBox
        {
            private bool color;
            public string AllocatedBy;
        }
    }

你的 ChessPiece 类是什么样子的? - Batu.Khan
公共枚举类型 ChessColor { 白色, 黑色,}; 类 ChessPiece { private Image DisplayedImage; private ChessColor DisplayedColor; private Point CurrentSquare; public ChessPiece(Image image, ChessColor color) { DisplayedImage = image; DisplayedColor = color; } } - Thair Abdalla
你可能希望将此移至gamedev.stackexchange.com - James
4
提醒一下,你应该创建像 BoardPiece 这样不含有 UI 元素引用的类。然后编写代码将数据模型渲染到屏幕上。将逻辑与 UI 分离是一个通常很好的想法,如果你尝试实现人工智能,这也将变得必要。 - default.kramer
1个回答

9
这是一个非常简单的实现,希望您不介意我从头开始做。显然它非常简单,没有拖放和动画,但它满足了您的要求。我将逐个部分进行说明。 InitializeGame - 在此处设置图像尺寸(它们应该是相同的)。 - 您在字典中添加了每种棋子类型/颜色与位图之间的关系。
注意:网格将被缩放,因此您可以使用任何大小的位图。 CreateBoard, DrawGame, DrawPieces 这些内容都很普通,需要注意的是为了保持简单,我在每次用户点击时都会执行一遍,但这不应该是太大的问题,毕竟这不是Crysis :D PickOrDropPiece 这是拾取/放置发生的逻辑,非常琐碎,我会让您自己看一下。 与您的代码之间的区别 我创建了一个Board类型,它保存了棋子并且您可以轻松地更新它。
请注意:不要删除Piece中的等式成员,它们有助于字典。
确保使用具有透明边框的32位位图。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox1.MouseDown += pictureBox1_MouseDown;
        }

        #region Properties

        private Board Board { get; set; }
        private Piece CurrentPiece { get; set; }
        private Dictionary<Piece, Bitmap> PieceBitmaps { get; set; }
        private int TileWidth { get; set; }
        private int TileHeight { get; set; }

        #endregion

        #region Events

        private void Form1_Load(object sender, EventArgs e)
        {
            InitializeGame();
            DrawGame();
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            PickOrDropPiece(e);
            DrawGame();
        }

        #endregion

        #region Methods

        private void InitializeGame()
        {
            TileWidth = 64;
            TileHeight = 64;

            Board = new Board();

            PieceBitmaps = new Dictionary<Piece, Bitmap>();
            PieceBitmaps.Add(new Piece(PieceType.Pawn, PieceColor.Black), new Bitmap("pawnblack.png"));
            PieceBitmaps.Add(new Piece(PieceType.Pawn, PieceColor.White), new Bitmap("pawnwhite.png"));
        }

        private void DrawGame()
        {
            var tileSize = new Size(TileWidth, TileHeight);
            Bitmap bitmap = CreateBoard(tileSize);
            DrawPieces(bitmap);
            pictureBox1.Image = bitmap;
        }

        private Bitmap CreateBoard(Size tileSize)
        {
            int tileWidth = tileSize.Width;
            int tileHeight = tileSize.Height;
            var bitmap = new Bitmap(tileWidth*8, tileHeight*8);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                for (int x = 0; x < 8; x++)
                {
                    for (int y = 0; y < 8; y++)
                    {
                        Brush brush = (x%2 == 0 && y%2 == 0) || (x%2 != 0 && y%2 != 0) ? Brushes.Black : Brushes.White;
                        graphics.FillRectangle(brush, new Rectangle(x*tileWidth, y*tileHeight, tileWidth, tileHeight));
                    }
                }
            }
            return bitmap;
        }

        private void DrawPieces(Bitmap bitmap)
        {
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                Board board = Board;
                for (int x = 0; x < 8; x++)
                {
                    for (int y = 0; y < 8; y++)
                    {
                        Piece piece = board.GetPiece(x, y);
                        if (piece != null)
                        {
                            Bitmap bitmap1 = PieceBitmaps[piece];

                            graphics.DrawImageUnscaled(bitmap1, new Point(x*TileWidth, y*TileHeight));
                        }
                    }
                }
            }
        }

        private void PickOrDropPiece(MouseEventArgs e)
        {
            Point location = e.Location;
            int x = location.X/TileWidth;
            int y = location.Y/TileHeight;
            bool pickOrDrop = CurrentPiece == null;
            if (pickOrDrop)
            {
                // Pick a piece
                Piece piece = Board.GetPiece(x, y);
                Board.SetPiece(x, y, null);
                if (piece != null)
                {
                    label1.Text = string.Format("You picked a {0} {1} at location {2},{3}", piece.Color, piece.Type, x,
                        y);
                }
                else
                {
                    label1.Text = "Nothing there !";
                }
                CurrentPiece = piece;
            }
            else
            {
                // Drop picked piece
                Board.SetPiece(x, y, CurrentPiece);
                label1.Text = string.Format("You dropped a {0} {1} at location {2},{3}", CurrentPiece.Color,
                    CurrentPiece.Type, x,
                    y);
                CurrentPiece = null;
            }
        }

        #endregion
    }

    public class Board
    {
        private readonly Piece[] _pieces;

        public Board()
        {
            _pieces = new Piece[8*8];
            PopulatePieces();
        }

        public Piece GetPiece(int x, int y)
        {
            int i = y*8 + x;
            return _pieces[i];
        }

        public void SetPiece(int x, int y, Piece piece)
        {
            int i = y*8 + x;
            _pieces[i] = piece;
        }

        private void PopulatePieces()
        {
            for (int i = 0; i < 8; i++)
            {
                SetPiece(i, 1, new Piece(PieceType.Pawn, PieceColor.Black));
                SetPiece(i, 7, new Piece(PieceType.Pawn, PieceColor.White));
            }
        }
    }

    public class Piece
    {
        private readonly PieceColor _color;
        private readonly PieceType _type;

        public Piece(PieceType type, PieceColor color)
        {
            _type = type;
            _color = color;
        }

        public PieceType Type
        {
            get { return _type; }
        }

        public PieceColor Color
        {
            get { return _color; }
        }

        protected bool Equals(Piece other)
        {
            return _color == other._color && _type == other._type;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != GetType()) return false;
            return Equals((Piece) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ((int) _color*397) ^ (int) _type;
            }
        }

        public static bool operator ==(Piece left, Piece right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Piece left, Piece right)
        {
            return !Equals(left, right);
        }
    }

    public enum PieceType
    {
        Pawn
    }

    public enum PieceColor
    {
        Black,
        White
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接