Added initial code commit
This commit is contained in:
parent
368cb29eaf
commit
dd63e0adf5
179
.gitignore
vendored
179
.gitignore
vendored
@ -1,7 +1,10 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
@ -10,6 +13,9 @@
|
|||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
@ -17,42 +23,62 @@
|
|||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
#wwwroot/
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
# MSTest test Results
|
# MSTest test Results
|
||||||
[Tt]est[Rr]esult*/
|
[Tt]est[Rr]esult*/
|
||||||
[Bb]uild[Ll]og.*
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
# NUNIT
|
# NUnit
|
||||||
*.VisualState.xml
|
*.VisualState.xml
|
||||||
TestResult.xml
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
# Build Results of an ATL Project
|
||||||
[Dd]ebugPS/
|
[Dd]ebugPS/
|
||||||
[Rr]eleasePS/
|
[Rr]eleasePS/
|
||||||
dlldata.c
|
dlldata.c
|
||||||
|
|
||||||
# DNX
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
project.lock.json
|
project.lock.json
|
||||||
project.fragment.lock.json
|
project.fragment.lock.json
|
||||||
artifacts/
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
*_i.c
|
*_i.c
|
||||||
*_p.c
|
*_p.c
|
||||||
*_i.h
|
*_h.h
|
||||||
*.ilk
|
*.ilk
|
||||||
*.meta
|
*.meta
|
||||||
*.obj
|
*.obj
|
||||||
|
*.iobj
|
||||||
*.pch
|
*.pch
|
||||||
*.pdb
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
*.pgc
|
*.pgc
|
||||||
*.pgd
|
*.pgd
|
||||||
*.rsp
|
*.rsp
|
||||||
@ -62,7 +88,9 @@ artifacts/
|
|||||||
*.tlh
|
*.tlh
|
||||||
*.tmp
|
*.tmp
|
||||||
*.tmp_proj
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
*.log
|
*.log
|
||||||
|
*.tlog
|
||||||
*.vspscc
|
*.vspscc
|
||||||
*.vssscc
|
*.vssscc
|
||||||
.builds
|
.builds
|
||||||
@ -90,6 +118,9 @@ ipch/
|
|||||||
*.vspx
|
*.vspx
|
||||||
*.sap
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
# TFS 2012 Local Workspace
|
||||||
$tf/
|
$tf/
|
||||||
|
|
||||||
@ -101,15 +132,25 @@ _ReSharper*/
|
|||||||
*.[Rr]e[Ss]harper
|
*.[Rr]e[Ss]harper
|
||||||
*.DotSettings.user
|
*.DotSettings.user
|
||||||
|
|
||||||
# JustCode is a .NET coding add-in
|
|
||||||
.JustCode
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
# TeamCity is a build add-in
|
||||||
_TeamCity*
|
_TeamCity*
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
# DotCover is a Code Coverage Tool
|
||||||
*.dotCover
|
*.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
|
||||||
_NCrunch_*
|
_NCrunch_*
|
||||||
.*crunch*.local.xml
|
.*crunch*.local.xml
|
||||||
@ -141,9 +182,9 @@ publish/
|
|||||||
# Publish Web Output
|
# Publish Web Output
|
||||||
*.[Pp]ublish.xml
|
*.[Pp]ublish.xml
|
||||||
*.azurePubxml
|
*.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
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
#*.pubxml
|
*.pubxml
|
||||||
*.publishproj
|
*.publishproj
|
||||||
|
|
||||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
@ -153,13 +194,15 @@ PublishScripts/
|
|||||||
|
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
# The packages folder can be ignored because of Package Restore
|
# The packages folder can be ignored because of Package Restore
|
||||||
**/packages/*
|
**/[Pp]ackages/*
|
||||||
# except build/, which is used as an MSBuild target.
|
# 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
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
#!**/packages/repositories.config
|
#!**/[Pp]ackages/repositories.config
|
||||||
# NuGet v3's project.json files produces more ignoreable files
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
*.nuget.props
|
*.nuget.props
|
||||||
*.nuget.targets
|
*.nuget.targets
|
||||||
|
|
||||||
@ -176,12 +219,15 @@ AppPackages/
|
|||||||
BundleArtifacts/
|
BundleArtifacts/
|
||||||
Package.StoreAssociation.xml
|
Package.StoreAssociation.xml
|
||||||
_pkginfo.txt
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
# Visual Studio cache files
|
# Visual Studio cache files
|
||||||
# files ending in .cache can be ignored
|
# files ending in .cache can be ignored
|
||||||
*.[Cc]ache
|
*.[Cc]ache
|
||||||
# but keep track of directories ending in .cache
|
# but keep track of directories ending in .cache
|
||||||
!*.[Cc]ache/
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
ClientBin/
|
ClientBin/
|
||||||
@ -192,9 +238,12 @@ ClientBin/
|
|||||||
*.jfm
|
*.jfm
|
||||||
*.pfx
|
*.pfx
|
||||||
*.publishsettings
|
*.publishsettings
|
||||||
node_modules/
|
|
||||||
orleans.codegen.cs
|
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
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
#bower_components/
|
#bower_components/
|
||||||
@ -209,15 +258,22 @@ _UpgradeReport_Files/
|
|||||||
Backup*/
|
Backup*/
|
||||||
UpgradeLog*.XML
|
UpgradeLog*.XML
|
||||||
UpgradeLog*.htm
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
# SQL Server files
|
# SQL Server files
|
||||||
*.mdf
|
*.mdf
|
||||||
*.ldf
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
# Business Intelligence projects
|
# Business Intelligence projects
|
||||||
*.rdl.data
|
*.rdl.data
|
||||||
*.bim.layout
|
*.bim.layout
|
||||||
*.bim_*.settings
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
# Microsoft Fakes
|
# Microsoft Fakes
|
||||||
FakesAssemblies/
|
FakesAssemblies/
|
||||||
@ -227,6 +283,7 @@ FakesAssemblies/
|
|||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
# Node.js Tools for Visual Studio
|
||||||
.ntvs_analysis.dat
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
# Visual Studio 6 build log
|
||||||
*.plg
|
*.plg
|
||||||
@ -234,6 +291,20 @@ FakesAssemblies/
|
|||||||
# Visual Studio 6 workspace options file
|
# Visual Studio 6 workspace options file
|
||||||
*.opt
|
*.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
|
# Visual Studio LightSwitch build output
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
@ -249,13 +320,79 @@ paket-files/
|
|||||||
# FAKE - F# Make
|
# FAKE - F# Make
|
||||||
.fake/
|
.fake/
|
||||||
|
|
||||||
# JetBrains Rider
|
# CodeRush personal settings
|
||||||
.idea/
|
.cr/personal
|
||||||
*.sln.iml
|
|
||||||
|
|
||||||
# CodeRush
|
|
||||||
.cr/
|
|
||||||
|
|
||||||
# Python Tools for Visual Studio (PTVS)
|
# Python Tools for Visual Studio (PTVS)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.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
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Pieces\Bishop.cs" />
|
||||||
<Compile Include="ChessGame.cs">
|
<Compile Include="ChessGame.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -57,13 +58,18 @@
|
|||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="FieldColorSet.cs" />
|
<Compile Include="FieldColorSet.cs" />
|
||||||
|
<Compile Include="Grid.cs" />
|
||||||
|
<Compile Include="Pieces\King.cs" />
|
||||||
|
<Compile Include="Pieces\Knight.cs" />
|
||||||
<Compile Include="MainForm.cs">
|
<Compile Include="MainForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="MainForm.Designer.cs">
|
<Compile Include="MainForm.Designer.cs">
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Piece.cs" />
|
<Compile Include="Pieces\Pawn.cs" />
|
||||||
|
<Compile Include="Pieces\AbstractPiece.cs" />
|
||||||
|
<Compile Include="Pieces\Rook.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
@ -71,6 +77,10 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Pieces\Queen.cs" />
|
||||||
|
<EmbeddedResource Include="ChessGame.resx">
|
||||||
|
<DependentUpon>ChessGame.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="MainForm.resx">
|
<EmbeddedResource Include="MainForm.resx">
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
<DependentUpon>MainForm.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
@ -78,7 +88,6 @@
|
|||||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<None Include="ClassDiagram.cd" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
using Chess;
|
using Chess;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using static Chess.Piece;
|
using static Chess.Piece;
|
||||||
@ -9,34 +11,53 @@ namespace ChessPanel
|
|||||||
{
|
{
|
||||||
public partial class ChessBoard : Panel
|
public partial class ChessBoard : Panel
|
||||||
{
|
{
|
||||||
public Field[,] fields;
|
private BackgroundWorker BGWorker = new BackgroundWorker();
|
||||||
|
public Grid fields;
|
||||||
|
public List<Piece> pieces;
|
||||||
|
|
||||||
public PieceColor activePlayer;
|
public PieceColor activePlayer;
|
||||||
private int gridSize = 8;
|
private int GRID_SIZE = 8;
|
||||||
public bool isSaved = true;
|
public bool isSaved = true;
|
||||||
Dictionary<Vector, PieceTeam> validTargetSpots = new Dictionary<Vector, PieceTeam>();
|
Dictionary<Field, PieceTeam> SelectedPieceTargetSpots = new Dictionary<Field, PieceTeam>();
|
||||||
private Vector? selectedField;
|
//private Vector? selectedField;
|
||||||
private Vector? SelectedField
|
//private Vector? SelectedField
|
||||||
|
//{
|
||||||
|
// get { return selectedField; }
|
||||||
|
// set { selectedField = value; HighlightValidTargetSpots(); }
|
||||||
|
//}
|
||||||
|
private Field selectedField;
|
||||||
|
|
||||||
|
private Field SelectedField
|
||||||
{
|
{
|
||||||
get { return selectedField; }
|
get { return selectedField; }
|
||||||
set { selectedField = value; HighlightValidTargetSpots(); }
|
set { selectedField = value; HighlightValidTargetSpots(); }
|
||||||
}
|
}
|
||||||
|
private bool FieldIsSelected
|
||||||
|
{
|
||||||
|
get { return selectedField != null; }
|
||||||
|
}
|
||||||
|
|
||||||
private void HighlightValidTargetSpots()
|
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();
|
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));
|
//SelectedPieceTargetSpots = selectedField.CurrentPiece.GetValidTargetFields(fields);
|
||||||
}
|
SelectedPieceTargetSpots = selectedField.CurrentPiece.validTargetSpots;
|
||||||
foreach (var item in validTargetSpots)
|
if (SelectedPieceTargetSpots == null)
|
||||||
{
|
SelectedPieceTargetSpots = selectedField.CurrentPiece.GetValidTargetFields(fields);
|
||||||
fields[(int)item.Key.X, (int)item.Key.Y].Highlight(item.Value);
|
|
||||||
}
|
}
|
||||||
|
if (SelectedPieceTargetSpots != null)
|
||||||
|
foreach (var TargetSpot in SelectedPieceTargetSpots)
|
||||||
|
{
|
||||||
|
TargetSpot.Key.Highlight(TargetSpot.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -44,119 +65,177 @@ namespace ChessPanel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void ResetValidTargetSpots()
|
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
|
public int GridSize
|
||||||
{
|
{
|
||||||
get { return gridSize; }
|
get { return GRID_SIZE; }
|
||||||
set { gridSize = value; }
|
set { GRID_SIZE = value; }
|
||||||
}
|
}
|
||||||
public ChessBoard()
|
public ChessBoard()
|
||||||
{
|
{
|
||||||
this.DoubleBuffered = true;
|
this.DoubleBuffered = true;
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
this.Resize += new System.EventHandler(this.ChessBoard_Resize);
|
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();
|
InitializeGrid();
|
||||||
InitializePieces();
|
InitializePieces();
|
||||||
activePlayer = PieceColor.White;
|
activePlayer = PieceColor.White;
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ValidTargetSpotCalculator_DoWork(object sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
BGWorkerData data = e.Argument as BGWorkerData;
|
||||||
|
List<Piece> 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 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;
|
isSaved = false;
|
||||||
#region Castling
|
#region Castling
|
||||||
if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.King && Math.Abs(newLocation.X - location.X) == 2)
|
if (PieceField.CurrentPiece.type == PieceType.King && Math.Abs(newPieceField.location.X - PieceField.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
|
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
|
#endregion
|
||||||
#region EnPassant
|
#region EnPassant
|
||||||
foreach (var item in fields) // Reset Enpassant Possible states each move
|
foreach (Piece item in pieces.Where(i => i.type == PieceType.Pawn)) // Reset Enpassant Possible states each move
|
||||||
{
|
item.EnPassantPossible = false;
|
||||||
if (item.CurrentPiece != null)
|
if (PieceField.CurrentPiece.type == PieceType.Pawn && !PieceField.CurrentPiece.HasMoved)
|
||||||
if (item.CurrentPiece.type == PieceType.Pawn)
|
PieceField.CurrentPiece.EnPassantPossible = true;
|
||||||
{
|
if (PieceField.CurrentPiece.type == PieceType.Pawn && newPieceField.location.X != PieceField.location.X && newPieceField.IsEmpty)
|
||||||
item.CurrentPiece.EnPassantPossible = false;
|
fields[newPieceField.location, 0, (PieceField.CurrentPiece.color == PieceColor.White ? 1 : -1)].CurrentPiece = null;
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
#endregion
|
#endregion
|
||||||
fields[(int)location.X, (int)location.Y].CurrentPiece.HasMoved = true; // Figur Bereits bewegt Status aktualisieren
|
PieceField.CurrentPiece.Move(newPieceField);
|
||||||
fields[(int)newLocation.X, (int)newLocation.Y].CurrentPiece = fields[(int)location.X, (int)location.Y].CurrentPiece; // Figur an neue Position kopieren
|
//PieceField.CurrentPiece.HasMoved = true; // Figur Bereits bewegt Status aktualisieren
|
||||||
fields[(int)location.X, (int)location.Y].CurrentPiece = null; // Alte Kopie der Figur löschen
|
//newPieceField.CurrentPiece = PieceField.CurrentPiece; // Figur an neue Position kopieren
|
||||||
|
//PieceField.CurrentPiece = null; // Alte Kopie der Figur löschen
|
||||||
if (togglePlayer)
|
if (togglePlayer)
|
||||||
ToggleActivePlayer();
|
ToggleActivePlayer();
|
||||||
|
if (skipValidTargetFieldCalculation) BeginTargetFieldCalculation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BGWorkerData
|
||||||
|
{
|
||||||
|
public BGWorkerData(PieceColor color, List<Piece> pieces, Grid fields)
|
||||||
|
{
|
||||||
|
this.color = color;
|
||||||
|
this.pieces = pieces;
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
public PieceColor color;
|
||||||
|
public List<Piece> pieces;
|
||||||
|
public Grid fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginTargetFieldCalculation()
|
||||||
|
{
|
||||||
|
if (BGWorker.WorkerSupportsCancellation)
|
||||||
|
BGWorker.CancelAsync();
|
||||||
|
else
|
||||||
|
BGWorker.RunWorkerAsync(new BGWorkerData(activePlayer, pieces, fields));
|
||||||
|
}
|
||||||
|
|
||||||
private void InitializePieces()
|
private void InitializePieces()
|
||||||
{
|
{
|
||||||
fields[0, 0].CurrentPiece = new Rook(PieceColor.Black);
|
pieces = new List<Piece>
|
||||||
fields[7, 0].CurrentPiece = new Rook(PieceColor.Black);
|
{
|
||||||
fields[0, 7].CurrentPiece = new Rook(PieceColor.White);
|
new Rook(PieceColor.Black, new Vector(0, 0), fields),
|
||||||
fields[7, 7].CurrentPiece = new Rook(PieceColor.White);
|
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);
|
new Knight(PieceColor.Black, new Vector(1, 0), fields),
|
||||||
fields[6, 0].CurrentPiece = new Knight(PieceColor.Black);
|
new Knight(PieceColor.Black, new Vector(6, 0), fields),
|
||||||
fields[1, 7].CurrentPiece = new Knight(PieceColor.White);
|
new Knight(PieceColor.White, new Vector(1, 7), fields),
|
||||||
fields[6, 7].CurrentPiece = new Knight(PieceColor.White);
|
new Knight(PieceColor.White, new Vector(6, 7), fields),
|
||||||
|
|
||||||
fields[2, 0].CurrentPiece = new Bishop(PieceColor.Black);
|
new Bishop(PieceColor.Black, new Vector(2, 0), fields),
|
||||||
fields[5, 0].CurrentPiece = new Bishop(PieceColor.Black);
|
new Bishop(PieceColor.Black, new Vector(5, 0), fields),
|
||||||
fields[2, 7].CurrentPiece = new Bishop(PieceColor.White);
|
new Bishop(PieceColor.White, new Vector(2, 7), fields),
|
||||||
fields[5, 7].CurrentPiece = new Bishop(PieceColor.White);
|
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);
|
new Queen(PieceColor.White, new Vector(3, 7), fields),
|
||||||
fields[3, 0].CurrentPiece = new Queen(PieceColor.Black);
|
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++)
|
for (int x = 0; x < 8; x++)
|
||||||
{
|
{
|
||||||
fields[x, 1].CurrentPiece = new Pawn(PieceColor.Black);
|
pieces.Add(new Pawn(PieceColor.Black, new Vector(x, 1), fields));
|
||||||
fields[x, 6].CurrentPiece = new Pawn(PieceColor.White);
|
pieces.Add(new Pawn(PieceColor.White, new Vector(x, 6), fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (Field field in fields)
|
||||||
|
{
|
||||||
|
field.RefreshPiece();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void InitializeGrid()
|
private void InitializeGrid()
|
||||||
{
|
{
|
||||||
this.fields = new Field[gridSize, gridSize];
|
this.fields = new Grid(GRID_SIZE);
|
||||||
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);
|
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 field = new Field(x, y)
|
||||||
field.Size = subPanelSize;
|
{
|
||||||
field.Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height);
|
Size = subPanelSize,
|
||||||
|
Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height)
|
||||||
|
};
|
||||||
field.FieldClick += FieldClicked;
|
field.FieldClick += FieldClicked;
|
||||||
fields[x, y] = field;
|
fields[x, y] = field;
|
||||||
this.Controls.Add(fields[x, y]);
|
this.Controls.Add(fields[x, y]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void FieldClicked(Vector coordinates)
|
private void FieldClicked(Field sender)
|
||||||
{
|
{
|
||||||
this.SuspendLayout();
|
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
|
ResetSelectedField(); // Auswahl zurücksetzen
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SelectedField == coordinates) // Erneutes Anklicken des Auswahlfeldes
|
if (SelectedField == sender) // Erneutes Anklicken des Auswahlfeldes
|
||||||
ResetSelectedField(); // Auswahl zurücksetzen
|
ResetSelectedField(); // Auswahl zurücksetzen
|
||||||
else // Tritt ein, wenn ein Feld angeklickt wurde, dass nicht das Auswahlfeld ist
|
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
|
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
|
if (!sender.IsEmpty && sender.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
|
SelectedField = sender; // Kein Feld ist ausgewählt: Angeklicktes Feld auswählen (!) AKTUALISIERT AUTOMATISCH DIE MARKIERUNGEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
@ -166,7 +245,7 @@ namespace ChessPanel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void ResetSelectedField()
|
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
|
SelectedField = null; // Erlaubte Zielfelder zurücksetzen
|
||||||
}
|
}
|
||||||
#region Helper Can be deleted
|
#region Helper Can be deleted
|
||||||
@ -186,11 +265,11 @@ namespace ChessPanel
|
|||||||
private void RefreshSize()
|
private void RefreshSize()
|
||||||
{
|
{
|
||||||
this.SuspendLayout();
|
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);
|
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].Size = subPanelSize;
|
||||||
fields[x, y].Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height);
|
fields[x, y].Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height);
|
||||||
|
@ -15,24 +15,25 @@ namespace Chess
|
|||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.board = new ChessBoard();
|
this.board = new ChessPanel.ChessBoard();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// board
|
// board
|
||||||
//
|
//
|
||||||
|
this.board.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||||
this.board.GridSize = 8;
|
this.board.GridSize = 8;
|
||||||
this.board.Cursor = Cursors.Hand;
|
|
||||||
this.board.Location = new System.Drawing.Point(0, 0);
|
this.board.Location = new System.Drawing.Point(0, 0);
|
||||||
this.board.Name = "board";
|
this.board.Name = "board";
|
||||||
int size = Math.Min(this.Size.Width, this.Size.Height);
|
this.board.Size = new System.Drawing.Size(100, 100);
|
||||||
board.Size = new System.Drawing.Size(size, size);
|
|
||||||
this.board.TabIndex = 0;
|
this.board.TabIndex = 0;
|
||||||
|
this.board.Paint += new System.Windows.Forms.PaintEventHandler(this.board_Paint);
|
||||||
//
|
//
|
||||||
// ChessGame
|
// ChessGame
|
||||||
//
|
//
|
||||||
this.Controls.Add(this.board);
|
this.Controls.Add(this.board);
|
||||||
this.Resize += new System.EventHandler(this.ResizeEvent);
|
this.Resize += new System.EventHandler(this.ResizeEvent);
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResizeEvent(object sender, EventArgs e)
|
private void ResizeEvent(object sender, EventArgs e)
|
||||||
@ -77,5 +78,10 @@ namespace Chess
|
|||||||
board.Size = new System.Drawing.Size(size, size);
|
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);
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
120
ChessPanel/ChessGame.resx
Normal file
120
ChessPanel/ChessGame.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
@ -1,107 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
|
||||||
<Class Name="ChessPanel.ChessBoard" Collapsed="true">
|
|
||||||
<Position X="19" Y="0.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AICAAAAAAAAAAAAQAQAACCAEAIAgJAAACgAAAEoABII=</HashCode>
|
|
||||||
<FileName>ChessBoard.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.ChessGame" Collapsed="true">
|
|
||||||
<Position X="20.75" Y="0.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAIAAAAEAAAAACAAAABAAAIAAAAAAAAAA=</HashCode>
|
|
||||||
<FileName>ChessGame.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Field" Collapsed="true">
|
|
||||||
<Position X="22.5" Y="0.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AABBgAEIEIYEIBAACAAAIAACADAAAEACAAAgQAAAABA=</HashCode>
|
|
||||||
<FileName>Field.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Form1" Collapsed="true">
|
|
||||||
<Position X="19" Y="1.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAEAAAACAAAAAAAACAAAACAAAAAAAAAAAAAAAAAAA=</HashCode>
|
|
||||||
<FileName>Form1.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Piece" Collapsed="true">
|
|
||||||
<Position X="10.75" Y="0.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAABAAAAAAAAAAAAAAAAAAAAEAABAACAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Rook" Collapsed="true">
|
|
||||||
<Position X="9.75" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Pawn" Collapsed="true">
|
|
||||||
<Position X="14.25" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Knight" Collapsed="true">
|
|
||||||
<Position X="5.25" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Bishop" Collapsed="true">
|
|
||||||
<Position X="7.5" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Queen" Collapsed="true">
|
|
||||||
<Position X="12" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.King" Collapsed="true">
|
|
||||||
<Position X="16.5" Y="1.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA=</HashCode>
|
|
||||||
<FileName>Piece.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Program" Collapsed="true">
|
|
||||||
<Position X="20.75" Y="1.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAA=</HashCode>
|
|
||||||
<FileName>Program.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Properties.Resources" Collapsed="true">
|
|
||||||
<Position X="22.5" Y="1.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAADAgQAQABAAAAIBEAAAIUAAIAAABAACAAAAIIA=</HashCode>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Class Name="Chess.Properties.Settings" Collapsed="true">
|
|
||||||
<Position X="19" Y="2.5" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAAAAAAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAA=</HashCode>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Class>
|
|
||||||
<Struct Name="Chess.FieldColorSet" Collapsed="true">
|
|
||||||
<Position X="19" Y="3.75" Width="1.5" />
|
|
||||||
<TypeIdentifier>
|
|
||||||
<HashCode>AAAQAQAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
|
||||||
<FileName>FieldColorSet.cs</FileName>
|
|
||||||
</TypeIdentifier>
|
|
||||||
</Struct>
|
|
||||||
<Font Name="Segoe UI" Size="9" />
|
|
||||||
</ClassDiagram>
|
|
@ -21,17 +21,35 @@ namespace Chess
|
|||||||
private FieldColorSet currentEnemyColorSet;
|
private FieldColorSet currentEnemyColorSet;
|
||||||
private FieldColorSet currentSelectedColorSet;
|
private FieldColorSet currentSelectedColorSet;
|
||||||
private FieldColorSet currentAllyColorSet;
|
private FieldColorSet currentAllyColorSet;
|
||||||
public delegate void ClickEventHandler(Vector coordinates);
|
public delegate void ClickEventHandler(Field sender);
|
||||||
public event ClickEventHandler FieldClick;
|
public event ClickEventHandler FieldClick;
|
||||||
public bool IsEmpty { get { return currentPiece == null; } }
|
public bool IsEmpty { get { return currentPiece == null; } }
|
||||||
public Piece currentPiece;
|
public Piece currentPiece;
|
||||||
public Piece CurrentPiece
|
public Piece CurrentPiece
|
||||||
{
|
{
|
||||||
get { return currentPiece; }
|
get
|
||||||
set { currentPiece = value; RefreshPiece(); }
|
{
|
||||||
|
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)
|
if (currentPiece == null)
|
||||||
this.BackgroundImage = ChessPanel.Properties.Resources.Empty;
|
this.BackgroundImage = ChessPanel.Properties.Resources.Empty;
|
||||||
@ -40,17 +58,17 @@ namespace Chess
|
|||||||
}
|
}
|
||||||
public void Deselect()
|
public void Deselect()
|
||||||
{
|
{
|
||||||
setActiveColorSet(currentNormalColorSet);
|
SetActiveColorSet(currentNormalColorSet);
|
||||||
}
|
}
|
||||||
public void Highlight(PieceTeam team) // validTargetField
|
public void Highlight(PieceTeam team) // validTargetField
|
||||||
{
|
{
|
||||||
switch (team)
|
switch (team)
|
||||||
{
|
{
|
||||||
case PieceTeam.Enemy:
|
case PieceTeam.Enemy:
|
||||||
setActiveColorSet(currentEnemyColorSet);
|
SetActiveColorSet(currentEnemyColorSet);
|
||||||
break;
|
break;
|
||||||
case PieceTeam.Ally:
|
case PieceTeam.Ally:
|
||||||
setActiveColorSet(currentAllyColorSet);
|
SetActiveColorSet(currentAllyColorSet);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -58,9 +76,9 @@ namespace Chess
|
|||||||
}
|
}
|
||||||
public new void Select() // selectedField
|
public new void Select() // selectedField
|
||||||
{
|
{
|
||||||
setActiveColorSet(currentSelectedColorSet);
|
SetActiveColorSet(currentSelectedColorSet);
|
||||||
}
|
}
|
||||||
private void setActiveColorSet(FieldColorSet set)
|
private void SetActiveColorSet(FieldColorSet set)
|
||||||
{
|
{
|
||||||
this.BackColor = set.NormalColor;
|
this.BackColor = set.NormalColor;
|
||||||
this.FlatAppearance.MouseDownBackColor = set.MouseDownColor;
|
this.FlatAppearance.MouseDownBackColor = set.MouseDownColor;
|
||||||
@ -68,34 +86,36 @@ namespace Chess
|
|||||||
}
|
}
|
||||||
public Field(int x, int y)
|
public Field(int x, int y)
|
||||||
{
|
{
|
||||||
this.currentNormalColorSet = (x + y) % 2 == 0 ? primaryNormalColorSet : secondaryNormalColorSet;
|
this.currentNormalColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryNormalColorSet : FieldColorSet.secondaryNormalColorSet;
|
||||||
this.currentAllyColorSet = (x + y) % 2 == 0 ? primaryValidFriendlyTargetFieldSet : secondaryValidFriendlyTargetFieldSet;
|
this.currentAllyColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryValidFriendlyTargetFieldSet : FieldColorSet.secondaryValidFriendlyTargetFieldSet;
|
||||||
this.currentEnemyColorSet = (x + y) % 2 == 0 ? primaryValidEnemyTargetFieldSet : secondaryValidEnemyTargetFieldSet;
|
this.currentEnemyColorSet = (x + y) % 2 == 0 ? FieldColorSet.primaryValidEnemyTargetFieldSet : FieldColorSet.secondaryValidEnemyTargetFieldSet;
|
||||||
this.currentSelectedColorSet = (x + y) % 2 == 0 ? primarySelectedColorSet : secondarySelectedColorSet;
|
this.currentSelectedColorSet = (x + y) % 2 == 0 ? FieldColorSet.primarySelectedColorSet : FieldColorSet.secondarySelectedColorSet;
|
||||||
|
|
||||||
|
|
||||||
this.FlatStyle = FlatStyle.Flat;
|
this.FlatStyle = FlatStyle.Flat;
|
||||||
this.FlatAppearance.BorderSize = 0;
|
this.FlatAppearance.BorderSize = 0;
|
||||||
this.setActiveColorSet(this.currentNormalColorSet);
|
this.SetActiveColorSet(this.currentNormalColorSet);
|
||||||
this.Cursor = Cursors.Arrow;
|
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.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.Name = string.Format($"field[{x},{y}]");
|
||||||
this.Text = "";
|
this.Text = string.Empty;
|
||||||
|
|
||||||
this.BackgroundImageLayout = ImageLayout.Zoom;
|
this.BackgroundImageLayout = ImageLayout.Zoom;
|
||||||
this.BackgroundImage = ChessPanel.Properties.Resources.Empty;
|
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()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.currentPiece.type.ToString();
|
if (IsEmpty)
|
||||||
|
return "leer";
|
||||||
|
return this.currentPiece.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,14 @@ namespace Chess
|
|||||||
{
|
{
|
||||||
struct FieldColorSet
|
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)
|
public FieldColorSet(Color MOC, Color MDC, Color NC)
|
||||||
{
|
{
|
||||||
MouseOverColor = MOC;
|
MouseOverColor = MOC;
|
||||||
|
169
ChessPanel/Grid.cs
Normal file
169
ChessPanel/Grid.cs
Normal file
@ -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);
|
||||||
|
//}
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a copy of the given array;
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="Array"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static T[,] CopyMultiArray<T>(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; } }
|
||||||
|
/// <summary>
|
||||||
|
/// Adds x and y values to Vector v and gets the field at the position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v">Vector</param>
|
||||||
|
/// <param name="x">X</param>
|
||||||
|
/// <param name="y">Y</param>
|
||||||
|
/// <returns>Field</returns>
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a field is endagered by a party
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="field">Reference to the Field that should be checked</param>
|
||||||
|
/// <param name="color">Color of the attacking party</param>
|
||||||
|
/// <param name="movePiece">Piece that virtually got moved</param>
|
||||||
|
/// <param name="targetPos">Field that the movePiece virtually moved to</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,11 @@ namespace Chess
|
|||||||
{
|
{
|
||||||
public partial class MainForm : Form
|
public partial class MainForm : Form
|
||||||
{
|
{
|
||||||
bool Fullscreen = false;
|
bool _fullscreen = false;
|
||||||
bool fullscreen
|
bool Fullscreen
|
||||||
{
|
{
|
||||||
get { return Fullscreen; }
|
get { return _fullscreen; }
|
||||||
set { Fullscreen = value; RefreshFullScreen(); }
|
set { _fullscreen = value; RefreshFullScreen(); }
|
||||||
}
|
}
|
||||||
public MainForm()
|
public MainForm()
|
||||||
{
|
{
|
||||||
@ -19,7 +19,7 @@ namespace Chess
|
|||||||
private void RefreshFullScreen()
|
private void RefreshFullScreen()
|
||||||
{
|
{
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
if (fullscreen)
|
if (Fullscreen)
|
||||||
{
|
{
|
||||||
this.WindowState = FormWindowState.Normal;
|
this.WindowState = FormWindowState.Normal;
|
||||||
this.FormBorderStyle = FormBorderStyle.None;
|
this.FormBorderStyle = FormBorderStyle.None;
|
||||||
@ -36,7 +36,7 @@ namespace Chess
|
|||||||
private void MainForm_KeyUp(object sender, KeyEventArgs e)
|
private void MainForm_KeyUp(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyCode == Keys.F11)
|
if (e.KeyCode == Keys.F11)
|
||||||
fullscreen = !fullscreen;
|
Fullscreen = !Fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
@ -46,7 +46,7 @@ namespace Chess
|
|||||||
|
|
||||||
private void MainForm_Load(object sender, EventArgs e)
|
private void MainForm_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
fullscreen = true;
|
Fullscreen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<Vector, PieceTeam> 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<Vector, PieceTeam> 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<Vector, PieceTeam> GetTargetFields(Field[,] fields, Vector location, PieceColor color)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> targetFields = new Dictionary<Vector, PieceTeam>();
|
|
||||||
|
|
||||||
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<Vector, PieceTeam> 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<Vector, PieceTeam> GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = false)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> targetFields = new Dictionary<Vector, PieceTeam>();
|
|
||||||
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<Vector, PieceTeam> 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<Vector, PieceTeam> GetTargetFields(Field[,] fields, Vector location, PieceColor color)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> targetFields = new Dictionary<Vector, PieceTeam>();
|
|
||||||
|
|
||||||
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<Vector, PieceTeam> 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<Vector, PieceTeam> GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = true)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> targetFields = new Dictionary<Vector, PieceTeam>();
|
|
||||||
|
|
||||||
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<Vector, PieceTeam> GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> 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<Vector, PieceTeam> GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) // ignoreKingCheck hat keinen Einfluss
|
|
||||||
{
|
|
||||||
return GetTargetFields(fields, location, this.color);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<Vector, PieceTeam> GetTargetFields(Field[,] fields, Vector location, PieceColor color)
|
|
||||||
{
|
|
||||||
Dictionary<Vector, PieceTeam> targetFields = new Dictionary<Vector, PieceTeam>();
|
|
||||||
#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
|
|
||||||
}
|
|
232
ChessPanel/Pieces/AbstractPiece.cs
Normal file
232
ChessPanel/Pieces/AbstractPiece.cs
Normal file
@ -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 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Figur
|
||||||
|
/// </summary>
|
||||||
|
public abstract class Piece
|
||||||
|
{
|
||||||
|
public PieceColor color;
|
||||||
|
public PieceType type;
|
||||||
|
public Dictionary<Field, PieceTeam> 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<Field, PieceTeam> RefreshValidTargetSpots(Grid fields, MoveMode mode = MoveMode.Normal)
|
||||||
|
{
|
||||||
|
this.validTargetSpots = this.GetValidTargetFields(fields, mode);
|
||||||
|
return validTargetSpots;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void RemoveTargetFieldsWhereKingIsEndangered(Grid fields, Dictionary<Field, PieceTeam> targetFields)
|
||||||
|
{
|
||||||
|
Field ownKingLocation = fields.GetKing(this.color).field;
|
||||||
|
foreach (var virtualTargetField in targetFields)
|
||||||
|
{
|
||||||
|
if (fields.IsFieldVirtuallyEndagered(ownKingLocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, virtualTargetField.Key))
|
||||||
|
targetFields.Remove(virtualTargetField.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the Move will leave your King endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="pieceLocation">Location of Piece to move</param>
|
||||||
|
/// <param name="simulatedLocation">Location to move Piece to</param>
|
||||||
|
/// <param name="color">Color of Piece to move</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
/* internal static bool MoveWillEndangerOwnKing(Grid fields, Vector pieceLocation, Vector simulatedLocation, PieceColor color)
|
||||||
|
{
|
||||||
|
// fields[simulateLocation].currentPiece = fields[pieceLocation].currentPiece;
|
||||||
|
// fields[pieceLocation].currentPiece = null;
|
||||||
|
// Check if own king is endangered
|
||||||
|
return FieldIsEndangered(fields, simulatedLocation, kingLocation, color, dontTestKingDanger: true);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a specific field can be reached by the figure while a virtual move is simulated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="movePiece">Piece that virtually got moved</param>
|
||||||
|
/// <param name="targetPos">Field that the movePiece virtually moved to</param>
|
||||||
|
/// <param name="possibleEndageredField">Field that should be checked</param>
|
||||||
|
/// <param name="fields">Current Game Grid</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal abstract bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos);
|
||||||
|
|
||||||
|
internal void Move(Field newPieceField)
|
||||||
|
{
|
||||||
|
this.field.CurrentPiece = null; // Remove piece from previous position
|
||||||
|
this.field = newPieceField; // Set pieces location to new field
|
||||||
|
newPieceField.CurrentPiece = this; // Set new fields piece to this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the Move will leave your movedPiece endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="pieceLocation">Location of Piece to move</param>
|
||||||
|
/// <param name="testLocation">Location to move Piece to</param>
|
||||||
|
/// <param name="color">Color of Piece to move</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
//internal static bool MoveWillEndangerPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
|
||||||
|
//{
|
||||||
|
// return false;
|
||||||
|
// //Grid simulatedField = fields;
|
||||||
|
// //simulatedField[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
// //return FieldIsEndangered(fields simulatedField, testLocation, color);
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if your King is currently endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Kings color</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
//private static bool KingIsEndangered(Grid fields, PieceColor color) => FieldIsEndangered(fields, GetKingLocation(fields, color), color, dontTestKingDanger: true);
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the testLocation is endangered by an enemy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Ally Color</param>
|
||||||
|
/// <param name="testLocation">Location to test</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
//private static bool FieldIsEndangered(Grid fields, Vector simulatedLocation, Vector testLocation, PieceColor color, bool dontTestKingDanger = false)
|
||||||
|
//{
|
||||||
|
// foreach (Field field in fields)
|
||||||
|
// {
|
||||||
|
// if (field.location != simulatedLocation
|
||||||
|
// && field.currentPiece != null
|
||||||
|
// && field.currentPiece.color != color
|
||||||
|
// && field.currentPiece.GetValidTargetFields(fields, dontTestKingDanger: dontTestKingDanger).ContainsKey(testLocation))
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
/*internal static bool IsEndangeredLocationForPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
|
||||||
|
{
|
||||||
|
bool returnValue = false;
|
||||||
|
Piece p = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
foreach (var field in fields)
|
||||||
|
{
|
||||||
|
if (field.currentPiece != null) if (field.currentPiece.color != color) if (field.currentPiece.GetValidTargetFields(fields, field.location, true).ContainsKey(testLocation))
|
||||||
|
{
|
||||||
|
returnValue = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p;
|
||||||
|
return returnValue;
|
||||||
|
}*/
|
||||||
|
/* internal static bool MoveWillEndangerKing(Grid fields, Vector pieceLocation, Vector pieceMovedLocation, PieceColor color) // This does not test if it is a valid move spot
|
||||||
|
{
|
||||||
|
bool returnValue = false;
|
||||||
|
Piece p1 = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
|
||||||
|
Piece p2 = fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece;
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p1;
|
||||||
|
returnValue = KingIsEndangered(fields, color);
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p1;
|
||||||
|
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p2;
|
||||||
|
return returnValue;
|
||||||
|
}*/
|
||||||
|
/* private static bool KingIsEndangered(Grid fields, PieceColor color)
|
||||||
|
{
|
||||||
|
Vector kingLocation = GetKingLocation(fields, color);
|
||||||
|
foreach (var field in fields)
|
||||||
|
{
|
||||||
|
if (field.currentPiece == null || field.currentPiece.color != color)
|
||||||
|
continue;
|
||||||
|
if (field.currentPiece.GetValidTargetFields(fields, field.location, dontTestKingDanger: true).ContainsKey(kingLocation))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
/// <summary>
|
||||||
|
/// Searches for the King of the given color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Kings color</param>
|
||||||
|
/// <returns>King location as Vector</returns>
|
||||||
|
private static Vector GetKingLocation(Grid fields, PieceColor color)
|
||||||
|
{
|
||||||
|
foreach (Field field in fields)
|
||||||
|
if (!field.IsEmpty && field.currentPiece.type == PieceType.King && field.currentPiece.color == color)
|
||||||
|
return field.location;
|
||||||
|
throw new Exception("King not found!");
|
||||||
|
}
|
||||||
|
virtual internal Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Normal, bool dontTestKingDanger = false)
|
||||||
|
{
|
||||||
|
var targetFields = GetTargetFields(fields, field, this.color);
|
||||||
|
if (!dontTestKingDanger)
|
||||||
|
{
|
||||||
|
Field kinglocation = fields.GetKing(this.color).field;
|
||||||
|
List<Field> remove = new List<Field>();
|
||||||
|
|
||||||
|
foreach (var item in targetFields.Keys)
|
||||||
|
{
|
||||||
|
if (fields.IsFieldVirtuallyEndagered(kinglocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, item))
|
||||||
|
remove.Add(item);
|
||||||
|
}
|
||||||
|
foreach (var item in remove)
|
||||||
|
{
|
||||||
|
targetFields.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetFields;
|
||||||
|
}
|
||||||
|
internal abstract Dictionary<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color);
|
||||||
|
internal static bool FieldIsVirtuallyEmpty(Field targetPos, Field skipField, Field possibleTargetField)
|
||||||
|
{
|
||||||
|
return (possibleTargetField.IsEmpty && possibleTargetField != targetPos)
|
||||||
|
|| possibleTargetField == skipField;
|
||||||
|
}
|
||||||
|
internal static bool CheckFieldCanBeReached(Field possibleEndageredField, Field targetPos, Piece movePiece, Field possibleTargetField, PieceColor color, out bool breakIt)
|
||||||
|
{
|
||||||
|
breakIt = false;
|
||||||
|
|
||||||
|
var skipField = movePiece.field;
|
||||||
|
if (FieldIsVirtuallyEmpty(targetPos, skipField, possibleTargetField))
|
||||||
|
{
|
||||||
|
if (possibleTargetField == possibleEndageredField)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var checkPiece = possibleTargetField == targetPos ? movePiece : possibleTargetField.CurrentPiece;
|
||||||
|
|
||||||
|
if (checkPiece.color != color && possibleTargetField == possibleEndageredField)
|
||||||
|
return true;
|
||||||
|
breakIt=true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//internal abstract Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false);
|
||||||
|
}
|
||||||
|
}
|
226
ChessPanel/Pieces/AbstractPiece.txt
Normal file
226
ChessPanel/Pieces/AbstractPiece.txt
Normal file
@ -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 };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Figur
|
||||||
|
/// </summary>
|
||||||
|
public abstract class Piece
|
||||||
|
{
|
||||||
|
public PieceColor color;
|
||||||
|
public PieceType type;
|
||||||
|
public Image image;
|
||||||
|
public bool HasMoved = false;
|
||||||
|
public Field field;
|
||||||
|
private Vector virtualPosition;//?
|
||||||
|
public bool EnPassantPossible = false; // Only in Pawn Class. Signs that this Piece has virtually not jumped two pieces, but one, reflective meaning: This.Figure can be attacked using Enpassant if this.type is Pawn
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return type.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Piece(Vector position, Grid fields)
|
||||||
|
{
|
||||||
|
this.field = fields[position];
|
||||||
|
fields[position].CurrentPiece = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void removeTargetFieldsWhereKingIsEndangered(Grid fields, Dictionary<Field, PieceTeam> targetFields)
|
||||||
|
{
|
||||||
|
Field ownKingLocation = fields.GetKing(this.color).field;
|
||||||
|
foreach (var virtualTargetField in targetFields)
|
||||||
|
{
|
||||||
|
if (fields.IsFieldVirtuallyEndagered(ownKingLocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, virtualTargetField.Key))
|
||||||
|
targetFields.Remove(virtualTargetField.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the Move will leave your King endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="pieceLocation">Location of Piece to move</param>
|
||||||
|
/// <param name="simulatedLocation">Location to move Piece to</param>
|
||||||
|
/// <param name="color">Color of Piece to move</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
/* internal static bool MoveWillEndangerOwnKing(Grid fields, Vector pieceLocation, Vector simulatedLocation, PieceColor color)
|
||||||
|
{
|
||||||
|
// fields[simulateLocation].currentPiece = fields[pieceLocation].currentPiece;
|
||||||
|
// fields[pieceLocation].currentPiece = null;
|
||||||
|
// Check if own king is endangered
|
||||||
|
return FieldIsEndangered(fields, simulatedLocation, kingLocation, color, dontTestKingDanger: true);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a specific field can be reached by the figure while a virtual move is simulated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="movePiece">Piece that virtually got moved</param>
|
||||||
|
/// <param name="targetPos">Field that the movePiece virtually moved to</param>
|
||||||
|
/// <param name="possibleEndageredField">Field that should be checked</param>
|
||||||
|
/// <param name="fields">Current Game Grid</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal abstract bool EndageresFieldWithVirtualMove(Grid fields, Field possibleEndageredField, Piece movePiece, Field targetPos);
|
||||||
|
|
||||||
|
internal void Move(Field newPieceField)
|
||||||
|
{
|
||||||
|
this.field.CurrentPiece = null; // Remove piece from previous position
|
||||||
|
this.field = newPieceField; // Set pieces location to new field
|
||||||
|
newPieceField.CurrentPiece = this; // Set new fields piece to this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the Move will leave your movedPiece endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="pieceLocation">Location of Piece to move</param>
|
||||||
|
/// <param name="testLocation">Location to move Piece to</param>
|
||||||
|
/// <param name="color">Color of Piece to move</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
//internal static bool MoveWillEndangerPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
|
||||||
|
//{
|
||||||
|
// return false;
|
||||||
|
// //Grid simulatedField = fields;
|
||||||
|
// //simulatedField[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
// //return FieldIsEndangered(fields simulatedField, testLocation, color);
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if your King is currently endangered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Kings color</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
//private static bool KingIsEndangered(Grid fields, PieceColor color) => FieldIsEndangered(fields, GetKingLocation(fields, color), color, dontTestKingDanger: true);
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the testLocation is endangered by an enemy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Ally Color</param>
|
||||||
|
/// <param name="testLocation">Location to test</param>
|
||||||
|
/// <returns>Bool</returns>
|
||||||
|
//private static bool FieldIsEndangered(Grid fields, Vector simulatedLocation, Vector testLocation, PieceColor color, bool dontTestKingDanger = false)
|
||||||
|
//{
|
||||||
|
// foreach (Field field in fields)
|
||||||
|
// {
|
||||||
|
// if (field.location != simulatedLocation
|
||||||
|
// && field.currentPiece != null
|
||||||
|
// && field.currentPiece.color != color
|
||||||
|
// && field.currentPiece.GetValidTargetFields(fields, dontTestKingDanger: dontTestKingDanger).ContainsKey(testLocation))
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
/*internal static bool IsEndangeredLocationForPiece(Grid fields, Vector pieceLocation, Vector testLocation, PieceColor color)
|
||||||
|
{
|
||||||
|
bool returnValue = false;
|
||||||
|
Piece p = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
foreach (var field in fields)
|
||||||
|
{
|
||||||
|
if (field.currentPiece != null) if (field.currentPiece.color != color) if (field.currentPiece.GetValidTargetFields(fields, field.location, true).ContainsKey(testLocation))
|
||||||
|
{
|
||||||
|
returnValue = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p;
|
||||||
|
return returnValue;
|
||||||
|
}*/
|
||||||
|
/* internal static bool MoveWillEndangerKing(Grid fields, Vector pieceLocation, Vector pieceMovedLocation, PieceColor color) // This does not test if it is a valid move spot
|
||||||
|
{
|
||||||
|
bool returnValue = false;
|
||||||
|
Piece p1 = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece;
|
||||||
|
Piece p2 = fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece;
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null;
|
||||||
|
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p1;
|
||||||
|
returnValue = KingIsEndangered(fields, color);
|
||||||
|
fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p1;
|
||||||
|
fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p2;
|
||||||
|
return returnValue;
|
||||||
|
}*/
|
||||||
|
/* private static bool KingIsEndangered(Grid fields, PieceColor color)
|
||||||
|
{
|
||||||
|
Vector kingLocation = GetKingLocation(fields, color);
|
||||||
|
foreach (var field in fields)
|
||||||
|
{
|
||||||
|
if (field.currentPiece == null || field.currentPiece.color != color)
|
||||||
|
continue;
|
||||||
|
if (field.currentPiece.GetValidTargetFields(fields, field.location, dontTestKingDanger: true).ContainsKey(kingLocation))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
/// <summary>
|
||||||
|
/// Searches for the King of the given color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">GameField</param>
|
||||||
|
/// <param name="color">Kings color</param>
|
||||||
|
/// <returns>King location as Vector</returns>
|
||||||
|
private static Vector GetKingLocation(Grid fields, PieceColor color)
|
||||||
|
{
|
||||||
|
foreach (Field field in fields)
|
||||||
|
if (!field.IsEmpty && field.currentPiece.type == PieceType.King && field.currentPiece.color == color)
|
||||||
|
return field.location;
|
||||||
|
throw new Exception("King not found!");
|
||||||
|
}
|
||||||
|
virtual internal Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false)
|
||||||
|
{
|
||||||
|
var targetFields = GetTargetFields(fields, field, this.color);
|
||||||
|
if (!dontTestKingDanger)
|
||||||
|
{
|
||||||
|
Field kinglocation = fields.GetKing(this.color).field;
|
||||||
|
List<Field> remove = new List<Field>();
|
||||||
|
|
||||||
|
foreach (var item in targetFields.Keys)
|
||||||
|
{
|
||||||
|
if (fields.IsFieldVirtuallyEndagered(kinglocation, (this.color == PieceColor.Black ? PieceColor.White : PieceColor.Black), this, item))
|
||||||
|
remove.Add(item);
|
||||||
|
}
|
||||||
|
foreach (var item in remove)
|
||||||
|
{
|
||||||
|
targetFields.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targetFields;
|
||||||
|
}
|
||||||
|
internal abstract Dictionary<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color);
|
||||||
|
internal static bool FieldIsVirtuallyEmpty(Field targetPos, Field skipField, Field possibleTargetField)
|
||||||
|
{
|
||||||
|
return (possibleTargetField.IsEmpty && possibleTargetField != targetPos)
|
||||||
|
|| possibleTargetField == skipField;
|
||||||
|
}
|
||||||
|
internal static bool checkFieldCanBeReached(Field possibleEndageredField, Field targetPos, Piece movePiece, Field possibleTargetField, PieceColor color, out bool breakIt)
|
||||||
|
{
|
||||||
|
breakIt = false;
|
||||||
|
|
||||||
|
var skipField = movePiece.field;
|
||||||
|
if (FieldIsVirtuallyEmpty(targetPos, skipField, possibleTargetField))
|
||||||
|
{
|
||||||
|
if (possibleTargetField == possibleEndageredField)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var checkPiece = possibleTargetField == targetPos ? movePiece : possibleTargetField.CurrentPiece;
|
||||||
|
|
||||||
|
if (checkPiece.color != color && possibleTargetField == possibleEndageredField)
|
||||||
|
return true;
|
||||||
|
breakIt=true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//internal abstract Dictionary<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false);
|
||||||
|
}
|
||||||
|
}
|
143
ChessPanel/Pieces/Bishop.cs
Normal file
143
ChessPanel/Pieces/Bishop.cs
Normal file
@ -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<Field, PieceTeam> 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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
return StaticGetTargetFields(fields, field, color);
|
||||||
|
}
|
||||||
|
internal static Dictionary<Field, PieceTeam> StaticGetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
Dictionary<Field, PieceTeam> targetFields = new Dictionary<Field, PieceTeam>();
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fields">Global Field Grid</param>
|
||||||
|
/// <param name="field">Field that should be checked for endager</param>
|
||||||
|
/// <param name="movePiece">Piece that should be moved</param>
|
||||||
|
/// <param name="targetPos">Target of the moved piece</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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
|
||||||
|
}
|
132
ChessPanel/Pieces/King.cs
Normal file
132
ChessPanel/Pieces/King.cs
Normal file
@ -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<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Normal, bool dontTestKingDanger = false)
|
||||||
|
{
|
||||||
|
var targetFields = GetTargetFields(fields, field, this.color);
|
||||||
|
if (!dontTestKingDanger)
|
||||||
|
{
|
||||||
|
List<Field> remove = new List<Field>();
|
||||||
|
|
||||||
|
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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
Dictionary<Field, PieceTeam> targetFields = new Dictionary<Field, PieceTeam>();
|
||||||
|
#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
|
||||||
|
}
|
98
ChessPanel/Pieces/Knight.cs
Normal file
98
ChessPanel/Pieces/Knight.cs
Normal file
@ -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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
Dictionary<Field, PieceTeam> targetFields = new Dictionary<Field, PieceTeam>();
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
80
ChessPanel/Pieces/Pawn.cs
Normal file
80
ChessPanel/Pieces/Pawn.cs
Normal file
@ -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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
MoveMode mode = MoveMode.Normal;
|
||||||
|
|
||||||
|
Dictionary<Field, PieceTeam> targetFields = new Dictionary<Field, PieceTeam>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
ChessPanel/Pieces/Queen.cs
Normal file
35
ChessPanel/Pieces/Queen.cs
Normal file
@ -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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
Dictionary<Field, PieceTeam> 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
|
||||||
|
}
|
141
ChessPanel/Pieces/Rook.cs
Normal file
141
ChessPanel/Pieces/Rook.cs
Normal file
@ -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<Field, PieceTeam> GetValidTargetFields(Grid fields, MoveMode mode = MoveMode.Any, bool dontTestKingDanger = false)
|
||||||
|
//{
|
||||||
|
// var targetFields = GetTargetFields(fields, field, this.color);
|
||||||
|
// if (!dontTestKingDanger)
|
||||||
|
// {
|
||||||
|
// Field kinglocation = fields.GetKing(this.color).field;
|
||||||
|
// 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<Field, PieceTeam> GetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
return StaticGetTargetFields(fields, field, color);
|
||||||
|
}
|
||||||
|
internal static Dictionary<Field, PieceTeam> StaticGetTargetFields(Grid fields, Field field, PieceColor color)
|
||||||
|
{
|
||||||
|
Dictionary<Field, PieceTeam> targetFields = new Dictionary<Field, PieceTeam>();
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user