棋局建议

本文关键字:棋局 | 更新日期: 2023-09-27 18:07:33

我对编程比较陌生,我正在开始一个制作国际象棋游戏的项目。现在我只上了2节课-棋子(嵌套的职业:骑士,主教,兵,王后,国王)- board(嵌套类:Position)

并最终引导主窗体屏幕中的所有内容。

目前我不想添加块运动或任何东西…我的目标是建立一个良好的根,使胸部游戏更容易编程。所以我想问一下是否有人能给我一些建议,告诉我如何才能更好地做到这一点。

我主要关注面向对象设计和多态性

Form1:

   public partial class Form1 : Form
  {
    Board board = new Board(new Point(25, 25));
    Peices peice = new Peices();

    public Form1()
    {      
      AllowTransparency = true;
      this.Controls.Add(board);
      //board.Controls.Add(p1);
      peice.putOnBoard(board);
      InitializeComponent();
    }
  }

Peice Class:

 class Peices
  {
      private List<PictureBox> peiceList = new List<PictureBox>();
      private static readonly Size PEICESSIZE = new Size(100,100);
      private static readonly Color PEICESBACKBROUDCOLOR  = Color.Transparent;

      private static Image _blackImage;
      public static Image blackImage
  {
    get { return _blackImage; }
    set { _blackImage = value; }
  }
      static Image _whiteImage;
      public static Image whiteImage
  {
    get { return _whiteImage; }
    set { _whiteImage = value; }
  }
      public Peices()
      {
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.A2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.B2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.C2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.D2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.E2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.F2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.G2 });
       peiceList.Add( new Pawn(Color.White) { Location = Board.Position.H2 });
       peiceList.Add(new Knight(Color.White) { Location = Board.Position.B1 });
       peiceList.Add(new Knight(Color.White) { Location = Board.Position.G1 });
       peiceList.Add(new Bishop(Color.White) { Location = Board.Position.C1 });
       peiceList.Add(new Bishop(Color.White) { Location = Board.Position.F1 });
       peiceList.Add(new Rook(Color.White) { Location = Board.Position.A1 });
       peiceList.Add(new Rook(Color.White) { Location = Board.Position.H1 });
       peiceList.Add(new Queen(Color.White) { Location = Board.Position.D1 });
       peiceList.Add(new King(Color.White) { Location = Board.Position.E1 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.A7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.B7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.C7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.D7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.E7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.F7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.G7 });
       peiceList.Add(new Pawn(Color.Black) { Location = Board.Position.H7 });
       peiceList.Add(new Knight(Color.Black) { Location = Board.Position.B8 });
       peiceList.Add(new Knight(Color.Black) { Location = Board.Position.G8 });
       peiceList.Add(new Bishop(Color.Black) { Location = Board.Position.C8 });
       peiceList.Add(new Bishop(Color.Black) { Location = Board.Position.F8 });
       peiceList.Add(new Rook(Color.Black) { Location = Board.Position.A8 });
       peiceList.Add(new Rook(Color.Black) { Location = Board.Position.H8 });
       peiceList.Add(new Queen(Color.Black) { Location = Board.Position.D8 });
       peiceList.Add(new King(Color.Black) { Location = Board.Position.E8 });      
      }
      public  void putOnBoard(Board board)
  {
   for (int i = 0; i < peiceList.Count; i++)
   {
     board.Controls.Add(peiceList[i]);
   }
  }
      static Image makeImageBackgroundInvis(Image pb)
 {
   Bitmap imgBitmap = (Bitmap)pb;
   imgBitmap.MakeTransparent(imgBitmap.GetPixel(0, 0));
   pb = imgBitmap;
   return pb;
 }
      public class Pawn : PictureBox
      {
        public Pawn( Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackPawn.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhitePawn.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }       
    }
      public class Knight : PictureBox
      {
        public Knight(Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackKnight.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhiteKnight.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }
      }
      public class Bishop : PictureBox
      {
        public Bishop(Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackBishop.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhiteBishop.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }
      }    
      public class Rook : PictureBox
      {
        public Rook(Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackRook.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhiteRook.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }
      }
      public class Queen : PictureBox
      {
        public Queen(Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackQueen.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhiteQueen.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }
      }
      public class King : PictureBox
      {
        public King(Color pawnColor)
        {
          blackImage = makeImageBackgroundInvis(Image.FromFile("BlackKing.bmp"));
          whiteImage = makeImageBackgroundInvis(Image.FromFile("WhiteKing.bmp"));
          BackColor = PEICESBACKBROUDCOLOR;
          Size = PEICESSIZE;
          if (pawnColor == Color.Black) { Image = blackImage; }
          if (pawnColor == Color.White) { Image = whiteImage; }
        }
      }
    } 

