Package cz.matfyz.aai.fantom.clients

Source Code of cz.matfyz.aai.fantom.clients.RandomAgent

/*
   This file is part of Fantom.

    Fantom 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.

    Fantom 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 Fantom.  If not, see <http://www.gnu.org/licenses/>.
*/
package cz.matfyz.aai.fantom.clients;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import cz.matfyz.aai.fantom.client.Agent;
import cz.matfyz.aai.fantom.client.ClientRunner;
import cz.matfyz.aai.fantom.game.Actor;
import cz.matfyz.aai.fantom.game.Graph;
import cz.matfyz.aai.fantom.game.Graph.Node;
import cz.matfyz.aai.fantom.message.ClientType;
import cz.matfyz.aai.fantom.message.MessageMoveBase.ActorMove;

public class RandomAgent implements Agent {
 
  public static final String CLIENT_NAME = "RandomAgent";

  private Random random = new Random(0);
 
  private ClientType clientType;
 
  private Graph game;

  private boolean lessRandom;

  enum Mode {
    RANDOM,
    CAREFULL, // If this is a phantom, do not go next to detectives. If this is a detective, move next to a phantom.
    OPPORTUNIST // If this a detective and there is a phantom around, catch it. If this is a phantom, do not commit a suicide.
  }
 
  @Override
  public void end(ClientType winner) {
    if(winner == clientType)
      System.err.println("I've won!!");
    else
      System.err.println("I've lost :(");
  }

  @Override
  public ClientType getClientType() {
    return clientType;
  }

  public ClientType getOpponentType() {
    return getClientType().equals(ClientType.PHANTOM) ? ClientType.DETECTIVE : ClientType.PHANTOM;
  }

  @Override
  public String getName() {
    return CLIENT_NAME + " - " + clientType.toString();
  }

  @Override
  public void initialize() {
  }

  @Override
  public ActorMove[] move() {
    System.err.println("It is my turn now.");
    List<Actor> actors = game.getActors(getClientType());
    List<Actor> opponents = game.getActors(getOpponentType());

    Set<Node> usedNodes = new HashSet<Node>(); // used by actors of this client
    Set<Node> dirtyNodes = new HashSet<Node>(); // reachable in one step by one of the opponent actors
    Set<Node> opponentsNodes = new HashSet<Node>(); // occupied by one of the opponent actors

    for(Actor actor : actors) {
      if(actor.getCurrentPosition() != null)
        usedNodes.add(actor.getCurrentPosition());
    }
   
    for(Actor opponent : opponents) {
      if(opponent.getCurrentPosition() != null) {
        opponentsNodes.add(opponent.getCurrentPosition());
      }

      for(ActorMove m : opponent.getLegalMoves(game)) {
        dirtyNodes.add(m.getTargetNode());
      }
    }
   
    Mode[] consideredModes = (this.lessRandom ? new Mode[] {Mode.OPPORTUNIST, Mode.CAREFULL, Mode.RANDOM} : new Mode[] {Mode.OPPORTUNIST, Mode.RANDOM});

    if(this.lessRandom) {
      if(getClientType().equals(ClientType.DETECTIVE)) {
        // 1. Catch him, if you can.
        // 2. Block him / go after him.
        // 3. Move randomly.
        consideredModes = new Mode[] {Mode.OPPORTUNIST, Mode.CAREFULL, Mode.RANDOM};
      } else {
        // 1. Keep safe.
        // 2. Do not commit a suicide.
        // 3. Move randomly.
        consideredModes = new Mode[] {Mode.CAREFULL, Mode.OPPORTUNIST, Mode.RANDOM};
      }
    } else {
      consideredModes = new Mode[] {Mode.OPPORTUNIST, Mode.RANDOM};
    }

    List<ActorMove> moves = new ArrayList<ActorMove>();
    for(Actor actor : actors) {
      String nodeId = actor.getCurrentPosition() == null ? "null" : actor.getCurrentPosition().getId();
      System.err.printf("Actor %s is at node %s, looking for a new position\n", actor.getId(), nodeId);

      List<ActorMove> available = actor.getLegalMoves(game);
      List<ActorMove> consideredMoves = new ArrayList<ActorMove>(available.size());

      for(Mode mode : consideredModes) {
        for(ActorMove m : available) {
          Node moveTarget = m.getTargetNode();
          if(usedNodes.contains(moveTarget) && !moveTarget.equals(actor.getCurrentPosition()))
          {
            continue; //cannot go there
          }

          System.err.println("Available move to: " + moveTarget.getId());
          if(m.getTransportType() != null) {
            System.err.println(" by: " + m.getTransportType().getName());
          }

          switch(mode) {
            case RANDOM:
              consideredMoves.add(m);
              break;
            case CAREFULL:
              if(  (getClientType().equals(ClientType.DETECTIVE) && dirtyNodes.contains(moveTarget))
                ||
                (getClientType().equals(ClientType.PHANTOM) && !dirtyNodes.contains(moveTarget) && !opponentsNodes.contains(moveTarget)) ) {
                consideredMoves.add(m);
              }
              break;
            case OPPORTUNIST:
              if(  (getClientType().equals(ClientType.DETECTIVE) && opponentsNodes.contains(moveTarget))
                ||
                (getClientType().equals(ClientType.PHANTOM) && !opponentsNodes.contains(moveTarget))) {
                consideredMoves.add(m);
              }
              break;
          }
        }

        if(!consideredMoves.isEmpty()) {
          break;
        }
      }

      if(consideredMoves.size() == 0) {
        System.err.printf("Actor %s is not going anywhere\n", actor.getId());
        continue;
      }

      ActorMove move = consideredMoves.get(random.nextInt(consideredMoves.size()));
      moves.add(move);
      if(actor.getCurrentPosition() != null) {
        usedNodes.remove(actor.getCurrentPosition());
      }
      usedNodes.add(move.getTargetNode());
      System.err.printf("Actor %s is going to node %s\n", actor.getId(), move.getTargetNode().getId());
    }
    System.err.println("My turn is over.");
    return moves.toArray(new ActorMove[moves.size()]);   
  }

  public ActorMove[] place() {
    return move();
  }
 
  @Override
  public void quit() {
  }

  @Override
  public void start(Graph graph) {
    this.game = graph;
   
    System.err.println("Starting a new game");
  }

  @Override
  public void update(ActorMove[] moves) {
    /*Properties[] state = game.serialize();
    for(Properties record : state) {
      String ln = Parser.encodeProperties(record);
      System.err.println(ln);
    }
    System.err.println();*/
  }
 
  public RandomAgent(ClientType type) {
    this(type, false);
  }

  public RandomAgent(ClientType type, boolean lessRandom) {
    this.clientType = type;
    this.lessRandom = lessRandom;
  }

  public static void main(String[] args) throws Exception {
    ClientType type = ClientType.valueOf(args[0]);
    boolean lessRandom = args.length > 1 && (args[1].equals("-l") || args[1].equals("--less"));
    RandomAgent agent = new RandomAgent(type, lessRandom);
   
    ClientRunner runner = new ClientRunner(agent);
    runner.run();
  }
}
TOP

Related Classes of cz.matfyz.aai.fantom.clients.RandomAgent

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.