diff --git a/ChessPanel.sln b/ChessPanel.sln new file mode 100644 index 0000000..8cdc4f9 --- /dev/null +++ b/ChessPanel.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chess", "ChessPanel\Chess.csproj", "{4F06559F-7350-4124-8CE9-05EEC4768EB0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4F06559F-7350-4124-8CE9-05EEC4768EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F06559F-7350-4124-8CE9-05EEC4768EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F06559F-7350-4124-8CE9-05EEC4768EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F06559F-7350-4124-8CE9-05EEC4768EB0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ChessPanel/App.config b/ChessPanel/App.config new file mode 100644 index 0000000..88fa402 --- /dev/null +++ b/ChessPanel/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ChessPanel/Chess.csproj b/ChessPanel/Chess.csproj new file mode 100644 index 0000000..6c20071 --- /dev/null +++ b/ChessPanel/Chess.csproj @@ -0,0 +1,133 @@ + + + + + Debug + AnyCPU + {4F06559F-7350-4124-8CE9-05EEC4768EB0} + WinExe + Properties + ChessPanel + ChessPanel + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + Component + + + Component + + + Component + + + + Form + + + MainForm.cs + + + + + + True + True + Resources.resx + + + MainForm.cs + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ChessPanel/ChessBoard.cs b/ChessPanel/ChessBoard.cs new file mode 100644 index 0000000..8661f02 --- /dev/null +++ b/ChessPanel/ChessBoard.cs @@ -0,0 +1,202 @@ +using Chess; +using System; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Forms; +using static Chess.Piece; + +namespace ChessPanel +{ + public partial class ChessBoard : Panel + { + public Field[,] fields; + public PieceColor activePlayer; + private int gridSize = 8; + public bool isSaved = true; + Dictionary validTargetSpots = new Dictionary(); + private Vector? selectedField; + private Vector? SelectedField + { + get { return selectedField; } + set { selectedField = value; 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 + { + fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].Select(); + } + ResetValidTargetSpots(); + if (selectedField.HasValue) + { + if (fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].CurrentPiece != null) + { + validTargetSpots = fields[(int)selectedField.Value.X, (int)selectedField.Value.Y].CurrentPiece.GetValidTargetFields(fields, new Vector(selectedField.Value.X, selectedField.Value.Y)); + } + foreach (var item in validTargetSpots) + { + fields[(int)item.Key.X, (int)item.Key.Y].Highlight(item.Value); + } + } + } + /// + /// Setzt die Markierungen sowie die Liste der möglichen Zielfelder zurück + /// + private void ResetValidTargetSpots() + { + foreach (var item in validTargetSpots) + { + fields[(int)item.Key.X, (int)item.Key.Y].Deselect(); + } + validTargetSpots.Clear(); // Markierung der Zielfelder zurücksetzen + } + public int GridSize + { + get { return gridSize; } + set { gridSize = value; } + } + public ChessBoard() + { + this.DoubleBuffered = true; + this.SuspendLayout(); + this.Resize += new System.EventHandler(this.ChessBoard_Resize); + InitializeGrid(); + InitializePieces(); + activePlayer = PieceColor.White; + this.ResumeLayout(false); + } + private void ToggleActivePlayer() => activePlayer = activePlayer == PieceColor.White ? PieceColor.Black : PieceColor.White; + private void DoPieceMove(Vector location, Vector newLocation, bool togglePlayer = true) + { + isSaved = false; + #region Castling + if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.King && Math.Abs(newLocation.X - location.X) == 2) + DoPieceMove(new Vector(((newLocation.X - location.X == -2) ? 0 : 7), location.Y), new Vector(location.X + (newLocation.X - location.X) / 2, location.Y), false /*Dont Toggle Player*/); // Move Rook + #endregion + #region EnPassant + foreach (var item in fields) // Reset Enpassant Possible states each move + { + if (item.CurrentPiece != null) + if (item.CurrentPiece.type == PieceType.Pawn) + { + item.CurrentPiece.EnPassantPossible = false; + } + } + if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.Pawn && !fields[(int)location.X, (int)location.Y].CurrentPiece.HasMoved) + fields[(int)location.X, (int)location.Y].CurrentPiece.EnPassantPossible = true; + if (fields[(int)location.X, (int)location.Y].CurrentPiece.type == PieceType.Pawn && newLocation.X != location.X && fields[(int)newLocation.X, (int)newLocation.Y].IsEmpty) + fields[(int)newLocation.X, (int)newLocation.Y + (fields[(int)location.X, (int)location.Y].CurrentPiece.color == PieceColor.White ? 1 : -1)].CurrentPiece = null; + #endregion + fields[(int)location.X, (int)location.Y].CurrentPiece.HasMoved = true; // Figur Bereits bewegt Status aktualisieren + fields[(int)newLocation.X, (int)newLocation.Y].CurrentPiece = fields[(int)location.X, (int)location.Y].CurrentPiece; // Figur an neue Position kopieren + fields[(int)location.X, (int)location.Y].CurrentPiece = null; // Alte Kopie der Figur löschen + if (togglePlayer) + ToggleActivePlayer(); + } + private void InitializePieces() + { + fields[0, 0].CurrentPiece = new Rook(PieceColor.Black); + fields[7, 0].CurrentPiece = new Rook(PieceColor.Black); + fields[0, 7].CurrentPiece = new Rook(PieceColor.White); + fields[7, 7].CurrentPiece = new Rook(PieceColor.White); + + fields[1, 0].CurrentPiece = new Knight(PieceColor.Black); + fields[6, 0].CurrentPiece = new Knight(PieceColor.Black); + fields[1, 7].CurrentPiece = new Knight(PieceColor.White); + fields[6, 7].CurrentPiece = new Knight(PieceColor.White); + + fields[2, 0].CurrentPiece = new Bishop(PieceColor.Black); + fields[5, 0].CurrentPiece = new Bishop(PieceColor.Black); + fields[2, 7].CurrentPiece = new Bishop(PieceColor.White); + fields[5, 7].CurrentPiece = new Bishop(PieceColor.White); + + fields[4, 0].CurrentPiece = new King(PieceColor.Black); + fields[3, 0].CurrentPiece = new Queen(PieceColor.Black); + + fields[3, 7].CurrentPiece = new Queen(PieceColor.White); + fields[4, 7].CurrentPiece = new King(PieceColor.White); + for (int x = 0; x < 8; x++) + { + fields[x, 1].CurrentPiece = new Pawn(PieceColor.Black); + fields[x, 6].CurrentPiece = new Pawn(PieceColor.White); + } + } + private void InitializeGrid() + { + this.fields = new Field[gridSize, gridSize]; + int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / gridSize; + System.Drawing.Size subPanelSize = new System.Drawing.Size(subPanelEdgeLength, subPanelEdgeLength); + for (int x = 0; x < this.gridSize; x++) + { + for (int y = 0; y < this.gridSize; y++) + { + Field field = new Field(x, y); + field.Size = subPanelSize; + field.Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height); + field.FieldClick += FieldClicked; + fields[x, y] = field; + this.Controls.Add(fields[x, y]); + } + } + } + private void FieldClicked(Vector coordinates) + { + this.SuspendLayout(); + if (SelectedField.HasValue && validTargetSpots.ContainsKey(coordinates)) // Ein erlaubtes Zielfeld wurde angeklickt + { + DoPieceMove(SelectedField.Value, coordinates); // Bewege Figur + ResetSelectedField(); // Auswahl zurücksetzen + } + else + { + if (SelectedField == coordinates) // Erneutes Anklicken des Auswahlfeldes + ResetSelectedField(); // Auswahl zurücksetzen + else // Tritt ein, wenn ein Feld angeklickt wurde, dass nicht das Auswahlfeld ist + { + if (SelectedField.HasValue) // Wenn ein Feld ausgewählt ist wird die Auswahl gelöscht falls nicht das Auswahlfeld angeklickt wurde + ResetSelectedField(); // Auswahl zurücksetzen + if (!fields[(int)coordinates.X, (int)coordinates.Y].IsEmpty && fields[(int)coordinates.X, (int)coordinates.Y].CurrentPiece.color == activePlayer) // Feld wird nur ausgewählt, wenn die Farbe der Figur mit der des aktiven Spielers übereinstimmt + SelectedField = coordinates; // Kein Feld ist ausgewählt: Angeklicktes Feld auswählen (!) AKTUALISIERT AUTOMATISCH DIE MARKIERUNGEN + } + } + this.ResumeLayout(false); + } + /// + /// Löscht die Auswahl des aktuell ausgewählten Feldes + /// + private void ResetSelectedField() + { + fields[(int)SelectedField.Value.X, (int)SelectedField.Value.Y].Deselect(); // Auswahl zurücksetzen + SelectedField = null; // Erlaubte Zielfelder zurücksetzen + } + #region Helper Can be deleted + static readonly string[] Columns = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH" }; + public static string IndexToColumn(int index) + { + if (index <= 0) + throw new IndexOutOfRangeException("index must be a positive number"); + + return Columns[index - 1]; + } + #endregion + private void ChessBoard_Resize(object sender, EventArgs e) + { + RefreshSize(); + } + private void RefreshSize() + { + this.SuspendLayout(); + int subPanelEdgeLength = Math.Min(this.Size.Width, this.Size.Height) / gridSize; + System.Drawing.Size subPanelSize = new System.Drawing.Size(subPanelEdgeLength, subPanelEdgeLength); + for (int x = 0; x < this.gridSize; x++) + { + for (int y = 0; y < this.gridSize; y++) + { + fields[x, y].Size = subPanelSize; + fields[x, y].Location = new System.Drawing.Point(x * subPanelSize.Width, y * subPanelSize.Height); + } + } + this.ResumeLayout(false); + } + } +} diff --git a/ChessPanel/ChessGame.cs b/ChessPanel/ChessGame.cs new file mode 100644 index 0000000..95879dd --- /dev/null +++ b/ChessPanel/ChessGame.cs @@ -0,0 +1,81 @@ +using ChessPanel; +using System; +using System.Windows.Forms; + +namespace Chess +{ + public class ChessGame : Panel + { + ChessBoard board; + public ChessGame() + { + InitializeComponent(); + RefreshSize(); + } + + private void InitializeComponent() + { + this.board = new ChessBoard(); + this.SuspendLayout(); + // + // board + // + this.board.GridSize = 8; + this.board.Cursor = Cursors.Hand; + this.board.Location = new System.Drawing.Point(0, 0); + this.board.Name = "board"; + int size = Math.Min(this.Size.Width, this.Size.Height); + board.Size = new System.Drawing.Size(size, size); + this.board.TabIndex = 0; + // + // ChessGame + // + this.Controls.Add(this.board); + this.Resize += new System.EventHandler(this.ResizeEvent); + this.ResumeLayout(false); + } + + private void ResizeEvent(object sender, EventArgs e) + { + RefreshSize(); + } + + internal void FormClosing(object sender, FormClosingEventArgs e) + { + if (board.isSaved) + { + e.Cancel = false; + } + else + { + switch (MessageBox.Show("Das aktuelle Spiel ist noch nicht gespeichert!\nMöchtest du es jetzt speichern?", "Speichern?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation)) + { + case DialogResult.Cancel: + e.Cancel = true; + break; + case DialogResult.Yes: + SaveGame(); + e.Cancel = false; + break; + case DialogResult.No: + e.Cancel = false; + break; + default: + break; + } + } + } + + private void SaveGame() + { + MessageBox.Show("TODO: SaveGame here!"); + } + + private void RefreshSize() + { + int size = Math.Min(this.Size.Width, this.Size.Height); + 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); + } + } +} diff --git a/ChessPanel/ClassDiagram.cd b/ChessPanel/ClassDiagram.cd new file mode 100644 index 0000000..2f5e006 --- /dev/null +++ b/ChessPanel/ClassDiagram.cd @@ -0,0 +1,107 @@ + + + + + + AICAAAAAAAAAAAAQAQAACCAEAIAgJAAACgAAAEoABII= + ChessBoard.cs + + + + + + AAAAAAAAAAAAIAAAAEAAAAACAAAABAAAIAAAAAAAAAA= + ChessGame.cs + + + + + + AABBgAEIEIYEIBAACAAAIAACADAAAEACAAAgQAAAABA= + Field.cs + + + + + + AAAAEAAAACAAAAAAAACAAAACAAAAAAAAAAAAAAAAAAA= + Form1.cs + + + + + + AAABAAAAAAAAAAAAAAAAAAAAEAABAACAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAgAAAA= + Piece.cs + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAA= + Program.cs + + + + + + AAAAAADAgQAQABAAAAIBEAAAIUAAIAAABAACAAAAIIA= + + + + + + AAAAAAAAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAA= + + + + + + AAAQAQAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAA= + FieldColorSet.cs + + + + \ No newline at end of file diff --git a/ChessPanel/Field.cs b/ChessPanel/Field.cs new file mode 100644 index 0000000..7174998 --- /dev/null +++ b/ChessPanel/Field.cs @@ -0,0 +1,101 @@ +using System; +using System.Windows.Forms; +using System.Drawing; +using static Chess.Piece; +using System.Windows; + +namespace Chess +{ + public class Field : Button + { + static readonly FieldColorSet primaryNormalColorSet = new FieldColorSet(Color.FromArgb(204, 204, 204), Color.FromArgb(153, 153, 153), Color.White); + static readonly FieldColorSet secondaryNormalColorSet = new FieldColorSet(Color.FromArgb(51, 51, 51), Color.FromArgb(102, 102, 102), Color.Black); + static readonly FieldColorSet primarySelectedColorSet = new FieldColorSet(Color.FromArgb(204, 204, 102), Color.FromArgb(153, 153, 102), Color.FromArgb(255, 255, 102)); + static readonly FieldColorSet secondarySelectedColorSet = new FieldColorSet(Color.FromArgb(204, 204, 51), Color.FromArgb(153, 153, 51), Color.FromArgb(255, 255, 51)); + static readonly FieldColorSet primaryValidFriendlyTargetFieldSet = new FieldColorSet(Color.FromArgb(102, 204, 102), Color.FromArgb(102, 153, 102), Color.FromArgb(102, 255, 102)); + static readonly FieldColorSet secondaryValidFriendlyTargetFieldSet = new FieldColorSet(Color.FromArgb(51, 204, 51), Color.FromArgb(51, 153, 51), Color.FromArgb(51, 255, 51)); + static readonly FieldColorSet primaryValidEnemyTargetFieldSet = new FieldColorSet(Color.FromArgb(204, 102, 102), Color.FromArgb(153, 102, 102), Color.FromArgb(255, 102, 102)); + static readonly FieldColorSet secondaryValidEnemyTargetFieldSet = new FieldColorSet(Color.FromArgb(204, 51, 51), Color.FromArgb(153, 51, 51), Color.FromArgb(255, 51, 51)); + public Vector location; + private FieldColorSet currentNormalColorSet; + private FieldColorSet currentEnemyColorSet; + private FieldColorSet currentSelectedColorSet; + private FieldColorSet currentAllyColorSet; + public delegate void ClickEventHandler(Vector coordinates); + public event ClickEventHandler FieldClick; + public bool IsEmpty { get { return currentPiece == null; } } + public Piece currentPiece; + public Piece CurrentPiece + { + get { return currentPiece; } + set { currentPiece = value; RefreshPiece(); } + } + + private void RefreshPiece() + { + if (currentPiece == null) + this.BackgroundImage = ChessPanel.Properties.Resources.Empty; + else + this.BackgroundImage = CurrentPiece.image; + } + public void Deselect() + { + setActiveColorSet(currentNormalColorSet); + } + public void Highlight(PieceTeam team) // validTargetField + { + switch (team) + { + case PieceTeam.Enemy: + setActiveColorSet(currentEnemyColorSet); + break; + case PieceTeam.Ally: + setActiveColorSet(currentAllyColorSet); + break; + default: + break; + } + } + public new void Select() // selectedField + { + setActiveColorSet(currentSelectedColorSet); + } + private void setActiveColorSet(FieldColorSet set) + { + this.BackColor = set.NormalColor; + this.FlatAppearance.MouseDownBackColor = set.MouseDownColor; + this.FlatAppearance.MouseOverBackColor = set.MouseOverColor; + } + public Field(int x, int y) + { + this.currentNormalColorSet = (x + y) % 2 == 0 ? primaryNormalColorSet : secondaryNormalColorSet; + this.currentAllyColorSet = (x + y) % 2 == 0 ? primaryValidFriendlyTargetFieldSet : secondaryValidFriendlyTargetFieldSet; + this.currentEnemyColorSet = (x + y) % 2 == 0 ? primaryValidEnemyTargetFieldSet : secondaryValidEnemyTargetFieldSet; + this.currentSelectedColorSet = (x + y) % 2 == 0 ? primarySelectedColorSet : secondarySelectedColorSet; + + + this.FlatStyle = FlatStyle.Flat; + this.FlatAppearance.BorderSize = 0; + this.setActiveColorSet(this.currentNormalColorSet); + this.Cursor = Cursors.Arrow; + + this.location = new Vector(x, y); // NICHT L(!)ocation, der gibt die Position des Buttons in Pixel auf dem Control an! + this.Name = string.Format($"field[{x},{y}]"); + this.Text = ""; + + this.BackgroundImageLayout = ImageLayout.Zoom; + this.BackgroundImage = ChessPanel.Properties.Resources.Empty; + + this.Click += clicked; + } + + private void clicked(object sender, EventArgs e) + { + FieldClick(this.location); + } + public override string ToString() + { + return this.currentPiece.type.ToString(); + } + } +} diff --git a/ChessPanel/FieldColorSet.cs b/ChessPanel/FieldColorSet.cs new file mode 100644 index 0000000..6c4917d --- /dev/null +++ b/ChessPanel/FieldColorSet.cs @@ -0,0 +1,17 @@ +using System.Drawing; +namespace Chess +{ + struct FieldColorSet + { + public FieldColorSet(Color MOC, Color MDC, Color NC) + { + MouseOverColor = MOC; + MouseDownColor = MDC; + NormalColor = NC; + } + public Color MouseOverColor { get; set; } + public Color MouseDownColor { get; set; } + public Color NormalColor { get; set; } + } + +} diff --git a/ChessPanel/MainForm.Designer.cs b/ChessPanel/MainForm.Designer.cs new file mode 100644 index 0000000..8ac61b2 --- /dev/null +++ b/ChessPanel/MainForm.Designer.cs @@ -0,0 +1,69 @@ +namespace Chess +{ + partial class MainForm + { + /// + /// Erforderliche Designervariable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Verwendete Ressourcen bereinigen. + /// + /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Vom Windows Form-Designer generierter Code + + /// + /// Erforderliche Methode für die Designerunterstützung. + /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. + /// + private void InitializeComponent() + { + this.chessGame = new Chess.ChessGame(); + this.SuspendLayout(); + // + // chessGame + // + this.chessGame.BackColor = System.Drawing.Color.Black; + this.chessGame.Dock = System.Windows.Forms.DockStyle.Fill; + this.chessGame.Location = new System.Drawing.Point(0, 0); + this.chessGame.Name = "chessGame"; + this.chessGame.Size = new System.Drawing.Size(1896, 1016); + this.chessGame.TabIndex = 0; + this.chessGame.UseWaitCursor = true; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1896, 1016); + this.Controls.Add(this.chessGame); + this.DoubleBuffered = true; + this.KeyPreview = true; + this.Name = "MainForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Color Board"; + this.UseWaitCursor = true; + this.WindowState = System.Windows.Forms.FormWindowState.Maximized; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.Load += new System.EventHandler(this.MainForm_Load); + this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + this.ResumeLayout(false); + + } + + #endregion + + private ChessGame chessGame; + } +} + diff --git a/ChessPanel/MainForm.cs b/ChessPanel/MainForm.cs new file mode 100644 index 0000000..b990f16 --- /dev/null +++ b/ChessPanel/MainForm.cs @@ -0,0 +1,52 @@ +using System; +using System.Windows.Forms; + +namespace Chess +{ + public partial class MainForm : Form + { + bool Fullscreen = false; + bool fullscreen + { + get { return Fullscreen; } + set { Fullscreen = value; RefreshFullScreen(); } + } + public MainForm() + { + InitializeComponent(); + } + + private void RefreshFullScreen() + { + this.SuspendLayout(); + if (fullscreen) + { + this.WindowState = FormWindowState.Normal; + this.FormBorderStyle = FormBorderStyle.None; + this.Bounds = Screen.PrimaryScreen.Bounds; + } + else + { + this.FormBorderStyle = FormBorderStyle.Sizable; + this.WindowState = FormWindowState.Maximized; + } + this.ResumeLayout(true); + } + + private void MainForm_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.F11) + fullscreen = !fullscreen; + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + chessGame.FormClosing(sender, e); + } + + private void MainForm_Load(object sender, EventArgs e) + { + fullscreen = true; + } + } +} diff --git a/ChessPanel/MainForm.resx b/ChessPanel/MainForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ChessPanel/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ChessPanel/Piece.cs b/ChessPanel/Piece.cs new file mode 100644 index 0000000..1ddde84 --- /dev/null +++ b/ChessPanel/Piece.cs @@ -0,0 +1,461 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using ChessPanel; +using System.Linq; +using System.Windows; + +namespace Chess +{ + public abstract class Piece + { + public enum PieceColor { White, Black }; + public enum PieceTeam { Enemy, Ally }; + public enum PieceType { King, Queen, Bishop, Rook, Knight, Pawn }; + public PieceColor color; + public PieceType type; + public Image image; + public bool HasMoved = false; + public bool EnPassantPossible = false; // Only in Pawn Class. Signs that this Piece has virtually not jumped two pieces, but one + internal static bool IsEndangeredLocationForPiece(Field[,] fields, Vector pieceLocation, Vector testLocation, PieceColor color) + { + bool returnValue = false; + Piece p = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece; + fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null; + foreach (var field in fields) + { + if (field.currentPiece != null) if (field.currentPiece.color != color) if (field.currentPiece.GetValidTargetFields(fields, field.location, true).ContainsKey(testLocation)) + { + returnValue = true; + break; + } + } + fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p; + return returnValue; + } + internal static bool MoveWillEndangerKing(Field[,] fields, Vector pieceLocation, Vector pieceMovedLocation, PieceColor color) // This does not test if it is a valid move spot + { + bool returnValue = false; + Piece p1 = fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece; + Piece p2 = fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece; + fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = null; + fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p1; + returnValue = KingIsEndangered(fields, color); + fields[(int)pieceLocation.X, (int)pieceLocation.Y].currentPiece = p1; + fields[(int)pieceMovedLocation.X, (int)pieceMovedLocation.Y].currentPiece = p2; + return returnValue; + } + + private static bool KingIsEndangered(Field[,] fields, PieceColor color) + { + Vector kingLocation = GetKingLocation(fields, color); + foreach (var field in fields) + { + if (field.currentPiece == null || field.currentPiece.color != color) + continue; + if (field.currentPiece.GetValidTargetFields(fields, field.location, testKingDanger: true).ContainsKey(kingLocation)) + { + return true; + } + } + return false; + } + + private static Vector GetKingLocation(Field[,] fields, PieceColor color) + { + foreach (var field in fields) + if (!field.IsEmpty && field.currentPiece.type == PieceType.King && field.currentPiece.color == color) + return field.location; + throw new Exception("King not found!"); + } + + internal abstract Dictionary GetValidTargetFields(Field[,] fields, Vector currentLocation, bool onlyAttackFields = false, bool testKingDanger = false); + } + public class Rook : Piece + { + public Rook(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) + { + var targetFields = GetTargetFields(fields, location, this.color); + /*if (!testKingDanger) + foreach (var item in targetFields) + if (MoveWillEndangerKing(fields, location, item.Key, this.color)) + targetFields.Remove(item.Key);*/ + return targetFields; + } + + internal static Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color) + { + Dictionary targetFields = new Dictionary(); + + for (int x = (int)location.X - 1; x >= 0; x--) // nach Links + { + if (fields[x, (int)location.Y].IsEmpty) + { + targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Ally); + } + else + { + if (fields[x, (int)location.Y].currentPiece.color != color) + targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Enemy); + break; + } + } + + + for (int x = (int)location.X + 1; x <= 7; x++) // nach Rechts + { + if (fields[x, (int)location.Y].IsEmpty) + { + targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Ally); + } + else + { + if (fields[x, (int)location.Y].currentPiece.color != color) + targetFields.Add(new Vector(x, (int)location.Y), PieceTeam.Enemy); + break; + } + } + + for (int y = (int)location.Y - 1; y >= 0; y--) // nach Unten + { + if (fields[(int)(int)location.X, y].IsEmpty) + { + targetFields.Add(new Vector((int)location.X, y), PieceTeam.Ally); + } + else + { + if (fields[(int)(int)location.X, y].currentPiece.color != color) + targetFields.Add(new Vector((int)location.X, y), PieceTeam.Enemy); + break; + } + } + + + for (int y = (int)location.Y + 1; y <= 7; y++) // nach Oben + { + if (fields[(int)(int)location.X, y].IsEmpty) + { + targetFields.Add(new Vector((int)location.X, y), PieceTeam.Ally); + } + else + { + if (fields[(int)(int)location.X, y].currentPiece.color != color) + targetFields.Add(new Vector((int)location.X, y), PieceTeam.Enemy); + break; + } + } + + return targetFields; + } + } // FINALIZED + public class Pawn : Piece + { + public Pawn(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool onlyAttackFields = false, bool testKingDanger = false) + { + var targetFields = GetTargetFields(fields, location, this.color, onlyAttackFields); + /*if (!testKingDanger) + foreach (var item in targetFields) + if (MoveWillEndangerKing(fields, location, item.Key, this.color)) + targetFields.Remove(item.Key);*/ + return targetFields; + } + + private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = false) + { + Dictionary targetFields = new Dictionary(); + int direction = this.color == PieceColor.White ? -1 : 1; + #region EnPassant + if (location.Y == (this.color == PieceColor.White ? 3 : 4)) + for (int x = -1; x < 2; x += 2) + if (location.X + x <= 7 && location.X + x >= 0) + if (fields[(int)location.X + x, (int)location.Y].currentPiece != null) + if (fields[(int)location.X + x, (int)location.Y].currentPiece.type == PieceType.Pawn) + if (fields[(int)location.X + x, (int)location.Y].currentPiece.color != this.color) + if (fields[(int)location.X + x, (int)location.Y].currentPiece.EnPassantPossible) + targetFields.Add(new Vector(location.X + x, location.Y + direction), PieceTeam.Enemy); + #endregion + #region Movement + if (!onlyAttackFields) + for (int y = 1; y < 1 + (HasMoved ? 1 : 2); y++) + { + if (location.Y + (direction * y) > 7 || location.Y + (direction * y) < 0) + break; + if (fields[(int)location.X, (int)location.Y + (direction * y)].IsEmpty) + targetFields.Add(new Vector(location.X, (int)location.Y + (direction * y)), PieceTeam.Ally); + else + break; + } + #endregion + #region Attack + for (int x = -1; x < 2; x += 2) + { + if (location.Y + (direction) > 7 || location.Y + (direction) < 0 || location.X + x > 7 || location.X + x < 0) + continue; + if (onlyAttackFields || (fields[(int)location.X + x, (int)location.Y + (direction)].currentPiece != null && fields[(int)location.X + x, (int)location.Y + (direction)].currentPiece.color != this.color)) + { + targetFields.Add(new Vector((int)location.X + x, (int)location.Y + (direction)), PieceTeam.Enemy); + } + } + #endregion + return targetFields; + } + } // EN-PASSANT MISSING + public class Knight : Piece + { + public Knight(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) + { + var targetFields = GetTargetFields(fields, location, this.color); + /* if (!testKingDanger) + foreach (var item in targetFields) + if (MoveWillEndangerKing(fields, location, item.Key, this.color)) + targetFields.Remove(item.Key);*/ + return targetFields; + } + + private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color) + { + Dictionary targetFields = new Dictionary(); + + for (int a = -1; a < 2; a += 2) + { + for (int b = -2; b < 3; b += 4) + { + if (!(a + (int)location.X > 7 || b + (int)location.Y < 0 || a + (int)location.X < 0 || b + (int)location.Y > 7)) + { + if (fields[a + (int)location.X, b + (int)location.Y].IsEmpty) + { + targetFields.Add(new Vector(a + (int)location.X, b + (int)location.Y), PieceTeam.Ally); + } + else + { + if (fields[a + (int)location.X, b + (int)location.Y].currentPiece.color != color) + targetFields.Add(new Vector(a + (int)location.X, b + (int)location.Y), PieceTeam.Enemy); + } + } + if (!(b + (int)location.X > 7 || a + (int)location.Y < 0 || b + (int)location.X < 0 || a + (int)location.Y > 7)) + { + if (fields[b + (int)location.X, a + (int)location.Y].IsEmpty) + { + targetFields.Add(new Vector(b + (int)location.X, a + (int)location.Y), PieceTeam.Ally); + } + else + { + if (fields[b + (int)location.X, a + (int)location.Y].currentPiece.color != color) + targetFields.Add(new Vector(b + (int)location.X, a + (int)location.Y), PieceTeam.Enemy); + } + } + } + } + + return targetFields; + } + } // FINALIZED + public class Bishop : Piece + { + public Bishop(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool onlyAttackFields = false, bool testKingDanger = false) + { + var targetFields = GetTargetFields(fields, location, this.color, onlyAttackFields); + /* if (!testKingDanger) + foreach (var item in targetFields) + if (MoveWillEndangerKing(fields, location, item.Key, this.color)) + targetFields.Remove(item.Key);*/ + return targetFields; + } + internal static Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color, bool onlyAttackFields = true) + { + Dictionary targetFields = new Dictionary(); + + for (int xy = 1; xy <= 7; xy++) // nach RechtsOben + { + if (location.X + xy > 7 || (int)location.Y + xy > 7) + break; + if (fields[xy + (int)location.X, xy + (int)location.Y].IsEmpty) + { + targetFields.Add(new Vector(xy + (int)location.X, xy + (int)location.Y), PieceTeam.Ally); + } + else + { + if (fields[xy + (int)location.X, xy + (int)location.Y].currentPiece.color != color) + targetFields.Add(new Vector(xy + (int)location.X, xy + (int)location.Y), PieceTeam.Enemy); + break; + } + } + for (int xy = 1; xy <= 7; xy++) // nach LinksOben + { + if (location.X - xy < 0 || (int)location.Y + xy > 7) + break; + if (fields[(int)location.X - xy, (int)location.Y + xy].IsEmpty) + { + targetFields.Add(new Vector(location.X - xy, (int)location.Y + xy), PieceTeam.Ally); + } + else + { + if (fields[(int)location.X - xy, (int)location.Y + xy].currentPiece.color != color) + targetFields.Add(new Vector(location.X - xy, (int)location.Y + xy), PieceTeam.Enemy); + break; + } + } + for (int xy = 1; xy <= 7; xy++) // nach RechtsUnten + { + if (location.X + xy > 7 || (int)location.Y - xy < 0) + break; + if (fields[xy + (int)location.X, (int)location.Y - xy].IsEmpty) + { + targetFields.Add(new Vector(xy + (int)location.X, (int)location.Y - xy), PieceTeam.Ally); + } + else + { + if (fields[xy + (int)location.X, (int)location.Y - xy].currentPiece.color != color) + targetFields.Add(new Vector(xy + (int)location.X, (int)location.Y - xy), PieceTeam.Enemy); + break; + } + } + for (int xy = 1; xy <= 7; xy++) // nach LinksUnten + { + if (location.X - xy < 0 || (int)location.Y - xy < 0) + break; + if (fields[(int)location.X - xy, (int)location.Y - xy].IsEmpty) + { + targetFields.Add(new Vector(location.X - xy, (int)location.Y - xy), PieceTeam.Ally); + } + else + { + if (fields[(int)location.X - xy, (int)location.Y - xy].currentPiece.color != color) + targetFields.Add(new Vector(location.X - xy, (int)location.Y - xy), PieceTeam.Enemy); + break; + } + } + return targetFields; + } + } // FINALIZED + public class Queen : Piece + { + public Queen(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) + { + Dictionary targetFields = Rook.GetTargetFields(fields, location, this.color); + targetFields = targetFields.Concat(Bishop.GetTargetFields(fields, location, this.color) + .Where(kvp => !targetFields.ContainsKey(kvp.Key))) + .OrderBy(c => c.Value) + .ToDictionary(c => c.Key, c => c.Value); + /*if (!testKingDanger) + foreach (var item in targetFields) + if (MoveWillEndangerKing(fields, location, item.Key, this.color)) + targetFields.Remove(item.Key);*/ + return targetFields; + } + } // FINALIZED + public class King : Piece + { + public King(PieceColor color) + { + type = (PieceType)Enum.Parse(typeof(PieceType), this.GetType().Name); + this.color = color; + this.image = (Image)ChessPanel.Properties.Resources.ResourceManager.GetObject($"{this.type.ToString()}{this.color.ToString()}"); + } + + internal override Dictionary GetValidTargetFields(Field[,] fields, Vector location, bool ignoreKingCheck = false, bool testKingDanger = false) // ignoreKingCheck hat keinen Einfluss + { + return GetTargetFields(fields, location, this.color); + } + + private Dictionary GetTargetFields(Field[,] fields, Vector location, PieceColor color) + { + Dictionary targetFields = new Dictionary(); + #region Castling + if (!this.HasMoved) // Only Castle if King did not move + foreach (var item in fields) + { + var itemLocation = item.location; + // Sucht nach Ally Turm und prüft, ob er sich schon bewegt hat + if (item.currentPiece != null && item.currentPiece.type == PieceType.Rook && !item.currentPiece.HasMoved && item.currentPiece.color == this.color) + { + if (itemLocation.X == 0 || itemLocation.X == 7) + { + bool castling = true; + for (int x = (itemLocation.X == 0 ? 1 : 5); (itemLocation.X == 0 ? x < 4 : x < 7); x++) + { + if (!fields[x, (int)location.Y].IsEmpty) + { + castling = false; + break; + } + } + if (castling) // Only Check endangered Fields if castling is generally possible + { + for (int x = (itemLocation.X == 0 ? 2 : 4); x < (itemLocation.X == 0 ? 5 : 7); x++) // König steht im Schach oder überschreitet bedrohtes Feld + { + if (IsEndangeredLocationForPiece(fields, location, new Vector(x, location.Y), color)) + { + castling = false; + break; + } + } + if (castling) + { + targetFields.Add(new Vector((itemLocation.X == 0 ? 2 : 6), itemLocation.Y), PieceTeam.Ally); + } + } + } + } + } + #endregion + #region Movement: 1 in every direction + for (int x = -1; x < 2; x++) + { + for (int y = -1; y < 2; y++) + { + if ((x == 0 && y == 0) || location.X + x > 7 || location.Y + y > 7 || location.X + x < 0 || location.Y + y < 0) + continue; + if (!IsEndangeredLocationForPiece(fields, location, new Vector(location.X + x, location.Y + y), color)) + if (fields[(int)location.X + x, (int)location.Y + y].IsEmpty) + { + targetFields.Add(new Vector(location.X + x, (int)location.Y + y), PieceTeam.Ally); + } + else + { + if (fields[(int)location.X + x, (int)location.Y + y].currentPiece.color != color) + targetFields.Add(new Vector(location.X + x, (int)location.Y + y), PieceTeam.Enemy); + continue; + } + } + } + #endregion + return targetFields; + } + } // CHECKMATE/CHECK-TEST MISSING +} \ No newline at end of file diff --git a/ChessPanel/Program.cs b/ChessPanel/Program.cs new file mode 100644 index 0000000..2b52112 --- /dev/null +++ b/ChessPanel/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.Windows.Forms; + +namespace Chess +{ + static class Program + { + /// + /// Der Haupteinstiegspunkt für die Anwendung. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/ChessPanel/Properties/AssemblyInfo.cs b/ChessPanel/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8848851 --- /dev/null +++ b/ChessPanel/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die einer Assembly zugeordnet sind. +[assembly: AssemblyTitle("ChessPanel")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ChessPanel")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("4f06559f-7350-4124-8ce9-05eec4768eb0")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ChessPanel/Properties/Resources.Designer.cs b/ChessPanel/Properties/Resources.Designer.cs new file mode 100644 index 0000000..3c9a831 --- /dev/null +++ b/ChessPanel/Properties/Resources.Designer.cs @@ -0,0 +1,193 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace ChessPanel.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChessPanel.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap BishopBlack { + get { + object obj = ResourceManager.GetObject("BishopBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap BishopWhite { + get { + object obj = ResourceManager.GetObject("BishopWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap Empty { + get { + object obj = ResourceManager.GetObject("Empty", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap KingBlack { + get { + object obj = ResourceManager.GetObject("KingBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap KingWhite { + get { + object obj = ResourceManager.GetObject("KingWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap KnightBlack { + get { + object obj = ResourceManager.GetObject("KnightBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap KnightWhite { + get { + object obj = ResourceManager.GetObject("KnightWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap PawnBlack { + get { + object obj = ResourceManager.GetObject("PawnBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap PawnWhite { + get { + object obj = ResourceManager.GetObject("PawnWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap QueenBlack { + get { + object obj = ResourceManager.GetObject("QueenBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap QueenWhite { + get { + object obj = ResourceManager.GetObject("QueenWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap RookBlack { + get { + object obj = ResourceManager.GetObject("RookBlack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap RookWhite { + get { + object obj = ResourceManager.GetObject("RookWhite", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/ChessPanel/Properties/Resources.resx b/ChessPanel/Properties/Resources.resx new file mode 100644 index 0000000..23e40c9 --- /dev/null +++ b/ChessPanel/Properties/Resources.resx @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\BishopBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\BishopWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Empty.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\KingBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\KingWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\KnightBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\KnightWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\PawnBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\PawnWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\QueenBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\QueenWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\RookBlack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\RookWhite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/ChessPanel/Resources/BishopBlack.png b/ChessPanel/Resources/BishopBlack.png new file mode 100644 index 0000000..0798e0b Binary files /dev/null and b/ChessPanel/Resources/BishopBlack.png differ diff --git a/ChessPanel/Resources/BishopWhite.png b/ChessPanel/Resources/BishopWhite.png new file mode 100644 index 0000000..7c2e095 Binary files /dev/null and b/ChessPanel/Resources/BishopWhite.png differ diff --git a/ChessPanel/Resources/Empty.png b/ChessPanel/Resources/Empty.png new file mode 100644 index 0000000..31873a9 Binary files /dev/null and b/ChessPanel/Resources/Empty.png differ diff --git a/ChessPanel/Resources/KingBlack.png b/ChessPanel/Resources/KingBlack.png new file mode 100644 index 0000000..dff14d8 Binary files /dev/null and b/ChessPanel/Resources/KingBlack.png differ diff --git a/ChessPanel/Resources/KingWhite.png b/ChessPanel/Resources/KingWhite.png new file mode 100644 index 0000000..b56d042 Binary files /dev/null and b/ChessPanel/Resources/KingWhite.png differ diff --git a/ChessPanel/Resources/KnightBlack.png b/ChessPanel/Resources/KnightBlack.png new file mode 100644 index 0000000..5f1819e Binary files /dev/null and b/ChessPanel/Resources/KnightBlack.png differ diff --git a/ChessPanel/Resources/KnightWhite.png b/ChessPanel/Resources/KnightWhite.png new file mode 100644 index 0000000..d690ef9 Binary files /dev/null and b/ChessPanel/Resources/KnightWhite.png differ diff --git a/ChessPanel/Resources/PawnBlack.png b/ChessPanel/Resources/PawnBlack.png new file mode 100644 index 0000000..1eef07f Binary files /dev/null and b/ChessPanel/Resources/PawnBlack.png differ diff --git a/ChessPanel/Resources/PawnWhite.png b/ChessPanel/Resources/PawnWhite.png new file mode 100644 index 0000000..b704ccf Binary files /dev/null and b/ChessPanel/Resources/PawnWhite.png differ diff --git a/ChessPanel/Resources/QueenBlack.png b/ChessPanel/Resources/QueenBlack.png new file mode 100644 index 0000000..f486fca Binary files /dev/null and b/ChessPanel/Resources/QueenBlack.png differ diff --git a/ChessPanel/Resources/QueenWhite.png b/ChessPanel/Resources/QueenWhite.png new file mode 100644 index 0000000..a75a99b Binary files /dev/null and b/ChessPanel/Resources/QueenWhite.png differ diff --git a/ChessPanel/Resources/RookBlack.png b/ChessPanel/Resources/RookBlack.png new file mode 100644 index 0000000..f90bc70 Binary files /dev/null and b/ChessPanel/Resources/RookBlack.png differ diff --git a/ChessPanel/Resources/RookWhite.png b/ChessPanel/Resources/RookWhite.png new file mode 100644 index 0000000..076aa65 Binary files /dev/null and b/ChessPanel/Resources/RookWhite.png differ diff --git a/ChessPanel/Vector.cs b/ChessPanel/Vector.cs new file mode 100644 index 0000000..83418e3 --- /dev/null +++ b/ChessPanel/Vector.cs @@ -0,0 +1,67 @@ +namespace Chess +{ + public class Vector + { + private int x; + private int y; + public int X + { + get { return x; } + set { x = value; } + } + public int Y + { + get { return y; } + set { y = value; } + } + public Vector(int x, int y) + { + this.x = x; + this.y = y; + } + public static Vector operator +(Vector v1, Vector v2) => new Vector(v1.x + v2.x, v1.y + v2.y); + public static Vector operator -(Vector v1, Vector v2) => new Vector(v1.x - v2.x, v1.y - v2.y); + public static Vector operator /(Vector v, int n) => new Vector(v.x / n, v.y / n); + public static Vector operator *(Vector v, int n) => new Vector(v.x * n, v.y * n); + public static Vector operator -(Vector v) => new Vector(-v.x, -v.y); + public static Vector operator +(Vector v) => v; + public static bool operator ==(Vector v1, Vector v2) + { + if (v1 as object == null || v2 as object == null) + { + return false; + } + else + { + return v1.x == v2.x && v1.y == v2.y; + } + } + public static bool operator !=(Vector v1, Vector v2) + { + if (v1 as object == null || v2 as object == null) + { + if (v1 as object == null && v2 as object == null) + { + return true; + } + return false; + } + else + { + return v1.x != v2.x || v1.y != v2.y; + } + } + public override bool Equals(object obj) + { + try + { + return this == obj as Vector; + } + catch (System.Exception) + { + return false; + } + } + public override string ToString() => $"({x}, {y})"; + } +}