Board Class:

class Board : Panel
{
  public static readonly Size BOARD_SIZE  = new Size(800,800);
  public static readonly int BOARD_ROW = 8;
  public static readonly int BOARD_COLUMN = 8;
  public static readonly Size BOARD_TILE_LENGTH = new Size((BOARD_SIZE.Height / BOARD_COLUMN), (BOARD_SIZE.Width / BOARD_ROW));
  private static readonly int BORD_PEICE_NUMBER = 64;
  public Board(Point locationPoint )
  {
    new Position();
    Size = BOARD_SIZE;
    Location = locationPoint;
    BackgroundImage = Image.FromFile("ChestBord.png");
  }

  public class Position
  {
   static public Point A1;
   static public Point A2;
   static public Point A3;
   static public Point A4;
   static public Point A5;
   static public Point A6;
   static public Point A7;
   static public Point A8;
   static public Point B1;
   static public Point B2;
   static public Point B3;
   static public Point B4;
   static public Point B5;
   static public Point B6;
   static public Point B7;
   static public Point B8;
   static public Point C1;
   static public Point C2;
   static public Point C3;
   static public Point C4;
   static public Point C5;
   static public Point C6;
   static public Point C7;
   static public Point C8;
   static public Point D1;
   static public Point D2;
   static public Point D3;
   static public Point D4;
   static public Point D5;
   static public Point D6;
   static public Point D7;
   static public Point D8;
   static public Point E1;
   static public Point E2;
   static public Point E3;
   static public Point E4;
   static public Point E5;
   static public Point E6;
   static public Point E7;
   static public Point E8;
   static public Point F1;
   static public Point F2;
   static public Point F3;
   static public Point F4;
   static public Point F5;
   static public Point F6;
   static public Point F7;
   static public Point F8;
   static public Point G1;
   static public Point G2;
   static public Point G3;
   static public Point G4;
   static public Point G5;
   static public Point G6;
   static public Point G7;
   static public Point G8;
   static public Point H1;
   static public Point H2;
   static public Point H3;
   static public Point H4;
   static public Point H5;
   static public Point H6;
   static public Point H7;
   static public Point H8;
     public Position()
    {
      A1 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      A2 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      A3 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      A4 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      A5 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      A6 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      A7 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      A8 = new Point(BOARD_TILE_LENGTH.Width*0, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      B1 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      B2 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      B3 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      B4 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      B5 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      B6 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      B7 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      B8 = new Point(BOARD_TILE_LENGTH.Width*1, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      C1 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      C2 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      C3 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      C4 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      C5 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      C6 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      C7 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      C8 = new Point(BOARD_TILE_LENGTH.Width*2, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      D1 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      D2 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      D3 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      D4 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      D5 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      D6 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      D7 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      D8 = new Point(BOARD_TILE_LENGTH.Width*3, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      E1 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      E2 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      E3 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      E4 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      E5 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      E6 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      E7 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      E8 = new Point(BOARD_TILE_LENGTH.Width*4, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      F1 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      F2 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      F3 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      F4 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      F5 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      F6 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      F7 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      F8 = new Point(BOARD_TILE_LENGTH.Width*5, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      G1 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      G2 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      G3 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      G4 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      G5 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      G6 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      G7 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      G8 = new Point(BOARD_TILE_LENGTH.Width*6, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
      H1 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*1);
      H2 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*2);
      H3 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*3);
      H4 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*4);
      H5 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*5);
      H6 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*6);
      H7 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*7);
      H8 = new Point(BOARD_TILE_LENGTH.Width*7, BOARD_SIZE.Width - (BOARD_TILE_LENGTH.Width)*8);
    }
  }
}

棋局建议

就我个人而言,我会创建一个BoardCoordinate类,它将处理所有的板定位逻辑,并允许您以多种方式(数字和id)访问坐标。

