import Board;
import Piece;
import Gamestate;

/** 
 *  OthelloRules
 *  Rules Class for the Othello game
 *  a project by Sam Rebelsky's CSC 152 class.
 *
 *  @author Alex Ford, Jonathan Emmons, Rob Park, Arrel Gray
 *  @version 1.0 of April - 2000
 *
 */

public class OthelloRules {
    
    /// +--------+---------------------------------------------------
    /// | Fields |
    /// +--------+

    int player;
    

    /** 
     *  startingPieces
     *  
     *  This method provides the board class with information on where to 
     *  place the initial pieces before the game starts.  These positions will
     *  be determined by the version of the game selected by the player through
     *  the GUI or TUI. The parameter is a blank GameState, with the rules for
     *  that particular game applied. The method returns the updated board 
     *  with the positions of the initial pieces.
     *
     */

    public int[][] startingPieces(Gamestate g) {   
  
        // initialize the board with the appropriate color tiles. I'm assuming
        // that Board and Gamestate are updated when the piece is constructed.

        Piece p44 = new Piece(4,4,0,g.getBoard);
        Piece p45 = new Piece(4,5,1,g.getBoard);
        Piece p54 = new Piece(5,4,1,g.getBoard);
        Piece p55 = new Piece(5,5,0,g.getBoard);

        return g;

    }//startingPieces
            


    /**
     *  getPlayer
     *
     *  This method is used to extract the field that tells whose turn
     *  it is.  This field will be used to determine the color of the piece to
     *  be played as well as to determine whether a particular move will be
     *  legal.  This field will need to be initialized, and different sets of
     *  rules may state that player one does not always go first.  Also, in the
     *  event of a player being unable to make a legal move or a rule variation
     *  which affects whose turn it is, it will be necessary to set this field.
     *  within the given rules class. This field will provide more flexibility
     *  than simply initializing it upon declaration of the field.  The method
     *  will not take parameters and will return an integer value representing
     *  the player.
     *
     */

    public int getPlayer() {
        
        return this.player;

    }//getPlayer

    
    /**
     *  numberPlayers
     *
     *  At some point in the game it will become necessary for other classes 
     *  to know the number of players playing the game.  This method will 
     *  provide that information by returning an integer corresponding to the
     *  number of players.  It will take a Board as its parameter to determine
     *  the number of players required for that board.
     *
     */

    public int numberPlayers(GameState g) {
        
        return 2;
    }//numberPlayers


    /**
     *  legalMove
     *
     *  This method provides a test to see whether or not a move the player
     *  requests is a legal move.  The method will need parameters including 
     *  which player is requesting the move as well as which space he wishes 
     *  to place his piece.  This method is also dependant upon a method in
     *  the board class that will return whether or not a given space on the 
     *  board is occupied and who has that space.  legalMove returns a boolean 
     *  value indicating whether or not a move is legal.  Alternate versions
     *  of the game's rules may include different definitions of a legal move.
     *
     *  Assume the player is represented by an integer and a square on the 
     *  board can be expressed as a column number and row number.
     *
     */

