Package tud.gamecontroller.players

Source Code of tud.gamecontroller.players.HumanPlayer

/*
    Copyright (C) 2010 Stephan Schiffel <stephan.schiffel@gmx.de>
                  2010 Nicolas JEAN <njean42@gmail.com>

    This file is part of GameController.

    GameController is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    GameController is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GameController.  If not, see <http://www.gnu.org/licenses/>.
*/

package tud.gamecontroller.players;

import java.util.ArrayList;
import java.util.List;

import tud.gamecontroller.ConnectionEstablishedNotifier;
import tud.gamecontroller.GDLVersion;
import tud.gamecontroller.auxiliary.ChangeableBoolean;
import tud.gamecontroller.game.MoveInterface;
import tud.gamecontroller.game.RoleInterface;
import tud.gamecontroller.game.RunnableMatchInterface;
import tud.gamecontroller.game.StateInterface;
import tud.gamecontroller.term.TermInterface;


public class HumanPlayer<TermType extends TermInterface, StateType extends StateInterface<TermType, ? extends StateType>>
    extends LocalPlayer<TermType, StateType> {
 
  protected List<? extends MoveInterface<TermType>> currentLegalMoves;
  protected boolean quickConfirm;
  protected MoveInterface<TermType> move;
 
  // synchronisers
  protected ChangeableBoolean confirmed;
  protected ChangeableBoolean legalMovesAvailable;
 
  private long messageReceiveTime;
 
  public HumanPlayer(String name) {
    super(name, GDLVersion.v2);
    confirmed = new ChangeableBoolean(false);
    currentLegalMoves = null;
    logger.info("HumanPlayer("+name+")");
    legalMovesAvailable = new ChangeableBoolean(false);
    quickConfirm = false;
    move = null;
  }
 
  public MoveInterface<TermType> getMove() {
    return move;
  }

  protected void waitForConfirmed(long timeout) {
    logger.info("waiting for a confirm from " + name + " ...");
    long endTime = System.currentTimeMillis() + timeout;
    long timeLeft = timeout;
    try {
      synchronized (confirmed) {
        while(!confirmed.isTrue() && timeLeft>0) {
          confirmed.wait(timeLeft);
          timeLeft = endTime - System.currentTimeMillis();
        }
      }
    } catch (InterruptedException e) {
      logger.severe("InterruptedException: "+e);
    }
    if(confirmed.isTrue()) {
      logger.info("move was confirmed by " + name);
    }else{
      logger.info("time ran out for " + name);
    }
  }
 
  @Override
  public void gameStart(RunnableMatchInterface<TermType, StateType> match, RoleInterface<TermType> role, ConnectionEstablishedNotifier notifier) {
    messageReceiveTime = System.currentTimeMillis();
    super.gameStart(match, role, notifier);
    computeLegalMoves();
    waitForConfirmed(messageReceiveTime + match.getStartclock()*1000 - 100 - System.currentTimeMillis());
  }

  @Override
  public MoveInterface<TermType> gamePlay(Object seesTerms, ConnectionEstablishedNotifier notifier) {
    messageReceiveTime = System.currentTimeMillis();
    return super.gamePlay(seesTerms, notifier);
  }

  @Override
  protected MoveInterface<TermType> getNextMove() {
    if(getCurrentStep() != 1) {
      computeLegalMoves();
    }
    waitForConfirmed(messageReceiveTime + match.getPlayclock()*1000 - 100 - System.currentTimeMillis());
    synchronized (legalMovesAvailable) {
      legalMovesAvailable.setFalse();
    }
    return move;
  }

  private void computeLegalMoves() {
    synchronized (legalMovesAvailable) {
      assert(!legalMovesAvailable.isTrue()); // otherwise we could forget an already submitted move
      synchronized (confirmed) {
        confirmed.setFalse();
        if (getGdlVersion() == GDLVersion.v1) { // Regular GDL
          currentLegalMoves = new ArrayList<MoveInterface<TermType>>(currentState.getLegalMoves(role));
        } else { // GDL-II
          currentLegalMoves = new ArrayList<MoveInterface<TermType>>(statesTracker.computeLegalMoves());
        }
       
        logger.info("new currentLegalMoves: "+currentLegalMoves);
        move = currentLegalMoves.iterator().next(); // sets default move for our player, in case he or she doesn't choose one
        if(quickConfirm && currentLegalMoves.size() == 1) {
          logger.info("quick confirming move: " + move);
          confirmed.setTrue();
          confirmed.notifyAll();
        }else{
          legalMovesAvailable.setTrue();
          logger.info("legalMovesAvailable set to True");
        }
      }
    }
  }

  public List<? extends MoveInterface<TermType>> getLegalMoves() {
    synchronized (legalMovesAvailable) {
      if (legalMovesAvailable.isTrue()) {
        return currentLegalMoves;
      } else {
        return null; // error value meaning there are no available moves at the moment
      }
    }
  }
 
  public boolean setMove(MoveInterface<TermType> move, int stepNumber) {
    logger.info("setMove("+move+", "+stepNumber+")");
    if (stepNumber == getCurrentStep()) {
      this.move = move;
      return true;
    } else {
      logger.warning("The server asks us to setMove() for step "+stepNumber+", but we are in step "+getCurrentStep());
      return false; // notifying the action cannot be performed
    }
  }
 
  public boolean confirm(int stepNumber) {
    logger.info("confirm("+stepNumber+") - currentStepNumber="+getCurrentStep());
    synchronized(confirmed) {
      if (stepNumber == getCurrentStep() && !confirmed.isTrue()) {
        confirmed.setTrue();
        confirmed.notifyAll();
        return true;
      } else {
        logger.warning("wrong step or move was already confirmed!");
        return false;
      }
    }
  }

  public boolean hasConfirmed(int stepNumber) {
    return stepNumber == getCurrentStep() && confirmed.isTrue();
  }

  public boolean getQuickConfirm() {
    return quickConfirm;
  }

  public void setQuickConfirm(boolean quickConfirm) {
    this.quickConfirm = quickConfirm;
  }
 
}
TOP

Related Classes of tud.gamecontroller.players.HumanPlayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.