Is this an abuse of the type system?

I am working on a hobby project for the game Barcque Chess . For those who did not play it, it has the same basic rules as chess, but the methods of moving and capturing are different.

Naturally, I have created a standard classes to play: GameState, Board, Squareand class designed for each part, inheriting from BasePiece.

Each part has two main virtual methods: GetPossibleMoves(Board board)and GetCapturedSquares(Board board, Square toSquare).

Now, one of the parts of the Simulator captures fragments, "imitating" the piece that it captures. For example, the Long Leaper can capture pieces by jumping over them. This means that the Simulator can jump over an opponent of Long Lipers to capture them (but cannot jump on anything else).

I performed functionality GetCapturedSquares()for all parts except the Simulator (this is definitely the hardest part).

My main algorithm for the Simulator was:

  • find all the squares with enemy figures on them
  • for every part of the enemy ...
    • create a simulated shape in the same place as the Simulator
    • find valid captures if the simulated figure moved to the selected square.
    • Verify that the enemy’s square is on this list of captured squares.

, , GetCapturedSquares() , . Dictionary, , System.Type :

var typeToPiece = new Dictionary<Type, BasePiece>() 
{
    {typeof(Pincer), new Pincer() { Color = this.Color, CurrentSquare = this.CurrentSquare}},
    {typeof(Withdrawer), new Withdrawer() { Color = this.Color, CurrentSquare = this.CurrentSquare }},
    {typeof(Coordinator), new Coordinator() { Color = this.Color, CurrentSquare = this.CurrentSquare }},
    {typeof(LongLeaper), new LongLeaper() { Color = this.Color, CurrentSquare = this.CurrentSquare }},
    {typeof(King), new King() { Color = this.Color, CurrentSquare = this.CurrentSquare }},
};
//...
var possibleMoves = typeToPiece[enemySquare.Occupant.GetType()].GetPossibleMoves(board, toSquare);

. enum string, , ? ? , , , .

+3
4

, abstract BasePiece, "" .

override . , protected , , :

abstract class BasePiece {
   protected BasePiece(BasePiece pieceToClone) {
      this.Color = pieceToClone.Color;
      this.CurrentSquare = pieceToClone.CurrentSquare;
   }
   public abstract BasePiece GetSimulatedClone();
}

class King : BasePiece {
   protected King(King pieceToClone) : base(pieceToClone) { }
   public King() { }
   public override BasePiece GetSimulatedClone() {
       return new King(this);
   }
}

, , , , .

+7

:

    private abstract class Piece {}
    private class King : Piece { }
    private class Imitator : Piece { }

    private void main(object sender, EventArgs e) {
        Piece x;
        x = CreateNewPiece(new King());
        x = CreateNewPiece(new Imitator());
    }

    private T CreateNewPiece<T>(T piece) where T : Piece, new() {
        return new T();
    }

new() generic .

+1

, , , . , , Mover, , . , , , , Mover, , . Mover, Imitator, , , "" .

, , , , , :

  • ( )
    • ,
    • , .
    • , , .

, .

Update

, , , , Mover. , KingMover, PincerMover .., . , , . Mover, , - Mover GetPossibleMoves, GetPossibleMoves Mover, . ImitatorMover , , , , , .

, , (, ..), , . .

+1

, , . .NET FCL - KeyedByTypeCollection<T>. , , , , GetType() ( - ), .

+1
source

Source: https://habr.com/ru/post/1719658/


All Articles