Guest User

Pokemon Crystal roaming simulator v1

a guest
Jun 30th, 2016
323
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. """Pokemon Crystal roaming simulator v1 by IceFlame"""
  2.  
  3. import random
  4. import collections
  5.  
  6. roamingMap = {
  7.     "29": ["30", "46"],
  8.     "30": ["29", "31"],
  9.     "31": ["30", "32", "36"],
  10.     "32": ["36", "31", "33"],
  11.     "33": ["32", "34"],
  12.     "34": ["33", "35"],
  13.     "35": ["34", "36"],
  14.     "36": ["35", "31", "32", "37"],
  15.     "37": ["36", "38", "42"],
  16.     "38": ["37", "39", "42"],
  17.     "39": ["38"],
  18.     "42": ["43", "44", "37", "38"],
  19.     "43": ["42", "44"],
  20.     "44": ["42", "43", "45"],
  21.     "45": ["44", "46"],
  22.     "46": ["45", "29"],
  23. }
  24.  
  25. def roamRandom(playerCurrent):
  26.     """Picks a random map with uniform probability, excluding player's current location."""
  27.     routes = roamingMap.keys()
  28.     while True:
  29.         route = random.choice(routes)
  30.         if route != playerCurrent:
  31.             return route
  32.  
  33. def roamNext(roamCurrent, playerCurrent, playerPrevPrev):
  34.     """Picks next location for Beast to roam to, from the current location."""
  35.     branches = roamingMap[roamCurrent]
  36.     L = len(branches)
  37.     while True:
  38.         rand = random.randint(0, 31)
  39.         if rand == 0:
  40.             return roamRandom(playerCurrent)
  41.         rand %= 4
  42.         if rand == 0 and branches[0] != playerPrevPrev:
  43.             return branches[0]
  44.         if rand == 1 and L > 1 and branches[1] != playerPrevPrev:
  45.             return branches[1]
  46.         if rand == 2 and L > 2 and branches[2] != playerPrevPrev:
  47.             return branches[2]
  48.         if rand == 3 and L > 3 and branches[3] != playerPrevPrev:
  49.             return branches[3]
  50.  
  51. def roamWithoutPlayer(reps, dummy=0):
  52.     """Counts number of times roamed to each route
  53.    if player is busy in a city/cave for a very long time.
  54.    Returns Counter with same keys as roamingMap."""
  55.     roamCurrent = roamRandom(None)
  56.     counts = collections.Counter()
  57.     for i in xrange(reps):
  58.         roamCurrent = roamNext(roamCurrent, None, None)
  59.         counts[roamCurrent] += 1
  60.     return counts
  61.  
  62. def roamResetWithoutPlayer(reps, maxMoves):
  63.     """Counts number of times roamed to each route for each move after reset
  64.    (if player is busy in a city/cave).
  65.    Returns list of Counters for [0 moves, 1 move, 2 moves, ... maxMoves moves]
  66.    Counters have same keys as roamingMap."""
  67.     counts = [collections.Counter() for j in xrange(maxMoves+1)]
  68.     for i in xrange(reps):
  69.         roamCurrent = roamRandom(None)
  70.         counts[0][roamCurrent] += 1
  71.         for j in xrange(1, maxMoves+1):
  72.             roamCurrent = roamNext(roamCurrent, None, None)
  73.             counts[j][roamCurrent] += 1
  74.     return counts
  75.  
  76. def roamWithPlayer(pattern, reps):
  77.     """Returns number of times Beast is on same route as player.
  78.    Params: "pattern" is a sequence of map names that player repeats "reps" times.
  79.    If map starts with "fly", this causes a random reset.
  80.    Other than route numbers, map names don't matter, so use something descriptive.
  81.    Note: if pattern has more than one target route, result is the total for both
  82.     (be careful if calculating percentages)."""
  83.     playerCurrent = pattern[0]
  84.     playerPrev = pattern[-1]
  85.     playerPrevPrev = pattern[-2]
  86.     roamCurrent = roamRandom(pattern[-1])
  87.     hits = 0
  88.     for i in xrange(reps):
  89.         for playerCurrent in pattern:
  90.             if playerCurrent.lower().startswith("fly"):
  91.                 roamCurrent = roamRandom(playerCurrent)
  92.             else:
  93.                 roamCurrent = roamNext(roamCurrent, playerCurrent, playerPrevPrev)
  94.             if roamCurrent == playerCurrent:
  95.                 hits += 1
  96.             playerPrevPrev = playerPrev
  97.             playerPrev = playerCurrent
  98.     return hits
  99.  
  100. if __name__ == "__main__":
  101.     print "***Make sure all the connections are two-way***"
  102.     twoWay = set()
  103.     for key in roamingMap:
  104.         for target in roamingMap[key]:
  105.             if key in roamingMap[target]:
  106.                 twoWay.add((min(key, target), max(key, target)))
  107.             else:
  108.                 print key, target, "only one way..."
  109.     for (a, b) in sorted(twoWay):
  110.         print a, b
  111.    
  112.     print "***Without player***"
  113.     reps = 100000
  114.     results = roamResetWithoutPlayer(reps, 3)
  115.     results.append(roamWithoutPlayer(reps))
  116.     print "route\treset\t1 move\t2 moves\t3 moves\tmany"
  117.     for k in sorted(roamingMap.keys()):
  118.         #need to transpose the results to print them
  119.         row = [k] + ["%.1f%%" % (100.0 * r[k] / reps) for r in results]
  120.         print "\t".join(row)
  121.  
  122.     print "***Investigate response to player behaviour***"    
  123.     reps = 100000
  124.     tests = [
  125.         ("Route 36: go in and out of Ruins of Alph (right inside through gatehouse)",
  126.             ["36", "gatehouse", "alph", "gatehouse"]),
  127.         ("Route 36 (extra dancing)",
  128.             ["36", "gatehouse", "alph", "gatehouse", "alph", "gatehouse"]),
  129.         ("Route 36 (more extra dancing)",
  130.             ["36", "gatehouse", "alph", "gatehouse", "alph", "gatehouse", "alph", "gatehouse"]),
  131.         ("Fly/Teleport to Mahogany, walk in and out of Pokemon Centre",
  132.             ["fly mahogany", "pokecentre", "mahogany", "42"]),
  133.         ("Fly/Teleport to Violet, walk in and out of Pokemon Centre",
  134.             ["fly violet", "pokecentre", "violet", "36"]),
  135.         ("Fly/Teleport twice to Mahogany",
  136.             ["fly mahogany", "fly mahogany", "42"]),
  137.         ("Fly/Teleport twice to Violet",
  138.             ["fly violet", "fly violet", "36"]),
  139.         ("Fly to Mahogany and Violet",
  140.             ["fly mahogany", "42", "fly violet", "36"]),
  141.     ]
  142.     for (desc, pattern) in tests:
  143.         hits = roamWithPlayer(pattern, reps)
  144.         print desc
  145.         targets = len([x for x in pattern if x in roamingMap])
  146.         reps *= targets  #correction for searching more than once in the pattern
  147.         print "%d/%d = %.1f%%" % (hits, reps, 100.0 * hits / reps)
RAW Paste Data