Jump to content
GaetanoH

Get closest bank!

Recommended Posts

Hello,

 

is there any way to get the closest bank starting from your current location?

 

Taken from my Stealth Quester's API:

public static Position getClosestBank(API api) {
	ArrayList<BankEntry> banks = new ArrayList<BankEntry>();
	for (Bank bank : Bank.values()) {
		if (!api.worlds.isMembersWorld() && !bank.isF2P)
			continue;
		List<IDirection> directions = api.finder.route(api, api.myPosition(), bank.walkablePosition);
		if (directions != null) {
			banks.add(new BankEntry(bank.walkablePosition, bank, directions.size()));
		}
	}
	banks.sort(new Comparator<BankEntry>() {
		public int compare(BankEntry entry1, BankEntry entry2) {
		        return entry1.directions - entry2.directions;
	        }
	});
	if (banks.size() > 0) {
		Bank closestBank = banks.get(0).bank;
		api.log("[DEBUG][BANKING] Closest bank is: " + closestBank + " " + banks.get(0).walkablePosition);
		return banks.get(0).walkablePosition;
	} else {
		return null;
	}
}

As you may notice this actually finds the closest bank based on webwalking paths and NOT PLAIN DISTANCE. The banks are associated "walkable" positions so it only polls those positions making the algorithm run a lot faster. This method may take up to ~15 seconds to execute if you poll all positions in every bank so I strongly advise you to do it like I did with the walkablePosition when defining the Bank enum.

public static class BankEntry {
	public BankEntry(Position walkablePosition, Bank bank, int directions) {
		this.walkablePosition = walkablePosition;
		this.bank = bank;
		this.directions = directions;
	}

	Position walkablePosition;
	Bank bank;
	int directions;
		
}

