private bool Valid_MovesLocations_Check(Piece_Base piece, Point newLocation) { Point _originalLocation = piece.Location; // текущая позиция фигуры piece.Location = newLocation; //назначает фигуре новую позицию для анализа, если король находится под прицелом bool _result = true; var lstPieces = this.Pieces.Where(x => x.Color != piece.Color && x.Location != newLocation).ToList(); // получить конкурирующие фигуры, чтобы увидеть, есть ли какой - либо мат if (lstPieces.Any()) // список соперников, которые атакуют выбранную фигуру { var king = this.Pieces.First(x => x.Color == piece.Color && x.GetType() == typeof(Piece_King)); var lstBoardPieces = this.Pieces.Where(x => !(x.Color != piece.Color && x.Location == newLocation)).ToList(); foreach (var p in lstPieces) { var lstMoves = Get_MovesLocations(p, lstBoardPieces); // получить места смещения каждой фигуры противника if (lstMoves.Any(x => x == king.Location)) { _result = false; // если хотя бы одна фигура соперника остается в пределах досягаемости короля, движение считается недействительным break; } } } piece.Location = _originalLocation; // назначаю оригинальное местоположение части return(_result); }
private void Move_Piece_Special(Piece_Base piece, Point targetLocation, ActionLog log) { if (piece.GetType() == typeof(Piece_Pawn)) { if (targetLocation.Y == (piece.Color == Player1.Color ? 0 : 7)) // игрок один коронует фигуру в верхнем ряду и игрок 2 в нижнем ряду { Piece_Base _newPiece = null; if (CurrentPlayer.Type == Player_Type.Human) { while (_newPiece == null) { var form = new PieceSelector(this.Resources, piece.Color); form.ShowDialog(); _newPiece = form.Selected_Piece; } _newPiece.Location = targetLocation; } Remove_Piece(piece, log); // Ликвидировать пешку Add_Piece(_newPiece, log); // добавить новую фигуру } var displacement = new Point(targetLocation.X - piece.Location.X, targetLocation.Y - piece.Location.Y); if ((displacement.X == -1 || displacement.X == 1) && displacement.Y == (CurrentPlayer.Equals(Player1) ? -1 : 1) && !this.Pieces.Any(x => x.Location == targetLocation)) { Point rivalLocation = new Point(targetLocation.X, targetLocation.Y + (CurrentPlayer.Equals(Player1) ? 1 : -1)); var romovePiece = this.Pieces.First(p => p.Location == rivalLocation); Remove_Piece(romovePiece, log); // удалить пешку соперника } } if (piece.GetType() == typeof(Piece_King)) { if (Math.Abs(piece.Location.X - targetLocation.X) == 2) // рокировка { Piece_Base _rock = null; if ((targetLocation.X - piece.Location.X) < 0) // { _rock = this.Pieces.FirstOrDefault(p => p.GetType() == typeof(Piece_Rook) && p.Location.X == 0 && p.Location.Y == piece.Location.Y); } else // { _rock = this.Pieces.FirstOrDefault(p => p.GetType() == typeof(Piece_Rook) && p.Location.X == 7 && p.Location.Y == piece.Location.Y); } var _newRookLoc = _rock.Location.X == 7 ? new Point(_rock.Location.X - 2, _rock.Location.Y) : new Point(_rock.Location.X + 3, _rock.Location.Y); log.Moves.Add(new MoveLog() { Piece = _rock, Original_Location = _rock.Location, New_Location = _newRookLoc }); _rock.Location = _newRookLoc; } } }
private Point[] Get_MovesLocations(Piece_Base piece, List <Piece_Base> boardPieces) { List <Point> lstAvailableCell = new List <Point>(); if (piece != null) { Array.ForEach(piece.Moves, x => { var displacement = x.Direction; if (piece.Color == Player2.Color) { displacement = new Point(displacement.X * -1, displacement.Y * -1); } Point _location = piece.Location; // начальная позиция, с которой начинается проверка ячеек while (true) { _location = new Point(_location.X + displacement.X, _location.Y + displacement.Y); //положение ячейки для проверки if (_location.X > 7 || _location.Y > 7 || _location.X < 0 || _location.Y < 0) { break; // координировать с доски "ДВИЖЕНИЕ НЕ ДОПУСКАЕТСЯ" } var _targetPiece = boardPieces.FirstOrDefault(y => y.Location == _location); if (x.Type.HasFlag(Elements.Move_Type.Special)) // специальное движение { if (!Get_MovesLocations_Special(piece, x, _targetPiece)) { break; // "НЕ РАЗРЕШАЕТ ДВИЖЕНИЯ" } } else { if (_targetPiece != null && _targetPiece.Color == piece.Color) // { break; //целевая фигура того же цвета, что и выбранная фигура "НЕ ДОПУСКАЕТ ДВИЖЕНИЯ" } } lstAvailableCell.Add(_location); // добавляет координату в список включенных ячеек "ПОЗВОЛЯЕТ ДВИЖЕНИЕ" if (_targetPiece != null && _targetPiece.Color != piece.Color) { break; // не допускает последующие перемещения в положение соперника } if (!x.IsLinear) { break; } } }); } return(lstAvailableCell.ToArray()); }
private void Add_Piece(Piece_Base piece, ActionLog log = null) { piece.SelectedImage = this.Resources.Image_SelectedTile; // назначает изображение для отображения, если выбрано this.Pieces.Add(piece); if (log != null) { log.Added_Piece = piece; } }
private void Set_SelectedPiece(Point cell_Location) { Board.Clear_EnabledMoves(); this.Pieces.ForEach(x => x.Selected = false); // отменяю все фишки Piece_Base _selectedPiece = this.Pieces.FirstOrDefault(x => x.Location == cell_Location && x.Color == CurrentPlayer.Color); //ищу ячейку для координаты, где она была нажата, только если это цвет, соответствующий игроку, который имеет ход if (_selectedPiece != null) { _selectedPiece.Selected = true; // ячейка выбрана Array.ForEach(_selectedPiece.EnabledMoves, loc => Board.Cells[loc.X, loc.Y].CanMove = true); // ячейки с включенным цветом } }
private bool Get_MovesLocations_Special(Piece_Base piece, Piece_Move move, Piece_Base rivalPiece) { // ИЗМЕНИТЬ ЛОГИКУ // возвращаем Tru при каждой проверке if (piece.GetType() == typeof(Piece_Pawn)) { if (move.Direction.X == 0 && move.Direction.Y == -1) // ячейка смещения на одну вперёд { return(rivalPiece == null); // ячейка спереди должна быть пустой } if (move.Direction.X == 0 && move.Direction.Y == -2) // переднее смещение 2 ячеек не позволяет отаковать { bool _condicion1 = rivalPiece == null; // ячейка назначения должна быть пустой bool _condicion2 = !this.Pieces.Any(p => p.Location.X == piece.Location.X && p.Location.Y == (CurrentPlayer.Number == 1 ? 5 : 2)); // передняя ячейка должна быть пустой bool _condicion3 = (CurrentPlayer.Number == 1 && piece.Location.Y == 6) || (CurrentPlayer.Number == 2 && piece.Location.Y == 1); // пешка должна ходить первой return(_condicion1 && _condicion2 && _condicion3); } if ((move.Direction.X == -1 || move.Direction.X == 1) && move.Direction.Y == -1) // атаковать соперника по диагонали { var lastAction = ActionLog.LastOrDefault(); if (rivalPiece == null && lastAction != null) // ЕСТЬ ПО ШАГУ { var Last_Move = lastAction.Moves.Last(); // Противостоящая пешка должна находиться в той же строке, что и перемещаемая фигура, в соседнем столбце и должна была переместиться в последний ход сыграло 2 ячейки if (CurrentPlayer.Number == 1 && piece.Location.Y == 3) // пешка движется вверх { var rival = this.Pieces.FirstOrDefault(p => p.Color != piece.Color && p.Location == new Point(piece.Location.X + move.Direction.X, piece.Location.Y)); if (rival != null && Last_Move.Piece.Equals(rival) && (Last_Move.New_Location.Y - Last_Move.Original_Location.Y) == 2) { return(true); } // Включить еду на ходу } if (CurrentPlayer.Number == 2 && piece.Location.Y == 4) // пешка движется вниз { var rival = this.Pieces.FirstOrDefault(p => p.Color != piece.Color && p.Location == new Point(piece.Location.X - move.Direction.X, piece.Location.Y)); if (rival != null && Last_Move.Piece.Equals(rival) && (Last_Move.New_Location.Y - Last_Move.Original_Location.Y) == -2) { return(true); } // Включить еду на ходу } } if (rivalPiece != null && rivalPiece.Color != piece.Color) { return(true); } // движение разрешено, только если в целевой позиции есть противник } } else if (piece.GetType() == typeof(Piece_King)) { if (GameState != State.Normal) { // король не может быть под прицелом return(false); } bool kingFirstMove = !ActionLog.Any(x => x.Moves.Any(y => y.Piece.Equals(piece))); if (!kingFirstMove) { return(false); } Point _moveDirection = CurrentPlayer.Number == 1 ? move.Direction : new Point(move.Direction.X * -1, move.Direction.Y * -1); Piece_Base _rock = null; if (_moveDirection.X < 0) { _rock = this.Pieces.FirstOrDefault(p => p.GetType() == typeof(Piece_Rook) && p.Location.X == 0 && p.Location.Y == piece.Location.Y); } else { _rock = this.Pieces.FirstOrDefault(p => p.GetType() == typeof(Piece_Rook) && p.Location.X == 7 && p.Location.Y == piece.Location.Y); } if (_rock == null) // если башня не существует, предполагается, что она была удалена или перемещена из своего первоначальной ячейки { return(false); } bool rookFirstMove = !ActionLog.Any(x => x.Moves.Any(y => y.Piece.Equals(piece))); if (!rookFirstMove) { return(false); } int _moveX = _moveDirection.X < 0 ? -1 : 1; Point _location = new Point(piece.Location.X + _moveX, piece.Location.Y); while (_location != _rock.Location) { bool _existPiece = this.Pieces.Any(p => p.Location == _location); if (_existPiece) { return(false); } // между королем и башней не должно быть места bool _attackLoc = this.Pieces.Any(p => p.Color != piece.Color && p.EnabledMoves != null && p.EnabledMoves.Any(y => y == _location)); if (_attackLoc) { return(false); // локация не может быть атакована соперником } _location = new Point(_location.X + _moveX, _location.Y); } return(true); // рокировка действительна } return(false); }
private void Remove_Piece(Piece_Base piece, ActionLog log) { this.Pieces.Remove(piece); //Удалить фигуру из списка фигур на доске log.Removed_Pieces.Add(piece); }