Advertisement
Dugongue

Untitled

Dec 22nd, 2021
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.70 KB | None | 0 0
  1. function Split(s, delimiter)
  2. result = {};
  3. for match in (s..delimiter):gmatch("(.-)"..delimiter) do
  4. table.insert(result, match);
  5. end
  6. return result;
  7. end
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18. function waitFrames(n)
  19. for i=1,n,1 do
  20. emu.frameadvance()
  21. end
  22. end
  23.  
  24. function waitForEvent(addr, eventType, val)
  25. val = val or nil
  26.  
  27. flag = false
  28. if (eventType == "r") then
  29. f = event.onmemoryread
  30. elseif (eventType == "w") then
  31. f = event.onmemorywrite
  32. elseif (eventType == "x") then
  33. f = event.onmemoryexecute
  34. else
  35. print("waitForEvent ERROR: invalid eventType")
  36. end
  37.  
  38. f(function()
  39. if (eventType == "x" or val == nil or mainmemory.readbyte(addr) == val) then
  40. flag = true
  41. end
  42. end)
  43.  
  44. while (~flag) do
  45. emu.frameadvance()
  46. end
  47.  
  48. if (~event.unregisterbyid(guid)) then
  49. print("waitForEvent ERROR: could not unregister event")
  50. end
  51. end
  52.  
  53. function waitForRead(addr, val)
  54. val = val or nil
  55. waitForEvent(addr, "r", val)
  56. end
  57.  
  58. function waitForWrite(addr, val)
  59. val = val or nil
  60. waitForEvent(addr, "w", val)
  61. end
  62.  
  63. function waitForExecute(addr)
  64. waitForEvent(addr, "x", nil)
  65. end
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75. function node(n)
  76. return { name = n, state = nil, parent = nil, children = nil, cn = 0, value = 0, visits = 0 }
  77. end
  78.  
  79. function selection(node)
  80. topChild = nil
  81. topScore = -999
  82.  
  83. c = math.sqrt(2)
  84. k = 0.5
  85.  
  86. for i, kid in pairs(node.children) do
  87. if (kid.visits > 0) then
  88. score = (kid.value / (kid.visits) ) + c * math.sqrt( ( 2 * math.log(node.visits) ) / (kid.visits) )
  89. else
  90. score = k + c * math.sqrt( ( 2 * math.log(node.visits) ) / (node.cn + 1) )
  91. end
  92. if score > topScore then
  93. topChild = kid
  94. topScore = score
  95. end
  96. end
  97.  
  98. --If unvisited child is chosen, increase the "expanded children" counter
  99. if topChild.visits == 0 then node.cn = node.cn + 1 end
  100.  
  101. return topChild
  102. end
  103.  
  104. function MonteCarloTreeSearch(game, n, root)
  105.  
  106. for i=1,n,1 do
  107. curNode = root
  108. curNode.visits = curNode.visits + 1
  109.  
  110. while (curNode.state ~= nil) do
  111. if (curNode.children == nil) then
  112. game.expand(curNode)
  113. end
  114. curNode = selection(curNode)
  115. curNode.visits = curNode.visits + 1
  116. end
  117.  
  118. memorysavestate.loadcorestate(curNode.parent.state)
  119. game.perform(curNode.name)
  120. curNode.state = memorysavestate.savecorestate()
  121.  
  122. game.rollout()
  123. result = game.score()
  124.  
  125. if game.loseFlag then
  126. result = 0
  127. game.loseFlag = false
  128. end
  129.  
  130. while (curNode ~= nil) do
  131. curNode.value = curNode.value + result;
  132. curNode = curNode.parent
  133. end
  134.  
  135. end
  136.  
  137. topKid = nil
  138. topScore = -999
  139.  
  140. for i, kid in pairs(root.children) do
  141. if (kid.value / kid.visits > topScore) then
  142. topKid = kid
  143. topScore = kid.value / kid.visits
  144. end
  145. end
  146.  
  147. return topKid
  148. end
  149.  
  150. function simulate(game, N, n)
  151.  
  152. for i, trigger in ipairs(game.winTriggers) do
  153. event.onmemoryexecute(game.setWinFlag, trigger)
  154. end
  155.  
  156. for i, trigger in ipairs(game.loseTriggers) do
  157. event.onmemoryexecute(game.setLoseFlag, trigger)
  158. end
  159.  
  160. root = node(nil)
  161. root.state = memorysavestate.savecorestate()
  162. for i=1,N,1 do
  163. root = MonteCarloTreeSearch(game, n, root)
  164. memorysavestate.loadcorestate(root.state)
  165. root.parent = nil
  166. end
  167. end
  168.  
  169. OnimushaTactics = {
  170. name = "Onimusha Tactics",
  171.  
  172. winFlag = false,
  173. winTriggers =
  174. {
  175.  
  176. },
  177. setWinFlag = function()
  178. winFlag = true
  179. end,
  180.  
  181. loseFlag = false,
  182. loseTriggers =
  183. {
  184.  
  185. },
  186. setLoseFlag = function()
  187. loseFlag = true
  188. end,
  189.  
  190. getActs = function()
  191. acts = {}
  192. -- If game mode is "unit select"
  193. -- List of actions =
  194. -- * Selecting each unit
  195. -- * Ending turn
  196. -- If game mode is "unit menu"
  197. -- List of actions =
  198. -- * Each Move //
  199. -- * Each Attack // For these two, run the appropriate function(s) to generate legal tiles then restore savestate
  200. -- * Done
  201. return acts
  202. end,
  203.  
  204. expand = function(p)
  205. acts = getActs()
  206.  
  207. kids = {}
  208. for k,v in pairs(acts) do
  209. kids[k] = node(k)
  210. kids[k].parent = p
  211. end
  212.  
  213. p.children = kids
  214. end,
  215.  
  216. perform = function(act)
  217. -- If action is "finish turn"
  218. -- Menu
  219. -- Select "finish turn"
  220. -- Press A
  221. -- Set wait for "start of player turn" game mode
  222.  
  223. -- If action is "select unit"
  224. -- Parse unit # from action string name
  225. -- Find x/y pos of that unit
  226. -- Move cursor to that position
  227. -- Press A
  228. -- Set wait for "unit menu" game mode
  229.  
  230. -- else if action is "move"
  231. -- Move cursor to "Move"
  232. -- Press A
  233. -- Set wait for "move" game mode
  234. -- Parse x/y position from action string name
  235. -- Move cursor to that position
  236. -- Press A
  237. -- Set wait for "unit menu" game mode
  238.  
  239. -- else if action is "attack"
  240. -- Move cursor to "Attack"
  241. -- Press A
  242. -- Set wait for "attack" game mode
  243. -- Parse x/y position from action string name
  244. -- Move cursor to that position
  245. -- Press A
  246. -- Set wait for "unit menu" game mode
  247.  
  248. -- else if action is "done"
  249. -- Select done
  250. -- Press A
  251. -- If all units are done, set wait for "start of player turn" function
  252. -- Else set wait for "unit select" game mode
  253. end,
  254.  
  255. rollout = function()
  256. --Rollout logic:
  257. ---Random action until end
  258. while (~winFlag and ~loseFlag) do
  259. acts = getActs()
  260. a = chooseRandom(acts) -- implement this
  261. perform(a)
  262. end
  263. end,
  264.  
  265. score = function()
  266. UNIT_ADDR = 0x28DC
  267. UNIT_SIZE = 0xEC
  268.  
  269. total = 0
  270. for i=0,15,1 do
  271. curUnit = UNIT_ADDR + UNIT_SIZE*i
  272. unitID = mainmemory.readbyte(curUnit)
  273. if unitID ~= 0 and unitID <= 15 then
  274. unitLVL = mainmemory.readbyte(curUnit+40)
  275. unitEXP = mainmemory.readbyte(curUnit+180)
  276. total = total + 100*unitLVL + unitEXP
  277. end
  278. end
  279.  
  280. return total
  281. end
  282. }
  283.  
  284. simulate(OnimushaTactics, 10, 10)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement