Package soc.qase.ai.waypoint

Source Code of soc.qase.ai.waypoint.WaypointMapGenerator

//--------------------------------------------------
// Name:      WaypointMapGenerator.java
// Author:      Bernard.Gorman@computing.dcu.ie
//--------------------------------------------------

package soc.qase.ai.waypoint;

import java.util.Vector;

import soc.qase.ai.kmeans.KMeansCalc;
import soc.qase.ai.kmeans.KMeansData;
import soc.qase.file.dm2.DM2Parser;
import soc.qase.state.Entity;
import soc.qase.state.World;
import soc.qase.tools.vecmath.Vector3f;

/*-------------------------------------------------------------------*/
/**  The WaypointMapGenerator class allows a WaypointMap to be automatically
*  generated from a DM2 recording, using techniques explained in our paper.
*  The set of all player positions are first read from the file, and are
*  then clustered to produce a set of n Waypoints. Optionally, the locations
*  at which items were collected in the demo are used to hold certain cluster
*  centroids constant during this process, ensuring that nodes will be allocated
*  to the positions at which items reside in the map. Edges are drawn between
*  pairs of waypoints wherever the player was observed to move directly from
*  one to the other. Finally, the Waypoints at which items reside are marked as
*  such. All the user need do to create a full navigation map, therefore, is
*  record himself running around the given level, collecting any necessary
*  items, and supply the DM2 file to the WaypointMapGenerator class.
@see soc.qase.file.dm2.DM2Parser
@see soc.qase.ai.kmeans.KMeansCalc
@see Waypoint
@see WaypointItem
@see WaypointMap */
/*-------------------------------------------------------------------*/
public class WaypointMapGenerator
{
/*-------------------------------------------------------------------*/
/**  Generate and return a WaypointMap by analysing a recorded DM2 demo.
*  This method also records the positions at which items were collected
*  in the demo, and holds these locations constant through the clustering
*  process.
@param dm2File filename of the DM2 demo to analyse
@param fNumNodes the number of nodes to generate for the WaypointMap.
*  If this number is less than 1, it is treated as a percentage of the
*  total number of observed player positions. If it is 1 or greater, it
*  is treated as an absolute number of nodes to generate.
@return the resulting WaypointMap */
/*-------------------------------------------------------------------*/
  public static WaypointMap generate(String dm2File, float fNumNodes)
  {
    int numNodes = 0;

    World world = null;
    WaypointMap wpMap = new WaypointMap();
    DM2Parser dm2p = new DM2Parser(dm2File);

    Vector isAlive = new Vector();
    Vector playerPos = new Vector();
    Vector waypointItems = new Vector();
    Vector pickupPos = new Vector();

    Vector3f currentPos = null, lastPos = null, itemPos = null;

    while((world = dm2p.getNextWorld()) != null)
    {
      currentPos = new Vector3f(world.getPlayer().getPlayerMove().getOrigin());

      if(lastPos == null || !currentPos.equals(lastPos))
      {
        playerPos.add(currentPos);
        isAlive.add(new Boolean(world.getPlayer().isAlive()));

        if(world.getPickupEntityIndex() != -1 && !duplicateItemNode(pickupPos, (itemPos = new Vector3f(world.getPickupEntity().getOrigin()))))
        {
          pickupPos.add(itemPos);
          waypointItems.add(world.getPickupEntity());
        }
      }

      lastPos = currentPos;
    }

    Vector3f[] playerPos3f = (Vector3f[])playerPos.toArray(new Vector3f[0]);
    Vector3f[] pickupPos3f = (Vector3f[])pickupPos.toArray(new Vector3f[0]);

    fNumNodes = Math.abs(fNumNodes);
    numNodes = Math.min(Math.round((fNumNodes < 1 ? fNumNodes * playerPos3f.length : fNumNodes)), playerPos3f.length);

    KMeansData kmResults = KMeansCalc.doKMeans(numNodes, playerPos3f, pickupPos3f);

    wpMap.addNode(kmResults.centroids);

    for(int i = 1; i < kmResults.clusterID.length; i++)
    {
      if(kmResults.clusterID[i] != kmResults.clusterID[i-1] && ((Boolean)isAlive.elementAt(i-1)).booleanValue())
        wpMap.addEdge(kmResults.clusterID[i-1], kmResults.clusterID[i], false);
    }

    wpMap.markItemNodes(kmResults.anchorClusterID, (Entity[])waypointItems.toArray(new Entity[0]), true);

    wpMap.lockMap();
    return wpMap;
  }

  private static boolean duplicateItemNode(Vector itemNodes, Vector3f itemPos)
  {
    for(int i = 0; i < itemNodes.size(); i++)
    {
      if(itemPos.equals((Vector3f)itemNodes.elementAt(i)))
        return true;
    }

    return false;
  }
}
TOP

Related Classes of soc.qase.ai.waypoint.WaypointMapGenerator

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.