例如:

public class BoardCoordinate
{
    private const string[] xCoordId = new string[]{"A","B","C","D","E","F","G","H"};
    private const string[] yCoordId = new string[]{"1","2","3","4","5","6","7","8"};
    private Dictionary<string, Point> idToPoint;
    public BoardCoordinate()
    {
        idToPoint = new Dictionary<string,Point>();
        for(int i = 0; i < xCoordId.length; i++)
        {
            for(int j = 0; j < yCoordId.length; j++)
            {
                idToPoint.Add(xCoordId[i] + yCoordId[j], new Point(i,j));
            }
        }
    }
    public string getId(Point point)
    {
        return xCoordId[point.x] + yCoordId[point.y];
    }
    public Point getPoint(string id)
    {
        if(idToPoint.ContainsKey(id))
        {
            return idToPoint[id];
        }
        return null;
    }
}

正如icemanind在评论中提到的,您希望将逻辑与显示分离,因此为什么BoardCoordinate只处理游戏逻辑所需的实际整数坐标。你可以很容易地拥有另一个类(例如你的Board类),它将转换/乘以适当的坐标来生成一个视觉坐标。例如,如果你想同时拥有游戏的2d和3d可视化,这将非常有用。在这种情况下,Board2D将以不同于Board3D的方式变换坐标,但BoardCoordinate不需要任何更改。

如果你愿意,你可以在类中为所有点的完整id(例如A1, A2, B1等)创建getter。

例如:

public Point A1 { 
    get { return getPoint("A1"); }
}

因为它只是一个helper类,所以您也可以选择将其设置为静态。

至于部件,我会将其分解为两种类型的类,一种用于视觉,一种用于逻辑,每种都有一个接口(例如IPieceDisplayIPieceLogic)。

IPieceLogic接口可能有一些必要的方法,将用于游戏的逻辑,如:

public interface IPieceLogic
{
    PieceType pieceType { get; }
    boolean isAlive { get; }
    List<Point> getAvailableMoves();
    boolean canMoveTo(Point position);
    void moveTo(Point newPosition);
    Point getPosition();
    void die();
}

然后为每种类型的Piece实现一个类。理论上,您可以使用单个PieceLogic类。要做到这一点,你需要抽象出每个棋子的移动逻辑,例如,创建一个MovementBehavior接口/类来定义棋子如何移动,PieceLogic将有一个MovementBehavior的实例用于所有的计算(例如KnightMoveBehavoir, QueenMoveBehavior等)。

IPieceDisplay可能看起来像这样:

public interface IPieceDisplay
{
    void animateTo(Point newPosition);
    void die();
    void select();
    void unselect();
    void draw();
    void setBitmap(Bitmap b);
}

同样,您将为每种类型的片段实现PieceDisplay类。对于一个非常简单的游戏,如果没有任何部分需要任何独特的视觉/动画/绘图逻辑,你可以求助于使用单个PieceDisplay实现。

最后,您将有一个Piece类,它将具有IPieceDisplayIPieceLogic的实例,并将处理对片段的视觉和逻辑更新。你的Board(或者可能是一个单独的BoardControllerGameController类)可以保存所有的Piece实例,并负责游戏流程、棋子交互和用户交互。

我能给你的第一条建议是枚举将成为你的朋友。

大多数棋盘是8x8的大小。总共64个平方。首先你要做的是创建一个类和枚举,像这样:

public enum PieceColors {
    Black,
    White
}
public enum PieceTypes {
    Rook,
    Pawn,
    Knight,
    Queen,
    King,
    Bishop
}
public class Piece {
    public PieceTypes PieceType { get; set; };
    public PieceColors PieceColor { get; set; };
    public Bitmap GetPieceBitmap()
    {
        // Return a Bitmap representing the piece based on PieceType and PieceColor
    }
}

然后是board class:

public class Board {
    public Piece[] Pieces { get; set; }
    public Board() {
         Pieces = new Piece[64];
         // Setup initial white pawns
         for (int x = 8; x < 16; x++)
         {
              Pieces[x].PieceColor = PieceColors.White;
              Pieces[x].PieceType = PieceTypes.Pawn;
         }
    }
}

这样的事情应该让你去!

相关文章: