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 };
///
/// Figur
///
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 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);
}
}
///
/// Tests if the Move will leave your King endangered.
///
/// GameField
/// Location of Piece to move
/// Location to move Piece to
/// Color of Piece to move
/// Bool
/* 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);
}*/
///
/// Checks if a specific field can be reached by the figure while a virtual move is simulated
///
/// Piece that virtually got moved
/// Field that the movePiece virtually moved to
/// Field that should be checked
/// Current Game Grid
///
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
}
///
/// Tests if the Move will leave your movedPiece endangered.
///
/// GameField
/// Location of Piece to move
/// Location to move Piece to
/// Color of Piece to move
/// Bool
//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);
//}
///
/// Tests if your King is currently endangered.
///
/// GameField
/// Kings color
///
//private static bool KingIsEndangered(Grid fields, PieceColor color) => FieldIsEndangered(fields, GetKingLocation(fields, color), color, dontTestKingDanger: true);
///
/// Tests if the testLocation is endangered by an enemy.
///
/// GameField
/// Ally Color
/// Location to test
/// Bool
//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;
}*/
///
/// Searches for the King of the given color.
///
/// GameField
/// Kings color
/// King location as Vector
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 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 remove = new List();
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 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 GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false);
}
}