예제 #1
0
        // Player constructor
        public ChessMove(Square initialSquare, Square targetSquare, float rating)
        {
            InitialSquare = initialSquare;
            TargetSquare  = targetSquare;
            if (ChessGrid.Pieces.ContainsKey(targetSquare))
            {
                Attack = (ChessGrid.GetPosition(targetSquare) != null);
            }
            Rating = rating;

            if (!Attack)
            {
                return;
            }
            ChessPiece piece = ChessGrid.GetPosition(initialSquare);

            if (piece.type == "knight")
            {
                ChessPiece        target       = ChessGrid.GetPosition(targetSquare);
                List <ChessPiece> surroundings = MovementUtil.SurroundingPieces(ChessGrid.Pieces, initialSquare);
                if (!surroundings.Contains(target))
                {
                    AddOne = true;
                }
            }
        }
예제 #2
0
 public bool CheckIfPositionIsValid(Vector3 position)
 {
     if (ChessGrid.CheckIfSquareIndexIsValid(CalculateSquareIndexFromBoardPosition(position)))
     {
         return(true);
     }
     return(false);
 }
 public void Init(object data)
 {
     board = generatorService.Generate_from_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR");
     foreach (var square in board)
     {
         ChessGrid.Add(square);
     }
 }
예제 #4
0
        public void GetGridTest()
        {
            int       height = 3, width = 3;
            String    expectedString = "* * *\n * * *\n* * *";
            ChessGrid cg             = new ChessGrid(height, width, '*');
            String    actualString   = cg.GetGrid();

            Assert.AreEqual(expectedString, actualString);
        }
예제 #5
0
        public void Init(object data)
        {
            this.board = generatorService.Generate();

            foreach (var square in board)
            {
                ChessGrid.Add(square);
            }
        }
예제 #6
0
 void Start()
 {
     float[,] costs = new float[width, height];
     for (int x = 0; x < width; x++)
     {
         for (int y = 0; y < width; y++)
         {
             costs[x, y] = 1.0f;
         }
     }
     grid = new ChessGrid(width, height, costs);
 }
예제 #7
0
        public static List <Square> GetPossibleMoves(Dictionary <Square, AiChessPiece> board, AiChessPiece piece, bool updateStrength, float[,] strength)
        {
            string        owner         = piece.Owner.Name;
            int           direction     = owner == "player1" ? 1 : -1;
            List <Square> possibleMoves = null;

            switch (piece.Type)
            {
            case "pawn":
            case "bishop": {
                possibleMoves = InfantryMoves(piece.Position, direction, updateStrength, strength);
                break;
            }

            case "king":
            case "queen": {
                possibleMoves = RoyaltyMoves(board, piece.Position, 3, owner, updateStrength, strength);
                break;
            }

            case "knight": {
                possibleMoves = RoyaltyMoves(board, piece.Position, 4, owner, updateStrength, strength);
                break;
            }

            case "rook": {
                possibleMoves = ArcherMoves(board, piece.Position, owner, updateStrength, strength);
                break;
            }
            }

            List <Square> cleaned     = new List <Square>();
            List <Square> surrounding = MovementUtil.SurroundingSquares(piece.Position);

            foreach (Square s in possibleMoves.Where(s => ChessGrid.ValidPosition(s)))
            {
                if (board.ContainsKey(s))
                {
                    if (piece.Type != "knight" && !s.AttackOnly && !surrounding.Contains(s))
                    {
                        // remove this if statement if we want pieces to be able to attack any squares they can reach
                        continue;
                    }
                    AiChessPiece target = board[s];
                    if (target.Owner == piece.Owner)
                    {
                        continue;
                    }
                }
                cleaned.Add(s);
            }
            return(cleaned);
        }
예제 #8
0
        // Spawn a moveplate at a position
        public static void Spawn(Square initial, Square target, bool attackOnly, Game controller)
        {
            // In world coordinates of moveplate
            float[]    coords = ChessGrid.GetRealPos(target);
            GameObject obj    = Instantiate(controller.movePlate, controller.movePlateParent.transform);

            obj.name = "MovePlate";
            obj.transform.localPosition = new Vector3(coords[0], coords[1]);
            obj.transform.localScale    = new Vector3(1, 1, 1);
            MovePlate movePlate = obj.GetComponent <MovePlate>();

            movePlate._chessMove = new ChessMove(initial, target, 0);
            movePlate.attackOnly = attackOnly;
            movePlate.Init();
        }
