private void newGame(chessGameMode mode)
 {
     _board.initNewChessGame(mode);
 }
    public void initNewChessGame(chessGameMode mode, List<pieceData> setup = null, chessPiece.TeamColor playerColor = chessPiece.TeamColor.NONE, int currentTurn = 0, bool isGameOver = false, int winner = -1)
    {
        clear();

        _gameMode = mode;
        _captured = new List<componentPiece>();

        //leaving this out here to make the switch simpler.
        if (_gameMode == chessGameMode.SOLO_SELF_ATTACK || _gameMode == chessGameMode.TWO_PLAYER_SELF_ATTACK)
        {
            chessPiece.canAttackOwnUnits = true;
        }
        else
        {
            chessPiece.canAttackOwnUnits = false;
        }
        if (_gameMode == chessGameMode.ASYNCHRONOUS)
        {
            moveSelectedPieceToLocation = moveSelectedPieceToLocationAsynchronous;
        }
        else
        {
            moveSelectedPieceToLocation = moveSelectedPieceToLocationLocal;
        }

        //Using a switch because this is a prototype. If it was a final product I would make each game mode derived from a base chessGameMode class
        // That would be so that any game mode wanted could be created, with inheiritance, and have more long-term flexibility.
        switch(_gameMode)
        {
            case chessGameMode.SOLO_SELF_ATTACK:
            case chessGameMode.SOLO:
                _playerColors = new chessPiece.TeamColor[1];
                _playerColors[0] = chessPiece.TeamColor.ALL;

                _playerActive = new bool[1];
                _playerActive[0] = true;
                break;
            case chessGameMode.TWO_PLAYER_SELF_ATTACK:
            case chessGameMode.TWO_PLAYER:
                _playerColors = new chessPiece.TeamColor[2];
                _playerColors[0] = chessPiece.TeamColor.WHITE;
                _playerColors[1] = chessPiece.TeamColor.BLACK;

                _playerActive = new bool[2];
                _playerActive[0] = true;
                _playerActive[1] = true;
                break;
            case chessGameMode.TWO_AND_A_DIETY:
                _playerColors = new chessPiece.TeamColor[3];
                _playerColors[0] = chessPiece.TeamColor.WHITE;
                _playerColors[1] = chessPiece.TeamColor.BLACK;
                _playerColors[2] = chessPiece.TeamColor.ALL;

                _playerActive = new bool[3];
                _playerActive[0] = true;
                _playerActive[1] = true;
                _playerActive[2] = true;
                break;
            case chessGameMode.ASYNCHRONOUS:
                _playerColors = new chessPiece.TeamColor[2];
                _playerColors[0] = playerColor;
                _playerColors[1] = (playerColor == chessPiece.TeamColor.WHITE)?(chessPiece.TeamColor.BLACK):(chessPiece.TeamColor.WHITE); //(playerColor == chessPiece.TeamColor.WHITE) ? (chessPiece.TeamColor.BLACK) : (chessPiece.TeamColor.WHITE);

                _playerActive = new bool[2];
                _playerActive[0] = true;
                _playerActive[1] = true;
                break;
        }

        _currentTurn = currentTurn;

        //Instead of creating sub classes for the pieces I am using the type pattern.

        //Sprites

        Sprite blackPawnSprite = Resources.Load<Sprite>("Pawn_Black");
        Sprite whitePawnSprite = Resources.Load<Sprite>("Pawn_White");

        Sprite blackRookSprite = Resources.Load<Sprite>("Rook_Black");
        Sprite whiteRookSprite = Resources.Load<Sprite>("Rook_White");

        Sprite blackKnightSprite = Resources.Load<Sprite>("Knight_Black");
        Sprite whiteKnightSprite = Resources.Load<Sprite>("Knight_White");

        Sprite blackBishopSprite = Resources.Load<Sprite>("Bishop_Black");
        Sprite whiteBishopSprite = Resources.Load<Sprite>("Bishop_White");

        Sprite blackQueenSprite = Resources.Load<Sprite>("Queen_Black");
        Sprite whiteQueenSprite = Resources.Load<Sprite>("Queen_White");

        Sprite blackKingSprite = Resources.Load<Sprite>("King_Black");
        Sprite whiteKingSprite = Resources.Load<Sprite>("King_White");

        ///////////////////////////// PAWNS ///////////////////////////////
        chessPieceType pawn = new chessPieceType("Pawn");
        pawn.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            Vector2 origin = piece.getLocation();
            int startY = 1;
            int forward = 1;
            if(piece.getTeamColor() == chessPiece.TeamColor.BLACK)
            {
                startY = 6;
                forward = -1;
            }

            List<Vector2> validMoves = new List<Vector2>();

            int tempX, tempY;

            tempX = (int)origin.x;
            tempY = (int)origin.y + (1 * forward);
            if(onBoard(tempX, tempY))   //Regular movement.
            {
                List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                if (piecesOnDest.Count == 0)
                {
                    validMoves.Add(new Vector2(tempX, tempY));
                    if ((int)origin.y == startY)    //You can only move 2 squares if another unit is not directly in front of this one. Also if it is at the origin then there is no need to check if 2 squares forward is off the board.
                    {
                        tempY += (1 * forward);
                        piecesOnDest = getPiecesAtLocation(tempX, tempY);
                        if(piecesOnDest.Count == 0)
                        {
                            validMoves.Add(new Vector2(tempX, tempY));
                        }
                        tempY -= (1 * forward); //because of the attack from start.
                    }
                }
                //This is inside the onboard check because if 1 square foward is off board then a pawn CANNOT attack, because it has to move at least 1 square forward, and the board is square.
                tempX -= 1; //Check left
                if(onBoard(tempX, tempY))
                {
                    piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if(piecesOnDest.Count > 0)
                    {
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                            validMoves.Add(new Vector2(tempX, tempY));
                    }
                }
                tempX += 2; //Switch to check right
                if (onBoard(tempX, tempY))
                {
                    piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count > 0)
                    {
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                            validMoves.Add(new Vector2(tempX, tempY));
                    }
                }
            }

            //DEBUG STUFF
            //foreach (Vector2 validMove in validMoves)
            //{
                //Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            //}

            return validMoves;
        };

        pawn.canAttack = delegate(int x, int y, controllerBoard board, chessPiece piece)
        {
            Vector2 origin = piece.getLocation();
            int forward = 1;
            if (piece.getTeamColor() == chessPiece.TeamColor.BLACK)
            {
                forward = -1;
            }

            int tempX, tempY;

            tempX = (int)origin.x + 1;
            tempY = (int)origin.y + (1 * forward);
            if((tempX == x) & (tempY == y))
                return true;

            tempX -= 2;
            if((tempX == x) & (tempY == y))
                return true;

            return false;
        };

        /////////////////////// ROOKS /////////////////////////
        chessPieceType rook = new chessPieceType("Rook");
        rook.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            List<Vector2> validMoves = new List<Vector2>();

            Vector2 origin = piece.getLocation();
            int tempX, tempY, dX, dY, count;

            count = 0;
            dX = 1;
            dY = 0;
            tempX = (int)origin.x;
            tempY = (int)origin.y;
            while(count < 4)    //1 for each direction
            {
                bool countCompleted = false;
                tempX += dX;
                tempY += dY;
                if (onBoard(tempX, tempY))
                {
                    List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count == 0)
                    {
                        validMoves.Add(new Vector2(tempX, tempY));
                    }
                    else
                    {
                        countCompleted = true;
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                        {
                            validMoves.Add(new Vector2(tempX, tempY));
                        }
                    }
                }
                else
                {
                    countCompleted = true;
                }

                if(countCompleted)
                {
                    tempX = (int)origin.x;
                    tempY = (int)origin.y;
                    count++;
                    switch(count)
                    {
                        case 1:
                            dX = 0;
                            dY = 1;
                            break;
                        case 2:
                            dX = -1;
                            dY = 0;
                            break;
                        case 3:
                            dX = 0;
                            dY = -1;
                            break;
                    }
                }
            }

            //DEBUG STUFF
            foreach (Vector2 validMove in validMoves)
            {
                Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            }

            return validMoves;
        };

        /////////////////////// KNIGHTS /////////////////////////
        chessPieceType knight = new chessPieceType("Knight");
        knight.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            List<Vector2> validMoves = new List<Vector2>();

            Vector2 origin = piece.getLocation();
            int tempX, tempY, dX, dY, count;

            count = 0;
            dX = 2;
            dY = -1;
            tempX = (int)origin.x;
            tempY = (int)origin.y;
            while (count < 8)    //1 for each direction
            {
                tempX += dX;
                tempY += dY;
                if (onBoard(tempX, tempY))
                {
                    List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count == 0)
                    {
                        validMoves.Add(new Vector2(tempX, tempY));
                    }
                    else
                    {
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                        {
                            validMoves.Add(new Vector2(tempX, tempY));
                        }
                    }
                }

                tempX = (int)origin.x;
                tempY = (int)origin.y;
                count++;
                switch (count)
                {
                    case 1:
                        dX = 2;
                        dY = 1;
                        break;
                    case 2:
                        dX = 1;
                        dY = 2;
                        break;
                    case 3:
                        dX = -1;
                        dY = 2;
                        break;
                    case 4:
                        dX = -2;
                        dY = 1;
                        break;
                    case 5:
                        dX = -2;
                        dY = -1;
                        break;
                    case 6:
                        dX = -1;
                        dY = -2;
                        break;
                    case 7:
                        dX = 1;
                        dY = -2;
                        break;
                }
            }

            //DEBUG STUFF
            foreach (Vector2 validMove in validMoves)
            {
                Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            }

            return validMoves;
        };

        /////////////////////// BISHOPS /////////////////////////
        chessPieceType bishop = new chessPieceType("Bishop");
        bishop.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            List<Vector2> validMoves = new List<Vector2>();

            Vector2 origin = piece.getLocation();
            int tempX, tempY, dX, dY, count;

            count = 0;
            dX = 1;
            dY = 1;
            tempX = (int)origin.x;
            tempY = (int)origin.y;
            while (count < 4)    //1 for each direction
            {
                bool countCompleted = false;
                tempX += dX;
                tempY += dY;
                if (onBoard(tempX, tempY))
                {
                    List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count == 0)
                    {
                        validMoves.Add(new Vector2(tempX, tempY));
                    }
                    else
                    {
                        countCompleted = true;
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                        {
                            validMoves.Add(new Vector2(tempX, tempY));
                        }
                    }
                }
                else
                {
                    countCompleted = true;
                }

                if (countCompleted)
                {
                    tempX = (int)origin.x;
                    tempY = (int)origin.y;
                    count++;
                    switch (count)
                    {
                        case 1:
                            dX = -1;
                            dY = 1;
                            break;
                        case 2:
                            dX = -1;
                            dY = -1;
                            break;
                        case 3:
                            dX = 1;
                            dY = -1;
                            break;
                    }
                }
            }

            //DEBUG STUFF
            foreach (Vector2 validMove in validMoves)
            {
                Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            }

            return validMoves;
        };

        /////////////////////// QUEENS /////////////////////////
        chessPieceType queen = new chessPieceType("Queen");
        queen.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            List<Vector2> validMoves = new List<Vector2>();

            Vector2 origin = piece.getLocation();
            int tempX, tempY, dX, dY, count;

            count = 0;
            dX = 1;
            dY = 0;
            tempX = (int)origin.x;
            tempY = (int)origin.y;
            while (count < 8)    //1 for each direction
            {
                bool countCompleted = false;
                tempX += dX;
                tempY += dY;
                if (onBoard(tempX, tempY))
                {
                    List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count == 0)
                    {
                        validMoves.Add(new Vector2(tempX, tempY));
                    }
                    else
                    {
                        countCompleted = true;
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                        {
                            validMoves.Add(new Vector2(tempX, tempY));
                        }
                    }
                }
                else
                {
                    countCompleted = true;
                }

                if (countCompleted)
                {
                    tempX = (int)origin.x;
                    tempY = (int)origin.y;
                    count++;
                    switch (count)
                    {
                        case 1:
                            dX = 1;
                            dY = 1;
                            break;
                        case 2:
                            dX = 0;
                            dY = 1;
                            break;
                        case 3:
                            dX = -1;
                            dY = 1;
                            break;
                        case 4:
                            dX = -1;
                            dY = 0;
                            break;
                        case 5:
                            dX = -1;
                            dY = -1;
                            break;
                        case 6:
                            dX = 0;
                            dY = -1;
                            break;
                        case 7:
                            dX = 1;
                            dY = -1;
                            break;
                    }
                }
            }

            //DEBUG STUFF
            foreach (Vector2 validMove in validMoves)
            {
                Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            }

            return validMoves;
        };

        /////////////////////// KINGS /////////////////////////
        chessPieceType king = new chessPieceType("King");
        king.generateMoveList = delegate(controllerBoard board, chessPiece piece, bool attackOwn)
        {
            //TODO: before production at least, is to optimize this. or optimize all other move list generation
            Debug.Log("Creating A New Valid Move List for Piece " + piece.gameObject.name);

            List<Vector2> validMoves = new List<Vector2>();

            Vector2 origin = piece.getLocation();
            int tempX, tempY, dX, dY, count;

            count = 0;
            dX = 1;
            dY = 0;
            tempX = (int)origin.x;
            tempY = (int)origin.y;
            while (count < 8)    //1 for each direction
            {
                tempX += dX;
                tempY += dY;
                if (onBoard(tempX, tempY))
                {
                    bool isValidMove = true;

                    foreach (componentPiece aPiece in _pieces)
                    {
                        chessPiece cPiece = (chessPiece)aPiece;
                        if (cPiece.getTeamColor() != piece.getTeamColor())
                        {
                            if (cPiece.getPieceTypeName().Equals("King"))   //Special case because kings have to caluclate other unit move positions
                            {
                                Vector2 otherKingLocation = cPiece.getLocation();
                                if((otherKingLocation.x >= (tempX - 1)) && (otherKingLocation.x <= (tempX + 1)) && (otherKingLocation.y >= (tempY - 1)) && (otherKingLocation.y <= (tempY +1)))
                                {
                                    isValidMove = false;
                                    break;
                                }
                            }
                            else if (cPiece.canAttack(tempX, tempY, this) == true)
                            {
                                isValidMove = false;
                                break;
                            }
                        }
                    }

                    List<componentPiece> piecesOnDest = getPiecesAtLocation(tempX, tempY);
                    if (piecesOnDest.Count > 0)
                    {
                        chessPiece pieceOnDest = (chessPiece)piecesOnDest[0];
                        if ((pieceOnDest.getTeamColor() != piece.getTeamColor()) || (attackOwn == true))
                        {
                            //Extra layer of checks has to be done to make sure if the unit is taken that it won't place yourself in check.
                            //I haven't put in those extra checks yet.
                        }
                        else
                        {
                            isValidMove = false;
                        }
                    }

                    if (isValidMove == true)
                    {
                        validMoves.Add(new Vector2(tempX, tempY));
                    }
                }

                tempX = (int)origin.x;
                tempY = (int)origin.y;
                count++;
                switch (count)
                {
                    case 1:
                        dX = 1;
                        dY = 1;
                        break;
                    case 2:
                        dX = 0;
                        dY = 1;
                        break;
                    case 3:
                        dX = -1;
                        dY = 1;
                        break;
                    case 4:
                        dX = -1;
                        dY = 0;
                        break;
                    case 5:
                        dX = -1;
                        dY = -1;
                        break;
                    case 6:
                        dX = 0;
                        dY = -1;
                        break;
                    case 7:
                        dX = 1;
                        dY = -1;
                        break;
                }
            }

            //clear the canAttackCache
            foreach (componentPiece aPiece in _pieces)
            {
                chessPiece cPiece = (chessPiece)aPiece;
                if (cPiece.getTeamColor() != piece.getTeamColor())
                {
                    if (!cPiece.getPieceTypeName().Equals("King"))   //Special case because kings have to caluclate other unit move positions
                    {
                        cPiece.clearCanAttackCache();
                    }
                }
            }

            //DEBUG STUFF
            foreach (Vector2 validMove in validMoves)
            {
                Debug.Log("Valid Move : (" + (int)validMove.x + "," + (int)validMove.y + ")");
            }

            return validMoves;
        };

        switch(_gameMode)
        {
            case chessGameMode.SOLO:
            case chessGameMode.SOLO_SELF_ATTACK:
            case chessGameMode.TWO_PLAYER:
            case chessGameMode.TWO_PLAYER_SELF_ATTACK:
            case chessGameMode.TWO_AND_A_DIETY:
                //Make Pawns
                for (int x = 0; x < 8; x++)
                {
                    createChessPiece("BlackPawn" + x, pawn, blackPawnSprite, x, 6, chessPiece.TeamColor.BLACK);
                    createChessPiece("WhitePawn" + x, pawn, whitePawnSprite, x, 1, chessPiece.TeamColor.WHITE);
                }
                //Make Rooks
                for (int x = 0; x < 2; x++)
                {
                    createChessPiece("BlackRook" + x, rook, blackRookSprite, (x == 0) ? (0) : (7), 7, chessPiece.TeamColor.BLACK);
                    createChessPiece("WhiteRook" + x, rook, whiteRookSprite, (x == 0) ? (0) : (7), 0, chessPiece.TeamColor.WHITE);
                }
                //Make Knights
                for (int x = 0; x < 2; x++)
                {
                    createChessPiece("BlackKnight" + x, knight, blackKnightSprite, (x == 0) ? (1) : (6), 7, chessPiece.TeamColor.BLACK);
                    createChessPiece("WhiteKnight" + x, knight, whiteKnightSprite, (x == 0) ? (1) : (6), 0, chessPiece.TeamColor.WHITE);
                }
                //Make Bishops
                for (int x = 0; x < 2; x++)
                {
                    createChessPiece("BlackBishop" + x, bishop, blackBishopSprite, (x == 0) ? (2) : (5), 7, chessPiece.TeamColor.BLACK);
                    createChessPiece("WhiteBishop" + x, bishop, whiteBishopSprite, (x == 0) ? (2) : (5), 0, chessPiece.TeamColor.WHITE);
                }
                //Make Queens
                createChessPiece("BlackQueen", queen, blackQueenSprite, 3, 7, chessPiece.TeamColor.BLACK);
                createChessPiece("WhiteQueen", queen, whiteQueenSprite, 3, 0, chessPiece.TeamColor.WHITE);
                //Make Kings
                createChessPiece("BlackKing", king, blackKingSprite, 4, 7, chessPiece.TeamColor.BLACK);
                createChessPiece("WhiteKing", king, whiteKingSprite, 4, 0, chessPiece.TeamColor.WHITE);
                break;
            case chessGameMode.ASYNCHRONOUS:
                foreach (pieceData pData in setup)
                {
                    chessPieceType type = null;
                    Sprite sprite = null;

                    switch(pData._type)
                    {
                        case enumChessPieceType.PAWN:
                            type = pawn;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whitePawnSprite) : (blackPawnSprite);
                            break;
                        case enumChessPieceType.ROOK:
                            type = rook;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whiteRookSprite) : (blackRookSprite);
                            break;
                        case enumChessPieceType.KNIGHT:
                            type = knight;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whiteKnightSprite) : (blackKnightSprite);
                            break;
                        case enumChessPieceType.BISHOP:
                            type = bishop;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whiteBishopSprite) : (blackBishopSprite);
                            break;
                        case enumChessPieceType.QUEEN:
                            type = queen;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whiteQueenSprite) : (blackQueenSprite);
                            break;
                        case enumChessPieceType.KING:
                            type = king;
                            sprite = (pData._color == chessPiece.TeamColor.WHITE) ? (whiteKingSprite) : (blackKingSprite);
                            break;
                    }

                    if (type != null)
                    {
                        chessPiece cPiece = createChessPiece(pData._name, type, sprite, pData._x, pData._y, pData._color);
                        if (pData._isAlive == false)
                        {
                            removePieceFromList(cPiece);
                            addPieceToCapturedList(cPiece);
                        }
                    }
                }
                break;
        }

        if(isGameOver == true)
        {
            gameOver(winner);
        }
        else
        {
            //Say the right turn.
            setupNewGameUI();
        }
    }
 public void setupNewGameUI(chessGameMode mode)
 {
     setGameMode("" + mode);
     showVictory(false);
 }