using System.Collections.Generic; namespace Chess { public class Posuniecie { private Pole figuraPole; public RuchFigury?[] mozliweRuchy; public Posuniecie() { poprzedniRuchy = new RuchFigury(1, 1); } public Posuniecie(Pole figuraPole) : this() { this.figuraPole = figuraPole; mozliweRuchy = Ruchy(); } public bool jestRuchMozliwy(Pole wybranePole) { InterfejsObslugiPoprzednichRuchow(false); for (int ruch = 0; ruch < mozliweRuchy.Length; ruch++) { if (mozliweRuchy[ruch] == null) { continue; } if (mozliweRuchy[ruch]?.x == wybranePole.lokalizacja.x && mozliweRuchy[ruch]?.y == wybranePole.lokalizacja.y) { if (!ACzyMoznaSieRuszyc(ruch, wybranePole)) { continue; } Szachownica.poprzednieRuchy.Add(new PoprzedniStanSzachownicy(figuraPole.figura, figuraPole.lokalizacja, (RuchFigury)mozliweRuchy[ruch], wybranePole.figura, ruch)); figuraPole.figura.pierwszyRuch = false; wybranePole.PrzydzialFigur(figuraPole.figura); figuraPole.PrzydzialFigur(new Figura(RodzajFigury.EMPTY)); if (!WybranieFigury.waiting) { Szachownica.KogoTerazTura = Szachownica.KogoTerazTura == Kolor.WHITE ? Kolor.BLACK : Kolor.WHITE; Figura.ZaaktualizujWszystkieAtaki(); if (SyndromOblezonejTwierdzy()) { Szachownica.Window.GameState.Text = "Szach"; Szachownica.Window.GameState.ForeColor = System.Drawing.Color.Firebrick; _ = Mat(); } else { Szachownica.Window.GameState.Text = ""; Szachownica.Window.GameState.ForeColor = System.Drawing.Color.OliveDrab; } } return true; } } return false; } public void InterfejsObslugiPoprzednichRuchow(bool show) { for (int i = 0; i < mozliweRuchy.Length; i++) { if (mozliweRuchy[i] == null) { continue; } if (figuraPole.figura.rodzajfigury == RodzajFigury.Pawn && ((i == 2 && nieJestZajetePole(figuraPole.lokalizacja.y + dir, figuraPole.lokalizacja.x + 1)) || (i == 3 && nieJestZajetePole(figuraPole.lokalizacja.y + dir, figuraPole.lokalizacja.x - 1)))) { continue; } Szachownica.pola[(int)mozliweRuchy[i]?.y, (int)mozliweRuchy[i]?.x].PossibleMove(show); } } public bool SyndromOblezonejTwierdzy() { return Szachownica.JakieToPole(RodzajFigury.King, Szachownica.KogoTerazTura).atakNaPole != Kolor.NONE; } public bool Mat() { List figuraPola = Szachownica.ZbierzWszystkieFiguryPola(Szachownica.KogoTerazTura); for (int j = 0; j < figuraPola.Count; j++) { figuraPole = figuraPola[j]; mozliweRuchy = Ruchy(); if (CzyKrolJestBezpieczny()) { return false; } } Szachownica.Window.GameState.Text = "Mat!"; Szachownica.Window.GameState.ForeColor = System.Drawing.Color.Firebrick; Szachownica.Window.ZatrzymajZegar(); return true; } public bool CzyKrolJestBezpieczny() { for (int ruch = 0; ruch < mozliweRuchy.Length; ruch++) { if (mozliweRuchy[ruch] == null) { continue; } if (!MoznaSieRuszac((int)mozliweRuchy[ruch]?.y, (int)mozliweRuchy[ruch]?.x)) { mozliweRuchy[ruch] = null; } } for (int i = 0; i < mozliweRuchy.Length; i++) { if (mozliweRuchy[i].HasValue) { return true; } } return false; } private bool MoznaSieRuszac(int y, int x) { Figura poprzedniePoleFigury = Szachownica.pola[y, x].figura; Szachownica.pola[y, x].figura = figuraPole.figura; figuraPole.figura = new Figura(RodzajFigury.EMPTY); Figura.ZaaktualizujWszystkieAtaki(); if (!SyndromOblezonejTwierdzy()) { figuraPole.figura = Szachownica.pola[y, x].figura; Szachownica.pola[y, x].figura = poprzedniePoleFigury; } else { figuraPole.figura = Szachownica.pola[y, x].figura; Szachownica.pola[y, x].figura = poprzedniePoleFigury; Figura.ZaaktualizujWszystkieAtaki(); return false; } return true; } private bool ACzyMoznaSieRuszyc(int move, Pole kliknietePole) { switch (figuraPole.figura.rodzajfigury) { case RodzajFigury.Pawn: figuraPole.figura.ruchODwaPola = move == 1; if (move == 2 && nieJestZajetePole(figuraPole.lokalizacja.y + dir, figuraPole.lokalizacja.x + 1)) { return false; } if (move == 3 && nieJestZajetePole(figuraPole.lokalizacja.y + dir, figuraPole.lokalizacja.x - 1)) { return false; } if (move == 4 || move == 5) { int xdir = move == 4 ? 1 : -1; Szachownica.pola[figuraPole.GetY, figuraPole.GetX + xdir].PrzydzialFigur(new Figura(RodzajFigury.EMPTY)); return true; } if ((figuraPole.GetY == 1 && figuraPole.figura.kolor == Kolor.WHITE) || (figuraPole.GetY == 6 && figuraPole.figura.kolor == Kolor.BLACK)) { WybranieFigury pieceSelection = new WybranieFigury(kliknietePole); pieceSelection.Show(); } break; case RodzajFigury.King: int ydir = Szachownica.KogoTerazTura == Kolor.WHITE ? 7 : 0; void castle(int tilex, int piecex) { Szachownica.pola[ydir, tilex].PrzydzialFigur(Szachownica.JakaToFigura(ydir, piecex)); Szachownica.pola[ydir, piecex].PrzydzialFigur(new Figura(RodzajFigury.EMPTY)); } if (move == 8) { castle(5, 7); } if (move == 9) { castle(3, 0); } break; default: break; } return true; } private RuchFigury? poprzedniRuchy; private int move; private RuchFigury?[] Ruchy() { RuchFigury?[] ruchy = new RuchFigury?[8]; move = 0; switch (figuraPole.figura.rodzajfigury) { case RodzajFigury.Bishop: ruchy = new RuchFigury?[32]; RuchLiniowy(ruchy, false); break; case RodzajFigury.Knight: ruchy[0] = destynacja(2, -1); ruchy[1] = destynacja(2, 1); ruchy[2] = destynacja(-2, 1); ruchy[3] = destynacja(-2, -1); ruchy[4] = destynacja(1, -2); ruchy[5] = destynacja(1, 2); ruchy[6] = destynacja(-1, -2); ruchy[7] = destynacja(-1, 2); break; case RodzajFigury.Queen: ruchy = new RuchFigury?[64]; RuchLiniowy(ruchy, false); poprzedniRuchy = new RuchFigury(1, 1); RuchLiniowy(ruchy, true); break; case RodzajFigury.Rook: ruchy = new RuchFigury?[32]; RuchLiniowy(ruchy, true); break; case RodzajFigury.King: ruchy = new RuchFigury?[10]; ruchy[0] = destynacja(1, -1); ruchy[1] = destynacja(1, 1); ruchy[2] = destynacja(-1, 1); ruchy[3] = destynacja(-1, -1); ruchy[4] = destynacja(1, 0); ruchy[5] = destynacja(-1, 0); ruchy[6] = destynacja(0, -1); ruchy[7] = destynacja(0, 1); bool CanCastle(int dir) { int range = dir == 1 ? 3 : 4; for (int i = 1; i < range; i++) { if (jestZajete(figuraPole.GetY, figuraPole.GetX + (i * dir)) || (Szachownica.pola[figuraPole.GetY, figuraPole.GetX + (i * dir)].atakNaPole != Kolor.NONE)) { return false; } } return true; } if (figuraPole.figura.pierwszyRuch && Szachownica.JakaToFigura(figuraPole.GetY, figuraPole.GetX + 3).pierwszyRuch) //right castling { ruchy[8] = CanCastle(1) ? destynacja(0, 2) : null; } if (figuraPole.figura.pierwszyRuch && Szachownica.JakaToFigura(figuraPole.GetY, figuraPole.GetX - 4).pierwszyRuch) //left castling { ruchy[9] = CanCastle(-1) ? destynacja(0, -2) : null; } break; case RodzajFigury.Pawn: ruchy = new RuchFigury?[6]; ruchy[0] = nieJestZajetePole(figuraPole.lokalizacja.y + (1 * dir), figuraPole.lokalizacja.x) ? destynacja(1 * dir, 0) : poprzedniRuchy = null; if (poprzedniRuchy != null) { ruchy[1] = nieJestZajetePole(figuraPole.GetY + (2 * dir), figuraPole.GetX) && figuraPole.figura.pierwszyRuch ? destynacja(2 * dir, 0) : null; } ruchy[2] = destynacja(dir, 1); ruchy[3] = destynacja(dir, -1); ruchy[4] = czyJestPionemPrzeciwnika(figuraPole.GetY, figuraPole.GetX + 1) && !jestZajete(figuraPole.GetY + dir, figuraPole.GetX + 1) ? destynacja(dir, 1) : null; ruchy[5] = czyJestPionemPrzeciwnika(figuraPole.GetY, figuraPole.GetX - 1) && !jestZajete(figuraPole.GetY + dir, figuraPole.GetX - 1) ? destynacja(dir, -1) : null; break; } return ruchy; } private int dir => figuraPole.figura.kolor == Kolor.BLACK ? 1 : -1; private void RuchLiniowy(RuchFigury?[] ruchy, bool liniaProsta) { int rookDir = liniaProsta ? 0 : 1; int bishopDir = liniaProsta ? 1 : -1; for (int i = 1; i < 9; i++) { ruchy[move] = destynacjaLiniowa(-i, i * bishopDir * rookDir); } poprzedniRuchy = new RuchFigury(1, 1); for (int i = 1; i < 9; i++) { ruchy[move] = destynacjaLiniowa(i, i * rookDir); } poprzedniRuchy = new RuchFigury(1, 1); for (int i = 1; i < 9; i++) { ruchy[move] = destynacjaLiniowa(i * rookDir, -i); } poprzedniRuchy = new RuchFigury(1, 1); for (int i = 1; i < 9; i++) { ruchy[move] = destynacjaLiniowa(i * bishopDir * rookDir, i); } } private RuchFigury? destynacjaLiniowa(int y, int x) { return poprzedniRuchy == null ? null : destynacja(y, x); } private RuchFigury? destynacja(int y, int x) { int LokacjaY = figuraPole.lokalizacja.y + y; int LokacjaX = figuraPole.lokalizacja.x + x; move++; if (czyDostepUdzielony(LokacjaY, LokacjaX)) { if (jestZajete(LokacjaY, LokacjaX) && figuraPole.figura.kolor != KolorPrzeciwnika(LokacjaY, LokacjaX)) { poprzedniRuchy = null; return new RuchFigury(LokacjaY, LokacjaX); } return jestZajete(LokacjaY, LokacjaX) ? (poprzedniRuchy = null) : (poprzedniRuchy = new RuchFigury(LokacjaY, LokacjaX)); } else { return poprzedniRuchy = null; } } private bool czyDostepUdzielony(int y, int x) { return Szachownica.czyMoznaWbic(y, x); } private bool jestZajete(int y, int x) { return Szachownica.pola[y, x].jestZajete(); } private bool czyJestPionemPrzeciwnika(int y, int x) { return czyDostepUdzielony(y, x) && jestZajete(y, x) && Szachownica.JakaToFigura(y, x).ruchODwaPola && jestPrzeciwnegoKoloru(y, x); } private bool nieJestZajetePole(int y, int x) { return czyDostepUdzielony(y, x) && !jestZajete(y, x); } private bool jestPrzeciwnegoKoloru(int y, int x) { return figuraPole.figura.kolor != KolorPrzeciwnika(y, x) && KolorPrzeciwnika(y, x) != Kolor.NONE; } private Kolor KolorPrzeciwnika(int y, int x) { return Szachownica.pola[y, x].figura.kolor; } } public struct RuchFigury { public int y, x; public RuchFigury(int y, int x) { this.y = y; this.x = x; } } }