예제 #9
0
    public static string BuildNotation(string type, Square initial, Square target, bool capture)
    {
        string notation = GetPieceAbbr(type, initial);

        if (capture)
        {
            ChessPiece targetPiece = ChessGrid.GetPosition(target);
            notation += " x " + GetPieceAbbr(targetPiece.type, target);
        }
        else
        {
            notation += " -> " + GetPosNotation(target);
        }

        return(notation);
    }
예제 #10
0
        // Movement for the Rook and its Attack range
        private static List <Square> ArcherMoves(Dictionary <Square, AiChessPiece> board, Square start, string owner, bool updateStrength, float[,] strength)
        {
            int           direction = owner == "player1" ? 1 : -1;
            List <Square> moves     = MovementUtil.SurroundingSquares(start);

            foreach (Square s in moves)
            {
                if (!board.ContainsKey(s))
                {
                    continue;
                }
                AiChessPiece target = board[s];
                if (target.Owner.Name != owner)
                {
                    s.AttackOnly = true;
                }
            }

            for (int i = -3; i <= 3; i++)
            {
                for (int j = -3; j <= 3; j++)
                {
                    if (i == 0 && j == 0)
                    {
                        continue;
                    }
                    Square s = new Square(start.X + i, start.Y + j);
                    if (updateStrength && ChessGrid.ValidPosition(s))
                    {
                        strength[s.X, s.Y] += direction * EvaluationValues.PieceStrength["rook"];
                    }
                    if (!board.ContainsKey(s))
                    {
                        continue;
                    }
                    AiChessPiece target = board[s];
                    if (target.Owner.Name != owner)
                    {
                        moves.Add(new Square(s.X, s.Y, true));
                    }
                }
            }
            return(moves);
        }
예제 #11
0
 // Validate that a square can be moved to, and then add it to the corresponding cache list
 private static bool ValidateSquare(Dictionary <Square, ChessPiece> board, ISet <Square> validMoves, ISet <Square> invalidMoves, Square current, string owner)
 {
     if (!ChessGrid.ValidPosition(current))
     {
         return(false);
     }
     if (board.ContainsKey(current))
     {
         if (board[current].Owner.Name == owner)
         {
             invalidMoves.Add(current);
             return(false);
         }
         validMoves.Add(current);
         return(true);
     }
     validMoves.Add(current);
     return(true);
 }
예제 #12
0
        private void Update()
        {
            Color color;

            // Determine raycasts - if the mouse is hovering over the object and released, then the piece that is being dragged will be moved here
            RaycastHit2D[] hits     = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
            bool           hovering = false;

            if (hits.Any(ray => ray.collider.gameObject == gameObject))
            {
                if (Input.GetMouseButtonUp(0) && !Game.Controller.die.rolling)  // make sure die is not rolling
                {
                    StartCoroutine(MovementUtil.Instance.MovePiece(_chessMove, attackOnly));
                }
                hovering = true;

                if (_chessMove.Attack && !Game.Controller.die.rolling)
                {
                    ChessPiece initialPiece = ChessGrid.GetPosition(_chessMove.InitialSquare);
                    ChessPiece targetPiece  = ChessGrid.GetPosition(_chessMove.TargetSquare);
                    Game.Controller.uiManager.UpdateAttack(UIManager.BuildNotation(initialPiece.type, _chessMove.InitialSquare, _chessMove.TargetSquare, true) + " - "
                                                           + CaptureMatrix.GetMin(initialPiece.type, targetPiece.type, _chessMove.AddOne) + "+ needed");
                }
            }

            // Interpolate color based on mouse input
            if (hovering)
            {
                color = _highlighted;
            }
            else
            {
                color = _chessMove.Attack ? _attacking : _initial;
            }
            _spriteRenderer.color = Color.Lerp(_spriteRenderer.color, color, 20 * Time.deltaTime);
        }