The BankEntry class was defined for the sake of being a data structure (as I'm used to lower level programming languages), you may find more "OOP" implementations for this or you can just remove the class altogether and do the data mapping inside that method.

 

 

EDIT: The purpose of this method is to actually find the closest bank without being forced to walk to it. You may walk to it if you want as the returned position is guaranteed to be accessible by the webwalker.

Edited by Token
  • Like 3
Link to comment
Share on other sites

 

This isn't 100% accurate though, what if you gto a ring of duelling and you are almost in the varrock?

It should return CW instead of varrock bcs its faster ^^

 

If you input an array of positions from the banks the webwalker will calculate the fastest route to a bank.

  • Like 1
Link to comment
Share on other sites

Without using web walking (not accurate if you have banks close to each other):

 

banks.sort(new Comparator<Area>() {
            public int compare(Area bank1, Area bank2) {
                return bank1.getRandomPosition().distance(myPosition()) - bank2.getRandomPosition().distance(myPosition());
            }
        });
First index in the collection will be to your closest position, last would be furthest. 
  • Like 2
Link to comment
Share on other sites

This isn't 100% accurate though, what if you gto a ring of duelling and you are almost in the varrock?

It should return CW instead of varrock bcs its faster ^^

 

If you input an array of positions from the banks the webwalker will calculate the fastest route to a bank.

I agree, Web would be ideal, i think i wrote that before the web even came out. So yeah it doesn't calculate the path heuristics. 

  • Like 1
Link to comment
Share on other sites

Taken from my Stealth Quester's API:

public static Position getClosestBank(API api) {
	ArrayList<BankEntry> banks = new ArrayList<BankEntry>();
	for (Bank bank : Bank.values()) {
		if (!api.worlds.isMembersWorld() && !bank.isF2P)
			continue;
		List<IDirection> directions = api.finder.route(api, api.myPosition(), bank.walkablePosition);
		if (directions != null) {
			banks.add(new BankEntry(bank.walkablePosition, bank, directions.size()));
		}
	}
	banks.sort(new Comparator<BankEntry>() {
		public int compare(BankEntry entry1, BankEntry entry2) {
		        return entry1.directions - entry2.directions;
	        }
	});
	if (banks.size() > 0) {
		Bank closestBank = banks.get(0).bank;
		api.log("[DEBUG][BANKING] Closest bank is: " + closestBank + " " + banks.get(0).walkablePosition);
		return banks.get(0).walkablePosition;
	} else {
		return null;
	}
}

As you may notice this actually finds the closest bank based on webwalking paths and NOT PLAIN DISTANCE. The banks are associated "walkable" positions so it only polls those positions making the algorithm run a lot faster. This method may take up to ~15 seconds to execute if you poll all positions in every bank so I strongly advise you to do it like I did with the walkablePosition when defining the Bank enum.

public static class BankEntry {
	public BankEntry(Position walkablePosition, Bank bank, int directions) {
		this.walkablePosition = walkablePosition;
		this.bank = bank;
		this.directions = directions;
	}

	Position walkablePosition;
	Bank bank;
	int directions;
		
}

The BankEntry class was defined for the sake of being a data structure (as I'm used to lower level programming languages), you may find more "OOP" implementations for this or you can just remove the class altogether and do the data mapping inside that method.

 

 

EDIT: The purpose of this method is to actually find the closest bank without being forced to walk to it. You may walk to it if you want as the returned position is guaranteed to be accessible by the webwalker.

best snippet 2k16

Link to comment
Share on other sites

Taken from my Stealth Quester's API:

public static Position getClosestBank(API api) {
	ArrayList<BankEntry> banks = new ArrayList<BankEntry>();
	for (Bank bank : Bank.values()) {
		if (!api.worlds.isMembersWorld() && !bank.isF2P)
			continue;
		List<IDirection> directions = api.finder.route(api, api.myPosition(), bank.walkablePosition);
		if (directions != null) {
			banks.add(new BankEntry(bank.walkablePosition, bank, directions.size()));
		}
	}
	banks.sort(new Comparator<BankEntry>() {
		public int compare(BankEntry entry1, BankEntry entry2) {
		        return entry1.directions - entry2.directions;
	        }
	});
	if (banks.size() > 0) {
		Bank closestBank = banks.get(0).bank;
		api.log("[DEBUG][BANKING] Closest bank is: " + closestBank + " " + banks.get(0).walkablePosition);
		return banks.get(0).walkablePosition;
	} else {
		return null;
	}
}

As you may notice this actually finds the closest bank based on webwalking paths and NOT PLAIN DISTANCE. The banks are associated "walkable" positions so it only polls those positions making the algorithm run a lot faster. This method may take up to ~15 seconds to execute if you poll all positions in every bank so I strongly advise you to do it like I did with the walkablePosition when defining the Bank enum.

public static class BankEntry {
	public BankEntry(Position walkablePosition, Bank bank, int directions) {
		this.walkablePosition = walkablePosition;
		this.bank = bank;
		this.directions = directions;
	}

	Position walkablePosition;
	Bank bank;
	int directions;
		
}

The BankEntry class was defined for the sake of being a data structure (as I'm used to lower level programming languages), you may find more "OOP" implementations for this or you can just remove the class altogether and do the data mapping inside that method.

 

 

EDIT: The purpose of this method is to actually find the closest bank without being forced to walk to it. You may walk to it if you want as the returned position is guaranteed to be accessible by the webwalker.

Sorry if this is grave digging but Im using this method and it's so fucking good

Would donate my organs to Token!!@!@@!

  • Like 2
Link to comment
Share on other sites

Some dank Java 8:

private enum Bank {
		    DRAYNOR(Banks.DRAYNOR),
		    AL_KHARID(Banks.AL_KHARID),
		    LUMBRIDGE(Banks.LUMBRIDGE_UPPER),
		    FALADOR_EAST(Banks.FALADOR_EAST),
		    FALADOR_WEST(Banks.FALADOR_WEST),
		    VARROCK_EAST(Banks.FALADOR_EAST),
		    VARROCK_WEST(Banks.VARROCK_WEST),
		    SEERS(Banks.CAMELOT),
		    CATHERBY(Banks.CATHERBY),
		    EDGEVILLE(Banks.EDGEVILLE),
		    YANILLE(Banks.YANILLE),
		    GNOME_STRONGHOLD(Banks.GNOME_STRONGHOLD),
		    ARDOUNGE_NORTH(Banks.ARDOUGNE_NORTH),
		    ARDOUNE_SOUTH(Banks.ARDOUGNE_SOUTH),
		    CASTLE_WARS(Banks.CASTLE_WARS),
		    DUEL_ARENA(Banks.DUEL_ARENA),
		    PEST_CONTROL(Banks.PEST_CONTROL),
		    CANIFIS(Banks.CANIFIS),
		    TZHAAR(Banks.TZHAAR);

		    private final Area area;

		    Bank(Area area) {
		        this.area = area;
		    }
		}

		public static Area closestTo(lemons.api.script.entities.Entity e) {
			HashMap<Bank, Integer> distMap = new HashMap<Bank, Integer>();
			for (Bank b : Bank.values()) {
				distMap.put(b, e.getPosition().distance(b.area.getRandomPosition()));
			}
			HashMap<Integer, Bank> distMapSorted = sortByDistance(distMap);
			Area cBank = distMapSorted.values().toArray(new Bank[Bank.values().length])[0].area;
			return cBank;
		}

		private static <K, V extends Comparable<? super V>> HashMap<V, K> sortByDistance(Map<K, V> map) {
			HashMap<V, K> result = new LinkedHashMap<>();
			Stream<Map.Entry<K, V>> st = map.entrySet().stream();
			st.sorted(Map.Entry.comparingByValue()).forEachOrdered(e -> result.put(e.getValue(), e.getKey()));
			return result;
		}
----------------------------------------------------------------------------------------------------------------
WebWalk.walk(closestTo(myPlayer());
Edited by LoudPacks
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing   1 member

×
×
  • Create New...