/* Connect 4 */
/* Referee (code fragment) */
/* requires implementation of Board b */
/* Author: Carsten Schuermann */


class ConnectFour {
    Board b; 
    Player p1;   /* p1 plays true */
    Player p2;   /* p2 plays false */

    ConnectFour (Player p1, Player p2) {
        init ();
        this.p1 = p1; this.p2 = p2;
        p1.init(true);
        p2.init(false);
    }

    void init () {
        b = new Board ();
    }

    void illegal (String s, int i) {
        System.out.println ("Illegal Move: Player " +  s + " moved to " + i);
    }

    /* Invariant: 
       Board b is ok, might be full.
       No winner yet.
    */
    int move (Boolean player) {
        b.print ();
        if (player) {System.out.println (p1.name() + " please make your move");}
        else {System.out.println (p2.name() + " please make your move");}

        if (b.tie ()) { System.out.println ("Tie!"); return 0;}
        else {
            if (player) {
                int m = p1.move ();
                try {b.insert (m, player); }
                catch (IllegalMove exn) {this.illegal (p1.name(), exn.i); return 2;}
                if (b.win (player)) {System.out.println ("Winner:" + p1.name()); return 1;}
                p2.inform (m);
            }
            else {
                int m = p2.move ();
                try {b.insert (m, player);}
                catch (IllegalMove exn) {this.illegal (p2.name(), exn.i); return 1;}
                if (b.win (player)) {System.out.println ("Winner:" + p1.name()); return 2;}
                p1.inform (m);
            };
            return (move (! player));
        }
    }
    
    int run () {
        this.init ();
        int result = this.move (true);
        b.print ();
        return (result);        
    }