huntforgold-commit Mailing List for Hunt for Gold (Page 2)
Status: Alpha
Brought to you by:
jews
This list is closed, nobody may subscribe to it.
2002 |
Jan
|
Feb
|
Mar
|
Apr
(19) |
May
(47) |
Jun
(29) |
Jul
(33) |
Aug
(56) |
Sep
(111) |
Oct
(120) |
Nov
(104) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(98) |
Feb
(51) |
Mar
(18) |
Apr
|
May
(2) |
Jun
(26) |
Jul
(58) |
Aug
(54) |
Sep
(43) |
Oct
(16) |
Nov
(22) |
Dec
(36) |
2004 |
Jan
(90) |
Feb
(18) |
Mar
(13) |
Apr
(52) |
May
(29) |
Jun
(26) |
Jul
(37) |
Aug
(1) |
Sep
(2) |
Oct
(3) |
Nov
(1) |
Dec
|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
|
2007 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2011 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Jesper P. <je...@us...> - 2004-07-06 18:31:18
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/gui In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1395 Added Files: DaughterLostFightGUI.java JailGUI.java Log Message: Initial import --- NEW FILE: DaughterLostFightGUI.java --- //--------------------------------------------------------------------------------- // $Id: DaughterLostFightGUI.java,v 1.1 2004/07/06 18:31:09 jews Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.gui; import net.sourceforge.huntforgold.graphics.GameScreen; import net.sourceforge.huntforgold.graphics.renders.BackgroundRenderer; import net.sourceforge.huntforgold.graphics.renders.BorderedTextBox; import net.sourceforge.huntforgold.graphics.renders.ContinueBox; import net.sourceforge.huntforgold.graphics.renders.ImageRenderer; import net.sourceforge.huntforgold.logic.GameState; import net.sourceforge.huntforgold.util.ResourceManager; import net.sourceforge.huntforgold.xml.Daughter; import java.awt.Color; import org.apache.log4j.Logger; /** * Renders the governor info screen */ public class DaughterLostFightGUI extends AbstractGUI { /** The logger */ private static Logger log = Logger.getLogger(GovernorTitleGUI.class); /** Daughter */ private final String battle = "daughterlostfight.battle"; /** Daughter x offset */ private final String battleX = "daughterlostfight.battle.x"; /** Daughter y offset */ private final String battleY = "daughterlostfight.battle.y"; /** * Creates a new DaughterLostFightGUI. * @param gs The gamestate associated with this screen. */ public DaughterLostFightGUI(GameState gs) { super(gs); } /** * Set options * @param daughter The daughter */ public void setOptions(Daughter daughter) { subRenders.clear(); subRenders.add(new BackgroundRenderer()); subRenders.add(new ImageRenderer(ResourceManager.getInteger(battleX), ResourceManager.getInteger(battleY), battle)); BorderedTextBox text = new BorderedTextBox(100, 40, "You lost the fight against " + daughter.getFiancee() + " and " + daughter.getName() + " cheers for her hero.", Color.black, GameScreen.getGameScreen().getWidth() - 200); subRenders.add(text); ContinueBox cb = new ContinueBox(gs, 550, 500); subRenders.add(cb); } } --- NEW FILE: JailGUI.java --- //--------------------------------------------------------------------------------- // $Id: JailGUI.java,v 1.1 2004/07/06 18:31:09 jews Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.gui; import net.sourceforge.huntforgold.graphics.GameScreen; import net.sourceforge.huntforgold.graphics.renders.BackgroundRenderer; import net.sourceforge.huntforgold.graphics.renders.BorderedTextBox; import net.sourceforge.huntforgold.graphics.renders.ContinueBox; import net.sourceforge.huntforgold.graphics.renders.ImageRenderer; import net.sourceforge.huntforgold.model.Time; import net.sourceforge.huntforgold.logic.GameState; import net.sourceforge.huntforgold.util.ResourceManager; import java.awt.Color; import org.apache.log4j.Logger; /** * Renders the jail */ public class JailGUI extends AbstractGUI { /** The logger */ private static Logger log = Logger.getLogger(JailGUI.class); /** x offset */ private final String x = "jail.jail.x"; /** y offset */ private final String y = "jail.jail.y"; /** The image of the jail */ private final String jail = "jail.jail"; /** * Creates a jail gui. * @param gs The gamestate associated with this screen. */ public JailGUI(GameState gs) { super(gs); } /** * Set options */ public void setOptions() { subRenders.clear(); subRenders.add(new BackgroundRenderer()); subRenders.add(new ImageRenderer(ResourceManager.getInteger(x), ResourceManager.getInteger(y), jail)); BorderedTextBox text = new BorderedTextBox(100, 40, "Your men flee from the battle in panic and you " + "are captured. Months pass in the jail, but " + "luckily some of your old crew finds you. " + "They trade you for some goods and agrees to " + "take you back as captain.", Color.black, GameScreen.getGameScreen().getWidth() - 200); subRenders.add(text); Time time = Time.getTime(); BorderedTextBox year = new BorderedTextBox(100, 450, time.getMonthAsString() + " " + time.getYear(), GameScreen.getGameScreen().getWidth() - 200); subRenders.add(year); ContinueBox continueBox = new ContinueBox(gs, 400, 450); subRenders.add(continueBox); } } |
From: Jesper P. <je...@us...> - 2004-07-06 18:30:24
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/logic In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1182 Modified Files: FencingState.java Log Message: Added support for losing a fight (player) Index: FencingState.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/logic/FencingState.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- FencingState.java 28 Jun 2004 18:24:25 -0000 1.10 +++ FencingState.java 6 Jul 2004 18:30:15 -0000 1.11 @@ -225,7 +225,16 @@ game.setCurrentState(DAUGHTER_MARRIAGE); } } - + + if (pf.getHitPoints() == 0) { + if (mode == SHIP) { + game.setCurrentState(JAIL); + } else if (mode == TOWN) { + game.setCurrentState(JAIL); + } else if (mode == MARRIAGE) { + game.setCurrentState(DAUGHTER_LOST_FIGHT); + } + } } /** |
From: Jesper P. <je...@us...> - 2004-07-06 18:29:15
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/logic In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv878 Modified Files: GameState.java Log Message: Added DAUGHTER_LOST_FIGHT and JAIL Index: GameState.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/logic/GameState.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- GameState.java 29 May 2004 09:14:45 -0000 1.30 +++ GameState.java 6 Jul 2004 18:29:05 -0000 1.31 @@ -116,6 +116,9 @@ /** Daughter fiancee state */ public static final String DAUGHTER_FIANCEE = "daughterFiancee"; + /** Daughter lost fight state */ + public static final String DAUGHTER_LOST_FIGHT = "daughterLostFight"; + /** Bank state */ public static final String BANK = "bank"; @@ -218,6 +221,9 @@ /** Insert governor */ public static final String INSERT_GOVERNOR = "insertGovernor"; + /** Jail */ + public static final String JAIL = "jail"; + /** * Creates a new GameState. * @param name the name of the state. |
From: Jesper P. <je...@us...> - 2004-07-06 18:28:48
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/logic In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv734 Added Files: DaughterLostFightState.java JailState.java Log Message: Initial import --- NEW FILE: DaughterLostFightState.java --- //--------------------------------------------------------------------------------- // $Id: DaughterLostFightState.java,v 1.1 2004/07/06 18:28:39 jews Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.logic; import net.sourceforge.huntforgold.gui.DaughterLostFightGUI; import net.sourceforge.huntforgold.xml.Daughter; import net.sourceforge.huntforgold.xml.Town; import org.apache.log4j.Logger; /** * Lost fight over governor's daughter */ public class DaughterLostFightState extends GameState { /** The logger */ private static Logger log = Logger.getLogger(DaughterLostFightState.class); /** * Creates a new DaughterLostFightState */ public DaughterLostFightState() { super(DAUGHTER_LOST_FIGHT); setRenderer(new DaughterLostFightGUI(this)); } /** * Called whenever the game enters this state. */ public void enter() { keyboard.setStickyMode(true); Town town = (Town)getValue(); Daughter daughter = (Daughter)town.getDaughter(); ((DaughterLostFightGUI)getRenderer()).setOptions(daughter); } /** * Goes to the next state * @param state The next state */ public void nextState(int state) { if (state == 0) { game.setCurrentState(INSIDE_TOWN); } else { log.fatal("Unknown option: " + state); System.exit(1); } } /** * Called whenever the game leaves this state. */ public void leave() { keyboard.setStickyMode(false); } } --- NEW FILE: JailState.java --- //--------------------------------------------------------------------------------- // $Id: JailState.java,v 1.1 2004/07/06 18:28:39 jews Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.logic; import net.sourceforge.huntforgold.graphics.renders.ShipRenderer; import net.sourceforge.huntforgold.gui.JailGUI; import net.sourceforge.huntforgold.model.Fleet; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.model.Ship; import net.sourceforge.huntforgold.model.ShipFactory; import net.sourceforge.huntforgold.model.Time; import net.sourceforge.huntforgold.model.Town; import net.sourceforge.huntforgold.model.World; import org.apache.log4j.Logger; /** * Jail */ public class JailState extends GameState { /** The logger */ private static Logger log = Logger.getLogger(JailState.class); /** * Creates a new JailState */ public JailState() { super(JAIL); setRenderer(new JailGUI(this)); } /** * Called whenever the game enters this state. */ public void enter() { keyboard.setStickyMode(true); player.decreaseGamePoints(10); Time time = Time.getTime(); time.increaseMonth(3); World world = World.getWorld(); ShipFactory shipFactory = ShipFactory.getShipFactory(); ShipRenderer shipRenderer = ShipRenderer.getShipRenderer(); Fleet fleet = player.getFleet(); Position position = fleet.getPosition(); double direction = fleet.getDirection(); boolean fromSea = player.isFromSea(); Town town = player.getCurrentTown(); Position crewPosition = player.getCrewPosition(); Ship[] ships = fleet.getShips(); for (int i = 0; i < ships.length; i++) { world.removeShip(ships[i]); fleet.removeShip(ships[i]); } Ship ship = shipFactory.createShip(7, player.getNationality()); ship.setDirection(direction); ship.setSails(Ship.FULL_SAILS); ship.setCrew(0); ship.setCannons(0); world.insertShip(ship, position); shipRenderer.setShip(ship); player.getFleet().addShip(ship); player.setCrewNumber(20); player.setCannons(4); player.setTavernVisited(false); player.setGovernorVisited(false); player.setBrothelVisited(false); player.setFromSea(fromSea); player.setCurrentTown(town); player.setCrewPosition(crewPosition); ((JailGUI)getRenderer()).setOptions(); } /** * Goes to the next state * @param state The next state */ public void nextState(int state) { if (state == 0) { if (player.isAttackShip()) { game.setCurrentState(SAILING); } else { game.setCurrentState(INSIDE_TOWN); } } else { log.fatal("Unknown option: " + state); System.exit(1); } } /** * Called whenever the game leaves this state. */ public void leave() { keyboard.setStickyMode(false); } } |
From: Mads P. H. <ma...@us...> - 2004-07-01 09:21:33
|
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12233 Modified Files: EditableRoute.java Log Message: Removed dos chars Index: EditableRoute.java =================================================================== RCS file: /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/util/EditableRoute.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- EditableRoute.java 1 Jul 2004 08:36:02 -0000 1.1 +++ EditableRoute.java 1 Jul 2004 09:21:23 -0000 1.2 @@ -1,105 +1,105 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- - -package net.sourceforge.huntforgold.util; - -import java.util.LinkedList; - -import net.sourceforge.huntforgold.model.path.Node; -import net.sourceforge.huntforgold.model.path.Route; - -/** - * This class is used to generate routes, i.e. it is possible to - * set otherwise private attributes - */ -public class EditableRoute { - - /** - * list of nodes - */ - private LinkedList nodes = new LinkedList(); - - /** - * name of the route - */ - private String name; - - /** - * revesible - */ - private boolean reversible; - - /** - * Constructor - * - */ - public EditableRoute() { - } - /** - * setReversible - * @param reversible Indication of reversible - */ - public void setReversible(boolean reversible) { - this.reversible = reversible; - } - - /** - * isReversible - * @return reversible Indication of reversible - */ - public boolean isReversible() { - return reversible; - } - - /** - * setName - * @param name the name of the route - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return name - */ - public String getName() { - return name; - } - - /** - * Create a route from this EditableRoute - * @return route - */ - public Route createRoute() { - Object [] tempNodes = nodes.toArray(); - Node[] finalNodes = new Node [tempNodes.length]; - for (int i = 0; i < tempNodes.length; i++) { - finalNodes[i] = (Node) tempNodes[i]; - } - return new Route(name, finalNodes, reversible); - } - - /** - * Add the next node - * @param node Node to add - */ - public void addNode(Node node) { - nodes.addLast(node); - String newName = ((Node)nodes.getFirst()).getName() + - " - " + - ((Node)nodes.getLast()).getName(); - setName(newName); - } - - /** - * Get the current number of nodes in the route - * @return the current number of nodes in the route - */ - public int getNodeCount() { - return nodes.size(); - } -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- + +package net.sourceforge.huntforgold.util; + +import java.util.LinkedList; + +import net.sourceforge.huntforgold.model.path.Node; +import net.sourceforge.huntforgold.model.path.Route; + +/** + * This class is used to generate routes, i.e. it is possible to + * set otherwise private attributes + */ +public class EditableRoute { + + /** + * list of nodes + */ + private LinkedList nodes = new LinkedList(); + + /** + * name of the route + */ + private String name; + + /** + * revesible + */ + private boolean reversible; + + /** + * Constructor + * + */ + public EditableRoute() { + } + /** + * setReversible + * @param reversible Indication of reversible + */ + public void setReversible(boolean reversible) { + this.reversible = reversible; + } + + /** + * isReversible + * @return reversible Indication of reversible + */ + public boolean isReversible() { + return reversible; + } + + /** + * setName + * @param name the name of the route + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return name + */ + public String getName() { + return name; + } + + /** + * Create a route from this EditableRoute + * @return route + */ + public Route createRoute() { + Object [] tempNodes = nodes.toArray(); + Node[] finalNodes = new Node [tempNodes.length]; + for (int i = 0; i < tempNodes.length; i++) { + finalNodes[i] = (Node) tempNodes[i]; + } + return new Route(name, finalNodes, reversible); + } + + /** + * Add the next node + * @param node Node to add + */ + public void addNode(Node node) { + nodes.addLast(node); + String newName = ((Node)nodes.getFirst()).getName() + + " - " + + ((Node)nodes.getLast()).getName(); + setName(newName); + } + + /** + * Get the current number of nodes in the route + * @return the current number of nodes in the route + */ + public int getNodeCount() { + return nodes.size(); + } +} |
From: Mads P. H. <ma...@us...> - 2004-07-01 09:10:44
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10327 Modified Files: Node.java Routable.java Route.java RouteManager.java Log Message: Removed dos chars Index: Node.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/Node.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Node.java 1 Jul 2004 06:27:52 -0000 1.1 +++ Node.java 1 Jul 2004 09:10:31 -0000 1.2 @@ -1,68 +1,68 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- - -package net.sourceforge.huntforgold.model.path; - -import net.sourceforge.huntforgold.model.Position; - -/** - * Models a node, i.e. a destination point in travel path - */ -public class Node { - - /** - * the position of this node in the world - */ - private Position position; - - /** - * the identifying name of this node - */ - private String name; - - /** - * Construct a node with the given characteristics - * @param name the name of the node - * @param position the position this node is at - */ - public Node(String name, Position position) { - setName(name); - setPosition(position); - } - /** - * Set the identifying name of the node - * @param name the name to give the node - */ - private void setName(String name) { - this.name = name; - } - - /** - * Get the name of the node - * @return the name of the node - */ - public String getName() { - return name; - } - - /** - * set the position of the node - * @param position the position this node is at - */ - private void setPosition(Position position) { - this.position = position; - } - - /** - * get the position of the node - * @return the position of the node - */ - public Position getPosition() { - return position; - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- + +package net.sourceforge.huntforgold.model.path; + +import net.sourceforge.huntforgold.model.Position; + +/** + * Models a node, i.e. a destination point in travel path + */ +public class Node { + + /** + * the position of this node in the world + */ + private Position position; + + /** + * the identifying name of this node + */ + private String name; + + /** + * Construct a node with the given characteristics + * @param name the name of the node + * @param position the position this node is at + */ + public Node(String name, Position position) { + setName(name); + setPosition(position); + } + /** + * Set the identifying name of the node + * @param name the name to give the node + */ + private void setName(String name) { + this.name = name; + } + + /** + * Get the name of the node + * @return the name of the node + */ + public String getName() { + return name; + } + + /** + * set the position of the node + * @param position the position this node is at + */ + private void setPosition(Position position) { + this.position = position; + } + + /** + * get the position of the node + * @return the position of the node + */ + public Position getPosition() { + return position; + } + +} Index: Routable.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/Routable.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Routable.java 1 Jul 2004 06:27:52 -0000 1.1 +++ Routable.java 1 Jul 2004 09:10:32 -0000 1.2 @@ -1,164 +1,164 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- - -package net.sourceforge.huntforgold.model.path; - -import net.sourceforge.huntforgold.model.Moveable; -import net.sourceforge.huntforgold.model.Position; -import net.sourceforge.huntforgold.util.Distance; - -/** - * This class is an abstract implementation of the Movable interface. - * It adds the notion of the Movable to move along a Route - */ -public abstract class Routable implements Moveable { - - /** - * The route that this routable is following - */ - private String routeName; - - /** - * The index of the next node in the route the routable is following - */ - private int nextNodeIndex; - - /** - * indication of which way we are traveling, from node 0 to node n or - * back again from node n to node 0 - */ - private boolean forward = true; - - /** - * simple cache of the number of nodes in the route - */ - private int nodesInRoute; - - /** - * RouteManager - */ - private static RouteManager routeManager = RouteManager.getRouteManager(); - - /** - * Get the index of the next node in the route - * @return the index of the next node in the route - */ - public int getNextNodeIndex() { - return nextNodeIndex; - } - - /** - * This method is used to set the next destination, - * when the routable reaches its current destination - * - */ - public void calculateNextNodeIndex() { - if (forward) { - nextNodeIndex++; - if (nextNodeIndex >= nodesInRoute && getRoute().isReversible()) { - forward = false; - nextNodeIndex = nodesInRoute - 1; - if (nextNodeIndex < 0) { - nextNodeIndex = 0; - } - } else if (nextNodeIndex >= nodesInRoute) { - //TODO - nextNodeIndex = nodesInRoute - 1; - } - } else { - nextNodeIndex--; - if (nextNodeIndex < 0 && getRoute().isReversible()) { - forward = true; - nextNodeIndex = 1; - } else if (nextNodeIndex < 0) { - nextNodeIndex = 0; - } - - } - } - - /** - * Get the name of the route that this routable is following - * @return the route name - */ - private Route getRoute() { - return routeManager.getRoute(routeName); - } - - /** - * Get the name of the route that this routable is following - * @return the route name - */ - public String getRouteName() { - return routeName; - } - - /** - * Set the name of the route that this routable must follow - * @param routeName the name of the route - */ - public void setRouteName(String routeName) { - this.routeName = routeName; - nodesInRoute = getRoute().getNodes().length; - - // Selecting the Node in the route which is closest to the current position - if (getPosition() != null) { - double minDistance = Double.MAX_VALUE; - int nodeIndex = 0; - int i; - for (i = 0; i < nodesInRoute; i++) { - double nextDistance = - Distance.getDistance(getPosition(), - getRoute().getNode(i).getPosition(), - Distance.DISTANCE_KM); - if (minDistance > nextDistance) { - minDistance = nextDistance; - nodeIndex = i; - } - } - nextNodeIndex = nodeIndex; - } else { - nextNodeIndex = 0; - } - } - - /** - * Set the name of the route that this routable must follow - * @param routeName the name of the route - * @param forward specify the initial direction the routable is going, forward from start to goal - * or backward from goal to start - */ - public void setRouteName(String routeName, boolean forward) { - this.forward = forward; - setRouteName(routeName); - } - - /** - * Get direction - * @return The direction - */ - public abstract double getDirection(); - - /** - * Get speed - * @return The current speed - */ - public abstract int getSpeed(); - - /** - * Get the position of the ship - * @return The position of the ship - */ - public abstract Position getPosition(); - - /** - * Get maximum speed - * @return The maximum speed - */ - public abstract int getMaxSpeed(); - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- + +package net.sourceforge.huntforgold.model.path; + +import net.sourceforge.huntforgold.model.Moveable; +import net.sourceforge.huntforgold.model.Position; +import net.sourceforge.huntforgold.util.Distance; + +/** + * This class is an abstract implementation of the Movable interface. + * It adds the notion of the Movable to move along a Route + */ +public abstract class Routable implements Moveable { + + /** + * The route that this routable is following + */ + private String routeName; + + /** + * The index of the next node in the route the routable is following + */ + private int nextNodeIndex; + + /** + * indication of which way we are traveling, from node 0 to node n or + * back again from node n to node 0 + */ + private boolean forward = true; + + /** + * simple cache of the number of nodes in the route + */ + private int nodesInRoute; + + /** + * RouteManager + */ + private static RouteManager routeManager = RouteManager.getRouteManager(); + + /** + * Get the index of the next node in the route + * @return the index of the next node in the route + */ + public int getNextNodeIndex() { + return nextNodeIndex; + } + + /** + * This method is used to set the next destination, + * when the routable reaches its current destination + * + */ + public void calculateNextNodeIndex() { + if (forward) { + nextNodeIndex++; + if (nextNodeIndex >= nodesInRoute && getRoute().isReversible()) { + forward = false; + nextNodeIndex = nodesInRoute - 1; + if (nextNodeIndex < 0) { + nextNodeIndex = 0; + } + } else if (nextNodeIndex >= nodesInRoute) { + //TODO + nextNodeIndex = nodesInRoute - 1; + } + } else { + nextNodeIndex--; + if (nextNodeIndex < 0 && getRoute().isReversible()) { + forward = true; + nextNodeIndex = 1; + } else if (nextNodeIndex < 0) { + nextNodeIndex = 0; + } + + } + } + + /** + * Get the name of the route that this routable is following + * @return the route name + */ + private Route getRoute() { + return routeManager.getRoute(routeName); + } + + /** + * Get the name of the route that this routable is following + * @return the route name + */ + public String getRouteName() { + return routeName; + } + + /** + * Set the name of the route that this routable must follow + * @param routeName the name of the route + */ + public void setRouteName(String routeName) { + this.routeName = routeName; + nodesInRoute = getRoute().getNodes().length; + + // Selecting the Node in the route which is closest to the current position + if (getPosition() != null) { + double minDistance = Double.MAX_VALUE; + int nodeIndex = 0; + int i; + for (i = 0; i < nodesInRoute; i++) { + double nextDistance = + Distance.getDistance(getPosition(), + getRoute().getNode(i).getPosition(), + Distance.DISTANCE_KM); + if (minDistance > nextDistance) { + minDistance = nextDistance; + nodeIndex = i; + } + } + nextNodeIndex = nodeIndex; + } else { + nextNodeIndex = 0; + } + } + + /** + * Set the name of the route that this routable must follow + * @param routeName the name of the route + * @param forward specify the initial direction the routable is going, forward from start to goal + * or backward from goal to start + */ + public void setRouteName(String routeName, boolean forward) { + this.forward = forward; + setRouteName(routeName); + } + + /** + * Get direction + * @return The direction + */ + public abstract double getDirection(); + + /** + * Get speed + * @return The current speed + */ + public abstract int getSpeed(); + + /** + * Get the position of the ship + * @return The position of the ship + */ + public abstract Position getPosition(); + + /** + * Get maximum speed + * @return The maximum speed + */ + public abstract int getMaxSpeed(); + +} Index: Route.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/Route.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Route.java 1 Jul 2004 06:27:52 -0000 1.1 +++ Route.java 1 Jul 2004 09:10:32 -0000 1.2 @@ -1,102 +1,102 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- - -package net.sourceforge.huntforgold.model.path; - -/** - * - * Models a Route, i.e. the intended way an object has to travel - */ -public class Route { - - /** - * the nodes that constitutes the ruote - */ - private Node[] nodes; - - /** - * The unique identifying name of the route - */ - private String name; - - /** - * indicates if this route is travable in both directions - */ - private boolean reversible; - - /** - * Construct a new Route with the given characteristics - * @param name the name of this route - * @param nodes the node[] that constitutes the route - * @param reversible boolean, if true the route can be traveled - * in both directions - */ - public Route(String name, Node[] nodes, boolean reversible) { - setName(name); - setNodes(nodes); - setReversible(reversible); - } - /** - * Set the nodes of this route - * @param nodes the node[] that constitutes the route - */ - private void setNodes(Node[] nodes) { - this.nodes = nodes; - } - - /** - * Get the nodes of this route - * @return the node[] that constitutes the route - */ - public Node[] getNodes() { - return nodes; - } - - /** - * Get the index'th node in this route - * @param index the index of the node in the routes - * @return the node number 'index' - */ - public Node getNode(int index) { - return nodes[index]; - } - - /** - * Sets the unique name of this route - * @param name the name to give to this route - */ - private void setName(String name) { - this.name = name; - } - - /** - * Gets the unique name of the route - * @return the name - */ - public String getName() { - return name; - } - - /** - * Indicate if this route can be traveled in both directions - * @param reversible boolean, if true the route can be traveled - * in both directions - */ - private void setReversible(boolean reversible) { - this.reversible = reversible; - } - - /** - * Get indication if this route can be traveled in both directions - * @return true if this this route can be traveled in both directions, - * false if it is one way only. - */ - public boolean isReversible() { - return reversible; - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- + +package net.sourceforge.huntforgold.model.path; + +/** + * + * Models a Route, i.e. the intended way an object has to travel + */ +public class Route { + + /** + * the nodes that constitutes the ruote + */ + private Node[] nodes; + + /** + * The unique identifying name of the route + */ + private String name; + + /** + * indicates if this route is travable in both directions + */ + private boolean reversible; + + /** + * Construct a new Route with the given characteristics + * @param name the name of this route + * @param nodes the node[] that constitutes the route + * @param reversible boolean, if true the route can be traveled + * in both directions + */ + public Route(String name, Node[] nodes, boolean reversible) { + setName(name); + setNodes(nodes); + setReversible(reversible); + } + /** + * Set the nodes of this route + * @param nodes the node[] that constitutes the route + */ + private void setNodes(Node[] nodes) { + this.nodes = nodes; + } + + /** + * Get the nodes of this route + * @return the node[] that constitutes the route + */ + public Node[] getNodes() { + return nodes; + } + + /** + * Get the index'th node in this route + * @param index the index of the node in the routes + * @return the node number 'index' + */ + public Node getNode(int index) { + return nodes[index]; + } + + /** + * Sets the unique name of this route + * @param name the name to give to this route + */ + private void setName(String name) { + this.name = name; + } + + /** + * Gets the unique name of the route + * @return the name + */ + public String getName() { + return name; + } + + /** + * Indicate if this route can be traveled in both directions + * @param reversible boolean, if true the route can be traveled + * in both directions + */ + private void setReversible(boolean reversible) { + this.reversible = reversible; + } + + /** + * Get indication if this route can be traveled in both directions + * @return true if this this route can be traveled in both directions, + * false if it is one way only. + */ + public boolean isReversible() { + return reversible; + } + +} Index: RouteManager.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/RouteManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- RouteManager.java 1 Jul 2004 08:54:01 -0000 1.2 +++ RouteManager.java 1 Jul 2004 09:10:32 -0000 1.3 @@ -1,198 +1,198 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- - -package net.sourceforge.huntforgold.model.path; - -import java.util.Map; -import java.util.List; -import java.util.HashMap; -import java.util.Iterator; -import java.util.StringTokenizer; -import java.util.ArrayList; - -import net.sourceforge.huntforgold.model.Position; -import net.sourceforge.huntforgold.util.Configuration; -import net.sourceforge.huntforgold.util.Distance; -import net.sourceforge.huntforgold.util.PositionHelper; -import net.sourceforge.huntforgold.xml.Huntforgold; -import net.sourceforge.huntforgold.xml.RoutesType; -import net.sourceforge.huntforgold.xml.RouteType; -import net.sourceforge.huntforgold.xml.NodeType; -import net.sourceforge.huntforgold.xml.TownType; -import net.sourceforge.huntforgold.xml.Alias; - -/** - * RouteManager singleton used for managing Routes - */ -public class RouteManager { - - /** The singleton instance */ - private static RouteManager routeManager = null; - - /** - * The routes of the game - */ - private Map routes; - - /** - * Constructor for RouteManager - */ - private RouteManager() { - initRoutes(); - } - - /** - * Get the RouteManager instance - * @return The RouteManager - */ - public static synchronized RouteManager getRouteManager() { - if (routeManager == null) { - routeManager = new RouteManager(); - } - return routeManager; - } - - /** - * Calculates the direction to go to get to the next node on the route - * @param routeable the routeable which needs a new direction - * @return the direction (from 0 to 2 PI) to go to get to the next node in the route - */ - public double calculateDirection(Routable routeable) { - double newDirection = 0; - Route route = (Route) routes.get(routeable.getRouteName()); - Position destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); - Position origen = routeable.getPosition(); - if (isDetstinationReached(destination, origen)) { - routeable.calculateNextNodeIndex(); - destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); - } - newDirection = PositionHelper.getRadianFromVector(destination.getX() - origen.getX(), - destination.getY() - origen.getY()); - return PositionHelper.fixAngle(newDirection); - } - - /** - * Tells wheter we are in a small enough radious of the targeted destination to allow - * the assumption that we are actually there - * @param destination the destination to reach - * @param origen the postion, to compare to the destination - * @return true if the orige is 'close' to the destination - */ - private boolean isDetstinationReached(Position destination, Position origen) { - boolean result = false; - if (Distance.getDistance(destination, - origen, - Distance.DISTANCE_KM) < 2.5) { - result = true; - } - return result; - } - - /** - * Find the route with the specified name - * @param routeName the name of the route to find - * @return the route with the specified name, or null if the name is unknown - */ - public Route getRoute(String routeName) { - Route route = null; - if (routes != null) { - route = (Route) routes.get(routeName); - } - return route; - } - /** - * reads the routes from the configuration into the cache - * @throws NullPointerException if the configured routes contains node names - * which are not defined in towns/town/name or routes/node/name - */ - private void initRoutes() throws NullPointerException { - Configuration conf = Configuration.getConfiguration(); - Huntforgold huntforgold = conf.getHuntforgold(); - // Max one but maybe zero rutes - RoutesType routeDefs = huntforgold.getRoutes(); - if (routeDefs != null) { - // The nodes are either towns or help nodes - List nodeList = routeDefs.getNode(); - nodeList.addAll(huntforgold.getTowns().getTown()); - Map nodeMap = new HashMap(nodeList.size()); - for (int i = 0; i < nodeList.size(); i++) { - //TODO Enhance by letting a Town be a Node - Object nodeDef = nodeList.get(i); - if (nodeDef instanceof TownType) { - TownType nodeType = (TownType) nodeDef; - nodeMap.put(nodeType.getName(), nodeType); - } else if (nodeDef instanceof NodeType) { - NodeType nodeType = (NodeType) nodeDef; - nodeMap.put(nodeType.getName(), nodeType); - } - } - List aliases = routeDefs.getAlias(); - int aliasNo = (aliases == null ? 0 : aliases.size()); - // Iterate through all route definitions in the configuration to instanciate all routes - routes = new HashMap(routeDefs.getRoute().size() + aliasNo); - Iterator routeIterator = routeDefs.getRoute().iterator(); - while (routeIterator.hasNext()) { - RouteType routeType = (RouteType)routeIterator.next(); - String routeName = routeType.getName(); - boolean reversible = routeType.isReversible(); - StringTokenizer nodeTokenizer = new StringTokenizer(routeType.getNodes(), ";"); - Node [] nodes = new Node [nodeTokenizer.countTokens()]; - int nodeIndex = 0; - while (nodeTokenizer.hasMoreTokens()) { - String nodeName = nodeTokenizer.nextToken(); - //TODO Enhance by letting a Town be a Node - Object nodeDef = nodeMap.get(nodeName); - - double longitude = 0; - double latitude = 0; - if (nodeDef instanceof TownType) { - TownType townType = (TownType)nodeDef; - longitude = townType.getLongitude(); - latitude = townType.getLatitude(); - } else if (nodeDef instanceof NodeType) { - NodeType nodeType = (NodeType) nodeDef; - longitude = nodeType.getLongitude(); - latitude = nodeType.getLatitude(); - } - Node node = new Node(nodeName, new Position(longitude, latitude)); - nodes[nodeIndex++] = node; - } - Route route = new Route(routeName, nodes, reversible); - routes.put(routeName, route); - } - // Iterate through all route aliases in the configuration to create concatinated routes - if (aliases != null) { - for (int i = 0; i < aliases.size(); i++) { - Alias alias = (Alias) aliases.get(i); - String routeName = alias.getName(); - boolean reversible = alias.isReversible(); - StringTokenizer nodeTokenizer = new StringTokenizer(alias.getRoutes(), ";"); - ArrayList nodes = new ArrayList(); - while (nodeTokenizer.hasMoreTokens()) { - String route = nodeTokenizer.nextToken(); - Node[] tmpNodes = ((Route)routes.get(route)).getNodes(); - for (int j = 0; j < tmpNodes.length; j++) { - nodes.add(tmpNodes[j]); - } - } - Node[] nodesA = new Node[nodes.size()]; - Route route = new Route(routeName, (Node[])nodes.toArray(nodesA), reversible); - routes.put(routeName, route); - - } - } - } - } - - /** - * Get an Iterator to all routes in the game - * @return Iterator to all routes in the game - */ - public Iterator getRouteIterator() { - return routes.values().iterator(); - } -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- + +package net.sourceforge.huntforgold.model.path; + +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.ArrayList; + +import net.sourceforge.huntforgold.model.Position; +import net.sourceforge.huntforgold.util.Configuration; +import net.sourceforge.huntforgold.util.Distance; +import net.sourceforge.huntforgold.util.PositionHelper; +import net.sourceforge.huntforgold.xml.Huntforgold; +import net.sourceforge.huntforgold.xml.RoutesType; +import net.sourceforge.huntforgold.xml.RouteType; +import net.sourceforge.huntforgold.xml.NodeType; +import net.sourceforge.huntforgold.xml.TownType; +import net.sourceforge.huntforgold.xml.Alias; + +/** + * RouteManager singleton used for managing Routes + */ +public class RouteManager { + + /** The singleton instance */ + private static RouteManager routeManager = null; + + /** + * The routes of the game + */ + private Map routes; + + /** + * Constructor for RouteManager + */ + private RouteManager() { + initRoutes(); + } + + /** + * Get the RouteManager instance + * @return The RouteManager + */ + public static synchronized RouteManager getRouteManager() { + if (routeManager == null) { + routeManager = new RouteManager(); + } + return routeManager; + } + + /** + * Calculates the direction to go to get to the next node on the route + * @param routeable the routeable which needs a new direction + * @return the direction (from 0 to 2 PI) to go to get to the next node in the route + */ + public double calculateDirection(Routable routeable) { + double newDirection = 0; + Route route = (Route) routes.get(routeable.getRouteName()); + Position destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); + Position origen = routeable.getPosition(); + if (isDetstinationReached(destination, origen)) { + routeable.calculateNextNodeIndex(); + destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); + } + newDirection = PositionHelper.getRadianFromVector(destination.getX() - origen.getX(), + destination.getY() - origen.getY()); + return PositionHelper.fixAngle(newDirection); + } + + /** + * Tells wheter we are in a small enough radious of the targeted destination to allow + * the assumption that we are actually there + * @param destination the destination to reach + * @param origen the postion, to compare to the destination + * @return true if the orige is 'close' to the destination + */ + private boolean isDetstinationReached(Position destination, Position origen) { + boolean result = false; + if (Distance.getDistance(destination, + origen, + Distance.DISTANCE_KM) < 2.5) { + result = true; + } + return result; + } + + /** + * Find the route with the specified name + * @param routeName the name of the route to find + * @return the route with the specified name, or null if the name is unknown + */ + public Route getRoute(String routeName) { + Route route = null; + if (routes != null) { + route = (Route) routes.get(routeName); + } + return route; + } + /** + * reads the routes from the configuration into the cache + * @throws NullPointerException if the configured routes contains node names + * which are not defined in towns/town/name or routes/node/name + */ + private void initRoutes() throws NullPointerException { + Configuration conf = Configuration.getConfiguration(); + Huntforgold huntforgold = conf.getHuntforgold(); + // Max one but maybe zero rutes + RoutesType routeDefs = huntforgold.getRoutes(); + if (routeDefs != null) { + // The nodes are either towns or help nodes + List nodeList = routeDefs.getNode(); + nodeList.addAll(huntforgold.getTowns().getTown()); + Map nodeMap = new HashMap(nodeList.size()); + for (int i = 0; i < nodeList.size(); i++) { + //TODO Enhance by letting a Town be a Node + Object nodeDef = nodeList.get(i); + if (nodeDef instanceof TownType) { + TownType nodeType = (TownType) nodeDef; + nodeMap.put(nodeType.getName(), nodeType); + } else if (nodeDef instanceof NodeType) { + NodeType nodeType = (NodeType) nodeDef; + nodeMap.put(nodeType.getName(), nodeType); + } + } + List aliases = routeDefs.getAlias(); + int aliasNo = (aliases == null ? 0 : aliases.size()); + // Iterate through all route definitions in the configuration to instanciate all routes + routes = new HashMap(routeDefs.getRoute().size() + aliasNo); + Iterator routeIterator = routeDefs.getRoute().iterator(); + while (routeIterator.hasNext()) { + RouteType routeType = (RouteType)routeIterator.next(); + String routeName = routeType.getName(); + boolean reversible = routeType.isReversible(); + StringTokenizer nodeTokenizer = new StringTokenizer(routeType.getNodes(), ";"); + Node [] nodes = new Node [nodeTokenizer.countTokens()]; + int nodeIndex = 0; + while (nodeTokenizer.hasMoreTokens()) { + String nodeName = nodeTokenizer.nextToken(); + //TODO Enhance by letting a Town be a Node + Object nodeDef = nodeMap.get(nodeName); + + double longitude = 0; + double latitude = 0; + if (nodeDef instanceof TownType) { + TownType townType = (TownType)nodeDef; + longitude = townType.getLongitude(); + latitude = townType.getLatitude(); + } else if (nodeDef instanceof NodeType) { + NodeType nodeType = (NodeType) nodeDef; + longitude = nodeType.getLongitude(); + latitude = nodeType.getLatitude(); + } + Node node = new Node(nodeName, new Position(longitude, latitude)); + nodes[nodeIndex++] = node; + } + Route route = new Route(routeName, nodes, reversible); + routes.put(routeName, route); + } + // Iterate through all route aliases in the configuration to create concatinated routes + if (aliases != null) { + for (int i = 0; i < aliases.size(); i++) { + Alias alias = (Alias) aliases.get(i); + String routeName = alias.getName(); + boolean reversible = alias.isReversible(); + StringTokenizer nodeTokenizer = new StringTokenizer(alias.getRoutes(), ";"); + ArrayList nodes = new ArrayList(); + while (nodeTokenizer.hasMoreTokens()) { + String route = nodeTokenizer.nextToken(); + Node[] tmpNodes = ((Route)routes.get(route)).getNodes(); + for (int j = 0; j < tmpNodes.length; j++) { + nodes.add(tmpNodes[j]); + } + } + Node[] nodesA = new Node[nodes.size()]; + Route route = new Route(routeName, (Node[])nodes.toArray(nodesA), reversible); + routes.put(routeName, route); + + } + } + } + } + + /** + * Get an Iterator to all routes in the game + * @return Iterator to all routes in the game + */ + public Iterator getRouteIterator() { + return routes.values().iterator(); + } +} |
From: Mads P. H. <ma...@us...> - 2004-07-01 09:09:46
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10090 Modified Files: AStar.java AbstractPathFinder.java DepthFirstSearch.java Node.java PathEvent.java PathFinder.java PathListener.java Log Message: Removed dos chars Index: AStar.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/AStar.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- AStar.java 1 Jul 2004 08:27:54 -0000 1.1 +++ AStar.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,254 +1,254 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * An implementation of the A* path finding algorithm. - * - * @author Gene McCulley - */ -public class AStar extends AbstractPathFinder { - - /** - * Possible nodes - */ - private SortedSet open; - - /** - * Possible nodes - */ - private Map openMap; - - /** - * Examined nodes - */ - private Map closed; - - /** - * current state - */ - private State state; - - - /** - * Create a new AStar calculating path from start to goal - * @param start The Start point - * @param goal The end point - */ - public AStar(Node start, Node goal) { - super(start, goal); - } - - /** - * Create a new AStar calculating path from start to goals - * @param start The Start point - * @param goals The end points - */ - public AStar(Node start, Collection goals) { - super(start, goals); - } - - /** - * State class keeping track of costs - */ - private class State implements Comparable { - - /** - * Current node - */ - private Node node; - - /** - * Initial costs - */ - private double costFromStart; - - /** - * costs untill goal is reached - */ - private double costToGoal; - - /** - * Parent state - */ - private State parent; - - /** - * Creates a new state corresponding to the Node and the path found so far - * @param node Current node - * @param costFromStart Current start cost - * @param parent The previous state before moving to this state - */ - public State(Node node, double costFromStart, State parent) { - this.node = node; - this.costFromStart = costFromStart; - costToGoal = minimumPathCostEstimate(node); - this.parent = parent; - } - - /** - * Estimation of minimal costs of traveling node to one of the goals - * @param node Node to examine - * @return Estimation of minimal costs - */ - private double minimumPathCostEstimate(Node node) { - double min = Double.MAX_VALUE; - for (Iterator i = goals.iterator(); i.hasNext(); ) { - double cost = node.getPathCostEstimate((Node)i.next()); - if (cost < min) { - min = cost; - } - } - - return min; - } - - /** - * Getter for costFromStart - * @return start costs - */ - public double getCostFromStart() { - return costFromStart; - } - - /** - * Returns total costs - * @return total costs - */ - public double getTotalCost() { - return costFromStart + costToGoal; - } - - /** - * Getter for node - * @return the node - */ - public Node getNode() { - return node; - } - - /** - * Getter for parent - * @return the parent - */ - public State getParent() { - return parent; - } - - /** - * Compare the cost of this state to another state - * @param other MUST be other State - * @return The cost difference (total cost) of the two states - */ - public int compareTo(Object other) { - double result = getTotalCost() - ((State)other).getTotalCost(); - if (result > 0) { - return 1; - } else if (result < 0) { - return -1; - } else { - return 0; - } - } - - /** - * Pretty print of the state - * @return Pretty print of the state - */ - public String toString() { - return "State: " + node + " costFromStart: " + costFromStart + - " costToGoal: " + costToGoal + " totalCost: " + - getTotalCost(); - } - - } - - /** - * Gets list of considdered nodes - * @return List of considdered nodes - */ - public List getConsideredPath() { - List result = new LinkedList(); - State s = state; - while (s != null) { - result.add(s.getNode()); - s = s.getParent(); - } - - Collections.reverse(result); - return result; - } - - /** - * Finds the path from start to goal(s) - * @return list of Nodes in the path - */ - public List findPath() { - open = new TreeSet(); - openMap = new HashMap(); - closed = new HashMap(); - State startState = new State(start, 0, null); - open.add(startState); - openMap.put(start, startState); - while (!(open.isEmpty() || aborted)) { - state = (State)open.first(); - open.remove(state); - openMap.remove(state.getNode()); - fireConsidered(); - if (goals.contains(state.getNode())) { - return getConsideredPath(); - } else { - Iterator neighbors = - state.getNode().getNeighbors().iterator(); - while (neighbors.hasNext()) { - Node newNode = (Node)neighbors.next(); - double newCost = state.getCostFromStart() + - state.getNode().getTraverseCost(newNode); - State openNode = (State)openMap.get(newNode); - if (openNode != null && - openNode.getCostFromStart() <= newCost) { - continue; - } - - State closedNode = (State)closed.get(newNode); - if (closedNode != null && - closedNode.getCostFromStart() <= newCost) { - continue; - } - - State newState = new State(newNode, newCost, state); - if (closedNode != null) { - closed.remove(newNode); - } - - if (openNode != null) { - open.remove(openNode); - openMap.remove(newNode); - } - - open.add(newState); - openMap.put(newNode, newState); - } - } - - closed.put(state.getNode(), state); - } - - return null; - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * An implementation of the A* path finding algorithm. + * + * @author Gene McCulley + */ +public class AStar extends AbstractPathFinder { + + /** + * Possible nodes + */ + private SortedSet open; + + /** + * Possible nodes + */ + private Map openMap; + + /** + * Examined nodes + */ + private Map closed; + + /** + * current state + */ + private State state; + + + /** + * Create a new AStar calculating path from start to goal + * @param start The Start point + * @param goal The end point + */ + public AStar(Node start, Node goal) { + super(start, goal); + } + + /** + * Create a new AStar calculating path from start to goals + * @param start The Start point + * @param goals The end points + */ + public AStar(Node start, Collection goals) { + super(start, goals); + } + + /** + * State class keeping track of costs + */ + private class State implements Comparable { + + /** + * Current node + */ + private Node node; + + /** + * Initial costs + */ + private double costFromStart; + + /** + * costs untill goal is reached + */ + private double costToGoal; + + /** + * Parent state + */ + private State parent; + + /** + * Creates a new state corresponding to the Node and the path found so far + * @param node Current node + * @param costFromStart Current start cost + * @param parent The previous state before moving to this state + */ + public State(Node node, double costFromStart, State parent) { + this.node = node; + this.costFromStart = costFromStart; + costToGoal = minimumPathCostEstimate(node); + this.parent = parent; + } + + /** + * Estimation of minimal costs of traveling node to one of the goals + * @param node Node to examine + * @return Estimation of minimal costs + */ + private double minimumPathCostEstimate(Node node) { + double min = Double.MAX_VALUE; + for (Iterator i = goals.iterator(); i.hasNext(); ) { + double cost = node.getPathCostEstimate((Node)i.next()); + if (cost < min) { + min = cost; + } + } + + return min; + } + + /** + * Getter for costFromStart + * @return start costs + */ + public double getCostFromStart() { + return costFromStart; + } + + /** + * Returns total costs + * @return total costs + */ + public double getTotalCost() { + return costFromStart + costToGoal; + } + + /** + * Getter for node + * @return the node + */ + public Node getNode() { + return node; + } + + /** + * Getter for parent + * @return the parent + */ + public State getParent() { + return parent; + } + + /** + * Compare the cost of this state to another state + * @param other MUST be other State + * @return The cost difference (total cost) of the two states + */ + public int compareTo(Object other) { + double result = getTotalCost() - ((State)other).getTotalCost(); + if (result > 0) { + return 1; + } else if (result < 0) { + return -1; + } else { + return 0; + } + } + + /** + * Pretty print of the state + * @return Pretty print of the state + */ + public String toString() { + return "State: " + node + " costFromStart: " + costFromStart + + " costToGoal: " + costToGoal + " totalCost: " + + getTotalCost(); + } + + } + + /** + * Gets list of considdered nodes + * @return List of considdered nodes + */ + public List getConsideredPath() { + List result = new LinkedList(); + State s = state; + while (s != null) { + result.add(s.getNode()); + s = s.getParent(); + } + + Collections.reverse(result); + return result; + } + + /** + * Finds the path from start to goal(s) + * @return list of Nodes in the path + */ + public List findPath() { + open = new TreeSet(); + openMap = new HashMap(); + closed = new HashMap(); + State startState = new State(start, 0, null); + open.add(startState); + openMap.put(start, startState); + while (!(open.isEmpty() || aborted)) { + state = (State)open.first(); + open.remove(state); + openMap.remove(state.getNode()); + fireConsidered(); + if (goals.contains(state.getNode())) { + return getConsideredPath(); + } else { + Iterator neighbors = + state.getNode().getNeighbors().iterator(); + while (neighbors.hasNext()) { + Node newNode = (Node)neighbors.next(); + double newCost = state.getCostFromStart() + + state.getNode().getTraverseCost(newNode); + State openNode = (State)openMap.get(newNode); + if (openNode != null && + openNode.getCostFromStart() <= newCost) { + continue; + } + + State closedNode = (State)closed.get(newNode); + if (closedNode != null && + closedNode.getCostFromStart() <= newCost) { + continue; + } + + State newState = new State(newNode, newCost, state); + if (closedNode != null) { + closed.remove(newNode); + } + + if (openNode != null) { + open.remove(openNode); + openMap.remove(newNode); + } + + open.add(newState); + openMap.put(newNode, newState); + } + } + + closed.put(state.getNode(), state); + } + + return null; + } + +} Index: AbstractPathFinder.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/AbstractPathFinder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- AbstractPathFinder.java 1 Jul 2004 08:27:54 -0000 1.1 +++ AbstractPathFinder.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,110 +1,110 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * Basic functionality of path finders. - * - * @author Gene McCulley - */ -public abstract class AbstractPathFinder implements PathFinder { - - /** - * Start node - */ - protected Node start; - - /** - * End Nodes - */ - protected Collection goals; - - /** - * List of PathListeners - */ - protected List listeners = new ArrayList(); - - /** - * Abort search indicator - */ - protected boolean aborted; - - /** - * Create a new PathFinder. - * - * @param start the Node to start with. - * @param goal the Node to end at. - */ - public AbstractPathFinder(Node start, Node goal) { - this.start = start; - goals = Collections.singletonList(goal); - } - - /** - * Create a new PathFinder. - * - * @param start the Node to start with. - * @param goals a Collection of Nodes to end at. - */ - public AbstractPathFinder(Node start, Collection goals) { - this.start = start; - this.goals = new ArrayList(goals); - } - - /** - * Sets abort = true - */ - public void abort() { - aborted = true; - } - - /** - * Execute the path finding algorithm. - */ - public void startSearch() { - List path = findPath(); - PathEvent event = new PathEvent(this, path); - for (Iterator i = listeners.iterator(); i.hasNext(); ) { - PathListener listener = (PathListener)i.next(); - listener.done(event); - } - } - - /** - * Notifies listeners about PathEvents - */ - protected void fireConsidered() { - PathEvent event = new PathEvent(this, null); - for (Iterator i = listeners.iterator(); i.hasNext(); ) { - PathListener listener = (PathListener)i.next(); - listener.considered(event); - } - } - - /** - * Add a PathListener - * @param l the PathListener to add - */ - public void addPathListener(PathListener l) { - listeners.add(l); - } - - /** - * Removes a PathListener - * @param l the PathListener to remove - */ - public void removePathListener(PathListener l) { - listeners.remove(l); - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Basic functionality of path finders. + * + * @author Gene McCulley + */ +public abstract class AbstractPathFinder implements PathFinder { + + /** + * Start node + */ + protected Node start; + + /** + * End Nodes + */ + protected Collection goals; + + /** + * List of PathListeners + */ + protected List listeners = new ArrayList(); + + /** + * Abort search indicator + */ + protected boolean aborted; + + /** + * Create a new PathFinder. + * + * @param start the Node to start with. + * @param goal the Node to end at. + */ + public AbstractPathFinder(Node start, Node goal) { + this.start = start; + goals = Collections.singletonList(goal); + } + + /** + * Create a new PathFinder. + * + * @param start the Node to start with. + * @param goals a Collection of Nodes to end at. + */ + public AbstractPathFinder(Node start, Collection goals) { + this.start = start; + this.goals = new ArrayList(goals); + } + + /** + * Sets abort = true + */ + public void abort() { + aborted = true; + } + + /** + * Execute the path finding algorithm. + */ + public void startSearch() { + List path = findPath(); + PathEvent event = new PathEvent(this, path); + for (Iterator i = listeners.iterator(); i.hasNext(); ) { + PathListener listener = (PathListener)i.next(); + listener.done(event); + } + } + + /** + * Notifies listeners about PathEvents + */ + protected void fireConsidered() { + PathEvent event = new PathEvent(this, null); + for (Iterator i = listeners.iterator(); i.hasNext(); ) { + PathListener listener = (PathListener)i.next(); + listener.considered(event); + } + } + + /** + * Add a PathListener + * @param l the PathListener to add + */ + public void addPathListener(PathListener l) { + listeners.add(l); + } + + /** + * Removes a PathListener + * @param l the PathListener to remove + */ + public void removePathListener(PathListener l) { + listeners.remove(l); + } + +} Index: DepthFirstSearch.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/DepthFirstSearch.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- DepthFirstSearch.java 1 Jul 2004 08:27:54 -0000 1.1 +++ DepthFirstSearch.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,96 +1,96 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * An implementation of the Depth First Search path finding algorithm. - * - * @author Gene McCulley - */ -public class DepthFirstSearch extends AbstractPathFinder { - - /** - * List of vissited Nodes - */ - private List visited; - - /** - * Creates a new DepthFirstSearch from start to goal - * @param start The start node - * @param goal The end node - */ - public DepthFirstSearch(Node start, Node goal) { - super(start, goal); - } - - /** - * Creates a new DepthFirstSearch from start to goals - * @param start The start node - * @param goals The end nodes - */ - public DepthFirstSearch(Node start, Collection goals) { - super(start, goals); - } - - /** - * Finds the path - * @return List of nodes in path if found null otherwise - */ - public List findPath() { - visited = new LinkedList(); - boolean found = search(start); - if (found) { - return visited; - } else { - return null; - } - } - - /** - * Get the considdered path - * @return List of nodes vissited so far - */ - public List getConsideredPath() { - return new ArrayList(visited); - } - - /** - * Search for a path from node to Goals - * @param node the node to start from - * @return true if path found false otherwise - */ - private boolean search(Node node) { - if (aborted) { - return false; - } - visited.add(node); - fireConsidered(); - if (goals.contains(node)) { - return true; - } else { - Iterator neighbors = node.getNeighbors().iterator(); - while (neighbors.hasNext()) { - Node neighbor = (Node)neighbors.next(); - if (!visited.contains(neighbor)) { - if (search(neighbor)) { - return true; - } - } - } - } - - visited.remove(node); - return false; - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * An implementation of the Depth First Search path finding algorithm. + * + * @author Gene McCulley + */ +public class DepthFirstSearch extends AbstractPathFinder { + + /** + * List of vissited Nodes + */ + private List visited; + + /** + * Creates a new DepthFirstSearch from start to goal + * @param start The start node + * @param goal The end node + */ + public DepthFirstSearch(Node start, Node goal) { + super(start, goal); + } + + /** + * Creates a new DepthFirstSearch from start to goals + * @param start The start node + * @param goals The end nodes + */ + public DepthFirstSearch(Node start, Collection goals) { + super(start, goals); + } + + /** + * Finds the path + * @return List of nodes in path if found null otherwise + */ + public List findPath() { + visited = new LinkedList(); + boolean found = search(start); + if (found) { + return visited; + } else { + return null; + } + } + + /** + * Get the considdered path + * @return List of nodes vissited so far + */ + public List getConsideredPath() { + return new ArrayList(visited); + } + + /** + * Search for a path from node to Goals + * @param node the node to start from + * @return true if path found false otherwise + */ + private boolean search(Node node) { + if (aborted) { + return false; + } + visited.add(node); + fireConsidered(); + if (goals.contains(node)) { + return true; + } else { + Iterator neighbors = node.getNeighbors().iterator(); + while (neighbors.hasNext()) { + Node neighbor = (Node)neighbors.next(); + if (!visited.contains(neighbor)) { + if (search(neighbor)) { + return true; + } + } + } + } + + visited.remove(node); + return false; + } + +} Index: Node.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/Node.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Node.java 1 Jul 2004 08:27:54 -0000 1.1 +++ Node.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,44 +1,44 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.Collection; - -/** - * The <code>Node</code> interface must be implemented by classes that want a - * <code>PathFinder<code> to find paths over them. - * - * @author Gene McCulley - */ -public interface Node { - - /** - * Returns the estimate of the cost to get from this node to the goal node. - * If unable to estimate, it is safe to return 0 or underestimate. - * Overestimates can result in failures to find a path. - * - * @return the estimate. - * @param goal The goal of the current search - */ - double getPathCostEstimate(Node goal); - - /** - * Returns the cost to get from this node to the dest node. - * - * @param dest the destination node - * @return the cost. - */ - double getTraverseCost(Node dest); - - /** - * Returns the neighbors of this node in the form of a Collection. - * - * @return the neighbors. - */ - Collection getNeighbors(); - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.Collection; + +/** + * The <code>Node</code> interface must be implemented by classes that want a + * <code>PathFinder<code> to find paths over them. + * + * @author Gene McCulley + */ +public interface Node { + + /** + * Returns the estimate of the cost to get from this node to the goal node. + * If unable to estimate, it is safe to return 0 or underestimate. + * Overestimates can result in failures to find a path. + * + * @return the estimate. + * @param goal The goal of the current search + */ + double getPathCostEstimate(Node goal); + + /** + * Returns the cost to get from this node to the dest node. + * + * @param dest the destination node + * @return the cost. + */ + double getTraverseCost(Node dest); + + /** + * Returns the neighbors of this node in the form of a Collection. + * + * @return the neighbors. + */ + Collection getNeighbors(); + +} Index: PathEvent.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/PathEvent.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- PathEvent.java 1 Jul 2004 08:27:54 -0000 1.1 +++ PathEvent.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,45 +1,45 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.EventObject; -import java.util.List; - -/** - * An encapsulation of the data describing an event related to a PathFinder. - * - * @author Gene McCulley - */ -public class PathEvent extends EventObject { - - /** - * List of Nodes in the path - */ - private List path; - - /** - * Create a new PathEvent. - * - * @param source the source of this event. - * @param path the path related to the event. - */ - public PathEvent(Object source, List path) { - super(source); - this.path = path; - } - - /** - * Returns the path related to this event. - * - * @return the path related to the event in the form of a list or null if - * no path was found. - */ - public List getPath() { - return path; - } - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.EventObject; +import java.util.List; + +/** + * An encapsulation of the data describing an event related to a PathFinder. + * + * @author Gene McCulley + */ +public class PathEvent extends EventObject { + + /** + * List of Nodes in the path + */ + private List path; + + /** + * Create a new PathEvent. + * + * @param source the source of this event. + * @param path the path related to the event. + */ + public PathEvent(Object source, List path) { + super(source); + this.path = path; + } + + /** + * Returns the path related to this event. + * + * @return the path related to the event in the form of a list or null if + * no path was found. + */ + public List getPath() { + return path; + } + +} Index: PathFinder.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/PathFinder.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- PathFinder.java 1 Jul 2004 08:27:54 -0000 1.1 +++ PathFinder.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,64 +1,64 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.List; - -/** - * The <code>PathFinder</code> interface is implemented by classes that provide - * a mechanism to find routes between nodes. - * - * A <code>PathFinder</code> is a <code>Runnable</code> so that you can use it - * either directly or as a Thread. To use it directly, just call findPath. - * This may take a while, so you may want to use it as a Thread. You do this - * by constructing the <code>PathFinder</code>, adding yourself as a - * <code>PathListener</code>, and then calling the start method. When the path - * has been found or all possible paths have been exhausted, a - * <code>PathEvent</code> will be sent. - * - * @author Gene McCulley - */ -public interface PathFinder { - - /** - * Find a path between the start and the goal Nodes. - * - * @return a List of Node elements. - */ - List findPath(); - - /** - * Abort the current path search. This only makes sense if you are using - * the threaded approach. The state of the pathfinder will be reset such - * that it is okay to call findPath again to start over. - */ - void abort(); - - /** - * Get the path currently being considered. This only makes sense if you are - * using the threaded approach. It is only safe to call this after having - * received a considered PathEvent. - * - * @return a List of Nodes in the considered path. - */ - List getConsideredPath(); - - /** - * Add a listener for PathEvents. - * - * @param l the listener to add. - */ - void addPathListener(PathListener l); - - /** - * Remove a listener for PathEvents. - * - * @param l the listener to remove. - */ - void removePathListener(PathListener l); - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.List; + +/** + * The <code>PathFinder</code> interface is implemented by classes that provide + * a mechanism to find routes between nodes. + * + * A <code>PathFinder</code> is a <code>Runnable</code> so that you can use it + * either directly or as a Thread. To use it directly, just call findPath. + * This may take a while, so you may want to use it as a Thread. You do this + * by constructing the <code>PathFinder</code>, adding yourself as a + * <code>PathListener</code>, and then calling the start method. When the path + * has been found or all possible paths have been exhausted, a + * <code>PathEvent</code> will be sent. + * + * @author Gene McCulley + */ +public interface PathFinder { + + /** + * Find a path between the start and the goal Nodes. + * + * @return a List of Node elements. + */ + List findPath(); + + /** + * Abort the current path search. This only makes sense if you are using + * the threaded approach. The state of the pathfinder will be reset such + * that it is okay to call findPath again to start over. + */ + void abort(); + + /** + * Get the path currently being considered. This only makes sense if you are + * using the threaded approach. It is only safe to call this after having + * received a considered PathEvent. + * + * @return a List of Nodes in the considered path. + */ + List getConsideredPath(); + + /** + * Add a listener for PathEvents. + * + * @param l the listener to add. + */ + void addPathListener(PathListener l); + + /** + * Remove a listener for PathEvents. + * + * @param l the listener to remove. + */ + void removePathListener(PathListener l); + +} Index: PathListener.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar/PathListener.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- PathListener.java 1 Jul 2004 08:27:54 -0000 1.1 +++ PathListener.java 1 Jul 2004 09:09:34 -0000 1.2 @@ -1,33 +1,33 @@ -//--------------------------------------------------------------------------------- -// $Id$ -// -// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) -// All rights reserved -//--------------------------------------------------------------------------------- -package net.sourceforge.huntforgold.model.path.astar; - -import java.util.EventListener; - -/** - * Classes that want to know about path finding events must implement the - * <code>PathListener</code> interface. - * - * @author Gene McCulley - */ -public interface PathListener extends EventListener { - - /** - * Called when the PathFinder is done. - * - * @param e the PathEvent containing the finished path. - */ - void done(PathEvent e); - - /** - * Called when a new path is being considered. - * - * @param e the PathEvent that belongs to the PathFinder. - */ - void considered(PathEvent e); - -} +//--------------------------------------------------------------------------------- +// $Id$ +// +// Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) +// All rights reserved +//--------------------------------------------------------------------------------- +package net.sourceforge.huntforgold.model.path.astar; + +import java.util.EventListener; + +/** + * Classes that want to know about path finding events must implement the + * <code>PathListener</code> interface. + * + * @author Gene McCulley + */ +public interface PathListener extends EventListener { + + /** + * Called when the PathFinder is done. + * + * @param e the PathEvent containing the finished path. + */ + void done(PathEvent e); + + /** + * Called when a new path is being considered. + * + * @param e the PathEvent that belongs to the PathFinder. + */ + void considered(PathEvent e); + +} |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:54:12
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7533 Modified Files: RouteManager.java Log Message: Fixed bug in getRoute which could cause a NPE Index: RouteManager.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/RouteManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- RouteManager.java 1 Jul 2004 06:27:52 -0000 1.1 +++ RouteManager.java 1 Jul 2004 08:54:01 -0000 1.2 @@ -98,7 +98,11 @@ * @return the route with the specified name, or null if the name is unknown */ public Route getRoute(String routeName) { - return (Route) routes.get(routeName); + Route route = null; + if (routes != null) { + route = (Route) routes.get(routeName); + } + return route; } /** * reads the routes from the configuration into the cache |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:43:07
|
Update of /cvsroot/huntforgold/editors/src/gfx In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5815 Added Files: routenodes.png Log Message: Initial import --- NEW FILE: routenodes.png --- PNG |
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/routeeditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5208 Added Files: CenterLocationStrategy.java EastLocationStrategy.java Location.java LocationStrategy.java NodeModel.java NorthEastLocationStrategy.java NorthLocationStrategy.java NorthWestLocationStrategy.java RouteActionListener.java RouteEditor.java ScrollableMap.java ScrollableTileList.java SouthEastLocationStrategy.java SouthLocationStrategy.java SouthWestLocationStrategy.java WestLocationStrategy.java package.html Log Message: Initial import --- NEW FILE: CenterLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: CenterLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for center (on tile) locations */ public class CenterLocationStrategy extends LocationStrategy { /** * Number of rows in the map */ private int tileRows; /** * Number of cols in the map */ private int tileCols; /** * Constructor for center strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected CenterLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; tileRows = map.getHeight() / 64; tileCols = map.getWidth() / 64; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean northWestIsWaterTile = false; boolean northIsWaterTile = false; boolean northEastIsWaterTile = false; boolean westIsWaterTile = false; boolean eastIsWaterTile = false; boolean southWestIsWaterTile = false; boolean southIsWaterTile = false; boolean southEastIsWaterTile = false; if (row > 0 && col > 0) { northWestIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col - 1))).isOnlyWater(); } if (row > 0) { northIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col))).isOnlyWater(); } if (row > 0 && col < tileCols - 1) { northEastIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col + 1))).isOnlyWater(); } if (col > 0) { westIsWaterTile = (landTiles.getLandTile(map.getTile(row, col - 1))).isOnlyWater(); } if (col < tileCols - 1) { eastIsWaterTile = (landTiles.getLandTile(map.getTile(row, col + 1))).isOnlyWater(); } if (row < tileRows - 1 && col > 0) { southWestIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col - 1))).isOnlyWater(); } if (row < tileRows - 1) { southIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col))).isOnlyWater(); } if (row < tileRows - 1 && col < tileCols - 1) { southEastIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col + 1))).isOnlyWater(); } if ((landTiles.getLandTile(map.getTile(row, col))).isOnlyWater()) { if (row > 0) { if (col > 0) { if (northWestIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col - 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col - 1, 8, goal)); } } if (northIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col, 6, goal)); neighbors.add(forcedGetLocation(row - 1, col, 7, goal)); neighbors.add(forcedGetLocation(row - 1, col, 8, goal)); } if (col < tileCols - 1) { if (northEastIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col + 1, 6, goal)); } } } if (col > 0) { if (westIsWaterTile) { neighbors.add(forcedGetLocation(row, col - 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col - 1, 2, goal)); neighbors.add(forcedGetLocation(row, col - 1, 5, goal)); neighbors.add(forcedGetLocation(row, col - 1, 8, goal)); } if (row < tileRows - 1) { if (southWestIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col - 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col - 1, 2, goal)); } } } if (row < tileRows - 1) { if (southIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col, 0, goal)); neighbors.add(forcedGetLocation(row + 1, col, 1, goal)); neighbors.add(forcedGetLocation(row + 1, col, 2, goal)); } if (col < tileCols - 1) { if (eastIsWaterTile) { neighbors.add(forcedGetLocation(row, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col + 1, 2, goal)); neighbors.add(forcedGetLocation(row, col + 1, 5, goal)); neighbors.add(forcedGetLocation(row, col + 1, 8, goal)); } if (southEastIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col + 1, 0, goal)); } } } } else { neighbors.add(forcedGetLocation(row, col, 0, goal)); neighbors.add(forcedGetLocation(row, col, 1, goal)); neighbors.add(forcedGetLocation(row, col, 2, goal)); neighbors.add(forcedGetLocation(row, col, 3, goal)); neighbors.add(forcedGetLocation(row, col, 5, goal)); neighbors.add(forcedGetLocation(row, col, 6, goal)); neighbors.add(forcedGetLocation(row, col, 7, goal)); neighbors.add(forcedGetLocation(row, col, 8, goal)); } } } --- NEW FILE: EastLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: EastLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for east (on tile) locations */ public class EastLocationStrategy extends LocationStrategy { /** * Number of cols in the map */ private int tileCols; /** * Constructor for east strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected EastLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; tileCols = map.getWidth() / 64; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean eastIsWaterTile = false; if (col < tileCols - 1) { eastIsWaterTile = (landTiles.getLandTile(map.getTile(row, col + 1))).isOnlyWater(); } if (col < tileCols - 1) { if (eastIsWaterTile) { neighbors.add(forcedGetLocation(row, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col + 1, 0, goal)); neighbors.add(forcedGetLocation(row, col + 1, 3, goal)); neighbors.add(forcedGetLocation(row, col + 1, 6, goal)); } } neighbors.add(forcedGetLocation(row, col, 1, goal)); neighbors.add(forcedGetLocation(row, col, 2, goal)); neighbors.add(forcedGetLocation(row, col, 4, goal)); } } --- NEW FILE: Location.java --- //--------------------------------------------------------------------------------- // $Id: Location.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; // Copyright (C) 2002 Cuspy Engineering Solutions, Inc. http://cuspy.com/ // This package is licensed under the GPL. import net.sourceforge.huntforgold.model.path.astar.Node; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * Node in pathfinding algorithm */ public class Location implements Node, Serializable { /** * The goal to reach when this Location is part of a path finding algorithm */ private Location goal; /** * The x coordinate of this location */ private int x; /** * The y coordinate of this location */ private int y; /** * The cost associated with visiting this location */ private int height; /** * Indication of whether this Location has been ruled out as a posible location to visit */ private boolean blocked; /** * Create a new Location on the specified position with the given goal * @param x The x coordinate of the location * @param y The y coordinate of the location * @param goal The goal of the location */ public Location(int x, int y, Location goal) { this.x = x; this.y = y; blocked = false; height = 1; this.goal = goal; } /** * Getter for the x coordinate * @return the x coordinate */ public int getX() { return x; } /** * Getter for the y coordinate * @return the y coordinate */ public int getY() { return y; } /** * Block or unblock the location * @param blocked true, if this location is ruled out as a possible place to visit, * false othervise */ public void setBlocked(boolean blocked) { this.blocked = blocked; } /** * Is the location blocked? True, if this location is ruled out as a possible place to visit, * false othervise * @return Indication of this location has been blocked */ public boolean getBlocked() { return blocked; } /** * Get the height, i.e. the cost visiting this Location * @return the height of the location */ public int getHeight() { return height; } /** * Set the height, i.e. the cost visiting this Location * @param height the cost visiting this Location */ public void setHeight(int height) { this.height = height; } /** * Get the distance between this Location and the passed Location * @param dest Location to calculate the destination to * @return the distance between this locaion and the passed location */ public double getDistance(Location dest) { double a = dest.x - x; double b = dest.y - y; return Math.sqrt(a * a + b * b); } /** * Calculates a cost estimate of adding this location to a path towards goal * @param goal the goal subject to the estimate * @return a cost estimate */ public double getPathCostEstimate(Node goal) { Location goalLoc = (Location)goal; return getDistance(goalLoc) * 0.99; } /** * Calculate the cost of going from this node to the passed node * @param dest to calulate the cost to go to from this location * @return the cost of going from this Locatioin to the passed node */ public double getTraverseCost(Node dest) { Location target = (Location)dest; double distance = getDistance(target); double diff = target.getHeight() - getHeight(); return Math.abs(diff) + distance; } /** * Get a collection of none blocked neighboring nodes of this Location * @return a collection of none blocked neighboring nodes of this Location */ public Collection getNeighbors() { List realNeighbors; if (goal != null) { //This location is not the goal it self List neighbors = NodeModel.getNeighbors(this); // We are close enough to the goal, add the goal as a neighbor if (Math.abs(x - goal.getX()) < 32 && Math.abs(y - goal.getY()) < 32) { neighbors.add(goal); } realNeighbors = new ArrayList(neighbors.size()); if (!blocked) { for (Iterator i = neighbors.iterator(); i.hasNext();) { Location loc = (Location) i.next(); if (loc != null && !loc.blocked) { realNeighbors.add(loc); } } } } else { realNeighbors = new ArrayList(0); } return realNeighbors; } /** * Get a String representation of this Location * @return a String representation of this Location */ public String toString() { return "node: x: " + x + " y: " + y; } /** * Get the current goal of this Location * @return the current goal of this Location */ public Location getGoal() { return goal; } } --- NEW FILE: LocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: LocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import net.sourceforge.huntforgold.graphics.LandTile; import java.util.List; /** * Abstract class for locations at some position on a tile. The interface is created to serve in a * strategypattern for locating neighboring locations in a NodeModel */ public abstract class LocationStrategy { /** * locationMatrix, needed context by any strategy */ protected Location[][][] locationMatrix; /** * landTiles, needed context by any strategy */ protected LandTileSet landTiles; /** * map, needed context by any strategy */ protected ScrollableMap map; /** * Factory method for creating the correct strategys * @param locationIndex index indicating the strategy to instantiate * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy * @return a LocationStrategy corresponding to the location index */ public static LocationStrategy getLocationStrategy(int locationIndex, Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { LocationStrategy result = null; switch (locationIndex) { case 0: result = new NorthWestLocationStrategy(locationMatrix, landTiles, map); break; case 1: result = new NorthLocationStrategy(locationMatrix, landTiles, map); break; case 2: result = new NorthEastLocationStrategy(locationMatrix, landTiles, map); break; case 3: result = new WestLocationStrategy(locationMatrix, landTiles, map); break; case 4: result = new CenterLocationStrategy(locationMatrix, landTiles, map); break; case 5: result = new EastLocationStrategy(locationMatrix, landTiles, map); break; case 6: result = new SouthWestLocationStrategy(locationMatrix, landTiles, map); break; case 7: result = new SouthLocationStrategy(locationMatrix, landTiles, map); break; case 8: result = new SouthEastLocationStrategy(locationMatrix, landTiles, map); break; default: throw new IllegalStateException("locationIndex [" + locationIndex + "] is not in the range [0,8]"); } return result; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public abstract void insertNeighbors(int row, int col, List neighbors, Location goal); /** * This method returns a Location from the specified position of the location model provided the, * point on the map is a water pixel. * If no Location exist in the model with these parameters one is created and cashed in the model * @param row position of the location model * @param col position of the location model * @param tileIndex position of the location model * @param goal the goal of the location in case a new Location must be created * @return a location at the specified position */ protected Location forcedGetLocation(int row, int col, int tileIndex, Location goal) { Location result; if (locationMatrix[row][col][tileIndex] == null) { int x = col * 64; int y = row * 64; int xMod = 0; int yMod = 0; switch (tileIndex) { case 0: xMod += 15; yMod += 15; break; case 1: xMod += 31; yMod += 15; break; case 2: xMod += 47; yMod += 15; break; case 3: xMod += 15; yMod += 31; break; case 4: xMod += 31; yMod += 31; break; case 5: xMod += 47; yMod += 31; break; case 6: xMod += 15; yMod += 47; break; case 7: xMod += 31; yMod += 47; break; case 8: xMod += 47; yMod += 47; break; } LandTile tile = landTiles.getLandTile(map.getTile(row, col)); if (tile.getTileMaskRGB(xMod, yMod) == LandTile.WATER_MASK) { setLocation(row, col, tileIndex, new Location(x + xMod, y + yMod, goal)); } } result = locationMatrix[row][col][tileIndex]; return result; } /** * Set a location associated with a given position on a tile * @param row row of tile in question * @param col column of tile in question * @param tilePos position on tile given by the above in tile as follows * 0 1 2 <br> * 3 4 5 <br> * 6 7 8 <br> * @param location Location to set */ public void setLocation(int row, int col, int tilePos, Location location) { locationMatrix[row][col][tilePos] = location; } } --- NEW FILE: NodeModel.java --- //--------------------------------------------------------------------------------- // $Id: NodeModel.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTile; import net.sourceforge.huntforgold.graphics.LandTileSet; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.model.Town; import net.sourceforge.huntforgold.model.path.Node; import net.sourceforge.huntforgold.model.path.astar.AStar; import net.sourceforge.huntforgold.model.path.astar.PathListener; import net.sourceforge.huntforgold.model.path.astar.PathEvent; import net.sourceforge.huntforgold.util.EditableRoute; import net.sourceforge.huntforgold.util.CoordinateTransform; import net.sourceforge.huntforgold.util.PositionHelper; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import org.apache.log4j.Logger; /** * Model of nodes usable for sailing */ public class NodeModel { /** The logger */ private static Logger log = Logger.getLogger(NodeModel.class); /** * number of rows in model */ private static int tileRows; /** * number of columns in model */ private static int tileCols; /** * Map the model represents */ private static ScrollableMap map; /** * List of nodes in a path */ private List includedNodes; /** * Matrix containing all location. locations are placed as * Tile-x-coordinate, Tile-y-coordinate, no-in-tile where no in tile is as follows * 0 1 2 <br> * 3 4 5 <br> * 6 7 8 <br> */ private static Location[][][] locationMatrix; /** * LandTileset used by the map */ private static LandTileSet landTiles; /** * Creates a NodeModel for a map * @param map the map * @param landTiles LandTileset used by the map * @param scaleFactor the current scale set on the map */ public NodeModel(ScrollableMap map, LandTileSet landTiles, double scaleFactor) { tileRows = (int) (map.getHeight() / scaleFactor / 64); tileCols = (int) (map.getWidth() / scaleFactor / 64); locationMatrix = new Location[tileRows][tileCols][9]; NodeModel.map = map; NodeModel.landTiles = landTiles; } /** * generates a new route between the specified towns * @param startTown name of start town * @param endTown name of end town */ public void generateRoute(String startTown, String endTown) { List towns = map.getTowns(); Town townOne = null; Town townTwo = null; for (int i = 0; i < towns.size(); i++) { Town town = (Town) towns.get(i); if (town.getName().equals(startTown)) { townOne = town; } else if (town.getName().equals(endTown)) { townTwo = town; } } if (townOne != null && townTwo != null) { int x1 = townOne.getPosition().getXAsPixel() / 64; int y1 = townOne.getPosition().getYAsPixel() / 64; Location goal = new Location(townTwo.getPosition().getXAsPixel(), townTwo.getPosition().getYAsPixel(), null); Location start = new Location(townOne.getPosition().getXAsPixel(), townOne.getPosition().getYAsPixel(), goal); //We need to be able to map a given location on a tile to an int in order to find the place in //the locationMatrix. The towns are probably not on these places on the tile, therefor we //initialize the start location by adding neighbors manually on the used posisions on the tile LandTile tile = landTiles.getLandTile(map.getTile(y1, x1)); int index = -1; for (int rowPixel = 15; rowPixel < 63; rowPixel += 16) { for (int colPixel = 15; colPixel < 63; colPixel += 16) { index++; if (tile.getTileMaskRGB(colPixel, rowPixel) == LandTile.WATER_MASK) { Location loc = new Location(x1 * 64 + colPixel, y1 * 64 + rowPixel, goal); setLocation(y1, x1, index, loc); } } } AStar aStar = new AStar(start, goal); aStar.addPathListener(new PathListener() { public void done(PathEvent pathEvent) { includedNodes = pathEvent.getPath(); String message; if (includedNodes == null) { message = new String("No path found "); } else { message = new String("Path of " + includedNodes.size() + " steps found"); } log.info(message); } public void considered(PathEvent pathEvent) { //Not implemented } }); //No need to start a new thread aStar.startSearch(); createRoute(includedNodes); } locationMatrix = null; } /** * Create a Route from the List of Nodes and add it to the map * @param includedNodes List containing the nodes to create the route from */ private void createRoute(List includedNodes) { if (includedNodes != null && !includedNodes.isEmpty()) { EditableRoute editableRoute = new EditableRoute(); editableRoute.setReversible(true); Location start = (Location)includedNodes.get(0); double startX = CoordinateTransform.convertPixelsToLongitude(start.getX()); double startY = CoordinateTransform.convertPixelsToLatitude(start.getY()); Location end = (Location)includedNodes.get(includedNodes.size() - 1); double endX = CoordinateTransform.convertPixelsToLongitude(end.getX()); double endY = CoordinateTransform.convertPixelsToLatitude(end.getY()); Position position = new Position(startX, startY); Node startNode = map.findTown(position, 10); String name = ""; if (startNode != null) { name = startNode.getName() + "-"; } else { log.warn("No start town found for route - aborting createRoute"); return; } position = new Position(endX, endY); Node endNode = map.findTown(position, 10); if (endNode != null) { name = name + endNode.getName(); } else { log.warn("No end town found for route - aborting createRoute"); return; } int index = 0; double previousX = startX; double previousY = startY; Node previousNode = new Node(startNode.getName(), new Position(previousX, previousY)); double previousAngle = Double.MAX_VALUE; Iterator iterator = includedNodes.iterator(); while (iterator.hasNext()) { //TODO try to replace this with the Node interface instead Location location = (Location) iterator.next(); if (location == start) { //We took care of the start location in the initialization continue; } double x = CoordinateTransform.convertPixelsToLongitude(location.getX()); double y = CoordinateTransform.convertPixelsToLatitude(location.getY()); position = new Position(x, y); Node currentNode = map.findNode(position, 10); if (currentNode == null) { currentNode = new Node("help" + name + "#" + index++, position); } x = currentNode.getPosition().getX(); y = currentNode.getPosition().getY(); boolean redundant = false; double relativeX = x - previousX; double relativeY = y - previousY; double angle = PositionHelper.getRadianFromVector(relativeX, relativeY); if (Math.abs(previousAngle - angle) < 0.00000000001 || (x == previousX && y == previousY) || currentNode.getName().equals(previousNode.getName()) ) { redundant = true; } if (!redundant) { editableRoute.addNode(previousNode); } previousNode = new Node(currentNode.getName(), new Position(x, y)); previousX = x; previousY = y; previousAngle = angle; } previousX = endX; previousY = endY; previousNode = new Node(endNode.getName(), new Position(previousX, previousY)); editableRoute.addNode(previousNode); if (editableRoute.getNodeCount() > 1) { map.addRoute(editableRoute.createRoute()); } } } /** * Get a location associated with a given position on a tile * @param row row of tile in question * @param col column of tile in question * @param tilePos position on tile given by the above in tile as follows * 0 1 2 <br> * 3 4 5 <br> * 6 7 8 <br> * @return location */ public static Location getLocation(int row, int col, int tilePos) { return locationMatrix[row][col][tilePos]; } /** * Set a location associated with a given position on a tile * @param row row of tile in question * @param col column of tile in question * @param tilePos position on tile given by the above in tile as follows * 0 1 2 <br> * 3 4 5 <br> * 6 7 8 <br> * @param location Location to set */ public static void setLocation(int row, int col, int tilePos, Location location) { locationMatrix[row][col][tilePos] = location; } /** * Gets the number of tile rows represented in this model * @return the number of tile rows represented in this model */ public int getTileRows() { return tileRows; } /** * Gets the number of tile cols represented in this model * @return the number of tile cols represented in this model */ public int getTileCols() { return tileCols; } /** * Get a list of neighboring locations for the location * @param location Location to get neighbors for * @return List of Location objects */ public static List getNeighbors(Location location) { List result = new ArrayList(8); { int pixelX = location.getX(); int pixelY = location.getY(); int tileX = pixelX - ((pixelX / 64) * 64); int tileY = pixelY - ((pixelY / 64) * 64); LandTile tile = landTiles.getLandTile(map.getTile(pixelY / 64, pixelX / 64)); int index; if (tile.isOnlyWater()) { index = 4; } else { index = getTileIndex(tileX, tileY); } insertNeighbors(pixelY / 64, pixelX / 64, index, location, result); } return result; } /** * insert neighboring locations in the neighbor list and cash any new discovered Locations * @param row tile row * @param col tile col * @param tileIndex index of the location in the model * @param location location to add to the model * @param neighbors List to add neighbors to */ private static void insertNeighbors(int row, int col, int tileIndex, Location location, List neighbors) { if (locationMatrix[row][col][tileIndex] == null) { locationMatrix[row][col][tileIndex] = location; } Location goal = location.getGoal(); LocationStrategy.getLocationStrategy(tileIndex, locationMatrix, landTiles, map). insertNeighbors(row, col, neighbors, goal); } /** * Get the tile index from 0 through 8 corresponding to the models representation of nodes on a * tile. * @param tileX x position on tile * @param tileY y position on tile * @return an int in the range 0 - 8 corresponding to the following position on the tile: * 0 1 2 <br> * 3 4 5 <br> * 6 7 8 <br> */ private static int getTileIndex(int tileX, int tileY) { int result = 4; switch (tileX) { case 15: switch (tileY) { case 15: result = 0; break; case 31: result = 1; break; case 47: result = 2; break; } break; case 31: switch (tileY) { case 15: result = 3; break; case 31: result = 4; break; case 47: result = 5; break; } break; case 47: switch (tileY) { case 15: result = 6; break; case 31: result = 7; break; case 47: result = 8; break; } } return result; } } --- NEW FILE: NorthEastLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: NorthEastLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for north east (on tile) locations */ public class NorthEastLocationStrategy extends LocationStrategy { /** * Number of cols in the map */ private int tileCols; /** * Constructor for north east strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected NorthEastLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; tileCols = map.getWidth() / 64; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean northIsWaterTile = false; boolean northEastIsWaterTile = false; boolean eastIsWaterTile = false; if (row > 0) { northIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col))).isOnlyWater(); } if (row > 0 && col < tileCols - 1) { northEastIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col + 1))).isOnlyWater(); } if (col < tileCols - 1) { eastIsWaterTile = (landTiles.getLandTile(map.getTile(row, col + 1))).isOnlyWater(); } if (row > 0) { if (northIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col, 7, goal)); neighbors.add(forcedGetLocation(row - 1, col, 8, goal)); } if (col < tileCols - 1) { if (northEastIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col + 1, 6, goal)); } } } if (col < tileCols - 1) { if (eastIsWaterTile) { neighbors.add(forcedGetLocation(row, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col + 1, 0, goal)); neighbors.add(forcedGetLocation(row, col + 1, 3, goal)); } } neighbors.add(forcedGetLocation(row, col, 1, goal)); neighbors.add(forcedGetLocation(row, col, 4, goal)); neighbors.add(forcedGetLocation(row, col, 5, goal)); } } --- NEW FILE: NorthLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: NorthLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for north (on tile) locations */ public class NorthLocationStrategy extends LocationStrategy { /** * Constructor for north strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected NorthLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean northIsWaterTile = false; if (row > 0) { northIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col))).isOnlyWater(); } if (row > 0) { if (northIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col, 6, goal)); neighbors.add(forcedGetLocation(row - 1, col, 7, goal)); neighbors.add(forcedGetLocation(row - 1, col, 8, goal)); } } neighbors.add(forcedGetLocation(row, col, 0, goal)); neighbors.add(forcedGetLocation(row, col, 2, goal)); neighbors.add(forcedGetLocation(row, col, 3, goal)); neighbors.add(forcedGetLocation(row, col, 4, goal)); neighbors.add(forcedGetLocation(row, col, 5, goal)); } } --- NEW FILE: NorthWestLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: NorthWestLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for north west (on tile) locations */ public class NorthWestLocationStrategy extends LocationStrategy { /** * Constructor for north west strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected NorthWestLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean northWestIsWaterTile = false; boolean northIsWaterTile = false; boolean westIsWaterTile = false; if (row > 0 && col > 0) { northWestIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col - 1))).isOnlyWater(); } if (row > 0) { northIsWaterTile = (landTiles.getLandTile(map.getTile(row - 1, col))).isOnlyWater(); } if (col > 0) { westIsWaterTile = (landTiles.getLandTile(map.getTile(row, col - 1))).isOnlyWater(); } if (row > 0) { if (col > 0) { if (northWestIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col - 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col - 1, 8, goal)); } } if (northIsWaterTile) { neighbors.add(forcedGetLocation(row - 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row - 1, col, 6, goal)); neighbors.add(forcedGetLocation(row - 1, col, 7, goal)); } } if (col > 0) { if (westIsWaterTile) { neighbors.add(forcedGetLocation(row, col - 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col - 1, 2, goal)); neighbors.add(forcedGetLocation(row, col - 1, 5, goal)); } } neighbors.add(forcedGetLocation(row, col, 1, goal)); neighbors.add(forcedGetLocation(row, col, 3, goal)); neighbors.add(forcedGetLocation(row, col, 4, goal)); } } --- NEW FILE: RouteActionListener.java --- //--------------------------------------------------------------------------------- // $Id: RouteActionListener.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import java.awt.event.ActionListener; import net.sourceforge.huntforgold.model.path.Route; import net.sourceforge.huntforgold.common.AbstractScrollableMap; /** * * An ActionListener which is based upon a relationship to a given position in a map */ public abstract class RouteActionListener implements ActionListener { /** * ScrollableMap defining the context of the action */ private AbstractScrollableMap map; /** * Node to create an action from */ private Route route; /** * Constructor for the ActionListener * @param map ScrollableMap defining the context of the action * @param route Route to create an action from */ public RouteActionListener(AbstractScrollableMap map, Route route) { this.map = map; this.route = route; } /** * Return the Route of this ActionListener * @return Route */ public Route getRoute() { return route; } /** * Return the map of this ActionListener * @return map */ public AbstractScrollableMap getMap() { return map; } } --- NEW FILE: RouteEditor.java --- //--------------------------------------------------------------------------------- // $Id: RouteEditor.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.TileSet; import net.sourceforge.huntforgold.graphics.LandTileSet; import net.sourceforge.huntforgold.graphics.LandTile; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.model.Town; import net.sourceforge.huntforgold.model.XMLLoader; import net.sourceforge.huntforgold.model.XMLSaver; import net.sourceforge.huntforgold.model.map.MapManager; import net.sourceforge.huntforgold.model.path.Node; import net.sourceforge.huntforgold.model.path.Route; import net.sourceforge.huntforgold.util.ResourceManager; [...1431 lines suppressed...] double y = CoordinateTransform.convertPixelsToLatitude(e.getY()); Position position = new Position(x, y); Node node = map.findNode(position, 50); if (node != null) { map.moveNode(node.getName(), position); } mouseMoved(e); } /** * Mouse moved * @param e The mouse event */ public void mouseMoved(MouseEvent e) { int row = e.getX() / map.getCurrentTileWidth(); int col = e.getY() / map.getCurrentTileHeight(); statusBar.setCursorCoord(row, col); } } } --- NEW FILE: ScrollableMap.java --- //--------------------------------------------------------------------------------- // $Id: ScrollableMap.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.model.path.Node; import net.sourceforge.huntforgold.model.path.Route; import net.sourceforge.huntforgold.common.AbstractScrollableMap; import net.sourceforge.huntforgold.graphics.TileSet; import net.sourceforge.huntforgold.util.EditableRoute; import net.sourceforge.huntforgold.util.CoordinateTransform; import java.util.Set; import java.util.HashSet; import java.util.Iterator; /** * Extension of the common scrollable map, used to edit routes */ public class ScrollableMap extends AbstractScrollableMap { /** * Constructs a scrollable map based upon a tile set and * a town tile set * @param tileSet The tile set * @param landTiles The land tile set * @param townTiles The town tile set */ public ScrollableMap(TileSet tileSet, TileSet landTiles, TileSet townTiles) { super(tileSet, landTiles, townTiles); } /** * Set the mouse pressed position * @param x The x position * @param y The y position */ public void mousePressed(int x, int y) { xClicked = x / tileWidth; yClicked = y / tileHeight; if (xClicked < nColumns && yClicked < nRows) { Position position = new Position(CoordinateTransform.convertPixelsToLongitude(x), CoordinateTransform.convertPixelsToLatitude(y)); Node node = findNode(position, 10); if (node == null) { node = new Node("help#" + helpNodeIndex++, position); } int i = tileIndex; switch (i) { case 0: //Start new route currentRoute = new EditableRoute(); currentRoute.setReversible(true); currentRoute.addNode(node); repaint(); break; case 2: //End of new route if (currentRoute != null) { currentRoute.addNode(node); Route newRoute = currentRoute.createRoute(); updateRoute(newRoute); currentRoute = null; repaint(); } break; default: //Add help node for new route if (currentRoute != null) { currentRoute.addNode(node); repaint(); } break; } } } /** * Move a node to a new position, and update all routes using this node * @param nodeName name of node to be moved to new position * @param position Position to move node to */ public void moveNode(String nodeName, Position position) { Node node = (Node) nodes.get(nodeName); if (node != null) { Node newNode = new Node(nodeName, position); nodes.put(newNode.getName(), newNode); //update routes Set routesToUpdate = new HashSet(); for (Iterator iterator = routes.values().iterator(); iterator.hasNext();) { Route route = (Route) iterator.next(); Node[] nodes = route.getNodes(); for (int i = 0; i < nodes.length; i++) { Node tempNode = nodes[i]; if (nodeName.equals(tempNode.getName())) { //We must regenerate the route routesToUpdate.add(route.getName()); break; } } } for (Iterator iterator = routesToUpdate.iterator(); iterator.hasNext();) { String routeName = (String) iterator.next(); Route route = (Route) routes.get(routeName); EditableRoute editableRoute = new EditableRoute(); editableRoute.setName(route.getName()); editableRoute.setReversible(route.isReversible()); Node[] nodes = route.getNodes(); for (int i = 0; i < nodes.length; i++) { Node tempNode = nodes[i]; if (nodeName.equals(tempNode.getName())) { editableRoute.addNode(newNode); } else { editableRoute.addNode(tempNode); } } updateRoute(editableRoute.createRoute()); } repaint(); } } /** * Remove a node, and update all routes using this node * @param nodeName name of node to be removed */ public void removeNode(String nodeName) { Node node = (Node) nodes.get(nodeName); if (node != null) { //update routes Set routesToUpdate = new HashSet(); for (Iterator iterator = routes.values().iterator(); iterator.hasNext();) { Route route = (Route) iterator.next(); Node[] nodes = route.getNodes(); for (int i = 0; i < nodes.length; i++) { Node tempNode = nodes[i]; if (nodeName.equals(tempNode.getName())) { //We must regenerate the route routesToUpdate.add(route.getName()); break; } } } for (Iterator iterator = routesToUpdate.iterator(); iterator.hasNext();) { String routeName = (String) iterator.next(); Route route = (Route) routes.get(routeName); EditableRoute editableRoute = new EditableRoute(); editableRoute.setName(route.getName()); editableRoute.setReversible(route.isReversible()); Node[] nodes = route.getNodes(); for (int i = 0; i < nodes.length; i++) { Node tempNode = nodes[i]; if (!nodeName.equals(tempNode.getName())) { editableRoute.addNode(tempNode); } } updateRoute(editableRoute.createRoute()); } //Remove the node from the model nodes.remove(nodeName); repaint(); } } } --- NEW FILE: ScrollableTileList.java --- //--------------------------------------------------------------------------------- // $Id: ScrollableTileList.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.TileSet; import net.sourceforge.huntforgold.common.AbstractScrollableMap; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Image; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.Scrollable; import org.apache.log4j.Logger; /** * Implements a scrollable tile list */ public class ScrollableTileList extends JComponent implements Scrollable { /** The logger */ private static Logger log = Logger.getLogger(ScrollableTileList.class); /** The tiles */ private BufferedImage[] tiles; /** The tile buttons */ private JButton[] tileButtons; /** Index of selected tile */ private byte selectedTile; /** The map */ private AbstractScrollableMap map; /** The icon width */ private static final int ICONWIDTH = 40; /** The icon height */ private static final int ICONHEIGHT = 40; /** The icon border size */ private static final int ICONBORDERSIZE = 1; /** The icon columns */ private static final int ICONCOLUMNS = 2; /** * Creates a ScrollableTileList based upon a tile set * @param tileSet The tile set */ public ScrollableTileList(TileSet tileSet) { TileSetListener listener = new TileSetListener(); tileButtons = new JButton[tileSet.getNumberOfTiles()]; tiles = new BufferedImage[tileSet.getNumberOfTiles()]; for (byte i = 0; i < tileSet.getNumberOfTiles(); i++) { tiles[i] = tileSet.getTile(i).getTile(); Image img = tiles[i].getScaledInstance(ICONWIDTH, ICONHEIGHT, Image.SCALE_SMOOTH); tileButtons[i] = new JButton(new ImageIcon(img)); tileButtons[i].setMargin(new Insets(ICONBORDERSIZE, ICONBORDERSIZE, ICONBORDERSIZE, ICONBORDERSIZE)); tileButtons[i].addActionListener(listener); String string = Integer.toString(i); tileButtons[i].setActionCommand(string); add(tileButtons[i]); } setLayout(new GridLayout(0, ICONCOLUMNS)); tileButtons[0].setBackground(Color.red); } /** * Set the scrollable map * @param map The map */ public void setMap(AbstractScrollableMap map) { this.map = map; } /** * Get the perferred viewport size * @return The vireport dimension */ public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } /** * Get the unit increment * @param visibleRect The visible rectangle * @param orientation The orientation * @param direction The direction * @return The increment */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return 100; } /** * Get the block increment * @param visibleRect The visible rectangle * @param orientation The orientation * @param direction The direction * @return The increment */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return 100; } /** * Should viewport width be tracked * @return True if the viewport should be tracked; otherwise false */ public boolean getScrollableTracksViewportWidth() { return true; } /** * Should viewport height be tracked * @return True if the viewport should be tracked; otherwise false */ public boolean getScrollableTracksViewportHeight() { return false; } /** * Implements a tile set listener */ class TileSetListener implements ActionListener { /** * Action listener interface * @param e The action event */ public void actionPerformed(ActionEvent e) { tileButtons[selectedTile].setBackground(Color.lightGray); Object tis = e.getSource(); String string = e.getActionCommand(); Byte b = Byte.decode(string); selectedTile = b.byteValue(); tileButtons[selectedTile].setBackground(Color.red); if (map != null) { map.setSelectedTile(selectedTile); } } } } --- NEW FILE: SouthEastLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: SouthEastLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for south east (on tile) locations */ public class SouthEastLocationStrategy extends LocationStrategy { /** * Number of rows in the map */ private int tileRows; /** * Number of cols in the map */ private int tileCols; /** * Constructor for south east strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected SouthEastLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; tileRows = map.getHeight() / 64; tileCols = map.getWidth() / 64; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean eastIsWaterTile = false; boolean southIsWaterTile = false; boolean southEastIsWaterTile = false; if (col < tileCols - 1) { eastIsWaterTile = (landTiles.getLandTile(map.getTile(row, col + 1))).isOnlyWater(); } if (row < tileRows - 1) { southIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col))).isOnlyWater(); } if (row < tileRows - 1 && col < tileCols - 1) { southEastIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col + 1))).isOnlyWater(); } if (col < tileCols - 1) { if (eastIsWaterTile) { neighbors.add(forcedGetLocation(row, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row, col + 1, 3, goal)); neighbors.add(forcedGetLocation(row, col + 1, 6, goal)); } } if (row < tileRows - 1) { if (southIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col, 1, goal)); neighbors.add(forcedGetLocation(row + 1, col, 2, goal)); } if (col < tileCols - 1) { if (southEastIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col + 1, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col + 1, 0, goal)); } } } neighbors.add(forcedGetLocation(row, col, 4, goal)); neighbors.add(forcedGetLocation(row, col, 5, goal)); neighbors.add(forcedGetLocation(row, col, 7, goal)); } } --- NEW FILE: SouthLocationStrategy.java --- //--------------------------------------------------------------------------------- // $Id: SouthLocationStrategy.java,v 1.1 2004/07/01 08:39:15 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.routeeditor; import net.sourceforge.huntforgold.graphics.LandTileSet; import java.util.List; /** * Strategy for south (on tile) locations */ public class SouthLocationStrategy extends LocationStrategy { /** * Number of rows in the map */ private int tileRows; /** * Constructor for south strategy * @param locationMatrix needed context by any strategy * @param landTiles needed context by any strategy * @param map needed context by any strategy */ protected SouthLocationStrategy(Location[][][] locationMatrix, LandTileSet landTiles, ScrollableMap map) { this.locationMatrix = locationMatrix; this.landTiles = landTiles; this.map = map; tileRows = map.getHeight() / 64; } /** * Inserts neighboring locations into the locationMatrix based on the info in the map * @param row current tile row * @param col current tile col * @param neighbors List to add found neighbors to * @param goal goal for the potential new neighbor locations */ public void insertNeighbors(int row, int col, List neighbors, Location goal) { boolean southIsWaterTile = false; if (row < tileRows - 1) { southIsWaterTile = (landTiles.getLandTile(map.getTile(row + 1, col))).isOnlyWater(); } if (row < tileRows - 1) { if (southIsWaterTile) { neighbors.add(forcedGetLocation(row + 1, col, 4, goal)); } else { neighbors.add(forcedGetLocation(row + 1, col, 0, goal)); neighbors.add(forcedGetLocation(row + 1, col, 1, goal)); neighbors.add(fo... [truncated message content] |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:37:21
|
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/routeeditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4938/routeeditor Log Message: Directory /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/routeeditor added to the repository |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:36:12
|
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4631 Added Files: EditableRoute.java Log Message: Initial import --- NEW FILE: EditableRoute.java --- //--------------------------------------------------------------------------------- // $Id: EditableRoute.java,v 1.1 2004/07/01 08:36:02 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.util; import java.util.LinkedList; import net.sourceforge.huntforgold.model.path.Node; import net.sourceforge.huntforgold.model.path.Route; /** * This class is used to generate routes, i.e. it is possible to * set otherwise private attributes */ public class EditableRoute { /** * list of nodes */ private LinkedList nodes = new LinkedList(); /** * name of the route */ private String name; /** * revesible */ private boolean reversible; /** * Constructor * */ public EditableRoute() { } /** * setReversible * @param reversible Indication of reversible */ public void setReversible(boolean reversible) { this.reversible = reversible; } /** * isReversible * @return reversible Indication of reversible */ public boolean isReversible() { return reversible; } /** * setName * @param name the name of the route */ public void setName(String name) { this.name = name; } /** * @return name */ public String getName() { return name; } /** * Create a route from this EditableRoute * @return route */ public Route createRoute() { Object [] tempNodes = nodes.toArray(); Node[] finalNodes = new Node [tempNodes.length]; for (int i = 0; i < tempNodes.length; i++) { finalNodes[i] = (Node) tempNodes[i]; } return new Route(name, finalNodes, reversible); } /** * Add the next node * @param node Node to add */ public void addNode(Node node) { nodes.addLast(node); String newName = ((Node)nodes.getFirst()).getName() + " - " + ((Node)nodes.getLast()).getName(); setName(newName); } /** * Get the current number of nodes in the route * @return the current number of nodes in the route */ public int getNodeCount() { return nodes.size(); } } |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:33:38
|
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/common In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4089 Modified Files: AbstractScrollableMap.java Log Message: Added support for routes Index: AbstractScrollableMap.java =================================================================== RCS file: /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/common/AbstractScrollableMap.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- AbstractScrollableMap.java 28 Apr 2004 18:16:11 -0000 1.3 +++ AbstractScrollableMap.java 1 Jul 2004 08:33:29 -0000 1.4 @@ -9,8 +9,11 @@ import net.sourceforge.huntforgold.graphics.TileSet; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.model.Town; +import net.sourceforge.huntforgold.model.path.Node; +import net.sourceforge.huntforgold.model.path.Route; import net.sourceforge.huntforgold.model.map.MapManager; -import net.sourceforge.huntforgold.util.CoordinateTransform; +import net.sourceforge.huntforgold.util.EditableRoute; +import net.sourceforge.huntforgold.util.Distance; import java.awt.Color; import java.awt.Container; @@ -21,6 +24,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.HashMap; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -78,6 +83,21 @@ /** A list of towns */ protected List towns; + /** A map of routes */ + protected Map routes; + + /** A map of nodes */ + protected Map nodes; + + /** The route which is being created */ + protected EditableRoute currentRoute; + + /** The highst usd index on help nodes */ + protected int helpNodeIndex; + + /** Propety used to inform about route changes */ + public static final String ROUTE_CHANGED = "route_changed"; + /** Propety used to inform about scale factor changes */ public static final String SCALE_FACTOR_CHANGED = "scaleFactor"; @@ -93,10 +113,12 @@ this.landTiles = landTiles; this.townTiles = townTiles; this.mapActive = false; - setSelectedTile((byte)1); + this.tileIndex = 1; this.towns = new ArrayList(); - setScaleFactor(1.0); + this.routes = new HashMap(); + this.nodes = new HashMap(); this.mapManager = MapManager.getMapManager(); + setScaleFactor(1.0); } /** @@ -104,16 +126,43 @@ * @param town The town */ public void addTown(Town town) { - int x1 = CoordinateTransform.convertLongitudeToPixels(town.getPosition().getX()) - - townTiles.getTileSize() / 2; - int y1 = CoordinateTransform.convertLatitudeToPixels(town.getPosition().getY()) - - townTiles.getTileSize() / 2; - String name = town.getName(); - Position position = new Position((double)x1, (double)y1); - towns.add(new Town(name, position, town.getStartYear(), - town.getEndYear(), town.getNationality(), town.getNumberOfForts(), - town.getNumberOfMen(), town.hasMerchant(), town.hasTavern(), town.hasBank(), - town.hasShipyard(), town.hasGovernor(), town.hasBrothel())); + towns.add(town); + nodes.put(town.getName(), new Node(town.getName(), town.getPosition())); + } + + /** + * Add a route to the map + * @param route The route + */ + public void addRoute(Route route) { + Node [] newNodes = new Node [route.getNodes().length]; + int i; + for (i = 0; i < newNodes.length; i++) { + Node tempNode = route.getNode(i); + String tempNodeName = tempNode.getName(); + newNodes[i] = tempNode; + nodes.put(tempNodeName, tempNode); + //Check if we have initial help nodes + if (tempNodeName.startsWith("help")) { + int helpIndex = + Integer.parseInt(tempNodeName.substring(tempNodeName.lastIndexOf("#") + 1).trim()); + if (helpIndex >= helpNodeIndex) { + helpNodeIndex = helpIndex + 1; + } + } + } + routes.put(route.getName(), + new Route(route.getName(), newNodes, route.isReversible())); + firePropertyChange(ROUTE_CHANGED, null, route); + } + + /** + * Removes a route from the map + * @param routeName The name of the route to remove + */ + public void removeRoute(String routeName) { + //TODO also remove any unused nodes + routes.remove(routeName); } /** @@ -250,15 +299,108 @@ //Towns for (Iterator townIt = towns.iterator(); townIt.hasNext(); ) { Town town = (Town)townIt.next(); - g.drawImage(townTiles.getTile((byte)0).getTile(), - (int)(town.getPosition().getX() * scaleFactor), - (int)(town.getPosition().getY() * scaleFactor), + g.drawImage(townTiles.getTile((byte)0).getTile(), + getImageCorner(town.getPosition().getXAsPixel()), + getImageCorner(town.getPosition().getYAsPixel()), tileWidth, tileHeight, this); + g.drawString(town.getName(), + getImageCorner(town.getPosition().getXAsPixel()), + getImageCorner(town.getPosition().getYAsPixel())); + } + } + + //Routes + for (Iterator routeIt = routes.values().iterator(); routeIt.hasNext(); ) { + Route route = (Route) routeIt.next(); + Node [] nodes = route.getNodes(); + //Draw start + g.drawImage(tileSet.getTile((byte)0).getTile(), + getImageCorner(nodes[0].getPosition().getXAsPixel()), + getImageCorner(nodes[0].getPosition().getYAsPixel()), + tileWidth, tileHeight, this); + //Draw end + int i = nodes.length - 1; + int x = (int) nodes[i].getPosition().getXAsPixel(); + int y = (int) nodes[i].getPosition().getYAsPixel(); + g.drawImage(tileSet.getTile((byte)2).getTile(), + getImageCorner(x), + getImageCorner(y), + tileWidth, tileHeight, this); + int x2 = nodes[i - 1].getPosition().getXAsPixel(); + int y2 = nodes[i - 1].getPosition().getYAsPixel(); + g.drawLine((int) (x * scaleFactor), + (int) (y * scaleFactor), + (int) (x2 * scaleFactor), + (int) (y2 * scaleFactor)); + //Draw help nodes + for (i = 1; i < nodes.length - 1; i++) { + x = nodes[i].getPosition().getXAsPixel(); + y = nodes[i].getPosition().getYAsPixel(); + g.drawImage(tileSet.getTile((byte)1).getTile(), + getImageCorner(x), + getImageCorner(y), + tileWidth, tileHeight, this); + x2 = nodes[i - 1].getPosition().getXAsPixel(); + y2 = nodes[i - 1].getPosition().getYAsPixel(); + g.drawLine((int) (x * scaleFactor), + (int) (y * scaleFactor), + (int) (x2 * scaleFactor), + (int) (y2 * scaleFactor)); + } + } + // Current Route + if (currentRoute != null) { + Route route = currentRoute.createRoute(); + Node [] nodes = route.getNodes(); + //Draw start + g.drawImage(tileSet.getTile((byte)0).getTile(), + getImageCorner(nodes[0].getPosition().getXAsPixel()), + getImageCorner(nodes[0].getPosition().getYAsPixel()), + tileWidth, tileHeight, this); + if (nodes.length > 1) { + //Draw end + int i = nodes.length - 1; + int x = nodes[i].getPosition().getXAsPixel(); + int y = nodes[i].getPosition().getYAsPixel(); + g.drawImage(tileSet.getTile((byte)2).getTile(), + getImageCorner(x), + getImageCorner(y), + tileWidth, tileHeight, this); + int x2 = nodes[i - 1].getPosition().getXAsPixel(); + int y2 = nodes[i - 1].getPosition().getYAsPixel(); + g.drawLine((int) (x * scaleFactor), + (int) (y * scaleFactor), + (int) (x2 * scaleFactor), + (int) (y2 * scaleFactor)); + //Draw help nodes + for (i = 1; i < nodes.length - 1; i++) { + x = nodes[i].getPosition().getXAsPixel(); + y = nodes[i].getPosition().getYAsPixel(); + g.drawImage(tileSet.getTile((byte)1).getTile(), + getImageCorner(x), + getImageCorner(y), + tileWidth, tileHeight, this); + x2 = nodes[i - 1].getPosition().getXAsPixel(); + y2 = nodes[i - 1].getPosition().getYAsPixel(); + g.drawLine((int) (x * scaleFactor), + (int) (y * scaleFactor), + (int) (x2 * scaleFactor), + (int) (y2 * scaleFactor)); + } } } } - + /** + * Converts a position double to an int representing the upper right cornor when drawing an icon + * @param pos x or y pos for a point on the map + * @return an int representing the corresponding cornor pos + */ + private int getImageCorner(double pos) { + return (int)((pos - tileSet.getTileSize() / 2) * scaleFactor); + } + + /** * Set the selected tile * @param tileIndex The tile index @@ -349,4 +491,103 @@ return towns; } + /** + * Get the a Map of currently defined routes + * @return the Map of Routes + */ + public Map getRoutes() { + return routes; + } + + /** + * This method is used to find a node with a given position. If no node exist on the position + * null is returned + * @param position Position at which there might be a node + * @param tolerance number of pixels the node can be away from position + * @return Null if no nodes are placed at the position, otherwise a node with the position + */ + public Node findNode(Position position, int tolerance) { + int x = position.getXAsPixel(); + int y = position.getYAsPixel(); + Node result = null; + double minDist = Double.MAX_VALUE; + for (Iterator iterator = nodes.values().iterator(); iterator.hasNext() && result == null;) { + Node node = (Node) iterator.next(); + Position currentPosition = node.getPosition(); + int origX = currentPosition.getXAsPixel(); + int origY = currentPosition.getYAsPixel(); + //Allow +- tolerance in difference + double distance = Distance.getDistance(position, currentPosition, Distance.DISTANCE_KM); + if (origX >= x - tolerance && + origX <= x + tolerance && + origY >= y - tolerance && + origY <= y + tolerance && + distance < minDist) { + result = new Node(node.getName(), + new Position(currentPosition.getX(), + currentPosition.getY())); + minDist = distance; + } + } + return result; + + } + + /** + * This method is used to find a node representing a town on a given position. + * If no town exist on the position null is returned + * @param position Position at which there might be a node + * @param tolerance number of pixels the town can be away from position + * @return Null if no town are placed at the position, otherwise a town with the position + */ + public Node findTown(Position position, int tolerance) { + int x = position.getXAsPixel(); + int y = position.getYAsPixel(); + Node result = null; + double minDist = Double.MAX_VALUE; + for (Iterator iterator = towns.iterator(); iterator.hasNext() && result == null;) { + Town node = (Town) iterator.next(); + Position currentPosition = node.getPosition(); + int origX = currentPosition.getXAsPixel(); + int origY = currentPosition.getYAsPixel(); + //Allow +- tolerance pixels in difference + double distance = Distance.getDistance(position, currentPosition, Distance.DISTANCE_KM); + if (origX >= x - tolerance && + origX <= x + tolerance && + origY >= y - tolerance && + origY <= y + tolerance && + distance < minDist) { + result = new Node(node.getName(), + new Position(currentPosition.getX(), + currentPosition.getY())); + minDist = distance; + } + } + return result; + + } + + /** + * update a route in the map - or add a route which has nodes with correct position format + * @param route The route + */ + public void updateRoute(Route route) { + Node [] newNodes = new Node [route.getNodes().length]; + int i; + for (i = 0; i < newNodes.length; i++) { + Node tempNode = route.getNode(i); + double x = tempNode.getPosition().getX(); + double y = tempNode.getPosition().getY(); + Position position = new Position(x, y); + String tempNodeName = tempNode.getName(); + Node newNode = new Node(tempNodeName, position); + newNodes[i] = newNode; + nodes.put(newNode.getName(), newNode); + } + Route oldRoute = (Route) routes.get(route.getName()); + routes.put(route.getName(), + new Route(route.getName(), newNodes, route.isReversible())); + firePropertyChange(ROUTE_CHANGED, oldRoute, route); + } + } |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:31:10
|
Update of /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/common In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3491 Modified Files: GotoTownMenu.java Log Message: Use getXAsPixel and getYAspixel on Position Index: GotoTownMenu.java =================================================================== RCS file: /cvsroot/huntforgold/editors/src/net/sourceforge/huntforgold/common/GotoTownMenu.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- GotoTownMenu.java 28 Jan 2004 13:34:45 -0000 1.1 +++ GotoTownMenu.java 1 Jul 2004 08:31:00 -0000 1.2 @@ -48,8 +48,8 @@ townMenuItem .addActionListener(new PositionActionListener(map, tempTown.getPosition()) { public void actionPerformed(ActionEvent ae) { - int x = (int) getPosition().getX(); - int y = (int) getPosition().getY(); + int x = getPosition().getXAsPixel(); + int y = getPosition().getYAsPixel(); map.setScaleFactor(1.0); map.setCenter(x, y); } |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:28:05
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2525 Added Files: AStar.java AbstractPathFinder.java DepthFirstSearch.java Node.java PathEvent.java PathFinder.java PathListener.java package.html Log Message: Initial import - based on the cuspy implementation --- NEW FILE: AStar.java --- //--------------------------------------------------------------------------------- // $Id: AStar.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; /** * An implementation of the A* path finding algorithm. * * @author Gene McCulley */ public class AStar extends AbstractPathFinder { /** * Possible nodes */ private SortedSet open; /** * Possible nodes */ private Map openMap; /** * Examined nodes */ private Map closed; /** * current state */ private State state; /** * Create a new AStar calculating path from start to goal * @param start The Start point * @param goal The end point */ public AStar(Node start, Node goal) { super(start, goal); } /** * Create a new AStar calculating path from start to goals * @param start The Start point * @param goals The end points */ public AStar(Node start, Collection goals) { super(start, goals); } /** * State class keeping track of costs */ private class State implements Comparable { /** * Current node */ private Node node; /** * Initial costs */ private double costFromStart; /** * costs untill goal is reached */ private double costToGoal; /** * Parent state */ private State parent; /** * Creates a new state corresponding to the Node and the path found so far * @param node Current node * @param costFromStart Current start cost * @param parent The previous state before moving to this state */ public State(Node node, double costFromStart, State parent) { this.node = node; this.costFromStart = costFromStart; costToGoal = minimumPathCostEstimate(node); this.parent = parent; } /** * Estimation of minimal costs of traveling node to one of the goals * @param node Node to examine * @return Estimation of minimal costs */ private double minimumPathCostEstimate(Node node) { double min = Double.MAX_VALUE; for (Iterator i = goals.iterator(); i.hasNext(); ) { double cost = node.getPathCostEstimate((Node)i.next()); if (cost < min) { min = cost; } } return min; } /** * Getter for costFromStart * @return start costs */ public double getCostFromStart() { return costFromStart; } /** * Returns total costs * @return total costs */ public double getTotalCost() { return costFromStart + costToGoal; } /** * Getter for node * @return the node */ public Node getNode() { return node; } /** * Getter for parent * @return the parent */ public State getParent() { return parent; } /** * Compare the cost of this state to another state * @param other MUST be other State * @return The cost difference (total cost) of the two states */ public int compareTo(Object other) { double result = getTotalCost() - ((State)other).getTotalCost(); if (result > 0) { return 1; } else if (result < 0) { return -1; } else { return 0; } } /** * Pretty print of the state * @return Pretty print of the state */ public String toString() { return "State: " + node + " costFromStart: " + costFromStart + " costToGoal: " + costToGoal + " totalCost: " + getTotalCost(); } } /** * Gets list of considdered nodes * @return List of considdered nodes */ public List getConsideredPath() { List result = new LinkedList(); State s = state; while (s != null) { result.add(s.getNode()); s = s.getParent(); } Collections.reverse(result); return result; } /** * Finds the path from start to goal(s) * @return list of Nodes in the path */ public List findPath() { open = new TreeSet(); openMap = new HashMap(); closed = new HashMap(); State startState = new State(start, 0, null); open.add(startState); openMap.put(start, startState); while (!(open.isEmpty() || aborted)) { state = (State)open.first(); open.remove(state); openMap.remove(state.getNode()); fireConsidered(); if (goals.contains(state.getNode())) { return getConsideredPath(); } else { Iterator neighbors = state.getNode().getNeighbors().iterator(); while (neighbors.hasNext()) { Node newNode = (Node)neighbors.next(); double newCost = state.getCostFromStart() + state.getNode().getTraverseCost(newNode); State openNode = (State)openMap.get(newNode); if (openNode != null && openNode.getCostFromStart() <= newCost) { continue; } State closedNode = (State)closed.get(newNode); if (closedNode != null && closedNode.getCostFromStart() <= newCost) { continue; } State newState = new State(newNode, newCost, state); if (closedNode != null) { closed.remove(newNode); } if (openNode != null) { open.remove(openNode); openMap.remove(newNode); } open.add(newState); openMap.put(newNode, newState); } } closed.put(state.getNode(), state); } return null; } } --- NEW FILE: AbstractPathFinder.java --- //--------------------------------------------------------------------------------- // $Id: AbstractPathFinder.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Basic functionality of path finders. * * @author Gene McCulley */ public abstract class AbstractPathFinder implements PathFinder { /** * Start node */ protected Node start; /** * End Nodes */ protected Collection goals; /** * List of PathListeners */ protected List listeners = new ArrayList(); /** * Abort search indicator */ protected boolean aborted; /** * Create a new PathFinder. * * @param start the Node to start with. * @param goal the Node to end at. */ public AbstractPathFinder(Node start, Node goal) { this.start = start; goals = Collections.singletonList(goal); } /** * Create a new PathFinder. * * @param start the Node to start with. * @param goals a Collection of Nodes to end at. */ public AbstractPathFinder(Node start, Collection goals) { this.start = start; this.goals = new ArrayList(goals); } /** * Sets abort = true */ public void abort() { aborted = true; } /** * Execute the path finding algorithm. */ public void startSearch() { List path = findPath(); PathEvent event = new PathEvent(this, path); for (Iterator i = listeners.iterator(); i.hasNext(); ) { PathListener listener = (PathListener)i.next(); listener.done(event); } } /** * Notifies listeners about PathEvents */ protected void fireConsidered() { PathEvent event = new PathEvent(this, null); for (Iterator i = listeners.iterator(); i.hasNext(); ) { PathListener listener = (PathListener)i.next(); listener.considered(event); } } /** * Add a PathListener * @param l the PathListener to add */ public void addPathListener(PathListener l) { listeners.add(l); } /** * Removes a PathListener * @param l the PathListener to remove */ public void removePathListener(PathListener l) { listeners.remove(l); } } --- NEW FILE: DepthFirstSearch.java --- //--------------------------------------------------------------------------------- // $Id: DepthFirstSearch.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * An implementation of the Depth First Search path finding algorithm. * * @author Gene McCulley */ public class DepthFirstSearch extends AbstractPathFinder { /** * List of vissited Nodes */ private List visited; /** * Creates a new DepthFirstSearch from start to goal * @param start The start node * @param goal The end node */ public DepthFirstSearch(Node start, Node goal) { super(start, goal); } /** * Creates a new DepthFirstSearch from start to goals * @param start The start node * @param goals The end nodes */ public DepthFirstSearch(Node start, Collection goals) { super(start, goals); } /** * Finds the path * @return List of nodes in path if found null otherwise */ public List findPath() { visited = new LinkedList(); boolean found = search(start); if (found) { return visited; } else { return null; } } /** * Get the considdered path * @return List of nodes vissited so far */ public List getConsideredPath() { return new ArrayList(visited); } /** * Search for a path from node to Goals * @param node the node to start from * @return true if path found false otherwise */ private boolean search(Node node) { if (aborted) { return false; } visited.add(node); fireConsidered(); if (goals.contains(node)) { return true; } else { Iterator neighbors = node.getNeighbors().iterator(); while (neighbors.hasNext()) { Node neighbor = (Node)neighbors.next(); if (!visited.contains(neighbor)) { if (search(neighbor)) { return true; } } } } visited.remove(node); return false; } } --- NEW FILE: Node.java --- //--------------------------------------------------------------------------------- // $Id: Node.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.Collection; /** * The <code>Node</code> interface must be implemented by classes that want a * <code>PathFinder<code> to find paths over them. * * @author Gene McCulley */ public interface Node { /** * Returns the estimate of the cost to get from this node to the goal node. * If unable to estimate, it is safe to return 0 or underestimate. * Overestimates can result in failures to find a path. * * @return the estimate. * @param goal The goal of the current search */ double getPathCostEstimate(Node goal); /** * Returns the cost to get from this node to the dest node. * * @param dest the destination node * @return the cost. */ double getTraverseCost(Node dest); /** * Returns the neighbors of this node in the form of a Collection. * * @return the neighbors. */ Collection getNeighbors(); } --- NEW FILE: PathEvent.java --- //--------------------------------------------------------------------------------- // $Id: PathEvent.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.EventObject; import java.util.List; /** * An encapsulation of the data describing an event related to a PathFinder. * * @author Gene McCulley */ public class PathEvent extends EventObject { /** * List of Nodes in the path */ private List path; /** * Create a new PathEvent. * * @param source the source of this event. * @param path the path related to the event. */ public PathEvent(Object source, List path) { super(source); this.path = path; } /** * Returns the path related to this event. * * @return the path related to the event in the form of a list or null if * no path was found. */ public List getPath() { return path; } } --- NEW FILE: PathFinder.java --- //--------------------------------------------------------------------------------- // $Id: PathFinder.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.List; /** * The <code>PathFinder</code> interface is implemented by classes that provide * a mechanism to find routes between nodes. * * A <code>PathFinder</code> is a <code>Runnable</code> so that you can use it * either directly or as a Thread. To use it directly, just call findPath. * This may take a while, so you may want to use it as a Thread. You do this * by constructing the <code>PathFinder</code>, adding yourself as a * <code>PathListener</code>, and then calling the start method. When the path * has been found or all possible paths have been exhausted, a * <code>PathEvent</code> will be sent. * * @author Gene McCulley */ public interface PathFinder { /** * Find a path between the start and the goal Nodes. * * @return a List of Node elements. */ List findPath(); /** * Abort the current path search. This only makes sense if you are using * the threaded approach. The state of the pathfinder will be reset such * that it is okay to call findPath again to start over. */ void abort(); /** * Get the path currently being considered. This only makes sense if you are * using the threaded approach. It is only safe to call this after having * received a considered PathEvent. * * @return a List of Nodes in the considered path. */ List getConsideredPath(); /** * Add a listener for PathEvents. * * @param l the listener to add. */ void addPathListener(PathListener l); /** * Remove a listener for PathEvents. * * @param l the listener to remove. */ void removePathListener(PathListener l); } --- NEW FILE: PathListener.java --- //--------------------------------------------------------------------------------- // $Id: PathListener.java,v 1.1 2004/07/01 08:27:54 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path.astar; import java.util.EventListener; /** * Classes that want to know about path finding events must implement the * <code>PathListener</code> interface. * * @author Gene McCulley */ public interface PathListener extends EventListener { /** * Called when the PathFinder is done. * * @param e the PathEvent containing the finished path. */ void done(PathEvent e); /** * Called when a new path is being considered. * * @param e the PathEvent that belongs to the PathFinder. */ void considered(PathEvent e); } --- NEW FILE: package.html --- <body> This package contains the a* algorithm, based on the excelent work of Gene McCulley over at <a href="http://www.cuspy.com/software/pathfinder/">cuspy</a>. <p> |
From: Mads P. H. <ma...@us...> - 2004-07-01 08:26:34
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2306/astar Log Message: Directory /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path/astar added to the repository |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:38:30
|
Update of /cvsroot/huntforgold/huntforgold/src/etc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17232 Modified Files: huntforgold.xsd Log Message: Added support for routes Index: huntforgold.xsd =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/etc/huntforgold.xsd,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- huntforgold.xsd 29 May 2004 09:20:30 -0000 1.5 +++ huntforgold.xsd 1 Jul 2004 06:38:22 -0000 1.6 @@ -13,6 +13,7 @@ <xsd:element ref="ships"/> <xsd:element ref="pirates"/> <xsd:element ref="towns"/> + <xsd:element ref="routes" maxOccurs="1" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> @@ -90,6 +91,16 @@ <xsd:sequence> <xsd:element name="ship" type="xsd:int"/> <xsd:element name="number" type="xsd:double"/> + <xsd:element ref="routeconfig" maxOccurs="unbounded" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="routeconfig"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="routename" type="xsd:string"/> + <xsd:element name="fraction" type="xsd:double"/> </xsd:sequence> </xsd:complexType> </xsd:element> @@ -201,4 +212,43 @@ </xsd:complexType> </xsd:element> + <xsd:element name="routes"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="route" maxOccurs="unbounded" minOccurs="1"/> + <xsd:element ref="alias" maxOccurs="unbounded" minOccurs="0"/> + <xsd:element ref="node" maxOccurs="unbounded" minOccurs="1"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="route"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + <xsd:element name="nodes" type="xsd:string"/> + <xsd:element name="reversible" type="xsd:boolean"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="alias"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + <xsd:element name="routes" type="xsd:string"/> + <xsd:element name="reversible" type="xsd:boolean"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="node"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + <xsd:element name="latitude" type="xsd:double"/> + <xsd:element name="longitude" type="xsd:double"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> </xsd:schema> |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:36:31
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/ai In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17034 Modified Files: ShipAI.java Log Message: Use route if configured when initializing ships Index: ShipAI.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/ai/ShipAI.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- ShipAI.java 5 Jan 2004 15:38:58 -0000 1.21 +++ ShipAI.java 1 Jul 2004 06:36:23 -0000 1.22 @@ -13,14 +13,18 @@ import net.sourceforge.huntforgold.model.ShipFactory; import net.sourceforge.huntforgold.model.Time; import net.sourceforge.huntforgold.model.World; +import net.sourceforge.huntforgold.model.path.RouteManager; +import net.sourceforge.huntforgold.model.path.Route; import net.sourceforge.huntforgold.model.map.MapManager; import net.sourceforge.huntforgold.model.player.Player; import net.sourceforge.huntforgold.util.Configuration; import net.sourceforge.huntforgold.util.CoordinateTransform; import net.sourceforge.huntforgold.util.MediaTimer; +import net.sourceforge.huntforgold.util.PositionHelper; import net.sourceforge.huntforgold.xml.Nationality; import net.sourceforge.huntforgold.xml.Shipstrength; import net.sourceforge.huntforgold.xml.Strength; +import net.sourceforge.huntforgold.xml.RouteconfigType; import java.awt.Color; import java.awt.image.BufferedImage; @@ -59,6 +63,11 @@ private World world; /** + * RouteManager + */ + private RouteManager routeManager; + + /** * Constructor for ShipAI */ private ShipAI() { @@ -67,6 +76,7 @@ mapManager = MapManager.getMapManager(); player = Player.getPlayer(); world = World.getWorld(); + routeManager = RouteManager.getRouteManager(); } /** @@ -152,8 +162,9 @@ Shipstrength ss = (Shipstrength)ships.get(k); int type = ss.getShip(); int numberOfShips = (int)(totalNumberOfShips * power * ss.getNumber()); + List routeConfigs = ss.getRouteconfig(); insertShips(numberOfShips, type, random, shipFactory, - diffX, minX, diffY, minY, nat.getIndex()); + diffX, minX, diffY, minY, nat.getIndex(), routeConfigs); } } } @@ -185,8 +196,14 @@ shipPosition.getY() <= topLeft.getY() && shipPosition.getY() >= bottomRight.getY()) { double oldDirection = ship.getDirection(); - int fixAngle = (int)((8.0 * oldDirection) / Math.PI); - double a = fixAngle * Math.PI / 8.0; + double a = 0; + Route route = routeManager.getRoute(ship.getRouteName()); + if (route == null) { + a = PositionHelper.fixAngle(ship.getDirection()); + } else { + a = PositionHelper.fixAngle(routeManager.calculateDirection(ship)); + } + ship.setDirection(a); double deltaX = delta * ship.getSpeed() * Math.cos(a) * 0.01; double deltaY = delta * ship.getSpeed() * Math.sin(a) * 0.01; @@ -199,6 +216,16 @@ world.moveShip(ship, newPosition); } else { ship.setDirection(oldDirection + Math.PI); + if (route != null && ship.getNextNodeIndex() != 0) { + if (ship.getNextNodeIndex() != route.getNodes().length - 1) { + log.warn("Ship " + ship.getUniqueId() + " on route " + ship.getRouteName() + + " is hitting land on its way to node " + + route.getNode(ship.getNextNodeIndex()).getName()); + } + // Mysteriously move the ship to the next node + world.moveShip(ship, routeManager.getRoute(ship.getRouteName()) + .getNode(ship.getNextNodeIndex()).getPosition()); + } } } } @@ -236,24 +263,68 @@ * @param diffY granularity in y direction * @param minY minimum y value * @param nationality nationality id + * @param routeConfigs list of RouteconfigTypes */ private void insertShips(int numberOfShips, int type, Random random, ShipFactory shipFactory, double diffX, double minX, double diffY, double minY, - int nationality) { + int nationality, List routeConfigs) { if (log.isDebugEnabled()) { log.debug("Creating " + numberOfShips + " for nationality #" + nationality + " of type: " + type); } + double[] routeCofigIndex; + if (routeConfigs != null) { + routeCofigIndex = new double[routeConfigs.size()]; + double currentFractionTotal = 0; + for (int i = 0; i < routeConfigs.size(); i++) { + RouteconfigType routeconfigType = (RouteconfigType) routeConfigs.get(i); + currentFractionTotal += routeconfigType.getFraction(); + routeCofigIndex[i] = currentFractionTotal; + if (currentFractionTotal > 1) { + log.warn("Nationality #" + nationality + " shiptype: " + type + + " has route fraction greater than 1"); + break; + } + } + } else { + routeCofigIndex = new double[1]; + routeCofigIndex[0] = 0.0; + } + for (int i = 0; i < numberOfShips; i++) { Ship ship = shipFactory.createShip(type, nationality); ship.setDirection(2 * Math.PI * random.nextDouble()); ship.setSails(Ship.BATTLE_SAILS); boolean finished = false; while (!finished) { - double x = diffX * random.nextDouble() + minX; - double y = diffY * random.nextDouble() + minY; - Position p = new Position(x, y); + int index = routeConfigs.size() + 1; + double fraction = random.nextDouble(); + for (int j = 0; j < routeCofigIndex.length; j++) { + double currentFraction = routeCofigIndex[j]; + if (fraction <= currentFraction) { + index = j; + break; + } + } + Position p = new Position(-1, -1); + if (index < routeConfigs.size() + 1) { + RouteconfigType routeconfigType = (RouteconfigType) routeConfigs.get(index); + String routename = routeconfigType.getRoutename(); + Route route = routeManager.getRoute(routename); + if (route != null) { + int nodeNum = random.nextInt(route.getNodes().length); + p = route.getNode(nodeNum).getPosition(); + ship.setPosition(p); + ship.setRouteName(routename, random.nextBoolean()); + } else { + log.warn("Trying to use non-existing route [" + routename + "]"); + } + } else { + double x = diffX * random.nextDouble() + minX; + double y = diffY * random.nextDouble() + minY; + p = new Position(x, y); + } if (mapManager.isInWater(p)) { world.insertShip(ship, p); addShip(ship); |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:34:01
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/graphics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16645 Modified Files: LandTile.java Log Message: Added isOnlyWater and hasWater Index: LandTile.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/graphics/LandTile.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- LandTile.java 5 Jan 2004 15:38:58 -0000 1.3 +++ LandTile.java 1 Jul 2004 06:33:52 -0000 1.4 @@ -42,6 +42,12 @@ /** Water tile */ private boolean water; + /** Only Water tile */ + private boolean onlyWater; + + /** has Water tile */ + private boolean hasWater; + /** * Construct a new land or water tile * @param tile The tile image @@ -85,9 +91,15 @@ } if (numOfWater >= numOfLand) { water = true; + if (numOfLand == 0) { + onlyWater = true; + } } else { water = false; } + if (numOfWater > 0) { + hasWater = true; + } } /** @@ -120,6 +132,22 @@ } /** + * Is the tile a water only tile ? + * @return True if there is no land on tile + */ + public boolean isOnlyWater() { + return onlyWater; + } + + /** + * does the tile have atleast one water pixel ? + * @return True if atleast one water pixel + */ + public boolean hasWater() { + return hasWater; + } + + /** * Find the nearest water position * @param position The offset position * @return The nearest position |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:32:03
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16424 Modified Files: Position.java Log Message: Added getXAsPixel and getYAsPixel Index: Position.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/Position.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- Position.java 5 Jan 2004 15:38:58 -0000 1.15 +++ Position.java 1 Jul 2004 06:31:42 -0000 1.16 @@ -11,6 +11,7 @@ import java.util.Comparator; import org.apache.log4j.Logger; +import net.sourceforge.huntforgold.util.CoordinateTransform; /** * Models a position @@ -68,6 +69,24 @@ } /** + * Get x as pixel + * + * @return The x pixel coordinate + */ + public int getXAsPixel() { + return CoordinateTransform.convertLongitudeToPixels(getX()); + } + + /** + * Get y as pixel + * + * @return The y pixel coordinate + */ + public int getYAsPixel() { + return CoordinateTransform.convertLatitudeToPixels(getY()); + } + + /** * Move to another position * * @param x Additional x coordinate |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:30:43
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16263 Modified Files: Fleet.java Ship.java Log Message: Extend Routable Index: Fleet.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/Fleet.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- Fleet.java 5 Jan 2004 15:38:58 -0000 1.16 +++ Fleet.java 1 Jul 2004 06:30:33 -0000 1.17 @@ -18,11 +18,12 @@ import java.util.Set; import org.apache.log4j.Logger; +import net.sourceforge.huntforgold.model.path.Routable; /** * Models a fleet (group of ships) */ -public class Fleet implements Moveable, Serializable { +public class Fleet extends Routable implements Serializable { /** The logger */ private static Logger log = Logger.getLogger(Fleet.class); Index: Ship.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/Ship.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- Ship.java 6 Jan 2004 16:40:19 -0000 1.24 +++ Ship.java 1 Jul 2004 06:30:33 -0000 1.25 @@ -11,11 +11,12 @@ import java.util.Comparator; import org.apache.log4j.Logger; +import net.sourceforge.huntforgold.model.path.Routable; /** * Models a ship */ -public class Ship implements Moveable, Serializable, Comparator { +public class Ship extends Routable implements Serializable, Comparator { /** The logger */ private static Logger log = Logger.getLogger(Ship.class); |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:28:02
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15764 Added Files: Node.java Routable.java Route.java RouteManager.java package.html Log Message: Initial import --- NEW FILE: Node.java --- //--------------------------------------------------------------------------------- // $Id: Node.java,v 1.1 2004/07/01 06:27:52 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path; import net.sourceforge.huntforgold.model.Position; /** * Models a node, i.e. a destination point in travel path */ public class Node { /** * the position of this node in the world */ private Position position; /** * the identifying name of this node */ private String name; /** * Construct a node with the given characteristics * @param name the name of the node * @param position the position this node is at */ public Node(String name, Position position) { setName(name); setPosition(position); } /** * Set the identifying name of the node * @param name the name to give the node */ private void setName(String name) { this.name = name; } /** * Get the name of the node * @return the name of the node */ public String getName() { return name; } /** * set the position of the node * @param position the position this node is at */ private void setPosition(Position position) { this.position = position; } /** * get the position of the node * @return the position of the node */ public Position getPosition() { return position; } } --- NEW FILE: Routable.java --- //--------------------------------------------------------------------------------- // $Id: Routable.java,v 1.1 2004/07/01 06:27:52 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path; import net.sourceforge.huntforgold.model.Moveable; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.util.Distance; /** * This class is an abstract implementation of the Movable interface. * It adds the notion of the Movable to move along a Route */ public abstract class Routable implements Moveable { /** * The route that this routable is following */ private String routeName; /** * The index of the next node in the route the routable is following */ private int nextNodeIndex; /** * indication of which way we are traveling, from node 0 to node n or * back again from node n to node 0 */ private boolean forward = true; /** * simple cache of the number of nodes in the route */ private int nodesInRoute; /** * RouteManager */ private static RouteManager routeManager = RouteManager.getRouteManager(); /** * Get the index of the next node in the route * @return the index of the next node in the route */ public int getNextNodeIndex() { return nextNodeIndex; } /** * This method is used to set the next destination, * when the routable reaches its current destination * */ public void calculateNextNodeIndex() { if (forward) { nextNodeIndex++; if (nextNodeIndex >= nodesInRoute && getRoute().isReversible()) { forward = false; nextNodeIndex = nodesInRoute - 1; if (nextNodeIndex < 0) { nextNodeIndex = 0; } } else if (nextNodeIndex >= nodesInRoute) { //TODO nextNodeIndex = nodesInRoute - 1; } } else { nextNodeIndex--; if (nextNodeIndex < 0 && getRoute().isReversible()) { forward = true; nextNodeIndex = 1; } else if (nextNodeIndex < 0) { nextNodeIndex = 0; } } } /** * Get the name of the route that this routable is following * @return the route name */ private Route getRoute() { return routeManager.getRoute(routeName); } /** * Get the name of the route that this routable is following * @return the route name */ public String getRouteName() { return routeName; } /** * Set the name of the route that this routable must follow * @param routeName the name of the route */ public void setRouteName(String routeName) { this.routeName = routeName; nodesInRoute = getRoute().getNodes().length; // Selecting the Node in the route which is closest to the current position if (getPosition() != null) { double minDistance = Double.MAX_VALUE; int nodeIndex = 0; int i; for (i = 0; i < nodesInRoute; i++) { double nextDistance = Distance.getDistance(getPosition(), getRoute().getNode(i).getPosition(), Distance.DISTANCE_KM); if (minDistance > nextDistance) { minDistance = nextDistance; nodeIndex = i; } } nextNodeIndex = nodeIndex; } else { nextNodeIndex = 0; } } /** * Set the name of the route that this routable must follow * @param routeName the name of the route * @param forward specify the initial direction the routable is going, forward from start to goal * or backward from goal to start */ public void setRouteName(String routeName, boolean forward) { this.forward = forward; setRouteName(routeName); } /** * Get direction * @return The direction */ public abstract double getDirection(); /** * Get speed * @return The current speed */ public abstract int getSpeed(); /** * Get the position of the ship * @return The position of the ship */ public abstract Position getPosition(); /** * Get maximum speed * @return The maximum speed */ public abstract int getMaxSpeed(); } --- NEW FILE: Route.java --- //--------------------------------------------------------------------------------- // $Id: Route.java,v 1.1 2004/07/01 06:27:52 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path; /** * * Models a Route, i.e. the intended way an object has to travel */ public class Route { /** * the nodes that constitutes the ruote */ private Node[] nodes; /** * The unique identifying name of the route */ private String name; /** * indicates if this route is travable in both directions */ private boolean reversible; /** * Construct a new Route with the given characteristics * @param name the name of this route * @param nodes the node[] that constitutes the route * @param reversible boolean, if true the route can be traveled * in both directions */ public Route(String name, Node[] nodes, boolean reversible) { setName(name); setNodes(nodes); setReversible(reversible); } /** * Set the nodes of this route * @param nodes the node[] that constitutes the route */ private void setNodes(Node[] nodes) { this.nodes = nodes; } /** * Get the nodes of this route * @return the node[] that constitutes the route */ public Node[] getNodes() { return nodes; } /** * Get the index'th node in this route * @param index the index of the node in the routes * @return the node number 'index' */ public Node getNode(int index) { return nodes[index]; } /** * Sets the unique name of this route * @param name the name to give to this route */ private void setName(String name) { this.name = name; } /** * Gets the unique name of the route * @return the name */ public String getName() { return name; } /** * Indicate if this route can be traveled in both directions * @param reversible boolean, if true the route can be traveled * in both directions */ private void setReversible(boolean reversible) { this.reversible = reversible; } /** * Get indication if this route can be traveled in both directions * @return true if this this route can be traveled in both directions, * false if it is one way only. */ public boolean isReversible() { return reversible; } } --- NEW FILE: RouteManager.java --- //--------------------------------------------------------------------------------- // $Id: RouteManager.java,v 1.1 2004/07/01 06:27:52 madsph Exp $ // // Copyright (c) 2002-2004 Hunt for Gold Team (http://huntforgold.sourceforge.net) // All rights reserved //--------------------------------------------------------------------------------- package net.sourceforge.huntforgold.model.path; import java.util.Map; import java.util.List; import java.util.HashMap; import java.util.Iterator; import java.util.StringTokenizer; import java.util.ArrayList; import net.sourceforge.huntforgold.model.Position; import net.sourceforge.huntforgold.util.Configuration; import net.sourceforge.huntforgold.util.Distance; import net.sourceforge.huntforgold.util.PositionHelper; import net.sourceforge.huntforgold.xml.Huntforgold; import net.sourceforge.huntforgold.xml.RoutesType; import net.sourceforge.huntforgold.xml.RouteType; import net.sourceforge.huntforgold.xml.NodeType; import net.sourceforge.huntforgold.xml.TownType; import net.sourceforge.huntforgold.xml.Alias; /** * RouteManager singleton used for managing Routes */ public class RouteManager { /** The singleton instance */ private static RouteManager routeManager = null; /** * The routes of the game */ private Map routes; /** * Constructor for RouteManager */ private RouteManager() { initRoutes(); } /** * Get the RouteManager instance * @return The RouteManager */ public static synchronized RouteManager getRouteManager() { if (routeManager == null) { routeManager = new RouteManager(); } return routeManager; } /** * Calculates the direction to go to get to the next node on the route * @param routeable the routeable which needs a new direction * @return the direction (from 0 to 2 PI) to go to get to the next node in the route */ public double calculateDirection(Routable routeable) { double newDirection = 0; Route route = (Route) routes.get(routeable.getRouteName()); Position destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); Position origen = routeable.getPosition(); if (isDetstinationReached(destination, origen)) { routeable.calculateNextNodeIndex(); destination = route.getNode(routeable.getNextNodeIndex()).getPosition(); } newDirection = PositionHelper.getRadianFromVector(destination.getX() - origen.getX(), destination.getY() - origen.getY()); return PositionHelper.fixAngle(newDirection); } /** * Tells wheter we are in a small enough radious of the targeted destination to allow * the assumption that we are actually there * @param destination the destination to reach * @param origen the postion, to compare to the destination * @return true if the orige is 'close' to the destination */ private boolean isDetstinationReached(Position destination, Position origen) { boolean result = false; if (Distance.getDistance(destination, origen, Distance.DISTANCE_KM) < 2.5) { result = true; } return result; } /** * Find the route with the specified name * @param routeName the name of the route to find * @return the route with the specified name, or null if the name is unknown */ public Route getRoute(String routeName) { return (Route) routes.get(routeName); } /** * reads the routes from the configuration into the cache * @throws NullPointerException if the configured routes contains node names * which are not defined in towns/town/name or routes/node/name */ private void initRoutes() throws NullPointerException { Configuration conf = Configuration.getConfiguration(); Huntforgold huntforgold = conf.getHuntforgold(); // Max one but maybe zero rutes RoutesType routeDefs = huntforgold.getRoutes(); if (routeDefs != null) { // The nodes are either towns or help nodes List nodeList = routeDefs.getNode(); nodeList.addAll(huntforgold.getTowns().getTown()); Map nodeMap = new HashMap(nodeList.size()); for (int i = 0; i < nodeList.size(); i++) { //TODO Enhance by letting a Town be a Node Object nodeDef = nodeList.get(i); if (nodeDef instanceof TownType) { TownType nodeType = (TownType) nodeDef; nodeMap.put(nodeType.getName(), nodeType); } else if (nodeDef instanceof NodeType) { NodeType nodeType = (NodeType) nodeDef; nodeMap.put(nodeType.getName(), nodeType); } } List aliases = routeDefs.getAlias(); int aliasNo = (aliases == null ? 0 : aliases.size()); // Iterate through all route definitions in the configuration to instanciate all routes routes = new HashMap(routeDefs.getRoute().size() + aliasNo); Iterator routeIterator = routeDefs.getRoute().iterator(); while (routeIterator.hasNext()) { RouteType routeType = (RouteType)routeIterator.next(); String routeName = routeType.getName(); boolean reversible = routeType.isReversible(); StringTokenizer nodeTokenizer = new StringTokenizer(routeType.getNodes(), ";"); Node [] nodes = new Node [nodeTokenizer.countTokens()]; int nodeIndex = 0; while (nodeTokenizer.hasMoreTokens()) { String nodeName = nodeTokenizer.nextToken(); //TODO Enhance by letting a Town be a Node Object nodeDef = nodeMap.get(nodeName); double longitude = 0; double latitude = 0; if (nodeDef instanceof TownType) { TownType townType = (TownType)nodeDef; longitude = townType.getLongitude(); latitude = townType.getLatitude(); } else if (nodeDef instanceof NodeType) { NodeType nodeType = (NodeType) nodeDef; longitude = nodeType.getLongitude(); latitude = nodeType.getLatitude(); } Node node = new Node(nodeName, new Position(longitude, latitude)); nodes[nodeIndex++] = node; } Route route = new Route(routeName, nodes, reversible); routes.put(routeName, route); } // Iterate through all route aliases in the configuration to create concatinated routes if (aliases != null) { for (int i = 0; i < aliases.size(); i++) { Alias alias = (Alias) aliases.get(i); String routeName = alias.getName(); boolean reversible = alias.isReversible(); StringTokenizer nodeTokenizer = new StringTokenizer(alias.getRoutes(), ";"); ArrayList nodes = new ArrayList(); while (nodeTokenizer.hasMoreTokens()) { String route = nodeTokenizer.nextToken(); Node[] tmpNodes = ((Route)routes.get(route)).getNodes(); for (int j = 0; j < tmpNodes.length; j++) { nodes.add(tmpNodes[j]); } } Node[] nodesA = new Node[nodes.size()]; Route route = new Route(routeName, (Node[])nodes.toArray(nodesA), reversible); routes.put(routeName, route); } } } } /** * Get an Iterator to all routes in the game * @return Iterator to all routes in the game */ public Iterator getRouteIterator() { return routes.values().iterator(); } } --- NEW FILE: package.html --- <body> This package contains the path model of the game. <p> The main classes are <code>RouteManager</code>, <code>Route</code> and <code>Node</code>. <p>The <code>RouteManager</code> manages all <code>Route</code>s in the game. This includes caching all of <code>Route</code>s, and the ability to tell a <code>Routable</code> which direction it needs in order to follow the <code>Route</code>. <p>A <code>Route</code> consists of a number of ordered <code>Node</code>s. A <code>Node</code> is esentially a <code>Position</code>, with some aditional information. </body> |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:26:43
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15552/path Log Message: Directory /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/model/path added to the repository |
From: Mads P. H. <ma...@us...> - 2004-07-01 06:25:02
|
Update of /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15262 Modified Files: PositionHelper.java Log Message: Made getRadianFromVector and fixAngle public Index: PositionHelper.java =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/net/sourceforge/huntforgold/util/PositionHelper.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- PositionHelper.java 5 Jan 2004 15:38:59 -0000 1.2 +++ PositionHelper.java 1 Jul 2004 06:24:53 -0000 1.3 @@ -31,7 +31,7 @@ * move to a new position. * @param weatherElements collection of WeatherElement object that * have impact on the ships movement - * @param delta the delta value + * @param delta the delta value, i.e. the time travelded * @return the moveables new position */ public static Position nextPosition(Moveable moveable, Collection weatherElements, double delta) { @@ -93,7 +93,7 @@ * @param yCoordinate - obvious! * @return the angel between the vector and the positive x-axis expressed in radians */ - private static double getRadianFromVector(double xCoordinate, double yCoordinate) { + public static double getRadianFromVector(double xCoordinate, double yCoordinate) { double result; if (xCoordinate == 0) { //special case if (yCoordinate < 0) { @@ -130,7 +130,7 @@ * @param direction the direction that needs to be rounded to one of the 16 possible directions. * @return a rounded direction. */ - private static double fixAngle(double direction) { + public static double fixAngle(double direction) { int fixAngle = (int)((8.0 * direction) / Math.PI); return fixAngle * Math.PI / 8.0; } |
From: Jesper P. <je...@us...> - 2004-06-29 06:33:12
|
Update of /cvsroot/huntforgold/huntforgold/src/etc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3765 Modified Files: caribbean.xml Log Message: Fixed 16200 bug Index: caribbean.xml =================================================================== RCS file: /cvsroot/huntforgold/huntforgold/src/etc/caribbean.xml,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- caribbean.xml 29 May 2004 09:20:30 -0000 1.12 +++ caribbean.xml 29 Jun 2004 06:33:04 -0000 1.13 @@ -123,7 +123,7 @@ </shipstrength> </strength> <strength> - <year>16200</year> + <year>1620</year> <power>0.15</power> <shipstrength> <ship>0</ship> @@ -617,7 +617,7 @@ </shipstrength> </strength> <strength> - <year>16200</year> + <year>1620</year> <power>0.15</power> <shipstrength> <ship>0</ship> |