    public boolean legalMove(Gamestate g, int player, int row, int column)
    {
    /** here, I am assuming that if the space is not occupied, I get "false."
     * Otherwise, I get a Piece object.
     */
        if (g.getBoard.isOccupied(row, column) == true){
            return false;
        } else
        if ((g.getboard.isOccupied(row - 1, col) true) &&
            (g.getBoard.isOccupied(row - 1, col).getColor() != player)) {
            int r = row - 2;
            int c = col;
            while(g.getBoard.isOccupied(r, c).getColor() != player &&
                  r > 0){
                r--;
            } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else
        if ((g.getBoard.isOccupied(row - 1, col + 1) true) &&
            (g.getBoard.isOccupied(row - 1, col + 1).getColor() != player)) {
            int r = row - 2;
            int c = col + 2;
            while(g.getBoard.isOccupied(r, c).getColor() != player &&
                  r > 0 && c <= g.getBoard.cols()){
                r--;
                c++;
            } // while 
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else 
        if ((g.getBoard.isOccupied(row, col + 1) true) &&
            (g.getBoard.isOccupied(row, col + 1).getColor() != player)) {
            int c = col + 2;
            int r = row;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      c <= g.getBoard.cols()){
                    c++;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else 
        if ((g.getBoard.isOccupied(row + 1, col + 1) true) &&
            (g.getBoard.isOccupied(row + 1, col + 1).getColor() != player)) {
            int c = col + 2;
            int r = row + 2;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      c <= g.getBoard.cols(), r <= g.getBoard.rows()) {
                    c++;
                    r++;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else  
        if ((g.getBoard.isOccupied(row + 1, col) true) &&
            (g.getBoard.isOccupied(row + 1, col).getColor() != player)) {
            int c = col;
            int r = row + 2;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      r <= g.getBoard.rows()){
                    r++;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else
        if ((g.getBoard.isOccupied(row + 1, col - 1) true) &&
            (g.getBoard.isOccupied(row + 1, col - 1).getColor() != player)) {
            int c = col - 2;
            int r = row + 2;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      r <= g.getBoard.rows(), c > 0){
                    c--;
                    r++;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else 
        if ((g.getBoard.isOccupied(row, col - 1) true) &&
            (g.getBoard.isOccupied(row, col - 1).getColor() != player)) {
            int c = col - 2;
            int r = row;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      c > 0){
                    c--;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else 
        if ((g.getBoard.isOccupied(row - 1, col - 1) true) &&
            (g.getBoard.isOccupied(row - 1, col - 1).getColor() != player)) {
            int c = col - 2;
            int r = row - 2;
                while(g.getBoard.isOccupied(r, c).getColor() != player &&
                      c > 0, r > 0){
                    c--;
                    r--;
                } // while
            if(g.getBoard.isOccupied(r, c).getColor() = player) {
                return true;
            } else {
                return false;
            }
        } else { 
            return false;
        }
} // legalMove(int player, gamestate g, int row, int column)
                    

    /**
     *  anyMove
     *
     *  This method is designed to determine whether or not a player has 
     *  a legal move available.  There are times in the game in which a player
     *  does not have a space he can move into that will surround one of his 
     *  opponent's pieces, and he will be forced to pass.  The method will need
     *  to know which player is attempting a move.  It will then check all 
     *  empty spaces on the board and test whether or not it is a valid option
     *  using legalMove.  If there is at least one legal move available, the
     *  method will return the boolean value true.  If not, it will return 
     *  false.  
     *
     *  This method can be implemented before every turn or whenever a
     *  player suspects he is "stuck," depending on the preference of the 
     *  designers of the appropriate class.
     *
     */

    public boolean anyMove(Gamestate g, int player) {
        
        int r;
        int c;
        boolean move = false;
        
        while (move == false)

        for (r=0; r<=7; r++)
            for (c=0; c<=7; c++) 
                if (legalMove(g,player,r,c) == true)
                    move = true;
        
        return move;
    }//anyMove


    /**
     *  allMoves
     *  
     *  This method is used by the AI and UI classes to determine the moves 
     *  available. The parameter is the current GameState and the current
     *  player and returns an array of all possible moves for that player, 
     *  where each entry is a boolean value: true if a move is legal in that
     *  position, false if not.
     *
     */

    public int[][] allMoves(GameState g, int player) {
        
        int r;
        int c;
        boolean[][] moves[8][8];

        for (r=0; r<=7; r++)
            for (c=0; c<=7; c++) 
                moves[r][c] = legalMove(g,player,r,c);
        return moves;
    }//allMoves
                    
                    

    /**
     *  endOfGame
     *
     *  This method returns a boolean value indicating whether or not the game
     *  is over.  The game should end when 
     *  1) there are no spaces open on the board
     *  2) no player is capable of making a legal move. 
     *  GameState is taken as a parameter and returns -1 if it is not the end 
     *  of the game, otherwise it returns an integer indicating the winner. 
     *  If the game is a tie, endOfGame returns -2 
     *
     */

    public int endOfGame(GameState g, int player)  {
        
        int nextPlayer = (player + 1) % 2
        if ((anyMove(g,player) == true) ||
            (anymove(g,nextPlayer == true)))
  
            return -1;
        else 
            if (g.getScore(0) == g.getScore(1)) 
                return -2;
        else
            if (g.getScore(0) > g.getScore(1))
                return 0;
        else
            if (g.getScore(0) < g.getScore(1))
                return 1;
    }//endOfGame
        
                 
} // interface OthelloRules