예제 #13
0
        public void DragOver(ChessFigure figure)
        {
            dynamic tempFigure = selectedFigure;

            if (tempFigure == null)
            {
                return;
            }

            if (!rulesService.Check(board, tempFigure, figure))
            {
                return;
            }

            var selectedSquare    = board[selectedFigure.Row, selectedFigure.Col];
            var destinationSquare = board[figure.Row, figure.Col];

            var selectedSquareIndex    = ChessGrid.IndexOf(selectedSquare);
            var destinationSquareIndex = ChessGrid.IndexOf(destinationSquare);

            var newSelectedSquare = new Square(selectedSquare.Row, selectedSquare.Col, selectedSquare.Color,
                                               new Empty(selectedSquare.Row, selectedSquare.Col));

            ChessGrid[selectedSquareIndex] = newSelectedSquare;

            selectedFigure.Row = destinationSquare.Row;
            selectedFigure.Col = destinationSquare.Col;

            var newDestinationSquare = new Square(destinationSquare.Row, destinationSquare.Col, destinationSquare.Color,
                                                  selectedFigure);

            ChessGrid[destinationSquareIndex] = newDestinationSquare;

            board[selectedSquare.Row, selectedSquare.Col]       = newSelectedSquare;
            board[destinationSquare.Row, destinationSquare.Col] = newDestinationSquare;
        }
예제 #14
0
        // Move a piece on the board
        public IEnumerator MovePiece(ChessMove chessMove, bool attackOnly)
        {
            ChessPiece initialPiece = ChessGrid.GetPosition(chessMove.InitialSquare);
            string     notation     = UIManager.BuildNotation(initialPiece.type, chessMove.InitialSquare, chessMove.TargetSquare, chessMove.Attack);
            Color      color        = Color.white;

            // Assume it will succeed if not an attack
            bool success = true;

            if (chessMove.Attack)
            {
                // Update attacking text
                ChessPiece targetPiece = ChessGrid.GetPosition(chessMove.TargetSquare);
                int        minNeeded   = CaptureMatrix.GetMin(initialPiece.type, targetPiece.type, chessMove.AddOne);
                Game.Controller.uiManager.UpdateAttack(UIManager.BuildNotation(initialPiece.type,
                                                                               chessMove.InitialSquare, chessMove.TargetSquare, true) + " - " + minNeeded + "+ needed.");

                // Only do the die roll if it is not a king attacking a pawn (this move is automatic)
                if (!(initialPiece.type == "king" && targetPiece.type == "pawn"))
                {
                    yield return(Game.Controller.die.Roll());

                    int num = Game.Controller.die.GetResult();
                    success = num >= minNeeded;
                }

                // Set color of move history text
                color = success ? Color.green : Color.red;
            }

            // set commander as having moved
            initialPiece.GetCommander().SetMoved();

            // Add move history record
            Game.Controller.uiManager.InsertMoveRecord(notation, false, color);

            if (success)
            {
                if (chessMove.Attack)
                {
                    // Play sounds
                    SoundManger.PlayAttackSuccessSound();
                    yield return(new WaitForSeconds(0.7f));

                    SoundManger.PlayCaptureSound();

                    ChessPiece targetPiece = ChessGrid.GetPosition(chessMove.TargetSquare);
                    // if king was taken, a player has won the game
                    if (targetPiece.type == "king")
                    {
                        Game.Winner(targetPiece.Owner.Name == "player1" ? "player2" : "player1");
                    }
                    targetPiece.transform.GetChild(0).GetComponent <SpriteRenderer>().enabled = false;   // Disable commander icon on this piece

                    // transition command authority to king if bishop was captured
                    if (targetPiece.type == "bishop")
                    {
                        Player player = targetPiece.Owner;
                        player.RemainingMoves--;
                        if (targetPiece.Owner == PovManager.Instance.Pov)
                        {
                            CommandDelegation.Instance.DisableButton(targetPiece.GetDivision());
                        }
                        player.TransitionCommand(targetPiece.GetDivision());
                    }

                    // move piece to graveyard
                    Graveyard grave = targetPiece.Owner.Name == "player1" ? player1Graveyard : player2Graveyard;
                    targetPiece.moveable = false;
                    targetPiece.dragging = true;
                    ChessGrid.Captured.Add(targetPiece);
                    grave.AddToGrave(targetPiece.gameObject.transform);
                }

                // If piece moves to the square it attacked (not an archer)
                if (!attackOnly)
                {
                    SoundManger.PlayMoveSound();
                    ChessGrid.SetPositionEmpty(initialPiece.Position);
                    ChessGrid.SetPosition(chessMove.TargetSquare, initialPiece);
                    initialPiece.SpriteRenderer.sortingOrder = 1;
                    initialPiece.Position = chessMove.TargetSquare;
                }
                else
                {
                    ChessGrid.SetPositionEmpty(chessMove.TargetSquare);
                }
            }
            else
            { // Attack Failed
                Game.Controller.lastMoveFailed = true;
                SoundManger.PlayAtackFailedSound();
            }

            // Increment turn regardless of fail/success
            DestroyMovePlates();
            Game.Controller.IncrementTurnCounter();
        }
