Package com.cburch.logisim.tools.move

Source Code of com.cburch.logisim.tools.move.SearchNode

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.tools.move;

import com.cburch.logisim.data.Direction;
import com.cburch.logisim.data.Location;

class SearchNode implements Comparable<SearchNode> {
  private static final int CROSSING_PENALTY = 20;
  private static final int TURN_PENALTY = 50;
 
  private final Location loc;
  private final Direction dir;
  private ConnectionData conn;
  private final Location dest;
  private int dist;
  private int heur;
  private boolean extendsWire;
  private SearchNode prev;
 
  public SearchNode(ConnectionData conn, Location src,
      Direction srcDir, Location dst) {
    this(src, srcDir, conn, dst, 0, srcDir != null, null);
  }
 
  private SearchNode(Location loc, Direction dir,
      ConnectionData conn, Location dest, int dist, boolean extendsWire,
      SearchNode prev) {
    this.loc = loc;
    this.dir = dir;
    this.conn = conn;
    this.dest = dest;
    this.dist = dist;
    this.heur = dist + this.getHeuristic();
    this.extendsWire = extendsWire;
    this.prev = prev;
  }
 
  private int getHeuristic() {
    Location cur = loc;
    Location dst = dest;
    Direction curDir = dir;
    int dx = dst.getX() - cur.getX();
    int dy = dst.getY() - cur.getY();
    int ret = -1;
    if (extendsWire) {
      ret = -1;
      if (curDir == Direction.EAST) {
        if (dx > 0) ret = dx / 10 * 9 + Math.abs(dy);
      } else if (curDir == Direction.WEST) {
        if (dx < 0) ret = -dx / 10 * 9 + Math.abs(dy);
      } else if (curDir == Direction.SOUTH) {
        if (dy > 0) ret = Math.abs(dx) + dy / 10 * 9;
      } else if (curDir == Direction.NORTH) {
        if (dy < 0) ret = Math.abs(dx) - dy / 10 * 9;
      }
    }
    if (ret < 0) {
      ret = Math.abs(dx) + Math.abs(dy);
    }
    boolean penalizeDoubleTurn = false;
    if (curDir == Direction.EAST) {
      penalizeDoubleTurn = dx < 0;
    } else if (curDir == Direction.WEST) {
      penalizeDoubleTurn = dx > 0;
    } else if (curDir == Direction.NORTH) {
      penalizeDoubleTurn = dy > 0;
    } else if (curDir == Direction.SOUTH) {
      penalizeDoubleTurn = dy < 0;
    } else if (curDir == null) {
      if (dx != 0 || dy != 0) ret += TURN_PENALTY;
    }
    if (penalizeDoubleTurn) {
      ret += 2 * TURN_PENALTY;
    } else if (dx != 0 && dy != 0) {
      ret += TURN_PENALTY;
    }
    return ret;
  }
 
  public SearchNode next(Direction moveDir, boolean crossing) {
    int newDist = dist;
    Direction connDir = conn.getDirection();
    Location nextLoc = loc.translate(moveDir, 10);
    boolean exWire = extendsWire && moveDir == connDir;
    if (exWire) {
      newDist += 9;
    } else {
      newDist += 10;
    }
    if (crossing) newDist += CROSSING_PENALTY;
    if (moveDir != dir) newDist += TURN_PENALTY;
    if (nextLoc.getX() < 0 || nextLoc.getY() < 0) {
      return null;
    } else {
      return new SearchNode(nextLoc, moveDir, conn, dest,
          newDist, exWire, this);
    }
  }
 
  public boolean isStart() {
    return prev == null;
  }
 
  public boolean isDestination() {
    return dest.equals(loc);
  }
 
  public SearchNode getPrevious() {
    return prev;
  }
 
  public int getDistance() {
    return dist;
  }
 
  public Location getLocation() {
    return loc;
  }
 
  public Direction getDirection() {
    return dir;
  }
 
  public int getHeuristicValue() {
    return heur;
  }
 
  public Location getDestination() {
    return dest;
  }
 
  public boolean isExtendingWire() {
    return extendsWire;
  }
 
  public ConnectionData getConnection() {
    return conn;
  }
 
  @Override
  public boolean equals(Object other) {
    if (other instanceof SearchNode) {
      SearchNode o = (SearchNode) other;
      return this.loc.equals(o.loc)
        && (this.dir == null ? o.dir == null : this.dir.equals(o.dir))
        && this.dest.equals(o.dest);
    } else {
      return false;
    }
  }
 
  @Override
  public int hashCode() {
    int dirHash = dir == null ? 0 : dir.hashCode();
    return ((loc.hashCode() * 31) + dirHash) * 31 + dest.hashCode();
  }
 
  public int compareTo(SearchNode o) {
    int ret = this.heur - o.heur;
   
    if (ret == 0) {
      return this.hashCode() - o.hashCode();
    } else {
      return ret;
    }
  }
 
  @Override
  public String toString() {
    return loc + "/" + (dir == null ? "null" : dir.toString())
      + (extendsWire ? "+" : "-")
      + "/" + dest + ":" + dist + "+" + (heur-dist);
  }
}
TOP

Related Classes of com.cburch.logisim.tools.move.SearchNode

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.