Advertisement
Guest User

Where in Time is Carmen Sandiego TAS bot

a guest
Jun 20th, 2011
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.84 KB | None | 0 0
  1. local function guessandcheck(action,condition,framedelay,lowguess,highguess,executeaction)
  2.     worstpossible=highguess
  3.     local state2=savestate.create()
  4.     local oldstate={}
  5.     for i=1,#condition.adr do
  6.         oldstate[i]=memory.readbyte(condition.adr[i])
  7.     end
  8.     local foundit=false
  9.     savestate.save(state2)
  10.     while not(foundit) do
  11.         savestate.load(state2)
  12.         guess=math.floor((highguess+lowguess)/2)
  13.         for i=1,guess do
  14.             emu.frameadvance()
  15.         end
  16.         for i=1,#action do
  17.             joypad.set(1,action[i])
  18.             emu.frameadvance()
  19.         end
  20.         for i=1,framedelay do
  21.             emu.frameadvance()
  22.         end
  23.         if condition.fn(unpack(oldstate),unpack(condition)) then
  24.             highguess=guess
  25.         else
  26.             lowguess=guess+1
  27.         end
  28.         foundit = (highguess==lowguess)
  29.     end
  30.     savestate.load(state2)
  31.     for i=1,lowguess do
  32.         emu.frameadvance()
  33.     end
  34.     if executeaction then
  35.         for i=1,#action do
  36.             joypad.set(1,action[i])
  37.             emu.frameadvance()
  38.         end
  39.     end
  40.  
  41.     if highguess==worstpossible then
  42.         print("BAD!")
  43.     end
  44.  
  45.     --while not(condition["fn"](oldstate,unpack(condition))) do
  46.     --  emu.frameadvance()
  47.     --end
  48. end
  49.  
  50.  
  51. function table.copy(t)
  52.   local t2 = {}
  53.   for k,v in pairs(t) do
  54.     t2[k] = v
  55.   end
  56.   return t2
  57. end
  58.  
  59.  
  60. --Copies tables of two dimensions.  There's probably a better way to do this...
  61. function table.copy2(t)
  62.   local t2 = {}
  63.   for k,v in pairs(t) do
  64.     t2[k]={}
  65.     for k2,v2 in pairs(t[k]) do
  66.       t2[k][k2] = v2
  67.     end
  68.   end
  69.   return t2
  70. end
  71.  
  72.  
  73. local function idleframes(n)
  74.     for i = 1,n do
  75.         emu.frameadvance()
  76.     end
  77. end
  78.  
  79.  
  80. --local function selectedsuspect(suspectnumber)
  81. --  if memory.readbyte(0x6039)==suspectnumber then
  82. --      return true
  83. --  else
  84. --      return false
  85. --  end
  86. --end
  87.  
  88.  
  89. local function fastmove(targetselection)
  90.     local currentselection=memory.readbyte(0x6E)
  91.     local downpresses=(targetselection-currentselection)%10
  92.     local uppresses=(currentselection-targetselection)%10
  93.     if currentselection==targetselection then
  94.         return {{}}
  95.     elseif downpresses==math.min(downpresses, uppresses) then
  96.         if downpresses==1 then
  97.             return {{down=1}}
  98.         else
  99.             return {{down=1,right=1}}
  100.         end
  101.     else
  102.         if uppresses==1 then
  103.             return {{up=1}}
  104.         else
  105.             return {{up=1,left=1}}
  106.         end
  107.     end
  108. end
  109.  
  110.  
  111. --Used to quickly input suspect properties in the evidence window.  Does not work on sex (note the mod 5 command).
  112. local function fastinput(targetproperty)
  113.     local currentproperty=memory.readbyte(0x6034 + memory.readbyte(0x6E))
  114.     local Apresses=(targetproperty-currentproperty)%5
  115.     local Bpresses=(currentproperty-targetproperty)%5
  116.     if currentproperty==targetproperty then
  117.         return {{}}
  118.     elseif Apresses==math.min(Apresses, Bpresses) then
  119.         return {{A=1}}
  120.     else
  121.         return {{B=1}}
  122.     end
  123. end
  124.  
  125.  
  126.  
  127. local function propertychanged(oldproperty,action)
  128.     if action[1]["A"] then
  129.         if memory.readbyte(0x6034+memory.readbyte(0x6E))==(oldproperty+1)%5 then
  130.             return true
  131.         else
  132.             return false
  133.         end
  134.     elseif action[1]["B"] then
  135.         if memory.readbyte(0x6034+memory.readbyte(0x6E))==(oldproperty-1)%5 then
  136.             return true
  137.         else
  138.             return false
  139.         end
  140.     else
  141.         return false
  142.     end
  143. end
  144.  
  145.  
  146. local function declareevidence(targetproperty)
  147.     local action=fastinput(targetproperty)
  148.     local infotype=0x6034+memory.readbyte(0x6E)
  149.     local condition={fn=propertychanged, adr={infotype}, action}
  150.     while not(memory.readbyte(infotype)==targetproperty) do
  151.         guessandcheck(action,condition,2,0,6,true)
  152.         emu.frameadvance()
  153.     end
  154. end
  155.  
  156. local function cursormoved(oldselection,action)
  157.     local total=0
  158.     for k,v in pairs(action[1]) do
  159.         if k=="down" or k=="right" then
  160.             total=total+1
  161.         elseif k=="up" or k=="left" then
  162.             total=total-1
  163.         end
  164.     end
  165.     if memory.readbyte(0x6E)==(oldselection+total)%10 then
  166.         return true
  167.     else
  168.         return false
  169.     end
  170. end
  171.  
  172.  
  173. local function madeselection(blah,targetselection)
  174.     if memory.readbyte(0x70)==targetselection then
  175.         return true
  176.     else
  177.         return false
  178.     end
  179. end
  180.  
  181.  
  182. local function movecursor(targetselection)
  183.     while not(memory.readbyte(0x6E)==targetselection) do
  184.         action=fastmove(targetselection)
  185.         joypad.set(1,action[1])
  186.         emu.frameadvance()
  187.         emu.frameadvance()
  188.     end
  189. end
  190.  
  191.  
  192. local function makeselection(targetselection)
  193.     guessandcheck({{A=1}},{fn=madeselection,adr={},targetselection},2,0,4,true)
  194. end
  195.  
  196.  
  197. local function makeselectionfast()
  198.     joypad.set(1,{A=1})
  199.     emu.frameadvance()
  200.     emu.frameadvance()
  201. end
  202.  
  203.  
  204. --Waits for beeps to finish and for control to be relinquished to player.  Unfortunately, 0x70=255 strictly AFTER control has been relinquished, so the script backtracks.
  205. local function waitforcontrol(backtrackframes)
  206.     local state2=savestate.create()
  207.     savestate.save(state2)
  208.     while not(memory.readbyte(0x70)==255) do
  209.         emu.frameadvance()
  210.     end
  211.  
  212.     if backtrackframes>0 then
  213.         local howlong=movie.framecount()
  214.         savestate.load(state2)
  215.         --print(howlong-movie.framecount())
  216.         while movie.framecount()<howlong-backtrackframes do
  217.             emu.frameadvance()
  218.         end
  219.     end
  220. end
  221.  
  222.  
  223. local function waitforcursorwarp(whereto)
  224.     if not whereto then
  225.         while memory.readbyte(0x6F)>250 do
  226.             emu.frameadvance()
  227.         end
  228.     else
  229.         while not(memory.readbyte(0x6F)==whereto) do
  230.             emu.frameadvance()
  231.         end
  232.     end
  233.     emu.frameadvance()
  234. end
  235.  
  236.  
  237. local function suspectproperties(suspectnumber)
  238.     --Fastest way to select characteristics:
  239.     --Sex: Male, press A.  Female, press B.
  240.     --Hair: Black, press A.  Blond, press A twice.  Brown, press B twice.  Red, press B.
  241.     --Eyes: Blue, press A.  Brown, press A twice.  Gray, press B twice.  Hazel, press B.
  242.     --Artist: Cassatt, press A.  Degas, press A twice.  Orozco, press B twice.  Van Gogh, press B.
  243.     --Author: Dostoyevsky, press A.  Hugo, press A twice.  Kipling, press B twice.  Porter, press B.
  244.  
  245.     --Selections:
  246.     --Sex: 6034 (0 none, 1 male, 2 female)
  247.     --Hair: 6035 (0 none, 1 black, 2 blond, 3 brown, 4 red)
  248.     --Eyes: 6036 (0 none, 1 blue, 2 brown, 3 gray, 4 hazel)
  249.     --Artist: 6037 (0 none, 1 Cassatt, 2 Degas, 3 Orozco, 4 Van Gogh)
  250.     --Author: 6038 (0 none, 1 Dostoyevsky, 2 Hugo, 3 Kipling, 4 Porter)
  251.     --These values are preserved even if you exit the evidence menu.   
  252.  
  253.     --Dossiers (star denotes optimal properties to set):
  254.     --0) Carmen Sandiego.  Female, *black, brown, *Degas, Dostoyevsky.  (2,1,2,2,1)
  255.     --1) Auntie Bellum.  Female, blonde, hazel, *Cassatt, *Porter.  (1,2,4,1,4)
  256.     --2) Earl E. Bird.  Male, *red, *brown, Orozco, Kipling.  (1,4,2,3,3)
  257.     --3) Justin Case.  Male, *black, *blue, Van Gogh, Hugo.  (1,1,1,3,2)
  258.     --4) Molly Coddle.  Female, brown, *blue, *Degas, Hugo.  (2,3,1,2,2)
  259.     --5) Lee and Bill Ding.  Male, *red, gray, *Degas, Kipling.  (1,4,3,2,3)
  260.     --6) Ernest Endeavor.  Male, blond, *blue, Cassatt, *Dostoyevsky.  (1,2,1,1,1)
  261.     --7) Lynn Gweeny.  Female, black, *gray, Van Gogh, *Dostoyevsky.  (2,1,3,4,1)
  262.     --8) Russ T. Hinge.  Male, blond, hazel, *Cassatt, *Hugo.  (1,2,4,1,2)
  263.     --9) Nosmo King.  Male, brown, *hazel, *Degas, Porter.  (1,3,4,2,4)
  264.     --10) Rudy Lepay.  Male, *brown, gray, *Orozco, Porter.  (1,3,3,3,4)
  265.     --11) Kari Meback.  Female, *brown, brown, *Van Gogh, Hugo.  (2,3,2,4,2)
  266.     --12) Minnie Series.  Female, blonde, *blue, Cassatt, *Kipling.  (2,2,1,1,3)
  267.     --13) Sybil Servant.  Female, *red, gray, Orozco, *Porter.  (2,4,3,3,4)
  268.     --14) Sharon Sharalike.  Female, *red, *hazel, Orozco, Kipling.  (2,4,4,3,3)
  269.     --15) Gene Yuss.  *Male, black, brown, *Van Gogh, *Dostoyevsky.  (1,1,2,4,1)
  270.     evidence={  [0]={{1,1},{3,2}},  --0) Carmen Sandiego (fastest?)
  271.             {{3,1},{4,4}},      --1) Auntie Bellum
  272.             {{1,4},{2,2}},      --2) Earl E. Bird
  273.             {{1,1},{2,1}},      --3) Justin Case
  274.             {{2,1},{3,2}},      --4) Molly Coddle
  275.             {{1,4},{3,2}},      --5) Lee and Bill Ding
  276.             {{2,1},{4,1}},      --6) Ernest Endeavor
  277.             {{2,3},{4,1}},      --7) Lynn Gweeny
  278.             {{3,1},{4,2}},      --8) Russ T. Hinge
  279.             {{2,4},{3,2}},      --9) Nosmo King
  280.             {{1,3},{3,3}},      --10) Rudy Lepay
  281.             {{1,3},{3,4}},      --11) Kari Meback
  282.             {{2,1},{4,3}},      --12) Minnie Series
  283.             {{1,4},{4,4}},      --13) Sybil Servant
  284.             {{1,4},{2,4}},      --14) Sharon Sharalike
  285.             {{0,1},{3,4},{4,1}}}    --15) Gene Yuss
  286.  
  287.     return evidence[suspectnumber]
  288. end
  289.  
  290.  
  291. local function inputallevidence()
  292.     local suspect=memory.readbyte(0x6014)
  293.     local evidence=suspectproperties(suspect)
  294.     for i=1,#evidence do
  295.         movecursor(evidence[i][1])
  296.         declareevidence(evidence[i][2])
  297.     end
  298.     movecursor(5)
  299.     makeselection(5)
  300. end
  301.  
  302.  
  303. local function getwarrant()
  304.     movecursor(8)
  305.     makeselectionfast()
  306.     waitforcursorwarp()
  307.     makeselection(0)
  308.     waitforcontrol(0)
  309.     inputallevidence()
  310.     idleframes(480)
  311.     waitforcontrol(0)
  312. end
  313.  
  314.  
  315. local function suspectlocation()
  316.     local i=0
  317.     while memory.readbyte(0x6017+i)<100 and i<14 do
  318.         location=memory.readbyte(0x6017+i)
  319.         i=i+1
  320.     end
  321.     return location
  322. end
  323.  
  324.  
  325. local function incommon(fromstart,fromend)
  326.     local shared={}
  327.     for i=0,47 do
  328.         if fromstart[i] and fromend[i] then
  329.             table.insert(shared,i)
  330.         end
  331.     end
  332.     if #shared>0 then
  333.         return shared
  334.     else
  335.         return false
  336.     end
  337. end
  338.  
  339.  
  340. local function makegraph()
  341.     local graph={}
  342.     for i=0,47 do
  343.         graph[i]={}
  344.         for j=0,3 do
  345.             graph[i][j]=memory.readbyte(0x62DA + 4*i + j)
  346.         end
  347.     end
  348.     return graph
  349. end
  350.  
  351.  
  352. --Concatenates tables in a sensible way.  Only concatenates elements whose indices are consecutive integers starting with 1.
  353. local function tableconcat(table1,table2)
  354.     local output=table1
  355.     for i=1,#table2 do
  356.         table.insert(table1,table2[i])
  357.     end
  358.     return output
  359. end
  360.  
  361.  
  362. local function shortestpaths()
  363.     local graph=makegraph()
  364.     local initial=memory.readbyte(0x6017)
  365.     local final=suspectlocation()
  366.  
  367.     local map={[0]={},{}}
  368.     map[0][initial]={{}}
  369.     map[1][final]={{}}
  370.     local depth=0
  371.     while not(incommon(map[0],map[1])) do
  372.             for i=0,47 do
  373.                 if map[depth%2][i] and #map[depth%2][i][1]==math.floor(depth/2) then
  374.                     for j=0,3 do
  375.                         local destination=graph[i][j]
  376.                         map[depth%2][destination]={}
  377.                         local temp=table.copy2(map[depth%2][i])
  378.                         for k=1,#temp do
  379.                             table.insert(temp[k],#temp[k]*(1-depth%2)+1, destination*(1-depth%2)+i*(depth%2))
  380.                             map[depth%2][destination][#map[depth%2][destination]+1]=table.copy(temp[k])
  381.                             temp=table.copy2(map[depth%2][i])
  382.                         end
  383.                     end
  384.                 end
  385.             end
  386.         depth=depth+1
  387.     end
  388.     shared=incommon(map[0],map[1])
  389.     local paths={}
  390.     for i=1,#shared do
  391.         for j=1,#map[0][shared[i]] do
  392.             for k=1,#map[1][shared[i]] do
  393.                 paths[#paths+1]=tableconcat(map[0][shared[i]][j],map[1][shared[i]][k])
  394.             end
  395.         end
  396.     end
  397.     return paths
  398. end
  399.  
  400.  
  401. local function bytematches(blah,address,value)
  402.     if memory.readbyte(address)==value then
  403.         return true
  404.     else
  405.         return false
  406.     end
  407. end
  408.  
  409.  
  410. local function nameentered()
  411.     local firstletter=bytematches(1,0x62CA,221)
  412.     local secondletter=bytematches(1,0x62CB,234)
  413.     local thirdletter=bytematches(1,0x62CC,221)
  414.     local fourthletter=bytematches(1,0x62CD,234)
  415.     local pressedstart=bytematches(1,0x01F4,208)
  416.     return firstletter and secondletter and thirdletter and fourthletter and pressedstart
  417. end
  418.  
  419.  
  420. local function enterbobo()
  421.     local action={  {right=1,A=1},{},{down=1,left=1},{down=1,A=1},
  422.             {},{right=1,up=1},{up=1,A=1},{},{left=1,down=1},
  423.             {down=1,A=1},{},{up=1,left=1},{up=1,A=1}}
  424.     guessandcheck(action,{fn=nameentered,adr={}},10,0,80,true)
  425. end
  426.  
  427.  
  428. local function fastcountdown()
  429.     idleframes(14)
  430.     for i=1,4 do
  431.         guessandcheck({{A=1}},{fn=bytematches,adr={},0x450,130},5,0,4,true)
  432.         idleframes(11)
  433.     end
  434.     guessandcheck({{A=1}},{fn=bytematches,adr={},0x349,201},5,0,60,true)
  435. end
  436.  
  437.  
  438. local function startgame()
  439.     idleframes(160)
  440.     guessandcheck({{A=1}},{fn=bytematches,adr={},0x1B,92},10,0,80,true)
  441.     while emu.framecount()<464 do
  442.         emu.frameadvance()
  443.     end
  444.     for i=1,2 do
  445.         joypad.set(1,{A=1})
  446.         emu.frameadvance()
  447.     end
  448.     --idleframes(200)
  449.     --guessandcheck({{A=1},{A=1}},{fn=bytematches,adr={},0x1B,78},40,0,80,true)
  450.     guessandcheck({{up=1}},{fn=bytematches,adr={},0x535,2},10,0,40,true)
  451.     guessandcheck({{A=1}},{fn=bytematches,adr={},0x52,10},10,0,10,true)
  452.     idleframes(200)
  453.     guessandcheck({{left=1}},{fn=bytematches,adr={},0x536,92},10,0,60,true)
  454.     guessandcheck({{A=1}},{fn=bytematches,adr={},0xC,1},10,0,10,true)
  455.     enterbobo()
  456.     guessandcheck({{A=1}},{fn=bytematches,adr={},0x1B,137},10,0,40,true)
  457.     guessandcheck({{A=1}},{fn=bytematches,adr={},0xD,0},10,0,40,true)
  458.  
  459.     idleframes(122)
  460.     waitforcontrol(0)
  461.     for i=1,6 do
  462.         makeselectionfast()
  463.         waitforcontrol(0)
  464.     end
  465.     makeselectionfast()
  466.     idleframes(20)
  467.     fastcountdown()
  468.     idleframes(20)
  469. end
  470.  
  471.  
  472. local function fastcapture(lazy)
  473.     movecursor(7)
  474.     makeselection(7)
  475.     waitforcursorwarp()
  476.     local capturesave=savestate.create()
  477.     savestate.save(capturesave)
  478.     local startframes=emu.framecount()
  479.     local quickest=10000
  480.     local perm={0,1,2}
  481.     local bestperm={}
  482.     if not(lazy) then
  483.         for i=1,3 do
  484.             for j=1,2 do
  485.                 while emu.framecount()-startframes<quickest do
  486.                     local k=1
  487.                     local gotem=false
  488.                     while k<4 and not(gotem) do
  489.                         movecursor(perm[k])
  490.                         makeselection(perm[k])
  491.                         if perm[k]==2 then
  492.                             idleframes(160)
  493.                         else
  494.                             idleframes(60)
  495.                         end
  496.                         if memory.readbyte(0x603A)==238 then
  497.                             gotem=true
  498.                             if (emu.framecount()-startframes)<quickest then
  499.                                 bestperm={}
  500.                                 quickest=emu.framecount()-startframes
  501.                                 for m=1,k do
  502.                                     bestperm[m]=perm[m]
  503.                                 end
  504.                             end
  505.                         else
  506.                             waitforcursorwarp()
  507.                             movecursor(7)
  508.                             makeselection(7)
  509.                             waitforcursorwarp()
  510.                             k=k+1
  511.                         end
  512.                     end
  513.                 end
  514.                 savestate.load(capturesave)
  515.                 perm[1],perm[2]=perm[2],perm[1]
  516.             end
  517.             perm[1],perm[2],perm[3]=perm[2],perm[3],perm[1]
  518.         end
  519.     else
  520.         bestperm={0,1,2}
  521.     end
  522.     savestate.load(capturesave)
  523.     for i=1,#bestperm-1 do
  524.         movecursor(bestperm[i])
  525.         makeselection(bestperm[i])
  526.         waitforcursorwarp()
  527.         movecursor(7)
  528.         makeselection(7)
  529.         waitforcursorwarp()
  530.     end
  531.     movecursor(bestperm[#bestperm])
  532.     makeselection(bestperm[#bestperm])
  533.     waitforcursorwarp()
  534. end
  535.  
  536.  
  537. local function betweencases()
  538.     for i=1,6 do
  539.         makeselectionfast()
  540.         waitforcontrol(0)
  541.     end
  542.     if memory.readbyte(0x6014)==0 then
  543.         makeselectionfast()
  544.         waitforcontrol(0)
  545.         makeselectionfast()
  546.         waitforcontrol(0)
  547.     end
  548.     makeselection(5)
  549.     waitforcursorwarp(4)
  550.     makeselectionfast()
  551.     waitforcursorwarp()
  552.     for i=1,6 do
  553.         makeselectionfast()
  554.         waitforcontrol(0)
  555.     end
  556.     makeselectionfast()
  557.     idleframes(20)
  558.     fastcountdown()
  559.     idleframes(20)
  560. end
  561.  
  562.  
  563. local function solvecase(path,getwarrantwhen)
  564.     waitforcursorwarp()
  565.     if getwarrantwhen==0 then
  566.         getwarrant()
  567.     end
  568.     for i=1,#path do
  569.         movecursor(6)
  570.         makeselectionfast()
  571.         waitforcursorwarp()
  572.         local enroute=false
  573.         local j=0
  574.         while not(enroute) and j<4 do
  575.             if memory.readbyte(0x6000+j)==path[i] then
  576.                 movecursor(j)
  577.                 makeselection(j)
  578.                 waitforcursorwarp()
  579.                 enroute=true
  580.             end
  581.             j=j+1
  582.         end
  583.         if i==getwarrantwhen then
  584.             getwarrant()
  585.         end
  586.     end
  587.     fastcapture()
  588.     betweencases()
  589. end
  590.  
  591. --Breadth: how many of the best runs to keep.  Depth: how many levels to beat before evaluating the tree.
  592. --tree[i]: runs to ith depth
  593. --tree[i][j]: jth run
  594. --tree[i][j][1]: savestate for jth run
  595. --tree[i][j][2]: frames of jth run
  596. local function bot(trunk,breadth,depth)
  597.     local tree={{}}
  598.     for i=1,#trunk[1] do
  599.         tree[1][i]={}
  600.         tree[1][i][1]=trunk[1][i][1]
  601.         tree[1][i][2]=trunk[1][i][2]
  602.     end
  603.     for i=2,depth+1 do
  604.         tree[i]={}
  605.     end
  606.     for i=1,depth do
  607.         for j=1,#tree[i] do
  608.             savestate.load(tree[i][j][1])
  609.             paths=shortestpaths()
  610.             for k=0,#paths do
  611.                 solvecase(paths[1],k)
  612.                 tree[i+1][#tree[i+1]+1]={}
  613.                 tree[i+1][#tree[i+1]][1]=savestate.create()
  614.                 savestate.save(tree[i+1][#tree[i+1]][1])
  615.                 newpaths=shortestpaths()
  616.                 tree[i+1][#tree[i+1]][2]=emu.framecount()+665*#newpaths[1]
  617.                 savestate.load(tree[i][j][1])
  618.             end
  619.         end
  620.     end
  621.     trunk={{}}
  622.     worstbranch={0,0}
  623.     for i=1,#tree[depth+1] do
  624.         for j=1,#trunk[1] do
  625.             if trunk[1][j][2]>worstbranch[2] then
  626.                 worstbranch={j,trunk[1][j][2]}
  627.             end
  628.         end
  629.         if #trunk[1]<breadth then
  630.             trunk[1][#trunk[1]+1]={}
  631.             trunk[1][#trunk[1]][1]=tree[depth+1][i][1]  --Copies savestate
  632.             trunk[1][#trunk[1]][2]=tree[depth+1][i][2]  --Copies estimated frame count
  633.         else
  634.             if tree[depth+1][i][2]<worstbranch[2] then
  635.                 trunk[1][worstbranch[1]][1]=tree[depth+1][i][1]
  636.                 trunk[1][worstbranch[1]][2]=tree[depth+1][i][2]
  637.             end
  638.         end
  639.     end
  640.     return trunk
  641. end
  642.  
  643.  
  644.  
  645.  
  646. local breadth=2
  647. local depth=1
  648. --startgame()
  649. firstsave=savestate.create()
  650. savestate.save(firstsave)
  651. paths=shortestpaths()
  652. trunk={{{firstsave,0}}}
  653.  
  654.  
  655. for i=1,78 do
  656.     trunk=bot(trunk,breadth,depth)
  657. end
  658.  
  659.  
  660. emu.pause()
  661.  
  662.  
  663.  
  664. --Interesting RAM addresses
  665. ---------------------------
  666. --0070: Selection being loaded.  Use this to get instant feedback instead of waiting for the beeps to finish.
  667. --04D7: Warrant suspect ID.
  668. --01F9: In main menu?
  669. --6025: # cases solved.
  670. --6016: Rank.
  671. --01ED, 0729, 603A, 6043, 6044: All seem to be consistent on the "suspect spotted" screen.  (603A and 6043 seem to be best.)
  672. --006F: Cursor warp.  After some actions, the cursor will warp to a particular selection.  This address signifies where the cursor will warp to, but only on the frame immediately
  673.  
  674. prior to the warp.  Note that any cursor movements prior to the warp are negated by it.
  675.  
  676. --Other notes
  677. -------------
  678. --Checked shortest path and aborted game 100 times (with some accidental repeats...).  The statistics follow:
  679. --3 games had a shortest path of 1
  680. --13 games had a shortest path of 2
  681. --51 games had a shortest path of 3
  682. --33 games had a shortest path of 4
  683.  
  684. --The same test was repeated by "forcing" the RNGs (the RNGs were randomized via the math.random function).  The sample size was 1000.  This resulted in the following
  685.  
  686. distribution:
  687. --94 games had a shortest path of 1
  688. --307 games hada  shortest path of 2
  689. --431 games had a shortest path of 3
  690. --168 games had a shortest path of 4
  691.  
  692. --This seems to fairly strongly indicate that the game's PRNG and Lua's PRNG are not accurate simulations of each other.
  693.  
  694. --First test ("natural" RNGs) repeated except with 1000 iterations.  New distribution follows:
  695. --76 games had a shortest path of 1
  696. --154 games had a shortest path of 2
  697. --469 games had a shortest path of 3
  698. --301 games had a shortest path of 4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement