/
Piece.cs
97 lines (85 loc) · 3.28 KB
/
Piece.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
namespace Valil.Chess.Model
{
/// <summary>
/// Implements a chess piece
/// </summary>
public abstract class Piece
{
/// <summary>
/// The number of piece types.
/// </summary>
public const int TypesNo = 12;
/// <summary>
/// Checks if the piece might move on this "board",
/// from the "from" square to the "to" square according to the chess rules.
/// It doesn't verify if its own king is in check after the move.
/// </summary>
/// <param name="board">The board</param>
/// <param name="from">The starting square</param>
/// <param name="to">The ending square</param>
/// <returns></returns>
public abstract bool MightMove(Board board, int from, int to);
/// <summary>
/// Verifies if the piece attacks the "to" square, on this board, from the "from" square.
/// </summary>
/// <param name="board">The board</param>
/// <param name="from">The starting square</param>
/// <param name="to">The ending square</param>
/// <returns></returns>
public virtual bool Attacks(Board board, int from, int to)
{
return MightMove(board, from, to);// usually a piece attacks a square if it can move there
}
/// <summary>
/// Generates the move.
/// In this class, the move is not verified if it puts its own king in check.
/// This is implemented in the BlackPiece and WhitePiece subclasses.
/// </summary>
/// <param name="board">The board</param>
/// <param name="from">The starting square</param>
/// <param name="to">The ending square</param>
/// <returns></returns>
internal virtual Move GenerateMove(Board board, int from, int to)
{
if (!MightMove(board, from, to)) { return null; }
Move move = new Move(board.Status, from, to);
move.ChangeSideToMove();// change side to move
move.SetEnPassantTarget(null);// reset the en passant target
if (board[to] == null)// if there is no capture
{
move.IncrementPly();// increment the ply
}
else// if there is a capture
{
move.ResetPly();// reset the ply
// if there this moves captures a rook
// and the ending squares is one of the board corners
// reset castling availability
if (board[to] is WhiteRook)
{
if (to == Board.A1)
{
move.MakeWhiteLongCastlingUnavail();
}
else if (to == Board.H1)
{
move.MakeWhiteShortCastlingUnavail();
}
}
else if (board[to] is BlackRook)
{
if (to == Board.A8)
{
move.MakeBlackLongCastlingUnavail();
}
else if (to == Board.H8)
{
move.MakeBlackShortCastlingUnavail();
}
}
}
return move;
}
}
}