国际象棋游戏建议

时间:2014-06-08 01:48:13

标签: c# design-patterns

我相对较新的编程和我开始制作国际象棋游戏的项目。现在我只做了2节课 -Peice(嵌套类:骑士,主教,典当,女王,国王) -Boeard(嵌套类:位置)

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

目前我不想添加片段动作或任何东西...... 我的目标是建立一个良好的根源,使胸部游戏更容易程序员。 所以我想问是否可以给我一些关于如何以更好的方式做到这一点的建议。

我主要关注Oriented对象设计和多态

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; }
        }
      }
    } 

董事会成员:

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);

    }
  }
}

2 个答案:

答案 0 :(得分:0)

我可以给你的第一条建议是enumerations将成为你的朋友。

大多数国际象棋棋盘都是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
    }
}

然后是董事会成员:

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;
         }
    }
}

这样的事情应该让你去!

答案 1 :(得分:0)

就个人而言,我会创建一个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等)。

例如:

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

因为它只是一个辅助类,所以你也可以选择将它设置为静态。

至于这些部分,我会把它分成两类,一类用于视觉,一类用于逻辑,每个类都有一个接口(例如IPieceDisplayIPieceLogic)。 / p>

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,{{ 1}}等。)。

QueenMoveBehavior可能看起来像这样:

IPieceDisplay

再次,您将为每种类型的片段实现public interface IPieceDisplay { void animateTo(Point newPosition); void die(); void select(); void unselect(); void draw(); void setBitmap(Bitmap b); } 类。对于一个非常简单的游戏,如果所有部分都不需要任何独特的视觉效果/动画/绘图逻辑,则可以使用单个PieceDisplay实现。

最后,您将拥有一个PieceDisplay类,该类具有PieceIPieceDisplay的实例,并且将处理对这些片段的视觉和逻辑更新。您的IPieceLogic(或者可能是单独的BoardBoardController类)可以容纳所有GameController个实例,并负责游戏流程,片段互动和用户相互作用。