/**
  * %W %E% 15-212: Fundamentals of Computer Science II, Spring 1998
  *
  * Copyright (c) 1998 Carnegie Mellon University
  *
  **/

/**
  * See the project handout for a description of what this file
  * does. In this comment, you will find information on the specific
  * protocols that the three methods must follow, and exactly what
  * they must do.
  *  
  * The implementation of the Player interface is your playing
  * strategy. Your player should take the information kept in State
  * and ExtraState (which is a member of State) and decide what to
  * do. The two files you need to understand to do this correctly are
  * Turn.java and State.java.
  *
  * This is an abstract class, so it has no constructor, and it should
  * not keep any variables itself. Any variables that you want to keep
  * should be placed in ExtraState, and they will be recieved as a
  * parameter when the function is next called.
  *
  * These functions are non-trivial to design. The first thing that
  * you should do is write a quick and dirty algorithm for whereDraw()
  * and whatPlay() as described in the project handout. Then, write a
  * countUp() function that find matches. This function doesn't have
  * to be that fast because it's run only once a game. HOWEVER, you
  * may find it useful to run countUp() from whereDraw() or
  * whatPlay(), in which case you will need to make sure that it runs
  * reasonably fast.
  *
  * None of the functions in this class should take more than a few
  * seconds to run. You will not find the perfect solution: they are
  * all NP-Complete problems.
  *
  * Guaranteed not to change.
  *
  * @author Salvatore Domenick Desiano
  * @version 1.15, 04/25/98 
  *
  **/

public abstract interface Player
{
  /** 
    * This function decides whether to draw from the pile or from the
    * deck. Using the information in State (and ExtraState), it should
    * return a Turn. For your convienience, Turn.java provides a few
    * pre-constructed turns for you to use. In general, you will be
    * returning either "Turn.drawPileTurn" or "Turn.drawDeckTurn".
    *
    * There are two special cases that you need to deal with. First,
    * if state.gameStage is State.firstCard, meaning that the other
    * player has just finished dealing and that you have the option to
    * take the first upcard, you must either draw from the pile
    * (Turn.drawPileTurn) or pass (Turn.passFirstCard, see rule 14 in
    * the project handout). Second, if state.gameStage is
    * State.passedFirstCard, this means that the other player has
    * passed on the first card, and you can either pick up the card
    * from the pile (Turn.drawPileTurn), or pass back to the other
    * player (Turn.passFirstCard).
    *
    * Note that your hand will always have 10 cards when this method is
    * called.
    *
    **/
  public Turn whereDraw ( State state );

  /** 
    * This function decides which card to drop. It is generally called
    * immediately after whereDraw(). In the case where whereDraw() has
    * passed the first card, this method will not be
    * called. Therefore, your hand will always have *11* cards when
    * this method is called.
    *
    * This function returns a Turn with the number member set to the
    * index of the card you want to drop (according to the ordering in
    * state.hand). The "me" member is not set by the Player, nor is
    * the "card" member. The only other member you need to set is the
    * "turnType", which must be one of the following:
    *
    * Turn.discard    Simple discard
    * Turn.gin        Discarding and calling gin (no cards out of matches)
    * Turn.knock      Discarding and knocking (total value of cards out of
    *                 matches is less than the value of the knocking card)
    *	    
    **/
  public Turn whatPlay ( State state );

  /** 
    * This function determines how best to arrange the cards in your
    * hand into matches, and calculates the total value of the cards not
    * matched.
    * 
    * This is a simple task that is hard to do. Once you have determined
    * the best arrangement, you should report it in the following way:
    * 
    * 1) Organize the cards in state.hand so that the matches are all
    *    grouped together.
    * 
    * 2) Set state.extra.matchDividers to indicate the points at which
    *    the matches split. For example, if your hand is broken into
    *    matches of 3, 3, and 4, you should create
    *    state.extra.matchDividers = new int[]{3,6}. If you have cards out
    *    of match, you should divide each of them into seperate
    *    matches. So, if you have a matches of 3, 4, and 3 loose cards, you
    *    should create state.extra.matchDividers = new int[]{3,7,8,9}. Of
    *    course, you could arrange the loose ones in front and create
    *    {1,2,3,8}.
    *
    * 3) Return the total value of the cards not in matches. If you
    *    have gin, you would return 0.
    *
    **/
  public int countUp ( State state );
}
