using System;
using System.Collections;

public class GameLogic
{
    private Board _board;
    private bool _soloGame, _endGame = false, _yourTurn=false;
    private GameGraphics _gameGraphics;
    private int _phase = 0, _outCome, _lastSquare, _newSquare, _otherPiece;
    private int[][] _dummyBoardSquares = new int[10][];
    private Player _currentPlayer, _winningPlayer = null;
    private Player[] _player = new Player[2];
    private StrategoClient _strategoClient;

    public GameLogic(String playerName, String opponentsName, bool soloGame, bool[] checkBoxValues, bool oneThroughNine, StrategoClient strategoClient, LoadingScreen loadingScreen)
    {
        _soloGame = soloGame;
        _board = new Board();
        _strategoClient = strategoClient;

        //if the game is networked
        if (_strategoClient != null)
        {
            _strategoClient.setGameLogic(this);
        }

        //if the player is blue
        if (checkBoxValues[0] == true)
        {
            _player[0] = new Player(playerName, 0, System.Drawing.Color.Blue);
            _player[1] = new Player(opponentsName, 1, System.Drawing.Color.Red);
            _currentPlayer = _player[1];
            _yourTurn = false;
        }
        //if the player is red
        else
        {
            _player[0] = new Player(playerName, 0, System.Drawing.Color.Red);
            _player[1] = new Player(opponentsName, 1, System.Drawing.Color.Blue);
            _currentPlayer = _player[0];
            _yourTurn = true;
        }

        _gameGraphics = new GameGraphics(this, checkBoxValues[1], checkBoxValues[2], oneThroughNine, _board, _player[0], loadingScreen);
//****start computer player here
    }

    public void startGame()
    {
        if (_soloGame == true)
        {
            this.setUpComputerPieces();
        }
        _phase = 1;
        _gameGraphics.startGame();
    }

    public void updateBoard(int[][] boardSquares)
    {
        for (int x = 0; x < boardSquares.Length; x++)
        {
            for (int y = 0; y < boardSquares[x].Length; y++)
            {
                _gameGraphics.getPiecesOnScreen()[x][y] = boardSquares[x][y];
                //if the piece belongs to the other player
                if (boardSquares[x][y] == 2)
                {
                    _board.getBoardSquares()[x][y].setPiece(new Piece(0, _player[1], _board.getBoardSquares()[x][y]));
                }
            }
        }
        this.startGame();
    }

