chess-board/ChessPanel/Pieces/AbstractPiece.txt

226 lines
11 KiB
Plaintext
Raw Normal View History

2017-11-16 18:06:29 +01:00
using System;
using System.Collections.Generic;
using System.Drawing;
using ChessPanel;
using System.Linq;
using System.Windows;
namespace Chess
{
public enum PieceColor { White, Black };
public enum PieceTeam { Enemy, Ally };
public enum PieceType { King, Queen, Bishop, Rook, Knight, Pawn };
public enum MoveMode { Any, Attack, Movement };
/// <summary>
/// Figur
/// </summary>
public abstract class Piece
{
public PieceColor color;
public PieceType type;
public Image image;
public bool HasMoved = false;
public Field field;
private Vector virtualPosition;//?
public bool EnPassantPossible = false; // Only in Pawn Class. Signs that this Piece has virtually not jumped two pieces, but one, reflective meaning: This.Figure can be attacked using Enpassant if this.type is Pawn
public override string ToString()
{
return type.ToString();
}
public Piece(Vector position, Grid fields)
{
this.field = fields[position];
fields[position].CurrentPiece = this;
}
internal void removeTargetFieldsWhereKingIsEndangered(Grid fields, Dictionary<Field, PieceTeam> targetFields)
{
Field ownKingLocation = fields.GetKing(this.color).field;
foreach (var virtualTargetField in targetFields)
{
if (fields.IsFieldVirtuallyEndagered(ownKingLocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, virtualTargetField.Key))
targetFields.Remove(virtualTargetField.Key);
}
}
/// <summary>
/// Tests if the Move will leave your King endangered.
/// </summary>
/// <param name="fields">GameField</param>
/// <param name="pieceLocation">Location of Piece to move</param>
/// <param name="simulatedLocation">Location to move Piece to</param>
/// <param name="color">Color of Piece to move</param>
/// <returns>Bool</returns>
/* internal static bool MoveWillEndangerOwnKing(Grid fields, Vector pieceLocation, Vector simulatedLocation, PieceColor color)
{
// fields[simulateLocation].currentPiece = fields[pieceLocation].currentPiece;
// fields[pieceLocation].currentPiece = null;
// Check if own king is endangered
return FieldIsEndangered(fields, simulatedLocation, kingLocation, color, dontTestKingDanger: true);
}*/
/// <summary>
/// Checks if a specific field can be reached by the figure while a virtual move is simulated
/// </summary>
/// <param name="movePiece">Piece that virtually got moved</param>
/// <param name="targetPos">Field that the movePiece virtually moved to</param>
/// <param name="possibleEndageredField">Field that should be checked</param>
/// <param name="fields">Current Game Grid</param>
/// <returns></returns>
internal abstract bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos);
internal void Move(Field newPieceField)
{
this.field.CurrentPiece = null; // Remove piece from previous position
this.field = newPieceField; // Set pieces location to new field
newPieceField.CurrentPiece = this; // Set new fields piece to this
}
/// <summary>
/// Tests if the Move will leave your movedPiece endangered.
/// </summary>
/// <param name="fields">GameField</param>
/// <param name="pieceLocation">Location of Piece to move</param>
/// <param name="testLocation">Location to move Piece to</param>
/// <param name="color">Color of Piece to move</param>
/// <returns>Bool</returns>
//internal static bool MoveWillEndangerPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
//{
// return false;
// //Grid simulatedField = fields;
// //simulatedField[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
// //return FieldIsEndangered(fields simulatedField, testLocation, color);
//}
/// <summary>
/// Tests if your King is currently endangered.
/// </summary>
/// <param name="fields">GameField</param>
/// <param name="color">Kings color</param>
/// <returns></returns>
//private static bool KingIsEndangered(Grid fields, PieceColor color) => FieldIsEndangered(fields, GetKingLocation(fields, color), color, dontTestKingDanger: true);
/// <summary>
/// Tests if the testLocation is endangered by an enemy.
/// </summary>
/// <param name="fields">GameField</param>
/// <param name="color">Ally Color</param>
/// <param name="testLocation">Location to test</param>
/// <returns>Bool</returns>
//private static bool FieldIsEndangered(Grid fields, Vector simulatedLocation, Vector testLocation, PieceColor color, bool dontTestKingDanger = false)
//{
// foreach (Field field in fields)
// {
// if (field.location != simulatedLocation
// && field.currentPiece != null
// && field.currentPiece.color != color
// && field.currentPiece.GetValidTargetFields(fields, dontTestKingDanger: dontTestKingDanger).ContainsKey(testLocation))
// return true;
// }
// return false;
//}
/*internal static bool IsEndangeredLocationForPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
{
bool returnValue = false;
Piece p = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
foreach (var field in fields)
{
if (field.currentPiece != null) if (field.currentPiece.color != color) if (field.currentPiece.GetValidTargetFields(fields, field.location, true).ContainsKey(testLocation))
{
returnValue = true;
break;
}
}
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p;
return returnValue;
}*/
/* internal static bool MoveWillEndangerKing(Grid fields, Vector pieceLocation, Vector pieceMovedLocation, PieceColor color) // This does not test if it is a valid move spot
{
bool returnValue = false;
Piece p1 = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
Piece p2 = fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece;
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p1;
returnValue = KingIsEndangered(fields, color);
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p1;
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p2;
return returnValue;
}*/
/* private static bool KingIsEndangered(Grid fields, PieceColor color)
{
Vector kingLocation = GetKingLocation(fields, color);
foreach (var field in fields)
{
if (field.currentPiece == null || field.currentPiece.color != color)
continue;
if (field.currentPiece.GetValidTargetFields(fields, field.location, dontTestKingDanger: true).ContainsKey(kingLocation))
{
return true;
}
}
return false;
}*/
/// <summary>
/// Searches for the King of the given color.
/// </summary>
/// <param name="fields">GameField</param>
/// <param name="color">Kings color</param>
/// <returns>King location as Vector</returns>
private static Vector GetKingLocation(Grid fields, PieceColor color)
{
foreach (Field field in fields)
if (!field.IsEmpty && field.currentPiece.type == PieceType.King && field.currentPiece.color == color)
return field.location;
throw new Exception("King not found!");
}
virtual internal Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false)
{
var targetFields = GetTargetFields(fields, field, this.color);
if (!dontTestKingDanger)
{
Field kinglocation = fields.GetKing(this.color).field;
List<Field> remove = new List<Field>();
foreach (var item in targetFields.Keys)
{
if (fields.IsFieldVirtuallyEndagered(kinglocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, item))
remove.Add(item);
}
foreach (var item in remove)
{
targetFields.Remove(item);
}
}
return targetFields;
}
internal abstract Dictionary<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color);
internal static bool FieldIsVirtuallyEmpty(Field targetPos, Field skipField, Field possibleTargetField)
{
return (possibleTargetField.IsEmpty && possibleTargetField != targetPos)
|| possibleTargetField == skipField;
}
internal static bool checkFieldCanBeReached(Field possibleEndageredField, Field targetPos, Piece movePiece, Field possibleTargetField, PieceColor color, out bool breakIt)
{
breakIt = false;
var skipField = movePiece.field;
if (FieldIsVirtuallyEmpty(targetPos, skipField, possibleTargetField))
{
if (possibleTargetField == possibleEndageredField)
return true;
}
else
{
var checkPiece = possibleTargetField == targetPos ? movePiece : possibleTargetField.CurrentPiece;
if (checkPiece.color != color && possibleTargetField == possibleEndageredField)
return true;
breakIt=true;
}
return false;
}
//internal abstract Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false);
}
}