Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Pokemon Crystal roaming simulator v1 by IceFlame"""
- import random
- import collections
- roamingMap = {
- "29": ["30", "46"],
- "30": ["29", "31"],
- "31": ["30", "32", "36"],
- "32": ["36", "31", "33"],
- "33": ["32", "34"],
- "34": ["33", "35"],
- "35": ["34", "36"],
- "36": ["35", "31", "32", "37"],
- "37": ["36", "38", "42"],
- "38": ["37", "39", "42"],
- "39": ["38"],
- "42": ["43", "44", "37", "38"],
- "43": ["42", "44"],
- "44": ["42", "43", "45"],
- "45": ["44", "46"],
- "46": ["45", "29"],
- }
- def roamRandom(playerCurrent):
- """Picks a random map with uniform probability, excluding player's current location."""
- routes = roamingMap.keys()
- while True:
- route = random.choice(routes)
- if route != playerCurrent:
- return route
- def roamNext(roamCurrent, playerCurrent, playerPrevPrev):
- """Picks next location for Beast to roam to, from the current location."""
- branches = roamingMap[roamCurrent]
- L = len(branches)
- while True:
- rand = random.randint(0, 31)
- if rand == 0:
- return roamRandom(playerCurrent)
- rand %= 4
- if rand == 0 and branches[0] != playerPrevPrev:
- return branches[0]
- if rand == 1 and L > 1 and branches[1] != playerPrevPrev:
- return branches[1]
- if rand == 2 and L > 2 and branches[2] != playerPrevPrev:
- return branches[2]
- if rand == 3 and L > 3 and branches[3] != playerPrevPrev:
- return branches[3]
- def roamWithoutPlayer(reps, dummy=0):
- """Counts number of times roamed to each route
- if player is busy in a city/cave for a very long time.
- Returns Counter with same keys as roamingMap."""
- roamCurrent = roamRandom(None)
- counts = collections.Counter()
- for i in xrange(reps):
- roamCurrent = roamNext(roamCurrent, None, None)
- counts[roamCurrent] += 1
- return counts
- def roamResetWithoutPlayer(reps, maxMoves):
- """Counts number of times roamed to each route for each move after reset
- (if player is busy in a city/cave).
- Returns list of Counters for [0 moves, 1 move, 2 moves, ... maxMoves moves]
- Counters have same keys as roamingMap."""
- counts = [collections.Counter() for j in xrange(maxMoves+1)]
- for i in xrange(reps):
- roamCurrent = roamRandom(None)
- counts[0][roamCurrent] += 1
- for j in xrange(1, maxMoves+1):
- roamCurrent = roamNext(roamCurrent, None, None)
- counts[j][roamCurrent] += 1
- return counts
- def roamWithPlayer(pattern, reps):
- """Returns number of times Beast is on same route as player.
- Params: "pattern" is a sequence of map names that player repeats "reps" times.
- If map starts with "fly", this causes a random reset.
- Other than route numbers, map names don't matter, so use something descriptive.
- Note: if pattern has more than one target route, result is the total for both
- (be careful if calculating percentages)."""
- playerCurrent = pattern[0]
- playerPrev = pattern[-1]
- playerPrevPrev = pattern[-2]
- roamCurrent = roamRandom(pattern[-1])
- hits = 0
- for i in xrange(reps):
- for playerCurrent in pattern:
- if playerCurrent.lower().startswith("fly"):
- roamCurrent = roamRandom(playerCurrent)
- else:
- roamCurrent = roamNext(roamCurrent, playerCurrent, playerPrevPrev)
- if roamCurrent == playerCurrent:
- hits += 1
- playerPrevPrev = playerPrev
- playerPrev = playerCurrent
- return hits
- if __name__ == "__main__":
- print "***Make sure all the connections are two-way***"
- twoWay = set()
- for key in roamingMap:
- for target in roamingMap[key]:
- if key in roamingMap[target]:
- twoWay.add((min(key, target), max(key, target)))
- else:
- print key, target, "only one way..."
- for (a, b) in sorted(twoWay):
- print a, b
- print "***Without player***"
- reps = 100000
- results = roamResetWithoutPlayer(reps, 3)
- results.append(roamWithoutPlayer(reps))
- print "route\treset\t1 move\t2 moves\t3 moves\tmany"
- for k in sorted(roamingMap.keys()):
- #need to transpose the results to print them
- row = [k] + ["%.1f%%" % (100.0 * r[k] / reps) for r in results]
- print "\t".join(row)
- print "***Investigate response to player behaviour***"
- reps = 100000
- tests = [
- ("Route 36: go in and out of Ruins of Alph (right inside through gatehouse)",
- ["36", "gatehouse", "alph", "gatehouse"]),
- ("Route 36 (extra dancing)",
- ["36", "gatehouse", "alph", "gatehouse", "alph", "gatehouse"]),
- ("Route 36 (more extra dancing)",
- ["36", "gatehouse", "alph", "gatehouse", "alph", "gatehouse", "alph", "gatehouse"]),
- ("Fly/Teleport to Mahogany, walk in and out of Pokemon Centre",
- ["fly mahogany", "pokecentre", "mahogany", "42"]),
- ("Fly/Teleport to Violet, walk in and out of Pokemon Centre",
- ["fly violet", "pokecentre", "violet", "36"]),
- ("Fly/Teleport twice to Mahogany",
- ["fly mahogany", "fly mahogany", "42"]),
- ("Fly/Teleport twice to Violet",
- ["fly violet", "fly violet", "36"]),
- ("Fly to Mahogany and Violet",
- ["fly mahogany", "42", "fly violet", "36"]),
- ]
- for (desc, pattern) in tests:
- hits = roamWithPlayer(pattern, reps)
- print desc
- targets = len([x for x in pattern if x in roamingMap])
- reps *= targets #correction for searching more than once in the pattern
- print "%d/%d = %.1f%%" % (hits, reps, 100.0 * hits / reps)
Advertisement
Add Comment
Please, Sign In to add comment