예제 #15
0
        // Get all possible moves for a player based on the current state of the board
        public static List <Square> GetPossibleMoves(Dictionary <Square, ChessPiece> board, ChessPiece piece)
        {
            // first check if piece's division has already moved - if so, return an empty list
            if (piece.GetCommander().Moved)
            {
                piece.moveable = false;
                return(new List <Square>());
            }

            _direction = piece.Owner.Name == "player1" ? 1 : -1;
            List <Square> possibleMoves = null;

            // Find moves based on type of piece
            switch (piece.type)
            {
            case "pawn":
            case "bishop": {
                possibleMoves = InfantryMoves(piece.Position, _direction);
                break;
            }

            case "king":
            case "queen": {
                possibleMoves = RoyaltyMoves(board, piece.Position, 3, piece.Owner.Name);
                break;
            }

            case "knight": {
                possibleMoves = RoyaltyMoves(board, piece.Position, 4, piece.Owner.Name);
                break;
            }

            case "rook": {
                possibleMoves = ArcherMoves(board, piece.Position, piece.Owner.Name);
                break;
            }
            }

            // Clean the squares based on if the positions are valid on the board + other rules
            List <Square> cleaned     = new List <Square>();
            List <Square> surrounding = SurroundingSquares(piece.Position);

            foreach (Square s in possibleMoves.Where(s => ChessGrid.ValidPosition(s)))
            {
                if (board.ContainsKey(s))
                {
                    if (piece.type != "knight" && !s.AttackOnly && !surrounding.Contains(s))
                    {
                        // remove this if statement if we want pieces to be able to attack any squares they can reach
                        continue;
                    }
                    ChessPiece target = board[s];
                    if (target.Owner == piece.Owner)
                    {
                        continue;
                    }
                }
                cleaned.Add(s);
            }

            piece.moveable = cleaned.Count > 0;
            return(cleaned);
        }
예제 #16
0
 internal void SetGrid(ChessGrid grid)
 {
     this.grid = grid;
 }
예제 #17
0
 public void OnSelectPiece(Piece chosenPiece)
 {
     ChessGrid.SelectPiece(chosenPiece);
     SquareSelector.ActivateSquareSelectors(ChessGrid.SelectedPiece.AvailableMoves, ChessGrid.SelectedPiece);
 }
예제 #18
0
 public void OnDeselectActivePiece()
 {
     ChessGrid.DeselectPiece();
     SquareSelector.DeactivateSquareSelectors();
 }
예제 #19
0
 public void OnSelectedPieceMove(Move move)
 {
     StartTurn();
     ChessGrid.MakeMove(move, gameController.ActivePlayer, gameController.GetOppositeToActivePlayer(), RotateToNewPlayer, HandlePromotion);
 }
예제 #20
0
 private void StartTurn()
 {
     TurnIsActive = true;
     ChessGrid.SaveMovedPiece();
 }