/// <summary> /// Use a board snapshot to create the board /// </summary> /// <param name="boardSnapshot"></param> public void LoadFromSnapshot(ChessBoardSnapshot boardSnapshot) { List <ChessPosition> boardDict = boardSnapshot.ToList(); if (boardDict.Count <= 0) { return; } foreach (KeyValuePair <int, ChessPieceScript> kvp in piecesDict) { Destroy(kvp.Value.gameObject); } piecesDict.Clear(); for (int i = 0; i < boardDict.Count; i++) { ChessPieceScript newPiece = Instantiate(piecePrefab, chessPiecesParent) .GetComponent <ChessPieceScript>(); newPiece.Position = boardDict[i]; piecesDict.Add(newPiece.Coord.ToArrayCoord(), newPiece); } }
/// <summary> /// Создать поле с фигурой /// </summary> /// <param name="parent">контейнер</param> /// <param name="position">позиция</param> /// <param name="size">размер</param> /// <param name="coord">позиция на доске</param> /// <param name="piece">фигура</param> /// <param name="onclick">действие по нажатию</param> /// <returns></returns> public static ChessPieceScript CreateChessPiece(Transform parent, Vector3 position, float size, BoardCoord coord, ChessPiece piece, UnityAction <BaseEventData> onclick) { if (piece == null) { throw new System.Exception("CreateChessPiece: параметр piece = null"); } string path = string.Format("Prefabs/{0}{1}", piece.PieceType.ToString(), piece.Color.ToString()); Object resource = Resources.Load(path); if (resource == null) { throw new System.Exception("Не найден ресурс " + path); } ChessPieceScript space = (Object.Instantiate(Resources.Load(path)) as GameObject).GetComponent <ChessPieceScript>(); space.SetCoordinates(coord); space.SetSize(size); space.transform.position = position; space.transform.SetParent(parent); space.Piece = piece; space.gameObject.name = string.Format("{0}_{1}", piece.PieceType.ToString(), piece.Color.ToString()); return(space); }
/// <summary> /// Обновить фигуры по их перемещению /// </summary> /// <param name="move">перемещение фигур</param> private void UpdateChessPieces(Stack <ChessMove> move) { if (move == null || move.Count == 0) { return; } ChessMove currentMove = move.Pop(); if (currentMove == null) { return; } ChessPieceScript pieceScript = FindChessPiece(currentMove.MovingPiece); if (!pieceScript) { Vector3 position = BoardCoordToTransformPosition(currentMove.From); pieceScript = UIBuilder.CreateChessPiece(PieceContainer, position, CurrentCellSize, currentMove.From, currentMove.MovingPiece, OnChessPieceClickHandler); pieceScript.gameObject.AddClickEventTrigger(OnChessPieceClickHandler); Destroy(FindChessPiece(currentMove.From).gameObject); } ChessPieceScript defeatedScript = FindChessPiece(currentMove.DefeatedPiece); /// скрыть захваченную фигуру if (defeatedScript) { defeatedScript.SetVisibility(false); } /// переместить фигуру if (pieceScript.Coordiantes != currentMove.To) { pieceScript.SetCoordinates(currentMove.To); Vector3 from = pieceScript.transform.position; Vector3 to = BoardCoordToTransformPosition(currentMove.To); StartCoroutine(ChessPieceMoveCoroutine(pieceScript, from, to, new UnityAction(() => { UpdateChessPieces(move); }))); } }
/// <summary> /// Корутина перемещения фигуры /// </summary> /// <param name="piece">фигура</param> /// <param name="from">начальная позиция</param> /// <param name="to">конечная позиция</param> /// <param name="complete">действие по завершению</param> /// <returns></returns> private IEnumerator ChessPieceMoveCoroutine(ChessPieceScript piece, Vector3 from, Vector3 to, UnityAction complete) { CanSelect = false; piece.transform.SetAsLastSibling(); float t = 0; while (t < 1) { t += Time.deltaTime * MovementSpeed; t = Mathf.Clamp01(t); piece.transform.position = Vector3.Lerp(from, to, t); yield return(null); } if (complete != null) { complete.Invoke(); } CanSelect = true; }
/// <summary> /// Обработка нажатия на фигуру /// </summary> /// <param name="data">параметр</param> public void OnChessPieceClickHandler(BaseEventData data) { if (!CanSelect || chessGame.Mate) { return; } PointerEventData pData = (PointerEventData)data; currentChessPiece = pData.pointerPress.GetComponent <ChessPieceScript>(); if (!currentChessPiece || currentChessPiece.Piece.Color != chessGame.CurrentPlayerColor) { return; } Highlight.transform.position = currentChessPiece.transform.position; Highlight.SetVisibility(true); ClearSpaceContainer(); CreateAvailableSpaces(currentChessPiece.Coordiantes); }
/// <summary> /// Make a move from the latest snapshot (Without generating the next snapshot) /// </summary> /// <param name="from">Current position's coordinate</param> /// <param name="to">Destination position's coordinate</param> /// <param name="resultPositions">The returning result of positions</param> /// <returns> /// TRUE if move is valid. /// </returns> private bool Move(ChessCoordinate from, ChessCoordinate to, out ChessPosition[] resultPositions) { resultPositions = null; if (!from.IsWithinRange()) { Debug.LogWarning("Failed to execute Move.\nReason: (" + from.x + ", " + from.y + ") is not within RANGE."); return(false); } if (!to.IsWithinRange()) { Debug.LogWarning("Failed to execute Move.\nReason: (" + to.x + ", " + to.y + ") is not within RANGE."); return(false); } if (!piecesDict.ContainsKey(from.ToArrayCoord())) { Debug.LogWarning("Failed to execute Move.\nReason: (" + from.x + ", " + from.y + ") is EMPTY."); return(false); } ChessPieceScript selectedPiece = piecesDict[from.ToArrayCoord()]; ChessPieceSpecialRule specialRule = ChessPieceSpecialRule.None; ChessPosition[] castlingPositions; if ( !IsValidMove(selectedPiece.Position, from, to, out specialRule) || !AdditionalMove(specialRule, selectedPiece.Position, out castlingPositions) ) { Debug.LogWarning("Failed to execute Move.\nReason: " + selectedPiece.Type + " (" + from.x + ", " + from.y + ") --> (" + to.x + ", " + to.y + ") is INVALID."); return(false); } selectedPiece.Coord = to; selectedPiece.HasMoved = true; // Pawn Promotion if (selectedPiece.Type.IsPawn()) { if ( selectedPiece.Type == ChessPieceType.WhitePawn && selectedPiece.Coord.y == 0 ) { selectedPiece.Type = ChessPieceType.WhiteQueen; } else if ( selectedPiece.Type == ChessPieceType.BlackPawn && selectedPiece.Coord.y == 7 ) { selectedPiece.Type = ChessPieceType.BlackQueen; } } if (piecesDict.ContainsKey(to.ToArrayCoord())) { Destroy(piecesDict[to.ToArrayCoord()].gameObject); } piecesDict.Remove(from.ToArrayCoord()); piecesDict.Remove(to.ToArrayCoord()); piecesDict.Add(to.ToArrayCoord(), selectedPiece); List <ChessPosition> resultPositionsList = new List <ChessPosition>() { new ChessPosition(ChessPieceType.None, from), new ChessPosition(selectedPiece.Type, to) }; if (castlingPositions != null) { for (int i = 0; i < castlingPositions.Length; i++) { resultPositionsList.Add(castlingPositions[i]); } } resultPositions = resultPositionsList.ToArray(); Debug.Log("Succeeded to execute Move.\n" + selectedPiece.Type + " (" + from.x + ", " + from.y + ") --> (" + to.x + ", " + to.y + ")."); return(true); }