diff --git a/.gitignore b/.gitignore
index 3c4efe2..8a30d25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
+*.rsuser
*.suo
*.user
*.userosscache
@@ -10,6 +13,9 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
+# Mono auto generated files
+mono_crash.*
+
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -17,42 +23,62 @@
[Rr]eleases/
x64/
x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+[Ll]ogs/
-# Visual Studio 2015 cache/options directory
+# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
-# NUNIT
+# NUnit
*.VisualState.xml
TestResult.xml
+nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
-# DNX
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
*_i.c
*_p.c
-*_i.h
+*_h.h
*.ilk
*.meta
*.obj
+*.iobj
*.pch
*.pdb
+*.ipdb
*.pgc
*.pgd
*.rsp
@@ -62,7 +88,9 @@ artifacts/
*.tlh
*.tmp
*.tmp_proj
+*_wpftmp.csproj
*.log
+*.tlog
*.vspscc
*.vssscc
.builds
@@ -90,6 +118,9 @@ ipch/
*.vspx
*.sap
+# Visual Studio Trace Files
+*.e2e
+
# TFS 2012 Local Workspace
$tf/
@@ -101,15 +132,25 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
-# JustCode is a .NET coding add-in
-.JustCode
-
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
# NCrunch
_NCrunch_*
.*crunch*.local.xml
@@ -141,9 +182,9 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
-# TODO: Comment the next line if you want to checkin your web deploy settings
+# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
-#*.pubxml
+*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
@@ -153,13 +194,15 @@ PublishScripts/
# NuGet Packages
*.nupkg
+# NuGet Symbol Packages
+*.snupkg
# The packages folder can be ignored because of Package Restore
-**/packages/*
+**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
-!**/packages/build/
+!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
-#!**/packages/repositories.config
-# NuGet v3's project.json files produces more ignoreable files
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
@@ -176,12 +219,15 @@ AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
-!*.[Cc]ache/
+!?*.[Cc]ache/
# Others
ClientBin/
@@ -192,9 +238,12 @@ ClientBin/
*.jfm
*.pfx
*.publishsettings
-node_modules/
orleans.codegen.cs
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
@@ -209,15 +258,22 @@ _UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
+*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
@@ -227,6 +283,7 @@ FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
+node_modules/
# Visual Studio 6 build log
*.plg
@@ -234,6 +291,20 @@ FakesAssemblies/
# Visual Studio 6 workspace options file
*.opt
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
@@ -249,13 +320,79 @@ paket-files/
# FAKE - F# Make
.fake/
-# JetBrains Rider
-.idea/
-*.sln.iml
-
-# CodeRush
-.cr/
+# CodeRush personal settings
+.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
-*.pyc
\ No newline at end of file
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
diff --git a/ChessPanel/Chess.csproj b/ChessPanel/Chess.csproj
index 6c20071..ba47077 100644
--- a/ChessPanel/Chess.csproj
+++ b/ChessPanel/Chess.csproj
@@ -47,6 +47,7 @@
+
Component
@@ -57,13 +58,18 @@
Component
+
+
+
Form
MainForm.cs
-
+
+
+
@@ -71,6 +77,10 @@
True
Resources.resx
+
+
+ ChessGame.cs
+
MainForm.cs
@@ -78,7 +88,6 @@
PublicResXFileCodeGenerator
Resources.Designer.cs
-
diff --git a/ChessPanel/ChessBoard.cs b/ChessPanel/ChessBoard.cs
index 8661f02..7c4dd38 100644
--- a/ChessPanel/ChessBoard.cs
+++ b/ChessPanel/ChessBoard.cs
@@ -1,6 +1,8 @@
using Chess;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
using System.Windows;
using System.Windows.Forms;
using static Chess.Piece;
@@ -9,34 +11,53 @@ namespace ChessPanel
{
public partial class ChessBoard : Panel
{
- public Field[,] fields;
+ private BackgroundWorker BGWorker = new BackgroundWorker();
+ public Grid fields;
+ public List pieces;
+
public PieceColor activePlayer;
- private int gridSize = 8;
+ private int GRID_SIZE = 8;
public bool isSaved = true;
- Dictionary validTargetSpots = new Dictionary();
- private Vector? selectedField;
- private Vector? SelectedField
+ Dictionary SelectedPieceTargetSpots = new Dictionary();
+ //private Vector? selectedField;
+ //private Vector? SelectedField
+ //{
+ // get { return selectedField; }
+ // set { selectedField = value; HighlightValidTargetSpots(); }
+ //}
+ private Field selectedField;
+
+ private Field SelectedField
{
get { return selectedField; }
set { selectedField = value; HighlightValidTargetSpots(); }
}
+ private bool FieldIsSelected
+ {
+ get { return selectedField != null; }
+ }
+
private void HighlightValidTargetSpots()
{
- if (selectedField.HasValue && fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].CurrentPiece != null) // Wenn das neu ausgewählte Feld eine Figur enthält, wird diese ausgewählt
+ if (FieldIsSelected && selectedField.CurrentPiece != null) // Wenn das neu ausgewählte Feld eine Figur enthält, wird diese ausgewählt
{
- fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].Select();
+ selectedField.Select();
}
ResetValidTargetSpots();
- if (selectedField.HasValue)
+ if (FieldIsSelected)
{
- if (fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].CurrentPiece != null)
+ if (selectedField.CurrentPiece != null)
{
- validTargetSpots = fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].CurrentPiece.GetValidTargetFields(fields, new Vector(selectedField.Value.X, selectedField.Value.Y));
- }
- foreach (var item in validTargetSpots)
- {
- fields[(int)item.Key.X, (int)item.Key.Y].Highlight(item.Value);
+ //SelectedPieceTargetSpots = selectedField.CurrentPiece.GetValidTargetFields(fields);
+ SelectedPieceTargetSpots = selectedField.CurrentPiece.validTargetSpots;
+ if (SelectedPieceTargetSpots == null)
+ SelectedPieceTargetSpots = selectedField.CurrentPiece.GetValidTargetFields(fields);
}
+ if (SelectedPieceTargetSpots != null)
+ foreach (var TargetSpot in SelectedPieceTargetSpots)
+ {
+ TargetSpot.Key.Highlight(TargetSpot.Value);
+ }
}
}
///
@@ -44,119 +65,177 @@ namespace ChessPanel
///
private void ResetValidTargetSpots()
{
- foreach (var item in validTargetSpots)
+ foreach (var validTarget in SelectedPieceTargetSpots)
{
- fields[(int)item.Key.X, (int)item.Key.Y].Deselect();
+ validTarget.Key.Deselect();
}
- validTargetSpots.Clear(); // Markierung der Zielfelder zurücksetzen
+ SelectedPieceTargetSpots.Clear(); // Markierung der Zielfelder zurücksetzen
}
public int GridSize
{
- get { return gridSize; }
- set { gridSize = value; }
+ get { return GRID_SIZE; }
+ set { GRID_SIZE = value; }
}
public ChessBoard()
{
this.DoubleBuffered = true;
this.SuspendLayout();
this.Resize += new System.EventHandler(this.ChessBoard_Resize);
+ // this.validTargetSpotCalculator.WorkerReportsProgress = true;// Progress
+ BGWorker.WorkerSupportsCancellation = true;
+ this.BGWorker.RunWorkerCompleted += ValidTargetSpotCalculator_RunWorkerCompleted;
+ this.BGWorker.DoWork += ValidTargetSpotCalculator_DoWork;
+ BeginTargetFieldCalculation();
InitializeGrid();
InitializePieces();
activePlayer = PieceColor.White;
this.ResumeLayout(false);
}
+
+ private void ValidTargetSpotCalculator_DoWork(object sender, DoWorkEventArgs e)
+ {
+ BGWorkerData data = e.Argument as BGWorkerData;
+ List ActivePlayerPieces = data.pieces.Where(i => i.color == data.color).ToList();
+ int total = ActivePlayerPieces.Count;
+ int count = 0;
+ foreach (var piece in ActivePlayerPieces)
+ {
+ if (BGWorker.CancellationPending)
+ {
+ e.Cancel = true;
+ return;
+ }
+ piece.RefreshValidTargetSpots(data.fields);
+ // validTargetSpotCalculator.ReportProgress((int)Math.Floor((float)(++count) / (float)total * 100f)); // Progress
+ }
+ }
+
+ private void ValidTargetSpotCalculator_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ throw new NotImplementedException();
+ }
+
private void ToggleActivePlayer() => activePlayer = activePlayer == PieceColor.White ? PieceColor.Black : PieceColor.White;
- private void DoPieceMove(Vector location, Vector newLocation, bool togglePlayer = true)
+ private void DoPieceMove(Field PieceField, Field newPieceField, bool togglePlayer = true, bool skipValidTargetFieldCalculation = false)
{
isSaved = false;
#region Castling
- if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.King && Math.Abs(newLocation.X - location.X) == 2)
- DoPieceMove(new Vector(((newLocation.X - location.X == -2) ? 0 : 7), location.Y), new Vector(location.X + (newLocation.X - location.X) / 2, location.Y), false /*Dont Toggle Player*/); // Move Rook
+ if (PieceField.CurrentPiece.type == PieceType.King && Math.Abs(newPieceField.location.X - PieceField.location.X) == 2)
+ DoPieceMove(fields[((newPieceField.location.X - PieceField.location.X == -2) ? 0 : 7), PieceField.location.Y], fields[PieceField.location.X + (newPieceField.location.X - PieceField.location.X) / 2, PieceField.location.Y], false /*Dont Toggle Player*/, true); // Move Rook
#endregion
#region EnPassant
- foreach (var item in fields) // Reset Enpassant Possible states each move
- {
- if (item.CurrentPiece != null)
- if (item.CurrentPiece.type == PieceType.Pawn)
- {
- item.CurrentPiece.EnPassantPossible = false;
- }
- }
- if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.Pawn && !fields[(int)location.X, (int)location.Y].CurrentPiece.HasMoved)
- fields[(int)location.X, (int)location.Y].CurrentPiece.EnPassantPossible = true;
- if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.Pawn && newLocation.X != location.X && fields[(int)newLocation.X, (int)newLocation.Y].IsEmpty)
- fields[(int)newLocation.X, (int)newLocation.Y + (fields[(int)location.X, (int)location.Y].CurrentPiece.color == PieceColor.White ? 1 : -1)].CurrentPiece = null;
+ foreach (Piece item in pieces.Where(i => i.type == PieceType.Pawn)) // Reset Enpassant Possible states each move
+ item.EnPassantPossible = false;
+ if (PieceField.CurrentPiece.type == PieceType.Pawn && !PieceField.CurrentPiece.HasMoved)
+ PieceField.CurrentPiece.EnPassantPossible = true;
+ if (PieceField.CurrentPiece.type == PieceType.Pawn && newPieceField.location.X != PieceField.location.X && newPieceField.IsEmpty)
+ fields[newPieceField.location, 0, (PieceField.CurrentPiece.color == PieceColor.White ? 1 : -1)].CurrentPiece = null;
#endregion
- fields[(int)location.X, (int)location.Y].CurrentPiece.HasMoved = true; // Figur Bereits bewegt Status aktualisieren
- fields[(int)newLocation.X, (int)newLocation.Y].CurrentPiece = fields[(int)location.X, (int)location.Y].CurrentPiece; // Figur an neue Position kopieren
- fields[(int)location.X, (int)location.Y].CurrentPiece = null; // Alte Kopie der Figur löschen
+ PieceField.CurrentPiece.Move(newPieceField);
+ //PieceField.CurrentPiece.HasMoved = true; // Figur Bereits bewegt Status aktualisieren
+ //newPieceField.CurrentPiece = PieceField.CurrentPiece; // Figur an neue Position kopieren
+ //PieceField.CurrentPiece = null; // Alte Kopie der Figur löschen
if (togglePlayer)
ToggleActivePlayer();
+ if (skipValidTargetFieldCalculation) BeginTargetFieldCalculation();
}
+
+ class BGWorkerData
+ {
+ public BGWorkerData(PieceColor color, List pieces, Grid fields)
+ {
+ this.color = color;
+ this.pieces = pieces;
+ this.fields = fields;
+ }
+ public PieceColor color;
+ public List pieces;
+ public Grid fields;
+ }
+
+ private void BeginTargetFieldCalculation()
+ {
+ if (BGWorker.WorkerSupportsCancellation)
+ BGWorker.CancelAsync();
+ else
+ BGWorker.RunWorkerAsync(new BGWorkerData(activePlayer, pieces, fields));
+ }
+
private void InitializePieces()
{
- fields[0, 0].CurrentPiece = new Rook(PieceColor.Black);
- fields[7, 0].CurrentPiece = new Rook(PieceColor.Black);
- fields[0, 7].CurrentPiece = new Rook(PieceColor.White);
- fields[7, 7].CurrentPiece = new Rook(PieceColor.White);
+ pieces = new List
+ {
+ new Rook(PieceColor.Black, new Vector(0, 0), fields),
+ new Rook(PieceColor.Black, new Vector(7, 0), fields),
+ new Rook(PieceColor.White, new Vector(0, 7), fields),
+ new Rook(PieceColor.White, new Vector(7, 7), fields),
- fields[1, 0].CurrentPiece = new Knight(PieceColor.Black);
- fields[6, 0].CurrentPiece = new Knight(PieceColor.Black);
- fields[1, 7].CurrentPiece = new Knight(PieceColor.White);
- fields[6, 7].CurrentPiece = new Knight(PieceColor.White);
+ new Knight(PieceColor.Black, new Vector(1, 0), fields),
+ new Knight(PieceColor.Black, new Vector(6, 0), fields),
+ new Knight(PieceColor.White, new Vector(1, 7), fields),
+ new Knight(PieceColor.White, new Vector(6, 7), fields),
- fields[2, 0].CurrentPiece = new Bishop(PieceColor.Black);
- fields[5, 0].CurrentPiece = new Bishop(PieceColor.Black);
- fields[2, 7].CurrentPiece = new Bishop(PieceColor.White);
- fields[5, 7].CurrentPiece = new Bishop(PieceColor.White);
+ new Bishop(PieceColor.Black, new Vector(2, 0), fields),
+ new Bishop(PieceColor.Black, new Vector(5, 0), fields),
+ new Bishop(PieceColor.White, new Vector(2, 7), fields),
+ new Bishop(PieceColor.White, new Vector(5, 7),fields),
+ new King(PieceColor.Black, new Vector(4, 0), fields),
+ new Queen(PieceColor.Black, new Vector(3, 0), fields),
- fields[4, 0].CurrentPiece = new King(PieceColor.Black);
- fields[3, 0].CurrentPiece = new Queen(PieceColor.Black);
+ new Queen(PieceColor.White, new Vector(3, 7), fields),
+ new King(PieceColor.White, new Vector(4, 7), fields)
+ };
- fields[3, 7].CurrentPiece = new Queen(PieceColor.White);
- fields[4, 7].CurrentPiece = new King(PieceColor.White);
for (int x = 0; x < 8; x++)
{
- fields[x, 1].CurrentPiece = new Pawn(PieceColor.Black);
- fields[x, 6].CurrentPiece = new Pawn(PieceColor.White);
+ pieces.Add(new Pawn(PieceColor.Black, new Vector(x, 1), fields));
+ pieces.Add(new Pawn(PieceColor.White, new Vector(x, 6), fields));
+ }
+
+
+ foreach (Field field in fields)
+ {
+ field.RefreshPiece();
}
}
private void InitializeGrid()
{
- this.fields = new Field[gridSize, gridSize];
- int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / gridSize;
+ this.fields = new Grid(GRID_SIZE);
+ int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / GRID_SIZE;
System.Drawing.Size subPanelSize = new System.Drawing.Size(subPanelEdgeLength, subPanelEdgeLength);
- for (int x = 0; x < this.gridSize; x++)
+ for (int x = 0; x < this.GRID_SIZE; x++)
{
- for (int y = 0; y < this.gridSize; y++)
+ for (int y = 0; y < this.GRID_SIZE; y++)
{
- Field field = new Field(x, y);
- field.Size = subPanelSize;
- field.Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height);
+ Field field = new Field(x, y)
+ {
+ Size = subPanelSize,
+ Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height)
+ };
field.FieldClick += FieldClicked;
fields[x, y] = field;
this.Controls.Add(fields[x, y]);
}
}
}
- private void FieldClicked(Vector coordinates)
+ private void FieldClicked(Field sender)
{
this.SuspendLayout();
- if (SelectedField.HasValue && validTargetSpots.ContainsKey(coordinates)) // Ein erlaubtes Zielfeld wurde angeklickt
+ if (FieldIsSelected && SelectedPieceTargetSpots.ContainsKey(sender)) // Ein erlaubtes Zielfeld wurde angeklickt
{
- DoPieceMove(SelectedField.Value, coordinates); // Bewege Figur
+ DoPieceMove(SelectedField, sender); // Bewege Figur
ResetSelectedField(); // Auswahl zurücksetzen
}
else
{
- if (SelectedField == coordinates) // Erneutes Anklicken des Auswahlfeldes
+ if (SelectedField == sender) // Erneutes Anklicken des Auswahlfeldes
ResetSelectedField(); // Auswahl zurücksetzen
else // Tritt ein, wenn ein Feld angeklickt wurde, dass nicht das Auswahlfeld ist
{
- if (SelectedField.HasValue) // Wenn ein Feld ausgewählt ist wird die Auswahl gelöscht falls nicht das Auswahlfeld angeklickt wurde
+ if (FieldIsSelected) // Wenn ein Feld ausgewählt ist wird die Auswahl gelöscht falls nicht das Auswahlfeld angeklickt wurde
ResetSelectedField(); // Auswahl zurücksetzen
- if (!fields[(int)coordinates.X, (int)coordinates.Y].IsEmpty && fields[(int)coordinates.X, (int)coordinates.Y].CurrentPiece.color == activePlayer) // Feld wird nur ausgewählt, wenn die Farbe der Figur mit der des aktiven Spielers übereinstimmt
- SelectedField = coordinates; // Kein Feld ist ausgewählt: Angeklicktes Feld auswählen (!) AKTUALISIERT AUTOMATISCH DIE MARKIERUNGEN
+ if (!sender.IsEmpty && sender.CurrentPiece.color == activePlayer) // Feld wird nur ausgewählt, wenn die Farbe der Figur mit der des aktiven Spielers übereinstimmt
+ SelectedField = sender; // Kein Feld ist ausgewählt: Angeklicktes Feld auswählen (!) AKTUALISIERT AUTOMATISCH DIE MARKIERUNGEN
}
}
this.ResumeLayout(false);
@@ -166,7 +245,7 @@ namespace ChessPanel
///
private void ResetSelectedField()
{
- fields[(int)SelectedField.Value.X, (int)SelectedField.Value.Y].Deselect(); // Auswahl zurücksetzen
+ SelectedField.Deselect(); // Auswahl zurücksetzen
SelectedField = null; // Erlaubte Zielfelder zurücksetzen
}
#region Helper Can be deleted
@@ -186,11 +265,11 @@ namespace ChessPanel
private void RefreshSize()
{
this.SuspendLayout();
- int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / gridSize;
+ int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / GRID_SIZE;
System.Drawing.Size subPanelSize = new System.Drawing.Size(subPanelEdgeLength, subPanelEdgeLength);
- for (int x = 0; x < this.gridSize; x++)
+ for (int x = 0; x < this.GRID_SIZE; x++)
{
- for (int y = 0; y < this.gridSize; y++)
+ for (int y = 0; y < this.GRID_SIZE; y++)
{
fields[x, y].Size = subPanelSize;
fields[x, y].Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height);
diff --git a/ChessPanel/ChessGame.cs b/ChessPanel/ChessGame.cs
index 95879dd..d29dbf2 100644
--- a/ChessPanel/ChessGame.cs
+++ b/ChessPanel/ChessGame.cs
@@ -15,24 +15,25 @@ namespace Chess
private void InitializeComponent()
{
- this.board = new ChessBoard();
+ this.board = new ChessPanel.ChessBoard();
this.SuspendLayout();
//
// board
//
+ this.board.Cursor = System.Windows.Forms.Cursors.Hand;
this.board.GridSize = 8;
- this.board.Cursor = Cursors.Hand;
this.board.Location = new System.Drawing.Point(0, 0);
this.board.Name = "board";
- int size = Math.Min(this.Size.Width, this.Size.Height);
- board.Size = new System.Drawing.Size(size, size);
+ this.board.Size = new System.Drawing.Size(100, 100);
this.board.TabIndex = 0;
+ this.board.Paint += new System.Windows.Forms.PaintEventHandler(this.board_Paint);
//
// ChessGame
//
this.Controls.Add(this.board);
this.Resize += new System.EventHandler(this.ResizeEvent);
this.ResumeLayout(false);
+
}
private void ResizeEvent(object sender, EventArgs e)
@@ -77,5 +78,10 @@ namespace Chess
board.Size = new System.Drawing.Size(size, size);
board.Location = this.Size.Width > this.Size.Height ? new System.Drawing.Point((this.Size.Width - size) / 2, 0) : new System.Drawing.Point(0, (this.Size.Height - size) / 2);
}
+
+ private void board_Paint(object sender, PaintEventArgs e)
+ {
+
+ }
}
}
diff --git a/ChessPanel/ChessGame.resx b/ChessPanel/ChessGame.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ChessPanel/ChessGame.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ChessPanel/ClassDiagram.cd b/ChessPanel/ClassDiagram.cd
deleted file mode 100644
index 2f5e006..0000000
--- a/ChessPanel/ClassDiagram.cd
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
- AICAAAAAAAAAAAAQAQAACCAEAIAgJAAACgAAAEoABII=
- ChessBoard.cs
-
-
-
-
-
- AAAAAAAAAAAAIAAAAEAAAAACAAAABAAAIAAAAAAAAAA=
- ChessGame.cs
-
-
-
-
-
- AABBgAEIEIYEIBAACAAAIAACADAAAEACAAAgQAAAABA=
- Field.cs
-
-
-
-
-
- AAAAEAAAACAAAAAAAACAAAACAAAAAAAAAAAAAAAAAAA=
- Form1.cs
-
-
-
-
-
- AAABAAAAAAAAAAAAAAAAAAAAEAABAACAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=
- Piece.cs
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAA=
- Program.cs
-
-
-
-
-
- AAAAAADAgQAQABAAAAIBEAAAIUAAIAAABAACAAAAIIA=
-
-
-
-
-
- AAAAAAAAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAA=
-
-
-
-
-
- AAAQAQAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAA=
- FieldColorSet.cs
-
-
-
-
\ No newline at end of file
diff --git a/ChessPanel/Field.cs b/ChessPanel/Field.cs
index 7174998..47240c6 100644
--- a/ChessPanel/Field.cs
+++ b/ChessPanel/Field.cs
@@ -21,17 +21,35 @@ namespace Chess
private FieldColorSet currentEnemyColorSet;
private FieldColorSet currentSelectedColorSet;
private FieldColorSet currentAllyColorSet;
- public delegate void ClickEventHandler(Vector coordinates);
+ public delegate void ClickEventHandler(Field sender);
public event ClickEventHandler FieldClick;
public bool IsEmpty { get { return currentPiece == null; } }
public Piece currentPiece;
public Piece CurrentPiece
{
- get { return currentPiece; }
- set { currentPiece = value; RefreshPiece(); }
+ get
+ {
+ return currentPiece;
+ }
+ set
+ {
+ currentPiece = value;
+ RefreshPiece();
+ }
+ }
+ public override string Text
+ {
+ get
+ {
+ return "";
+ var pos = location.ToString();
+ if (IsEmpty)
+ return pos + Environment.NewLine + "leer";
+ return pos + Environment.NewLine + currentPiece.ToString();
+ }
}
- private void RefreshPiece()
+ public void RefreshPiece()
{
if (currentPiece == null)
this.BackgroundImage = ChessPanel.Properties.Resources.Empty;
@@ -40,17 +58,17 @@ namespace Chess
}
public void Deselect()
{
- setActiveColorSet(currentNormalColorSet);
+ SetActiveColorSet(currentNormalColorSet);
}
public void Highlight(PieceTeam team) // validTargetField
{
switch (team)
{
case PieceTeam.Enemy:
- setActiveColorSet(currentEnemyColorSet);
+ SetActiveColorSet(currentEnemyColorSet);
break;
case PieceTeam.Ally:
- setActiveColorSet(currentAllyColorSet);
+ SetActiveColorSet(currentAllyColorSet);
break;
default:
break;
@@ -58,9 +76,9 @@ namespace Chess
}
public new void Select() // selectedField
{
- setActiveColorSet(currentSelectedColorSet);
+ SetActiveColorSet(currentSelectedColorSet);
}
- private void setActiveColorSet(FieldColorSet set)
+ private void SetActiveColorSet(FieldColorSet set)
{
this.BackColor = set.NormalColor;
this.FlatAppearance.MouseDownBackColor = set.MouseDownColor;
@@ -68,34 +86,36 @@ namespace Chess
}
public Field(int x, int y)
{
- this.currentNormalColorSet = (x + y) % 2 == 0 ? primaryNormalColorSet : secondaryNormalColorSet;
- this.currentAllyColorSet = (x + y) % 2 == 0 ? primaryValidFriendlyTargetFieldSet : secondaryValidFriendlyTargetFieldSet;
- this.currentEnemyColorSet = (x + y) % 2 == 0 ? primaryValidEnemyTargetFieldSet : secondaryValidEnemyTargetFieldSet;
- this.currentSelectedColorSet = (x + y) % 2 == 0 ? primarySelectedColorSet : secondarySelectedColorSet;
+ this.currentNormalColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryNormalColorSet : FieldColorSet.secondaryNormalColorSet;
+ this.currentAllyColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryValidFriendlyTargetFieldSet : FieldColorSet.secondaryValidFriendlyTargetFieldSet;
+ this.currentEnemyColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryValidEnemyTargetFieldSet : FieldColorSet.secondaryValidEnemyTargetFieldSet;
+ this.currentSelectedColorSet = (x + y) % 2 == 0 ? FieldColorSet.primarySelectedColorSet : FieldColorSet.secondarySelectedColorSet;
this.FlatStyle = FlatStyle.Flat;
this.FlatAppearance.BorderSize = 0;
- this.setActiveColorSet(this.currentNormalColorSet);
+ this.SetActiveColorSet(this.currentNormalColorSet);
this.Cursor = Cursors.Arrow;
this.location = new Vector(x, y); // NICHT L(!)ocation, der gibt die Position des Buttons in Pixel auf dem Control an!
this.Name = string.Format($"field[{x},{y}]");
- this.Text = "";
+ this.Text = string.Empty;
this.BackgroundImageLayout = ImageLayout.Zoom;
this.BackgroundImage = ChessPanel.Properties.Resources.Empty;
- this.Click += clicked;
+ this.Click += Clicked;
}
- private void clicked(object sender, EventArgs e)
+ private void Clicked(object sender, EventArgs e)
{
- FieldClick(this.location);
+ FieldClick(this);
}
public override string ToString()
{
- return this.currentPiece.type.ToString();
+ if (IsEmpty)
+ return "leer";
+ return this.currentPiece.ToString();
}
}
}
diff --git a/ChessPanel/FieldColorSet.cs b/ChessPanel/FieldColorSet.cs
index 6c4917d..36b7265 100644
--- a/ChessPanel/FieldColorSet.cs
+++ b/ChessPanel/FieldColorSet.cs
@@ -3,6 +3,14 @@ namespace Chess
{
struct FieldColorSet
{
+ public static readonly FieldColorSet primaryNormalColorSet = new FieldColorSet(Color.FromArgb(204, 204, 204), Color.FromArgb(153, 153, 153), Color.White);
+ public static readonly FieldColorSet secondaryNormalColorSet = new FieldColorSet(Color.FromArgb(51, 51, 51), Color.FromArgb(102, 102, 102), Color.Black);
+ public static readonly FieldColorSet primarySelectedColorSet = new FieldColorSet(Color.FromArgb(204, 204, 102), Color.FromArgb(153, 153, 102), Color.FromArgb(255, 255, 102));
+ public static readonly FieldColorSet secondarySelectedColorSet = new FieldColorSet(Color.FromArgb(204, 204, 51), Color.FromArgb(153, 153, 51), Color.FromArgb(255, 255, 51));
+ public static readonly FieldColorSet primaryValidFriendlyTargetFieldSet = new FieldColorSet(Color.FromArgb(102, 204, 102), Color.FromArgb(102, 153, 102), Color.FromArgb(102, 255, 102));
+ public static readonly FieldColorSet secondaryValidFriendlyTargetFieldSet = new FieldColorSet(Color.FromArgb(51, 204, 51), Color.FromArgb(51, 153, 51), Color.FromArgb(51, 255, 51));
+ public static readonly FieldColorSet primaryValidEnemyTargetFieldSet = new FieldColorSet(Color.FromArgb(204, 102, 102), Color.FromArgb(153, 102, 102), Color.FromArgb(255, 102, 102));
+ public static readonly FieldColorSet secondaryValidEnemyTargetFieldSet = new FieldColorSet(Color.FromArgb(204, 51, 51), Color.FromArgb(153, 51, 51), Color.FromArgb(255, 51, 51));
public FieldColorSet(Color MOC, Color MDC, Color NC)
{
MouseOverColor = MOC;
diff --git a/ChessPanel/Grid.cs b/ChessPanel/Grid.cs
new file mode 100644
index 0000000..f9f3e44
--- /dev/null
+++ b/ChessPanel/Grid.cs
@@ -0,0 +1,169 @@
+using Chess;
+using System;
+using System.Windows;
+using System.Collections;
+
+namespace ChessPanel
+{
+ public class Grid : IEnumerable
+ {
+ public Grid(int GridSize)
+ {
+ fields = new Field[GridSize, GridSize];
+ this.GridSize = GridSize;
+ }
+ //public Grid(Field[,] fields)
+ //{
+ // this.GridSize = fields.GetLength(0);
+ // this.fields = CopyMultiArray(fields);
+ //}
+ ///
+ /// Creates a copy of the given array;
+ ///
+ ///
+ ///
+ ///
+ private static T[,] CopyMultiArray(T[,] Array)
+ {
+ int[] dim = new int[] { Array.GetLength(0), Array.GetLength(1) };
+ T[,] Copy = new T[dim[0], dim[1]];
+ for (int x = 0; x < dim[0]; x++)
+ for (int y = 0; y < dim[1]; y++)
+ Copy[x, y] = Array[x, y];
+ return Copy;
+ }
+ //public Grid(Grid fields) : this(fields.fields) { }
+ public Field[,] fields;
+ public int GridSize;
+ public Field this[Vector v] { get { return fields[(int)v.X, (int)v.Y]; } set { fields[(int)v.X, (int)v.Y] = value; } }
+
+ internal Piece GetKing(PieceColor color)
+ {
+ foreach (Field item in this)
+ {
+ if (item.CurrentPiece?.color == color && item.CurrentPiece?.type == PieceType.King)
+ return item.CurrentPiece;
+ }
+ throw new Exception("No King found");
+ }
+
+ public Field this[int x, int y] { get { return fields[x, y]; } set { fields[x, y] = value; } }
+ public Field this[double x, double y] { get { return fields[(int)x, (int)y]; } set { fields[(int)x, (int)y] = value; } }
+ ///
+ /// Adds x and y values to Vector v and gets the field at the position
+ ///
+ /// Vector
+ /// X
+ /// Y
+ /// Field
+ public Field this[Vector v, int x, int y] { get { return fields[x + (int)v.X, y + (int)v.Y]; } set { fields[x + (int)v.X, y + (int)v.Y] = value; } }
+ public Field this[int x, int y, Vector v] { get { return fields[x + (int)v.X, y + (int)v.Y]; } set { fields[x + (int)v.X, y + (int)v.Y] = value; } }
+ public Field this[Vector v, double x, double y]
+ {
+ get
+ {
+ return fields[(int)x + (int)v.X, (int)y + (int)v.Y];
+ }
+ set
+ {
+ fields[(int)x + (int)v.X, (int)y + (int)v.Y] = value;
+ }
+ }
+ public Field this[double x, double y, Vector v] { get { return fields[(int)x + (int)v.X, (int)y + (int)v.Y]; } set { fields[(int)x + (int)v.X, (int)y + (int)v.Y] = value; } }
+ public Field GetFieldWithOffset(Field f, double x, double y)
+ {
+ int _x = (int)(f.location.X + x);
+ int _y = (int)(f.location.Y + y);
+ return fields[_x, _y];
+ }
+
+
+
+ ///
+ /// Checks if a field is endagered by a party
+ ///
+ /// Reference to the Field that should be checked
+ /// Color of the attacking party
+ /// Piece that virtually got moved
+ /// Field that the movePiece virtually moved to
+ ///
+ public bool IsFieldVirtuallyEndagered(Field field, PieceColor color, Piece movePiece, Field targetPos)
+ {
+ foreach (Field item in this)
+ {
+ if (item.IsEmpty) continue; // Feld ist leer
+ if (item == movePiece.field) continue; // Quellfeld muss nicht geprüft werden
+
+ Piece p = item.CurrentPiece;
+ if (p.color != color) continue; // Figur ist kein Gegner
+
+ // Ask every Piece of the other party if it can attack the specified field
+ if (p.EndageresFieldWithVirtualMove(this, field, movePiece, targetPos))
+ //if (item.currentPiece.GetValidTargetFields(movePiece, targetPos).ContainsKey(field))
+ return true;
+ }
+ return false;
+
+ }
+
+
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new FieldEnum(fields);
+ }
+ }
+
+ // When you implement IEnumerable, you must also implement IEnumerator.
+ public class FieldEnum : IEnumerator
+ {
+ public Field[,] field;
+
+ // Enumerators are positioned before the first element
+ // until the first MoveNext() call.
+ int position = -1;
+ int width;
+ int height;
+
+ public FieldEnum(Field[,] list)
+ {
+ field = list;
+ width = list.GetLength(0);
+ height = list.GetLength(1);
+ }
+
+ public bool MoveNext()
+ {
+ position++;
+ return (position < field.Length);
+ }
+
+ public void Reset()
+ {
+ position = -1;
+ }
+
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public Field Current
+ {
+ get
+ {
+ try
+ {
+ return field[position % 8, position / 8];
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ChessPanel/MainForm.cs b/ChessPanel/MainForm.cs
index b990f16..e3ee155 100644
--- a/ChessPanel/MainForm.cs
+++ b/ChessPanel/MainForm.cs
@@ -5,11 +5,11 @@ namespace Chess
{
public partial class MainForm : Form
{
- bool Fullscreen = false;
- bool fullscreen
+ bool _fullscreen = false;
+ bool Fullscreen
{
- get { return Fullscreen; }
- set { Fullscreen = value; RefreshFullScreen(); }
+ get { return _fullscreen; }
+ set { _fullscreen = value; RefreshFullScreen(); }
}
public MainForm()
{
@@ -19,7 +19,7 @@ namespace Chess
private void RefreshFullScreen()
{
this.SuspendLayout();
- if (fullscreen)
+ if (Fullscreen)
{
this.WindowState = FormWindowState.Normal;
this.FormBorderStyle = FormBorderStyle.None;
@@ -36,7 +36,7 @@ namespace Chess
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F11)
- fullscreen = !fullscreen;
+ Fullscreen = !Fullscreen;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
@@ -46,7 +46,7 @@ namespace Chess
private void MainForm_Load(object sender, EventArgs e)
{
- fullscreen = true;
+ Fullscreen = true;
}
}
}
diff --git a/ChessPanel/Piece.cs b/ChessPanel/Piece.cs
deleted file mode 100644
index 1ddde84..0000000
--- a/ChessPanel/Piece.cs
+++ /dev/null
@@ -1,461 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using ChessPanel;
-using System.Linq;
-using System.Windows;
-
-namespace Chess
-{
- public abstract class Piece
- {
- public enum PieceColor { White, Black };
- public enum PieceTeam { Enemy, Ally };
- public enum PieceType { King, Queen, Bishop, Rook, Knight, Pawn };
- public PieceColor color;
- public PieceType type;
- public Image image;
- public bool HasMoved = false;
- public bool EnPassantPossible = false; // Only in Pawn Class. Signs that this Piece has virtually not jumped two pieces, but one
- internal static bool IsEndangeredLocationForPiece(Field[,] 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(Field[,] 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(Field[,] 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, testKingDanger: true).ContainsKey(kingLocation))
- {
- return true;
- }
- }
- return false;
- }
-
- private static Vector GetKingLocation(Field[,] fields, PieceColor color)
- {
- foreach (var field in fields)
- if (!field.IsEmpty && field.currentPiece.type == PieceType.King && field.currentPiece.color == color)
- return field.location;
- throw new Exception("King not found!");
- }
-
- internal abstract Dictionary GetValidTargetFields(Field[,] fields, Vector currentLocation, bool onlyAttackFields = false, bool testKingDanger = false);
- }
- public class Rook : Piece
- {
- public Rook(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false)
- {
- var targetFields = GetTargetFields(fields, location, this.color);
- /*if (!testKingDanger)
- foreach (var item in targetFields)
- if (MoveWillEndangerKing(fields, location, item.Key, this.color))
- targetFields.Remove(item.Key);*/
- return targetFields;
- }
-
- internal static Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color)
- {
- Dictionary targetFields = new Dictionary();
-
- for (int x = (int)location.X - 1; x >= 0; x--) // nach Links
- {
- if (fields[x, (int)location.Y].IsEmpty)
- {
- targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Ally);
- }
- else
- {
- if (fields[x, (int)location.Y].currentPiece.color != color)
- targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Enemy);
- break;
- }
- }
-
-
- for (int x = (int)location.X + 1; x <= 7; x++) // nach Rechts
- {
- if (fields[x, (int)location.Y].IsEmpty)
- {
- targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Ally);
- }
- else
- {
- if (fields[x, (int)location.Y].currentPiece.color != color)
- targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Enemy);
- break;
- }
- }
-
- for (int y = (int)location.Y - 1; y >= 0; y--) // nach Unten
- {
- if (fields[(int)(int)location.X, y].IsEmpty)
- {
- targetFields.Add(new Vector((int)location.X, y), PieceTeam.Ally);
- }
- else
- {
- if (fields[(int)(int)location.X, y].currentPiece.color != color)
- targetFields.Add(new Vector((int)location.X, y), PieceTeam.Enemy);
- break;
- }
- }
-
-
- for (int y = (int)location.Y + 1; y <= 7; y++) // nach Oben
- {
- if (fields[(int)(int)location.X, y].IsEmpty)
- {
- targetFields.Add(new Vector((int)location.X, y), PieceTeam.Ally);
- }
- else
- {
- if (fields[(int)(int)location.X, y].currentPiece.color != color)
- targetFields.Add(new Vector((int)location.X, y), PieceTeam.Enemy);
- break;
- }
- }
-
- return targetFields;
- }
- } // FINALIZED
- public class Pawn : Piece
- {
- public Pawn(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool onlyAttackFields = false, bool testKingDanger = false)
- {
- var targetFields = GetTargetFields(fields, location, this.color, onlyAttackFields);
- /*if (!testKingDanger)
- foreach (var item in targetFields)
- if (MoveWillEndangerKing(fields, location, item.Key, this.color))
- targetFields.Remove(item.Key);*/
- return targetFields;
- }
-
- private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = false)
- {
- Dictionary targetFields = new Dictionary();
- int direction = this.color == PieceColor.White ? -1 : 1;
- #region EnPassant
- if (location.Y == (this.color == PieceColor.White ? 3 : 4))
- for (int x = -1; x < 2; x += 2)
- if (location.X + x <= 7 && location.X + x >= 0)
- if (fields[(int)location.X + x, (int)location.Y].currentPiece != null)
- if (fields[(int)location.X + x, (int)location.Y].currentPiece.type == PieceType.Pawn)
- if (fields[(int)location.X + x, (int)location.Y].currentPiece.color != this.color)
- if (fields[(int)location.X + x, (int)location.Y].currentPiece.EnPassantPossible)
- targetFields.Add(new Vector(location.X + x, location.Y + direction), PieceTeam.Enemy);
- #endregion
- #region Movement
- if (!onlyAttackFields)
- for (int y = 1; y < 1 + (HasMoved ? 1 : 2); y++)
- {
- if (location.Y + (direction * y) > 7 || location.Y + (direction * y) < 0)
- break;
- if (fields[(int)location.X, (int)location.Y + (direction * y)].IsEmpty)
- targetFields.Add(new Vector(location.X, (int)location.Y + (direction * y)), PieceTeam.Ally);
- else
- break;
- }
- #endregion
- #region Attack
- for (int x = -1; x < 2; x += 2)
- {
- if (location.Y + (direction) > 7 || location.Y + (direction) < 0 || location.X + x > 7 || location.X + x < 0)
- continue;
- if (onlyAttackFields || (fields[(int)location.X + x, (int)location.Y + (direction)].currentPiece != null && fields[(int)location.X + x, (int)location.Y + (direction)].currentPiece.color != this.color))
- {
- targetFields.Add(new Vector((int)location.X + x, (int)location.Y + (direction)), PieceTeam.Enemy);
- }
- }
- #endregion
- return targetFields;
- }
- } // EN-PASSANT MISSING
- public class Knight : Piece
- {
- public Knight(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false)
- {
- var targetFields = GetTargetFields(fields, location, this.color);
- /* if (!testKingDanger)
- foreach (var item in targetFields)
- if (MoveWillEndangerKing(fields, location, item.Key, this.color))
- targetFields.Remove(item.Key);*/
- return targetFields;
- }
-
- private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color)
- {
- Dictionary targetFields = new Dictionary();
-
- for (int a = -1; a < 2; a += 2)
- {
- for (int b = -2; b < 3; b += 4)
- {
- if (!(a + (int)location.X > 7 || b + (int)location.Y < 0 || a + (int)location.X < 0 || b + (int)location.Y > 7))
- {
- if (fields[a + (int)location.X, b + (int)location.Y].IsEmpty)
- {
- targetFields.Add(new Vector(a + (int)location.X, b + (int)location.Y), PieceTeam.Ally);
- }
- else
- {
- if (fields[a + (int)location.X, b + (int)location.Y].currentPiece.color != color)
- targetFields.Add(new Vector(a + (int)location.X, b + (int)location.Y), PieceTeam.Enemy);
- }
- }
- if (!(b + (int)location.X > 7 || a + (int)location.Y < 0 || b + (int)location.X < 0 || a + (int)location.Y > 7))
- {
- if (fields[b + (int)location.X, a + (int)location.Y].IsEmpty)
- {
- targetFields.Add(new Vector(b + (int)location.X, a + (int)location.Y), PieceTeam.Ally);
- }
- else
- {
- if (fields[b + (int)location.X, a + (int)location.Y].currentPiece.color != color)
- targetFields.Add(new Vector(b + (int)location.X, a + (int)location.Y), PieceTeam.Enemy);
- }
- }
- }
- }
-
- return targetFields;
- }
- } // FINALIZED
- public class Bishop : Piece
- {
- public Bishop(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool onlyAttackFields = false, bool testKingDanger = false)
- {
- var targetFields = GetTargetFields(fields, location, this.color, onlyAttackFields);
- /* if (!testKingDanger)
- foreach (var item in targetFields)
- if (MoveWillEndangerKing(fields, location, item.Key, this.color))
- targetFields.Remove(item.Key);*/
- return targetFields;
- }
- internal static Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = true)
- {
- Dictionary targetFields = new Dictionary();
-
- for (int xy = 1; xy <= 7; xy++) // nach RechtsOben
- {
- if (location.X + xy > 7 || (int)location.Y + xy > 7)
- break;
- if (fields[xy + (int)location.X, xy + (int)location.Y].IsEmpty)
- {
- targetFields.Add(new Vector(xy + (int)location.X, xy + (int)location.Y), PieceTeam.Ally);
- }
- else
- {
- if (fields[xy + (int)location.X, xy + (int)location.Y].currentPiece.color != color)
- targetFields.Add(new Vector(xy + (int)location.X, xy + (int)location.Y), PieceTeam.Enemy);
- break;
- }
- }
- for (int xy = 1; xy <= 7; xy++) // nach LinksOben
- {
- if (location.X - xy < 0 || (int)location.Y + xy > 7)
- break;
- if (fields[(int)location.X - xy, (int)location.Y + xy].IsEmpty)
- {
- targetFields.Add(new Vector(location.X - xy, (int)location.Y + xy), PieceTeam.Ally);
- }
- else
- {
- if (fields[(int)location.X - xy, (int)location.Y + xy].currentPiece.color != color)
- targetFields.Add(new Vector(location.X - xy, (int)location.Y + xy), PieceTeam.Enemy);
- break;
- }
- }
- for (int xy = 1; xy <= 7; xy++) // nach RechtsUnten
- {
- if (location.X + xy > 7 || (int)location.Y - xy < 0)
- break;
- if (fields[xy + (int)location.X, (int)location.Y - xy].IsEmpty)
- {
- targetFields.Add(new Vector(xy + (int)location.X, (int)location.Y - xy), PieceTeam.Ally);
- }
- else
- {
- if (fields[xy + (int)location.X, (int)location.Y - xy].currentPiece.color != color)
- targetFields.Add(new Vector(xy + (int)location.X, (int)location.Y - xy), PieceTeam.Enemy);
- break;
- }
- }
- for (int xy = 1; xy <= 7; xy++) // nach LinksUnten
- {
- if (location.X - xy < 0 || (int)location.Y - xy < 0)
- break;
- if (fields[(int)location.X - xy, (int)location.Y - xy].IsEmpty)
- {
- targetFields.Add(new Vector(location.X - xy, (int)location.Y - xy), PieceTeam.Ally);
- }
- else
- {
- if (fields[(int)location.X - xy, (int)location.Y - xy].currentPiece.color != color)
- targetFields.Add(new Vector(location.X - xy, (int)location.Y - xy), PieceTeam.Enemy);
- break;
- }
- }
- return targetFields;
- }
- } // FINALIZED
- public class Queen : Piece
- {
- public Queen(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false)
- {
- Dictionary targetFields = Rook.GetTargetFields(fields, location, this.color);
- targetFields = targetFields.Concat(Bishop.GetTargetFields(fields, location, this.color)
- .Where(kvp => !targetFields.ContainsKey(kvp.Key)))
- .OrderBy(c => c.Value)
- .ToDictionary(c => c.Key, c => c.Value);
- /*if (!testKingDanger)
- foreach (var item in targetFields)
- if (MoveWillEndangerKing(fields, location, item.Key, this.color))
- targetFields.Remove(item.Key);*/
- return targetFields;
- }
- } // FINALIZED
- public class King : Piece
- {
- public King(PieceColor color)
- {
- type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
- this.color = color;
- this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
- }
-
- internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) // ignoreKingCheck hat keinen Einfluss
- {
- return GetTargetFields(fields, location, this.color);
- }
-
- private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color)
- {
- Dictionary targetFields = new Dictionary();
- #region Castling
- if (!this.HasMoved) // Only Castle if King did not move
- foreach (var item in fields)
- {
- var itemLocation = item.location;
- // Sucht nach Ally Turm und prüft, ob er sich schon bewegt hat
- if (item.currentPiece != null && item.currentPiece.type == PieceType.Rook && !item.currentPiece.HasMoved && item.currentPiece.color == this.color)
- {
- if (itemLocation.X == 0 || itemLocation.X == 7)
- {
- bool castling = true;
- for (int x = (itemLocation.X == 0 ? 1 : 5); (itemLocation.X == 0 ? x < 4 : x < 7); x++)
- {
- if (!fields[x, (int)location.Y].IsEmpty)
- {
- castling = false;
- break;
- }
- }
- if (castling) // Only Check endangered Fields if castling is generally possible
- {
- for (int x = (itemLocation.X == 0 ? 2 : 4); x < (itemLocation.X == 0 ? 5 : 7); x++) // König steht im Schach oder überschreitet bedrohtes Feld
- {
- if (IsEndangeredLocationForPiece(fields, location, new Vector(x, location.Y), color))
- {
- castling = false;
- break;
- }
- }
- if (castling)
- {
- targetFields.Add(new Vector((itemLocation.X == 0 ? 2 : 6), itemLocation.Y), PieceTeam.Ally);
- }
- }
- }
- }
- }
- #endregion
- #region Movement: 1 in every direction
- for (int x = -1; x < 2; x++)
- {
- for (int y = -1; y < 2; y++)
- {
- if ((x == 0 && y == 0) || location.X + x > 7 || location.Y + y > 7 || location.X + x < 0 || location.Y + y < 0)
- continue;
- if (!IsEndangeredLocationForPiece(fields, location, new Vector(location.X + x, location.Y + y), color))
- if (fields[(int)location.X + x, (int)location.Y + y].IsEmpty)
- {
- targetFields.Add(new Vector(location.X + x, (int)location.Y + y), PieceTeam.Ally);
- }
- else
- {
- if (fields[(int)location.X + x, (int)location.Y + y].currentPiece.color != color)
- targetFields.Add(new Vector(location.X + x, (int)location.Y + y), PieceTeam.Enemy);
- continue;
- }
- }
- }
- #endregion
- return targetFields;
- }
- } // CHECKMATE/CHECK-TEST MISSING
-}
\ No newline at end of file
diff --git a/ChessPanel/Pieces/AbstractPiece.cs b/ChessPanel/Pieces/AbstractPiece.cs
new file mode 100644
index 0000000..f89aa94
--- /dev/null
+++ b/ChessPanel/Pieces/AbstractPiece.cs
@@ -0,0 +1,232 @@
+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 { Normal, Attack, Movement };
+
+ ///
+ /// Figur
+ ///
+ public abstract class Piece
+ {
+ public PieceColor color;
+ public PieceType type;
+ public Dictionary validTargetSpots;
+ public Image image;
+ public bool HasMoved = false;
+ public Field field;
+ 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;
+ }
+
+ public Dictionary RefreshValidTargetSpots(Grid fields, MoveMode mode = MoveMode.Normal)
+ {
+ this.validTargetSpots = this.GetValidTargetFields(fields, mode);
+ return validTargetSpots;
+ }
+
+ 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.Normal, 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);
+ }
+}
\ No newline at end of file
diff --git a/ChessPanel/Pieces/AbstractPiece.txt b/ChessPanel/Pieces/AbstractPiece.txt
new file mode 100644
index 0000000..dda78d1
--- /dev/null
+++ b/ChessPanel/Pieces/AbstractPiece.txt
@@ -0,0 +1,226 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/ChessPanel/Pieces/Bishop.cs b/ChessPanel/Pieces/Bishop.cs
new file mode 100644
index 0000000..80b2209
--- /dev/null
+++ b/ChessPanel/Pieces/Bishop.cs
@@ -0,0 +1,143 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class Bishop : Piece
+ {
+ public Bishop(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+
+ private static bool AddFieldToTargetFields(Grid fields, Field field, int x, int y, Dictionary targetFields, PieceColor color)
+ {
+ if (fields[field.location, x, y].IsEmpty)
+ {
+ targetFields.Add(fields[field.location, x, y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[field.location, x, y].CurrentPiece?.color != color)
+ targetFields.Add(fields[field.location, x, y], PieceTeam.Enemy);
+ return true;
+ }
+ return false;
+ }
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ return StaticGetTargetFields(fields, field, color);
+ }
+ internal static Dictionary StaticGetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ Dictionary targetFields = new Dictionary();
+
+ #region nach RechtsOben
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (CheckOutOfBounds(field, xy, xy) || AddFieldToTargetFields(fields, field, xy, xy, targetFields, color))
+ break;
+ }
+ #endregion
+
+ // LinksOben
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (CheckOutOfBounds(field, -xy, xy) || AddFieldToTargetFields(fields, field, -xy, xy, targetFields, color))
+ break;
+ }
+
+ // RechtsUnten
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (CheckOutOfBounds(field, xy, -xy) || AddFieldToTargetFields(fields, field, xy, -xy, targetFields, color))
+ break;
+ }
+
+ // LinksUnten
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (CheckOutOfBounds(field, -xy, -xy) || AddFieldToTargetFields(fields, field, -xy, -xy, targetFields, color))
+ break;
+ }
+ return targetFields;
+ }
+
+ private static bool CheckOutOfBounds(Field field, int x, int y)
+ {
+ return field.location.X + x > 7 || (int)field.location.Y + y > 7
+ || field.location.X + x < 0 || (int)field.location.Y + y < 0;
+ }
+
+ ///
+ ///
+ ///
+ /// Global Field Grid
+ /// Field that should be checked for endager
+ /// Piece that should be moved
+ /// Target of the moved piece
+ ///
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos)
+ {
+ return StaticEndageresFieldWithVirtualMove(fields, this.field, possibleEndageredField, movePiece, targetPos, color);
+ }
+
+ internal static bool StaticEndageresFieldWithVirtualMove(Grid fields, Field thisField, Field possibleEndageredField, Piece movePiece, Field targetPos, PieceColor color)
+ {
+ var skipField = movePiece.field;
+
+ for (int xy = 1; xy <= 7; xy++) // nach RechtsOben
+ {
+ if (thisField.location.X + xy > 7 || thisField.location.Y + xy > 7)
+ break;
+
+ var possibleTargetField = fields.GetFieldWithOffset(thisField, xy, xy);
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (thisField.location.X - xy < 0 || thisField.location.Y + xy > 7) // LinksOben
+ break;
+ var possibleTargetField = fields.GetFieldWithOffset(thisField, -xy, xy);
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (thisField.location.X + xy > 7 || thisField.location.Y - xy < 0) // RechtsUnten
+ break;
+ var possibleTargetField = fields.GetFieldWithOffset(thisField, xy, -xy);
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ for (int xy = 1; xy <= 7; xy++)
+ {
+ if (thisField.location.X - xy < 0 || thisField.location.Y - xy < 0) // LinksUnten
+ break;
+ var possibleTargetField = fields.GetFieldWithOffset(thisField, -xy, -xy);
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ return false;
+ }
+ } // FINALIZED
+}
diff --git a/ChessPanel/Pieces/King.cs b/ChessPanel/Pieces/King.cs
new file mode 100644
index 0000000..ebdf73f
--- /dev/null
+++ b/ChessPanel/Pieces/King.cs
@@ -0,0 +1,132 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class King : Piece
+ {
+ public King(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field field, Piece movePiece, Field targetPos)
+ {
+ //#region Movement: 1 in every direction
+ //for (int x = -1; x < 2; x++)
+ //{
+ // for (int y = -1; y < 2; y++)
+ // {
+ // if ((x == 0 && y == 0) || field.location.X + x > 7 || field.location.Y + y > 7 || field.location.X + x < 0 || field.location.Y + y < 0)
+ // continue;
+ // if (!fields.IsFieldVirtuallyEndagered(fields[field.location, x, y], (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, fields[field.location, x, y]))
+ // if ((fields[field.location, x, y].IsEmpty && fields[field.location, x, y] != targetPos) || fields[field.location, x, y] == movePiece.field)
+ // {
+ // if (fields[field.location, x, y] == field)
+ // return true;
+ // continue;
+ // }
+ // else
+ // {
+ // if (fields[field.location, x, y].currentPiece.color != color)
+ // if (fields[field.location, x, y] == field)
+ // return true;
+ // break;
+ // }
+ // }
+ //}
+ //#endregion
+ return false;
+ }
+
+ internal override Dictionary GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Normal, bool dontTestKingDanger = false)
+ {
+ var targetFields = GetTargetFields(fields, field, this.color);
+ if (!dontTestKingDanger)
+ {
+ List remove = new List();
+
+ foreach (var virtualKinglocation in targetFields.Keys)
+ {
+ if (fields.IsFieldVirtuallyEndagered(virtualKinglocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, virtualKinglocation))
+ remove.Add(virtualKinglocation);
+ }
+ foreach (var item in remove)
+ {
+ targetFields.Remove(item);
+ }
+ }
+ return targetFields;
+ }
+
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ Dictionary targetFields = new Dictionary();
+ #region Castling
+ if (!this.HasMoved && false) // Only Castle if King did not move
+ foreach (Field item in fields)
+ {
+ var itemLocation = item.location;
+ // Sucht nach Ally Turm und prüft, ob er sich schon bewegt hat
+ if (item.currentPiece != null && item.currentPiece.type == PieceType.Rook && !item.currentPiece.HasMoved && item.currentPiece.color == this.color)
+ {
+ if (itemLocation.X == 0 || itemLocation.X == 7)
+ {
+ bool castling = true;
+ for (int x = (itemLocation.X == 0 ? 1 : 5); (itemLocation.X == 0 ? x < 4 : x < 7); x++)
+ {
+ if (!fields[x, (int)field.location.Y].IsEmpty)
+ {
+ castling = false;
+ break;
+ }
+ }
+ if (castling) // Only Check endangered Fields if castling is generally possible
+ {
+ for (int x = (itemLocation.X == 0 ? 2 : 4); x < (itemLocation.X == 0 ? 5 : 7); x++) // König steht im Schach oder überschreitet bedrohtes Feld
+ {
+ if (fields.IsFieldVirtuallyEndagered(fields[x, field.location.Y], (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, fields[x, field.location.Y]))
+ {
+ castling = false;
+ break;
+ }
+ }
+ if (castling)
+ {
+ targetFields.Add(fields[(itemLocation.X == 0 ? 2 : 6), itemLocation.Y], PieceTeam.Ally);
+ }
+ }
+ }
+ }
+ }
+ #endregion
+ #region Movement: 1 in every direction
+ for (int x = -1; x < 2; x++)
+ {
+ for (int y = -1; y < 2; y++)
+ {
+ if ((x == 0 && y == 0) || field.location.X + x > 7 || field.location.Y + y > 7 || field.location.X + x < 0 || field.location.Y + y < 0)
+ continue;
+
+ if (fields[field.location, x, y].IsEmpty)
+ {
+ targetFields.Add(fields[field.location, x, y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[field.location, x, y].currentPiece.color != color)
+ targetFields.Add(fields[field.location, x, y], PieceTeam.Enemy);
+ continue;
+ }
+ }
+ }
+ #endregion
+ return targetFields;
+ }
+ } // CHECKMATE/CHECK-TEST MISSING
+}
\ No newline at end of file
diff --git a/ChessPanel/Pieces/Knight.cs b/ChessPanel/Pieces/Knight.cs
new file mode 100644
index 0000000..cf663db
--- /dev/null
+++ b/ChessPanel/Pieces/Knight.cs
@@ -0,0 +1,98 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class Knight : Piece
+ {
+ public Knight(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field field, Piece movePiece, Field targetPos)
+ {
+ for (int a = -1; a < 2; a += 2)
+ {
+ for (int b = -2; b < 3; b += 4)
+ {
+ if (!(a + (int)field.location.X > 7 || b + (int)field.location.Y < 0 || a + (int)field.location.X < 0 || b + (int)field.location.Y > 7))
+ {
+ if ((fields[field.location,a,b].IsEmpty && fields[field.location, a, b] != targetPos) || fields[field.location, a, b] == movePiece.field)
+ {
+ if (fields[field.location, a, b] == field)
+ return true;
+ continue;
+ }
+ else
+ {
+ if (fields[field.location, a, b].CurrentPiece?.color != color)
+ if (fields[field.location, a, b] == field)
+ return true;
+ break;
+ }
+ }
+ if (!(b + (int)field.location.X > 7 || a + (int)field.location.Y < 0 || b + (int)field.location.X < 0 || a + (int)field.location.Y > 7))
+ {
+ if ((fields[field.location, b, a].IsEmpty && fields[field.location, b, a] != targetPos) || fields[field.location, b, a] == movePiece.field)
+ {
+ if (fields[field.location, b, a] == field)
+ return true;
+ continue;
+ }
+ else
+ {
+ if (fields[field.location, b, a].CurrentPiece?.color != color)
+ if (fields[field.location, b, a] == field)
+ return true;
+ break;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ Dictionary targetFields = new Dictionary();
+
+ for (int a = -1; a < 2; a += 2)
+ {
+ for (int b = -2; b < 3; b += 4)
+ {
+ if (!(a + (int)field.location.X > 7 || b + (int)field.location.Y < 0 || a + (int)field.location.X < 0 || b + (int)field.location.Y > 7))
+ {
+ if (fields[field.location,a,b].IsEmpty)
+ {
+ targetFields.Add(fields[field.location, a, b], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[field.location, a, b].CurrentPiece?.color != color)
+ targetFields.Add(fields[field.location, a, b], PieceTeam.Enemy);
+ }
+ }
+ if (!(b + (int)field.location.X > 7 || a + (int)field.location.Y < 0 || b + (int)field.location.X < 0 || a + (int)field.location.Y > 7))
+ {
+ if (fields[field.location, b, a].IsEmpty)
+ {
+ targetFields.Add(fields[field.location, b, a], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[field.location, b, a].CurrentPiece?.color != color)
+ targetFields.Add(fields[field.location, b, a], PieceTeam.Enemy);
+ }
+ }
+ }
+ }
+ return targetFields;
+ }
+ } // FINALIZED
+}
diff --git a/ChessPanel/Pieces/Pawn.cs b/ChessPanel/Pieces/Pawn.cs
new file mode 100644
index 0000000..f17b2c1
--- /dev/null
+++ b/ChessPanel/Pieces/Pawn.cs
@@ -0,0 +1,80 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class Pawn : Piece
+ {
+ public Pawn(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field field, Piece movePiece, Field targetPos) // Pawn does not care about virtually moved pieces, if field is in range it can attack
+ {
+ int direction = this.color == PieceColor.White ? -1 : 1;
+ #region Attack
+ for (int x = -1; x < 2; x += 2)
+ {
+ if (field.location.Y + (direction) > 7 || field.location.Y + (direction) < 0 || field.location.X + x > 7 || field.location.X + x < 0)
+ continue;
+ if (fields[field.location, x, direction] == field)
+ return true;
+ }
+ #endregion
+ return false;
+ }
+
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ MoveMode mode = MoveMode.Normal;
+
+ Dictionary targetFields = new Dictionary();
+ int direction = this.color == PieceColor.White ? -1 : 1;
+ #region Movement
+ if (mode == MoveMode.Normal || mode == MoveMode.Movement)
+ for (int y = 1; y < 1 + (HasMoved ? 1 : 2); y++)
+ {
+ if (field.location.Y + (direction * y) > 7 || field.location.Y + (direction * y) < 0)
+ break;
+ if (fields[field.location, 0, (direction * y)].IsEmpty)
+ targetFields.Add(fields[field.location, 0, (direction * y)], PieceTeam.Ally);
+ else
+ break;
+ }
+ #endregion
+ #region Attack
+ if (mode == MoveMode.Normal || mode == MoveMode.Attack)
+ {
+ #region EnPassant
+ if (field.location.Y == (this.color == PieceColor.White ? 3 : 4))
+ for (int x = -1; x < 2; x += 2)
+ if (field.location.X + x <= 7 && field.location.X + x >= 0)
+ if (fields[field.location, x, 0].CurrentPiece != null
+ && fields[field.location, x, 0].CurrentPiece.type == PieceType.Pawn
+ && fields[field.location, x, 0].CurrentPiece.color != this.color
+ && fields[field.location, x, 0].CurrentPiece.EnPassantPossible)
+ targetFields.Add(fields[field.location, x, direction], PieceTeam.Enemy);
+ #endregion
+ for (int x = -1; x < 2; x += 2)
+ {
+ if (field.location.Y + (direction) > 7 || field.location.Y + (direction) < 0 || field.location.X + x > 7 || field.location.X + x < 0)
+ continue;
+ if (fields[field.location, x, direction].CurrentPiece != null && fields[field.location, x, direction].CurrentPiece.color != this.color)
+ {
+ targetFields.Add(fields[field.location, x, direction], PieceTeam.Enemy);
+ }
+ }
+ #endregion
+ }
+ return targetFields;
+ }
+
+ }
+
+}
diff --git a/ChessPanel/Pieces/Queen.cs b/ChessPanel/Pieces/Queen.cs
new file mode 100644
index 0000000..bb00ee6
--- /dev/null
+++ b/ChessPanel/Pieces/Queen.cs
@@ -0,0 +1,35 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class Queen : Piece
+ {
+ public Queen(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos)
+ {
+ return Rook.StaticEndageresFieldWithVirtualMove(fields, this.field, possibleEndageredField, movePiece, targetPos, color)
+ || Bishop.StaticEndageresFieldWithVirtualMove(fields, this.field, possibleEndageredField, movePiece, targetPos, color);
+ }
+
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ Dictionary targetFields = Rook.StaticGetTargetFields(fields, field, this.color); // Take Rook fields
+ targetFields = targetFields.Concat(Bishop.StaticGetTargetFields(fields, field, this.color) // Add Bishop; Rook + Bishop = Queen
+ .Where(kvp => !targetFields.ContainsKey(kvp.Key)))
+ .OrderBy(c => c.Value)
+ .ToDictionary(c => c.Key, c => c.Value);
+ return targetFields;
+ }
+ } // FINALIZED
+}
diff --git a/ChessPanel/Pieces/Rook.cs b/ChessPanel/Pieces/Rook.cs
new file mode 100644
index 0000000..79e6c5b
--- /dev/null
+++ b/ChessPanel/Pieces/Rook.cs
@@ -0,0 +1,141 @@
+using Chess;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows;
+
+namespace ChessPanel
+{
+ public class Rook : Piece
+ {
+ public Rook(PieceColor color, Vector position, Grid fields) : base(position, fields)
+ {
+ type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name);
+ this.color = color;
+ this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}");
+ }
+ //internal override 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;
+ // foreach (var item in targetFields)
+ // if (fields.IsFieldVirtuallyEndagered(kinglocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, item.Key))
+ // targetFields.Remove(item.Key);
+ // }
+ // return targetFields;
+ //}
+
+ internal override Dictionary GetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ return StaticGetTargetFields(fields, field, color);
+ }
+ internal static Dictionary StaticGetTargetFields(Grid fields, Field field, PieceColor color)
+ {
+ Dictionary targetFields = new Dictionary();
+ for (int x = (int)field.location.X - 1; x >= 0; x--) // nach Links
+ {
+ if (fields[x, field.location.Y].IsEmpty)
+ {
+ targetFields.Add(fields[x, field.location.Y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[x, (int)field.location.Y].currentPiece.color != color)
+ targetFields.Add(fields[x, field.location.Y], PieceTeam.Enemy);
+ break;
+ }
+ }
+ for (int x = (int)field.location.X + 1; x <= 7; x++) // nach Rechts
+ {
+ if (fields[x, (int)field.location.Y].IsEmpty)
+ {
+ targetFields.Add(fields[x, field.location.Y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[x, (int)field.location.Y].currentPiece.color != color)
+ targetFields.Add(fields[x, field.location.Y], PieceTeam.Enemy);
+ break;
+ }
+ }
+ for (int y = (int)field.location.Y - 1; y >= 0; y--) // nach Unten
+ {
+ if (fields[(int)field.location.X, y].IsEmpty)
+ {
+ targetFields.Add(fields[field.location.X, y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[(int)field.location.X, y].currentPiece.color != color)
+ targetFields.Add(fields[field.location.X, y], PieceTeam.Enemy);
+ break;
+ }
+ }
+ for (int y = (int)field.location.Y + 1; y <= 7; y++) // nach Oben
+ {
+ if (fields[(int)field.location.X, y].IsEmpty)
+ {
+ targetFields.Add(fields[field.location.X, y], PieceTeam.Ally);
+ }
+ else
+ {
+ if (fields[(int)field.location.X, y].currentPiece.color != color)
+ targetFields.Add(fields[field.location.X, y], PieceTeam.Enemy);
+ break;
+ }
+ }
+ return targetFields;
+ }
+
+ internal override bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos)
+ {
+ return StaticEndageresFieldWithVirtualMove(fields, this.field, possibleEndageredField, movePiece, targetPos, color);
+ }
+
+ internal static bool StaticEndageresFieldWithVirtualMove(Grid fields, Field thisField, Field possibleEndageredField, Piece movePiece, Field targetPos, PieceColor color)
+ {
+ if (possibleEndageredField.location.X != thisField.location.X && possibleEndageredField.location.Y != thisField.location.Y) // Field can not be reached horizontally nor vertically
+ return false;
+
+ for (int x = (int)thisField.location.X - 1; x >= 0; x--) // nach Links
+ {
+ var possibleTargetField = fields[x, thisField.location.Y];
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ for (int x = (int)thisField.location.X + 1; x <= 7; x++) // nach Rechts
+ {
+ var possibleTargetField = fields[x, thisField.location.Y];
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ for (int y = (int)thisField.location.Y - 1; y >= 0; y--) // nach Oben
+ {
+ var possibleTargetField = fields[thisField.location.X, y];
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ for (int y = (int)thisField.location.Y + 1; y <= 7; y++) // nach Unten
+ {
+ var possibleTargetField = fields[thisField.location.X, y];
+
+ if (CheckFieldCanBeReached(possibleEndageredField, targetPos, movePiece, possibleTargetField, color, out bool breakIt))
+ return true;
+ if (breakIt)
+ break;
+ }
+ return false;
+ }
+ } // FINALIZED
+}