    public void setUpComputerPieces()
    {
        ArrayList emptySquares = new ArrayList(40);

        //if you are the blue player
        if (_player[0].getPlayerColor().Equals(System.Drawing.Color.Blue))
        {
            for (int x = 6; x < 10; x++)
            {
                for (int y = 0; y < _board.getBoardSquares()[x].Length; y++)
                {
                    emptySquares.Add(_board.getBoardSquares()[x][y]);
                }
            }
        }
        //if you are the red player
        else
        {
            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < _board.getBoardSquares()[x].Length; y++)
                {
                    emptySquares.Add(_board.getBoardSquares()[x][y]);
                }
            }
        }

        int[] setUpPieces = new int[12];
        setUpPieces[0] = 6;
        setUpPieces[1] = 1;
        setUpPieces[2] = 8;
        setUpPieces[3] = 5;
        setUpPieces[4] = 4;
        setUpPieces[5] = 4;
        setUpPieces[6] = 4;
        setUpPieces[7] = 3;
        setUpPieces[8] = 2;
        setUpPieces[9] = 1;
        setUpPieces[10] = 1;
        setUpPieces[11] = 1;
        ArrayList randomNumbers = new ArrayList(setUpPieces.Length);
        for (int x = 0; x < setUpPieces.Length; x++)
        {
            randomNumbers.Add(x);
        }
        Random rand = new Random();
        while (emptySquares.Count > 0)
        {
            int num = rand.Next(randomNumbers.Count), square = rand.Next(emptySquares.Count);
            ((BoardSquare)emptySquares[square]).setPiece(new Piece(((int)randomNumbers[num]), _player[1], ((BoardSquare)emptySquares[square])));
            _player[1].getPieces().Add(((BoardSquare)emptySquares[square]).getPiece());
            setUpPieces[((int)randomNumbers[num])]--;
            emptySquares.RemoveAt(square);
            if (setUpPieces[((int)randomNumbers[num])] == 0)
            {
                randomNumbers.RemoveAt(num);
            }
        }
    }

    public delegate void displayResultsOfMoveDelegate(int outCome, int lastSquare, int newSquare, int otherPiece, int[][] boardSquares);

    public void displayResultsOfMove(int outCome, int lastSquare, int newSquare, int otherPiece, int[][] boardSquares)
    {
        _yourTurn = false;

        _outCome = outCome;
        _lastSquare = lastSquare;
        _newSquare = newSquare;
        _otherPiece = otherPiece;

        for (int x = 0; x < boardSquares.Length; x++)
        {
            _dummyBoardSquares[x] = new int[10];
            for (int y = 0; y < boardSquares[x].Length; y++)
            {
                _dummyBoardSquares[x][y] = boardSquares[x][y];
            }
        }

        //if this player moved the piece
        if (_currentPlayer.Equals(_player[0]))
        {
            //a piece was attacked
            if (outCome != 3)
            {
                _board.getBoardSquares()[newSquare / 10][newSquare % 10].setPiece(new Piece(otherPiece, _player[1], _board.getBoardSquares()[newSquare / 10][newSquare % 10]));
                _gameGraphics.setAttackedSquare(newSquare);
                _gameGraphics.getPiecesOnScreen()[newSquare / 10][newSquare % 10] = 3;
                //_gameGraphics.startTimer();
            }
            //a piece was not attacked
            else
            {
                this.updateGame();
                _gameGraphics.setLastClickedSquare(200);
            }
        }
        //if the other player moved the piece
        else
        {
            //a piece was attacked
            if (outCome != 3)
            {
                _board.getBoardSquares()[lastSquare / 10][lastSquare % 10].setPiece(new Piece(otherPiece, _player[1], _board.getBoardSquares()[lastSquare / 10][lastSquare % 10]));
                _gameGraphics.setAttackedSquare(newSquare);
                _gameGraphics.getPiecesOnScreen()[lastSquare / 10][lastSquare % 10] = 3;
                //_gameGraphics.startTimer();
            }
            //a piece was not attacked
            else
            {
                this.updateGame();
                _gameGraphics.setLastClickedSquare(200);
            }
        }
        _gameGraphics.invalidateBoardPanel();
    }

    public void updateGame()
    {
        //if this player moved the piece aka player 0
        if (_currentPlayer.Equals(_player[0]))
        {
            //both pieces died
            if (_outCome == 0)
            {
                _player[1].getPiecesInGraveard()[_otherPiece]++;
                _player[0].getPiecesInGraveard()[_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece().getRank()]++;
                _player[1].getPieces().Remove(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece());
                _player[0].getPieces().Remove(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(null);
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);
            }
            //attacker died
            else if (_outCome == 1)
            {
                _player[0].getPiecesInGraveard()[_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece().getRank()]++;
                _player[0].getPieces().Remove(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());


                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(new Piece(0, _player[1], _board.getBoardSquares()[_newSquare / 10][_newSquare % 10]));

                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);
            }
            //defender died
            else if (_outCome == 2)
            {
                _player[1].getPiecesInGraveard()[_otherPiece]++;
                _player[1].getPieces().Remove(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece());

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece().setCurrentSquare(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10]);
            }
            //non attack move
            else
            {
                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece().setCurrentSquare(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10]);
            }
        }
        //if the other player moved the piece aka player 1
        else
        {
            //both pieces died
            if (_outCome == 0)
            {
                _player[0].getPiecesInGraveard()[_otherPiece]++;
                _player[1].getPiecesInGraveard()[_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece().getRank()]++;
                _player[0].getPieces().Remove(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece());
                _player[1].getPieces().Remove(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(null);
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);
            }
            //attacker died
            else if (_outCome == 1)
            {
                _player[1].getPiecesInGraveard()[_otherPiece]++;
                _player[1].getPieces().Remove(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());

                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);
            }
            //defender died
            else if (_outCome == 2)
            {
                _player[0].getPiecesInGraveard()[_board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece().getRank()]++;
                _player[0].getPieces().Remove(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece());

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(new Piece(0, _player[1], _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10]));
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece().setCurrentSquare(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10]);
            }
            //non attack move
            else
            {
                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].setPiece(_board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].getPiece());
                _board.getBoardSquares()[_lastSquare / 10][_lastSquare % 10].setPiece(null);

                _board.getBoardSquares()[_newSquare / 10][_newSquare % 10].getPiece().setCurrentSquare(_board.getBoardSquares()[_newSquare / 10][_newSquare % 10]);
            }
        }

        for (int x = 0; x < _dummyBoardSquares.Length; x++)
        {
            for (int y = 0; y < _dummyBoardSquares[x].Length; y++)
            {
                _gameGraphics.getPiecesOnScreen()[x][y] = _dummyBoardSquares[x][y];
                //if the piece belongs to the other player
                if (_dummyBoardSquares[x][y] == 2)
                {
                    _board.getBoardSquares()[x][y].setPiece(new Piece(0, _player[1], _board.getBoardSquares()[x][y]));
                }
            }
        }

        if (_strategoClient.isSocketConnected() == true)
        {
            _strategoClient.writeChangeTurn();
        }
    }

    //determines what happens when two pieces collide
    public int processMove(BoardSquare attacking, BoardSquare defending)
    {
        int outCome = 0; //0 = your piece wins, 1 = their piece wins, 2 = tie
        //if the enemy piece is the flag
        if (defending.getPiece().getRank() == 11)
        {
            _player[defending.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[defending.getPiece().getRank()]++;
            this.gameOver(attacking.getPiece().getPlayer(), 1);
        }
        //if the enemy piece is a bomb
        else if (defending.getPiece().getRank() == 0)
        {
            //if your piece is a miner
            if (attacking.getPiece().getRank() == 3)
            {
                _player[defending.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[defending.getPiece().getRank()]++;
                _player[defending.getPiece().getPlayer().getIndex()].getPieces().Remove(defending.getPiece());
                defending.setPiece(attacking.getPiece());
                defending.getPiece().setCurrentSquare(defending);
                attacking.setPiece(null);
            }
            //if your piece is not a miner
            else
            {
                _player[attacking.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[attacking.getPiece().getRank()]++;
                _player[attacking.getPiece().getPlayer().getIndex()].getPieces().Remove(attacking.getPiece());
                attacking.setPiece(null);
                outCome = 1;
            }
        }
        //if the enemy piece is a marshal and your piece is a spy
        else if (defending.getPiece().getRank() == 10 && attacking.getPiece().getRank() == 1)
        {
            _player[defending.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[defending.getPiece().getRank()]++;
            _player[defending.getPiece().getPlayer().getIndex()].getPieces().Remove(defending.getPiece());
            defending.setPiece(attacking.getPiece());
            defending.getPiece().setCurrentSquare(defending);
            attacking.setPiece(null);
        }
        //if the enemy piece and your piece fall into the default rank processing
        else
        {
            //if your piece is greater than the enemy piece
            if (attacking.getPiece().getRank() > defending.getPiece().getRank())
            {
                _player[defending.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[defending.getPiece().getRank()]++;
                _player[defending.getPiece().getPlayer().getIndex()].getPieces().Remove(defending.getPiece());
                defending.setPiece(attacking.getPiece());
                defending.getPiece().setCurrentSquare(defending);
                attacking.setPiece(null);
            }
            //if the enemy piece is equal to your piece
            else if (attacking.getPiece().getRank() == defending.getPiece().getRank())
            {
                _player[defending.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[defending.getPiece().getRank()]++;
                _player[attacking.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[attacking.getPiece().getRank()]++;
                _player[defending.getPiece().getPlayer().getIndex()].getPieces().Remove(defending.getPiece());
                _player[attacking.getPiece().getPlayer().getIndex()].getPieces().Remove(attacking.getPiece());
                defending.setPiece(null);
                attacking.setPiece(null);
                outCome = 2;
            }
            //if the enemy piece is greater than the attacking piece
            else
            {
                _player[attacking.getPiece().getPlayer().getIndex()].getPiecesInGraveard()[attacking.getPiece().getRank()]++;
                _player[attacking.getPiece().getPlayer().getIndex()].getPieces().Remove(attacking.getPiece());
                attacking.setPiece(null);
                outCome = 1;
            }
        }
        return outCome;
    }

    //checks to see if the scout is able to move more than one square in a given direction
    public bool validScoutMove(BoardSquare lastClickedSquare, BoardSquare clickedSquare)
    {
        //row move
        if ((lastClickedSquare.getIndex() / 10) == (clickedSquare.getIndex() / 10))
        {
            int x = (lastClickedSquare.getIndex() / 10);
            //0->9
            if ((lastClickedSquare.getIndex() % 10) < (clickedSquare.getIndex() % 10))
            {
                //loops through all the squares in the path
                for (int y = (lastClickedSquare.getIndex() % 10) + 1; y < (clickedSquare.getIndex() % 10); y++)
                {
                    //if a square on the path contains a piece and blocks this scout from getting to the clicked square
                    if (_board.getBoardSquares()[x][y].getPiece() != null || _board.getBoardSquares()[x][y].getIndex() == 42 || _board.getBoardSquares()[x][y].getIndex() == 43 || _board.getBoardSquares()[x][y].getIndex() == 52 || _board.getBoardSquares()[x][y].getIndex() == 53 || _board.getBoardSquares()[x][y].getIndex() == 46 || _board.getBoardSquares()[x][y].getIndex() == 47 || _board.getBoardSquares()[x][y].getIndex() == 56 || _board.getBoardSquares()[x][y].getIndex() == 57)
                    {
                        return false;
                    }
                }
            }
            //9->0
            else
            {
                //loops through all the squares in the path
                for (int y = (lastClickedSquare.getIndex() % 10) - 1; y > (clickedSquare.getIndex() % 10); y--)
                {
                    //if a square on the path contains a piece and blocks this scout from getting to the clicked square
                    if (_board.getBoardSquares()[x][y].getPiece() != null || _board.getBoardSquares()[x][y].getIndex() == 42 || _board.getBoardSquares()[x][y].getIndex() == 43 || _board.getBoardSquares()[x][y].getIndex() == 52 || _board.getBoardSquares()[x][y].getIndex() == 53 || _board.getBoardSquares()[x][y].getIndex() == 46 || _board.getBoardSquares()[x][y].getIndex() == 47 || _board.getBoardSquares()[x][y].getIndex() == 56 || _board.getBoardSquares()[x][y].getIndex() == 57)
                    {
                        return false;
                    }
                }
            }
            //if the scout tries to move to a water square
            if (_board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 42 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 43 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 52 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 53 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 46 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 47 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 56 || _board.getBoardSquares()[x][clickedSquare.getIndex() % 10].getIndex() == 57)
            {
                return false;
            }
        }
        //column move
        else if ((lastClickedSquare.getIndex() % 10) == (clickedSquare.getIndex() % 10))
        {
            int y = (lastClickedSquare.getIndex() % 10);
            //0->9
            if ((lastClickedSquare.getIndex() / 10) < (clickedSquare.getIndex() / 10))
            {
                //loops through all the squares in the path
                for (int x = (lastClickedSquare.getIndex() / 10) + 1; x < (clickedSquare.getIndex() / 10); x++)
                {
                    //if a square on the path contains a piece and blocks this scout from getting to the clicked square
                    if (_board.getBoardSquares()[x][y].getPiece() != null || _board.getBoardSquares()[x][y].getIndex() == 42 || _board.getBoardSquares()[x][y].getIndex() == 43 || _board.getBoardSquares()[x][y].getIndex() == 52 || _board.getBoardSquares()[x][y].getIndex() == 53 || _board.getBoardSquares()[x][y].getIndex() == 46 || _board.getBoardSquares()[x][y].getIndex() == 47 || _board.getBoardSquares()[x][y].getIndex() == 56 || _board.getBoardSquares()[x][y].getIndex() == 57)
                    {
                        return false;
                    }
                }
            }
            //9->0
            else
            {
                //loops through all the squares in the path
                for (int x = (lastClickedSquare.getIndex() / 10) - 1; x > (clickedSquare.getIndex() / 10); x--)
                {
                    //if a square on the path contains a piece and blocks this scout from getting to the clicked square
                    if (_board.getBoardSquares()[x][y].getPiece() != null || _board.getBoardSquares()[x][y].getIndex() == 42 || _board.getBoardSquares()[x][y].getIndex() == 43 || _board.getBoardSquares()[x][y].getIndex() == 52 || _board.getBoardSquares()[x][y].getIndex() == 53 || _board.getBoardSquares()[x][y].getIndex() == 46 || _board.getBoardSquares()[x][y].getIndex() == 47 || _board.getBoardSquares()[x][y].getIndex() == 56 || _board.getBoardSquares()[x][y].getIndex() == 57)
                    {
                        return false;
                    }
                }
            }
            //if the scout tries to move to a water square
            if (_board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 42 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 43 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 52 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 53 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 46 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 47 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 56 || _board.getBoardSquares()[(clickedSquare.getIndex() / 10)][y].getIndex() == 57)
            {
                return false;
            }
        }
        else
        {
            return false;
        }
        return true;
    }

    //changes the current player to the next player
    public void nextTurn()
    {
        //if the game is a single player
        if (_soloGame == true)
        {
            if (_endGame == false)
            {
                //if it is this player's turn
                if (_currentPlayer.Equals(_player[0]))
                {
                    _yourTurn = true;
                    _currentPlayer = _player[1];
                    _gameGraphics.setPlayer(_currentPlayer);
                }
                //if it is the other player's turn
                else
                {
                    _yourTurn = true;
                    _currentPlayer = _player[0];
                    _gameGraphics.setPlayer(_currentPlayer);
                }
                //loops through the current player's pieces to make sure they can move a piece or that they have a piece that can move
                int ableToMakeMove = this.playerAbleToMakeMove(_currentPlayer);
                //if the player does not have any other pieces besides bombs and the flag
                if (ableToMakeMove == 2)
                {
                    if (_currentPlayer.Equals(_player[0]))
                    {
                        this.gameOver(_player[1], 2);
                    }
                    else
                    {
                        this.gameOver(_player[0], 2);
                    }
                }
                //if the player cannot move any of their pieces
                else if (ableToMakeMove == 3)
                {
                    if (_currentPlayer.Equals(_player[0]))
                    {
                        this.gameOver(_player[1], 3);
                    }
                    else
                    {
                        this.gameOver(_player[0], 3);
                    }
                }
            }
        }
        //if the game is a multiplayer
        else
        {
            //if it is this player's turn
            if (_currentPlayer.Equals(_player[0]))
            {
                _yourTurn = false;
                _currentPlayer = _player[1];
            }
            //if it is the other player's turn
            else
            {
                _yourTurn = true;
                _currentPlayer = _player[0];
            }
        }
        _gameGraphics.setCurrentTurnField(_currentPlayer);
    }

    public bool unableToMoveAtStart()
    {
        //if the player is the blue player
        if (_player[0].getPlayerColor().Equals(System.Drawing.Color.Blue))
        {
            int x = 3;
            for (int y1 = _board.getBoardSquares().Length - 1; y1 >= 0; y1 -= 4)
            {
                int y2 = y1 - 1;

                //if either of the two bottlenecks contains a piece other than either the flag and a bomb or just bombs
                if (!((_board.getBoardSquares()[x][y1].getPiece().getRank() == 0 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 0) || (_board.getBoardSquares()[x][y1].getPiece().getRank() == 11 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 0) || (_board.getBoardSquares()[x][y1].getPiece().getRank() == 0 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 11)))
                {
                    return false;
                }
            }
        }
        //if the player is the red player
        else
        {
            int x = 6;
            for (int y1 = 0; y1 < _board.getBoardSquares().Length; y1 += 4)
            {
                int y2 = y1 + 1;

                //if either of the two bottlenecks contains a piece other than either the flag and a bomb or just bombs
                if (!((_board.getBoardSquares()[x][y1].getPiece().getRank() == 0 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 0) || (_board.getBoardSquares()[x][y1].getPiece().getRank() == 11 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 0) || (_board.getBoardSquares()[x][y1].getPiece().getRank() == 0 && _board.getBoardSquares()[x][y2].getPiece().getRank() == 11)))
                {
                    return false;
                }
            }
        }
        return true;
    }

    //determines whether a player can make a valid move
    public int playerAbleToMakeMove(Player player)
    {
        bool hasMoveablePiece = false, aPieceCanMove = false;
        for (int x = 0; x < player.getPieces().Count; x++)
        {
            Piece piece = ((Piece)player.getPieces()[x]);

            //if the piece is not a bomb or the flag
            if (piece.getRank() != 0 && piece.getRank() != 11)
            {
                //if the player does not currently have a piece that is not a bomb or the flag, it now does
                if (hasMoveablePiece == false)
                {
                    hasMoveablePiece = true;
                }
                //loops through the pieces adjacent squares to see if it can move to one of them
                for (int y = 0; y < piece.getCurrentSquare().getOneMoveSquares().Count; y++)
                {
                    BoardSquare square = ((BoardSquare)piece.getCurrentSquare().getOneMoveSquares()[y]);
                    //if an adjacent square is empty or it has an enemy piece in it
                    if (square.getPiece() == null || (square.getPiece() != null && !square.getPiece().getPlayer().Equals(player)))
                    {
                        aPieceCanMove = true;
                        y = piece.getCurrentSquare().getOneMoveSquares().Count;
                        x = player.getPieces().Count;
                    }
                }
            }
        }
        //if the player does not have any other pieces besides bombs and the flag
        if (hasMoveablePiece == false)
        {
            return 2;
        }
        //if the player cannot move any of their pieces
        else if (aPieceCanMove == false)
        {
            return 3;
        }
        //a player has not lost the game
        else
        {
            return 0;
        }
    }

    public delegate void checkGameOverDelegate(int winningPlayer, int winType, int lastSquare, int newSquare, int otherPiece);

    public void checkGameOver(int winningPlayer, int winType, int lastSquare, int newSquare, int otherPiece)
    {
        //if the flag was captured
        if (winType == 1)
        {
            //if this player moved the piece
            if (_currentPlayer.Equals(_player[0]))
            {
                _board.getBoardSquares()[newSquare / 10][newSquare % 10].setPiece(new Piece(otherPiece, _player[1], _board.getBoardSquares()[newSquare / 10][newSquare % 10]));
                _gameGraphics.setAttackedSquare(newSquare);
                _gameGraphics.getPiecesOnScreen()[newSquare / 10][newSquare % 10] = 3;
            }
            //if the other player moved the piece
            else
            {
                _board.getBoardSquares()[lastSquare / 10][lastSquare % 10].setPiece(new Piece(otherPiece, _player[1], _board.getBoardSquares()[lastSquare / 10][lastSquare % 10]));
                _gameGraphics.setAttackedSquare(newSquare);
                _gameGraphics.getPiecesOnScreen()[lastSquare / 10][lastSquare % 10] = 3;
            }
            _gameGraphics.invalidateBoardPanel();
        }
        //if the game has ended in a draw
        if (winType == 4)
        {
            this.gameOver(null, winType);
        }
        //if a player has left
        else if (winType == 5)
        {
            //if the game is already over
            if (_endGame == true)
            {
                this.gameOver(null, winType);
            }
            //if the game is now over because the other player left
            else
            {
                this.gameOver(_player[0], winType);
            }
        }
        //if any of the single victor wins has happened
        else
        {
            //if red has won the game
            if (winningPlayer == 0)
            {
                //if player[0] is the red player
                if (_player[0].getPlayerColor().Equals(System.Drawing.Color.Red))
                {
                    this.gameOver(_player[0], winType);
                }
                //if player[1] is the red player
                else
                {
                    this.gameOver(_player[1], winType);
                }
            }
            //if blue has won the game
            else
            {
                //if player[0] is the blue player
                if (_player[0].getPlayerColor().Equals(System.Drawing.Color.Blue))
                {
                    this.gameOver(_player[0], winType);
                }
                //if player[1] is the blue player
                else
                {
                    this.gameOver(_player[1], winType);
                }
            }
        }
    }

    public void gameOver(Player winningPlayer, int winType)
    {
        _endGame = true;

        if (winType != 6)
        {
            _winningPlayer = winningPlayer;
        }


        //if the game has ended in a draw
        if (winType == 4)
        {
            _gameGraphics.setCurrentTurnFieldEndGame("The game has ended in a draw!", System.Drawing.Color.White);
            _gameGraphics.displayEndMessage("Both players have agreed to a draw!");
        }
        //if a player has left
        else if(winType == 5)
        {
            //if the game was already over
            if (winningPlayer == null)
            {
                _gameGraphics.appendToChatBox(_player[1].getPlayerName() + " has left the game!");
                //if player[0] is the player who did not leave
                if (winningPlayer.Equals(_player[0]))
                {
                    _gameGraphics.displayEndMessage(_player[1].getPlayerName() + " has left");
                }
                //if player[1] is the player who did not leave
                else
                {
                    _gameGraphics.displayEndMessage(_player[0].getPlayerName() + " has left");
                }
            }
            //if the game is now over because the other player has left
            else
            {
                _gameGraphics.setCurrentTurnFieldEndGame(winningPlayer.getPlayerName() + " wins the game!", winningPlayer.getPlayerColor());
                //if player[0] is the player who did not leave
                if (winningPlayer.Equals(_player[0]))
                {
                    _gameGraphics.displayEndMessage(_player[1].getPlayerName() + " has left, you win!");
                }
                //if player[1] is the player who did not leave
                else
                {
                    _gameGraphics.displayEndMessage(_player[0].getPlayerName() + " has left, you win!");
                }
            }
        }
        //if the server has disconnected
        else if (winType == 6)
        {
            //if the game was not already over
            if (_winningPlayer == null)
            {
                _gameGraphics.setCurrentTurnFieldEndGame("The game has ended in a draw!", System.Drawing.Color.White);
                _gameGraphics.displayEndMessage("Server disconnected so game is a draw.");
            }
            //if the game has been over
            else
            {
                _gameGraphics.displayEndMessage("Server disconnected so game has been canceled.");
            }
        }
        //if any of the single victor wins has happened 
        else
        {
            _gameGraphics.setCurrentTurnFieldEndGame(winningPlayer.getPlayerName() + " wins the game!", winningPlayer.getPlayerColor());

            //if a player has captured another player's flag
            if (winType == 1)
            {
                int random = new Random().Next(3);

                //if you won the game
                if (winningPlayer.Equals(_player[0]))
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("You have captured the opponents flag!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("Your opponent was a noob for putting his flag there!");
                    }
                    else if (random == 2)
                    {
                        _gameGraphics.displayEndMessage("You pwned the opponents flag!");
                    }
                }
                //if you lost the game
                else
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("Your flag has been captured!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("You lost your flag noob!");
                    }
                    else if (random == 2)
                    {
                        _gameGraphics.displayEndMessage("Your flag has been pwned!");
                    }
                }
            }
            //if a player has lost all of their moveable units
            else if (winType == 2)
            {
                int random = new Random().Next(2);

                //if won the game
                if (winningPlayer.Equals(_player[0]))
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("You have captured all your opponents moveable pieces!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("Your opponent has lost all of their moveable pieces!");
                    }
                }
                //if you lost the game
                else
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("You have no moveable pieces left!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("You lost all of your moveable pieces!");
                    }
                }
            }
            //if a player has units left but they cannot make any moves
            else if (winType == 3)
            {
                int random = new Random().Next(2);

                //if won the game
                if (winningPlayer.Equals(_player[0]))
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("Your opponent has no moves left!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("Your opponent cannot move anymore pieces!");
                    }
                }
                //if you lost the game
                else
                {
                    if (random == 0)
                    {
                        _gameGraphics.displayEndMessage("You are not able to move any units!");
                    }
                    else if (random == 1)
                    {
                        _gameGraphics.displayEndMessage("Your units are unable to move!");
                    }
                }
            }
        }
    }

    public void updateBoardPieces(int[][] boardSquares)
    {
        for (int x = 0; x < boardSquares.Length; x++)
        {
            for (int y = 0; y < boardSquares[x].Length; y++)
            {
                //if the piece belongs to you
                if (boardSquares[x][y] / 100 == 1)
                {
                    _gameGraphics.getPiecesOnScreen()[x][y] = 1;
                }
                //if the piece belongs to the other player
                else if (boardSquares[x][y] / 100 == 2)
                {
                    _board.getBoardSquares()[x][y].setPiece(new Piece((boardSquares[x][y] % 200), _player[1], _board.getBoardSquares()[x][y]));
                    _gameGraphics.getPiecesOnScreen()[x][y] = 3;
                }
                //if there is no piece
                else
                {
                    _gameGraphics.getPiecesOnScreen()[x][y] = boardSquares[x][y];
                }
            }
        }
        _gameGraphics.invalidateBoardPanel();
    }

    public GameGraphics getGameGraphics()
    {
        return _gameGraphics;
    }

    //gets the current phase of the game
    public int getPhase()
    {
        return _phase;
    }

    public bool isSoloGame()
    {
        return _soloGame;
    }

    public StrategoClient getStrategoClient()
    {
        return _strategoClient;
    }

    public Player[] getPlayers()
    {
        return _player;
    }

    public bool isYourTurn()
    {
        return _yourTurn;
    }

    public bool hasGameEnded()
    {
        return _endGame;
    }

    public Player getCurrentPlayer()
    {
        return _currentPlayer;
    }
}