From a3a562a38235196c8a87df7ca9d6d7a336ecb01e Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:05:58 +0900 Subject: [PATCH 01/12] fixed blink interval constant --- src/stationary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stationary.py b/src/stationary.py index b3d77b2..6ff22d2 100644 --- a/src/stationary.py +++ b/src/stationary.py @@ -119,8 +119,8 @@ def stationary_timeline(): queue = [] heapq.heappush(queue, (waituntil+1.017,0)) - #blink_int = reidentified_rng.range(3.0, 12.0) + 0.3 - blink_int = reidentified_rng.rangefloat(3,12) + 0.3 + #blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + blink_int = reidentified_rng.rangefloat(3,12) + 0.285 heapq.heappush(queue, (waituntil+blink_int,1)) while queue: From f2c22d51a5d52271e0cdff4c1ae05003fda9e3bd Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:06:38 +0900 Subject: [PATCH 02/12] added blink count on debug text --- src/rngtool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rngtool.py b/src/rngtool.py index 25235c6..b68b68c 100644 --- a/src/rngtool.py +++ b/src/rngtool.py @@ -81,7 +81,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40)->Tuple[ if state!=IDLE and time_counter - prev_time>0.7: state = IDLE - print(debug_txt) + print(debug_txt, len(blinks)) cv2.destroyAllWindows() return (blinks, intervals, offset_time) From 530ceff8de12dba960e8d0169218e3fc7ffc3424 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:06:49 +0900 Subject: [PATCH 03/12] Create eye.png --- barry/eye.png | Bin 0 -> 1119 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 barry/eye.png diff --git a/barry/eye.png b/barry/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..5950cf734abb9f3629075d1ab417d939c899a9a6 GIT binary patch literal 1119 zcmV-l1fctgP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf1N2EmK~y+TT~yn0 zBQ+FkX-0D&JFye8VT%Vol;tPjYv3z*qIlTULKYGyb}nPjMWd1EBNs1>OEniut?oXp zqkjGQQvebyi^DW~c)tK}ynB9Ad-42LfsS z>CoF5UDsh=_=(pzkMUlZ0;x%PPhpIKA*gI*t>dt;ZV;d!!%QZ!LvJTMKR@FzI09Rk zj0@8gX%dh{fRxNM+9D^gL8|h&(Xv=*=ZWfO%Cb041fa~BQmoPlx`6d5deT3H4#Zz9$g}t!S=WG@vqstb{kDon^=ivaus+&q%8ktWLQAWan_~2aXZ%!x2ug zD1N5Pyp&ea%)DO1lr0kK7p8J0X@b10I4ObS&Xz33(UJ+PMtRn=R4RpDe1PWUs%da> zu|ZWe5#V&{S)m+N*}&vAmXKnZ2h6rd&uVt#5vQ?-3ycK$XdeQC7)u5-6c#@B{R#J9 z@3B8T;{E-A6L*$GOiO~d(~RBI3l6WxD0A@%G%KkCwg3Ne-1Y6S!_(6v9(Vs>PopO? z6m#7?qaRL`*AqOjOhSZU!Xr@%O7g8ql9>^f{V?F+;S28We#hrOek0fySjv%1C7i4& zNF>Q{o{YEwwNn(m3QVh(PzTKgtfD6avJ+|DX}~aXG8Gh=W;oC3*R+C8a~;hIWZ-z# z1Vq^VcgcHvV`!C_%2HDWvQ#5CltU0DYB&T=X7Xc*tYpNs%$FRA!el6OR<%e`X9lIj zq+ld+g5~+yXwKK3fs>sqL#3u8v^_-+syxGLwZeM6#`R^1n{AC7-rL+q@GLdVn6ROz z5}~-gBMXkeoWPAR4Cv-!jqPQNZ>}x~(&FZ-jewW!nPHKs*a<|I*l`BpL6xCswr6@X zqp{tr@!_h(hwBQr*DY=dbh8z9EkQ~$%8^m3^r=|8nG3~e84*$^^diS)!}G-e&Mv{a zHUy~g?M6n0bz7k>a})$gnIkP7z_G;A^`vrOWe^+;J*!FIDDEg{jIAWF_egINgWI-7 z(^ROqA;m=kdX{9$F`;47Wf$>_z*72>9Uvvp>v7=$1v<-P5?F+$j-!zZa=qdS*KeNv z#E Date: Mon, 10 Jan 2022 09:06:55 +0900 Subject: [PATCH 04/12] Update memo.md --- memo.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/memo.md b/memo.md index 4001c2b..ef83512 100644 --- a/memo.md +++ b/memo.md @@ -2,11 +2,12 @@ memo.md type : roi_x, roi_y, roi_w, roi_h munchlax : 730, 670 ,50, 60 -home/eye_blur : 905, 750, 55, 55 -home/eye_normal : 905, 480, 55, 200 -ruin/eye : 920, 490, 35, 50 -secretbase/eye : 870, 680, 85, 90 -underground/eye : 925, 520, 35, 35 -trophygarden/eye : 930, 505, 30, 30 -mtcoronet/eye : 930, 510, 30, 40 -spearpillar/eye : 935,505,25,30 \ No newline at end of file +trainer/home/eye_blur : 905, 750, 55, 55 +trainer/home/eye_normal : 905, 480, 55, 200 +trainer/ruin/eye : 920, 490, 35, 50 +trainer/secretbase/eye : 870, 680, 85, 90 +trainer/underground/eye : 925, 520, 35, 35 +trainer/trophygarden/eye : 930, 505, 30, 30 +trainer/mtcoronet/eye : 930, 510, 30, 40 +trainer/spearpillar/eye : 935,505,25,30 +barry/eye : 1065, 490, 30, 35 \ No newline at end of file From 44fbe894a91b1894442b73295ff55db3d307d1f3 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Mon, 10 Jan 2022 09:07:17 +0900 Subject: [PATCH 05/12] minor update --- src/tidsid.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tidsid.py b/src/tidsid.py index 97916f4..154e181 100644 --- a/src/tidsid.py +++ b/src/tidsid.py @@ -13,16 +13,17 @@ def getids(r): tid,sid = r&0xFFFF, r>>16 return g7tid, tid, sid -def generate_dangerintervals_list(k): +def generate_dangerintervals_list(k,eps): lst = [] for b in range(1< Date: Mon, 10 Jan 2022 09:11:56 +0900 Subject: [PATCH 06/12] Create starter.py --- src/starter.py | 175 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/starter.py diff --git a/src/starter.py b/src/starter.py new file mode 100644 index 0000000..d3d9ab9 --- /dev/null +++ b/src/starter.py @@ -0,0 +1,175 @@ +import rngtool +import calc +import cv2 +import time +from xorshift import Xorshift +import heapq + +def firstspecify(): + imgpath = "./trainer/home/eye_blur.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + blinks, intervals, offset_time = rngtool.tracking_blink(player_eye, 905, 750, 55, 55) + prng = rngtool.recov(blinks, intervals) + + waituntil = time.perf_counter() + diff = round(waituntil-offset_time) + prng.getNextRandSequence(diff) + + state = prng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + +def reidentify(): + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + + imgpath = "./barry/eye.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + + observed_blinks, _, offset_time = rngtool.tracking_blink(player_eye, 1065, 490, 30, 35,size=20) + reidentified_rng = rngtool.reidentifyByBlinks(Xorshift(*state), observed_blinks,npc=1) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(diff, waituntil-offset_time) + reidentified_rng.advances(max(diff,0)*2) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + advances = 0 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + + while True: + waituntil += 1.018 + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + #player/barry + advances += 1 + r = reidentified_rng.next() + print(f"advances:{advances}, blinks:{hex(r&0xF)}", end=" ") + #barry/player + advances += 1 + r = reidentified_rng.next() + print(f"advances:{advances}, blinks:{hex(r&0xF)}", end=" ") + print() + +def starter_timeline(): + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + + imgpath = "./barry/eye.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + + observed_blinks, _, offset_time = rngtool.tracking_blink(player_eye, 1065, 490, 30, 35,size=20) + reidentified_rng = rngtool.reidentifyByBlinks(Xorshift(*state), observed_blinks,npc=1) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(waituntil-offset_time) + reidentified_rng.advances(max(diff,0)*2) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + #timecounter reset + advances = 0 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + print("next message 'I heard them say professor...'") + + for _ in [0]*20: + waituntil += 1.018 + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + #player/barry + advances += 1 + r = reidentified_rng.next() + print(f"advances:{advances}, blinks:{hex(r&0xF)}", end=" ") + #barry/player + advances += 1 + r = reidentified_rng.next() + print(f"advances:{advances}, blinks:{hex(r&0xF)}", end=" ") + print() + + #advances(reference:https://github.com/Lincoln-LM/Project_Xs/blob/main/configs/config_starter.json) + advances += 41 #"advance_delay" + reidentified_rng.advances(41) + waituntil = time.perf_counter() + print("press A") + queue = [] + + #first(?) starly + advances += 1 + #blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + heapq.heappush(queue, waituntil+blink_int) + + #second(?) starly + advances += 1 + #blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + heapq.heappush(queue, waituntil+blink_int) + print("next massage:'What's going on?!'") + for _ in range(4): + advances += 1 + w = heapq.heappop(queue) + next_time = w - time.perf_counter() or 0 + if next_time>0: + time.sleep(next_time) + + #blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + heapq.heappush(queue, w+blink_int) + print(f"advances:{advances}, interval:{blink_int}") + + #advances(reference:https://github.com/Lincoln-LM/Project_Xs/blob/main/configs/config_starter.json) + advances += 49 #"advance_delay_2" + reidentified_rng.advances(49) + print("press A") + + #advance(+1 when select sterter) + advances += 1 + while queue: + advances += 1 + w = heapq.heappop(queue) + next_time = w - time.perf_counter() or 0 + if next_time>0: + time.sleep(next_time) + + #blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + + heapq.heappush(queue, w+blink_int) + print(f"advances:{advances}, interval:{blink_int}") + + +if __name__ == "__main__": + #firstspecify() + #reidentify() + starter_timeline() \ No newline at end of file From 86a55f8b8fa7bfa6e74ce0ca8b7b830f70b31601 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Sat, 15 Jan 2022 21:47:15 +0900 Subject: [PATCH 07/12] added reidentifyByIntervals function added reidentifyByIntervals this function allows for reidentification in less time --- src/rngtool.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/rngtool.py b/src/rngtool.py index b68b68c..4cfffa0 100644 --- a/src/rngtool.py +++ b/src/rngtool.py @@ -165,6 +165,19 @@ def recov(blinks:List[int],rawintervals:List[int])->Xorshift: return result def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: + """reidentify Xorshift state by type of observed blinks. + + Args: + rng (Xorshift): identified rng + observed_blinks (List[int]): + npc (int, optional): num of npcs. Defaults to 0. + search_max (int, optional): . Defaults to 10**6. + search_min (int, optional): . Defaults to 0. + + Returns: + Xorshift: reidentified rng + """ + if search_maxXorshift: + """reidentify Xorshift state by intervals of observed blinks. + This method is faster than "reidentifyByBlinks" in most cases since it can be reidentified by less blinking. + + Args: + rng (Xorshift): [description] + rawintervals (List[int]): list of intervals of blinks. 6 or more is recommended. + npc (int, optional): [description]. Defaults to 0. + search_max ([type], optional): [description]. Defaults to 10**6. + search_min (int, optional): [description]. Defaults to 0. + + Returns: + Xorshift: [description] + """ + intervals = rawintervals[1:] + if search_maxXorshift: """Recover the xorshift from the interval of Munchlax blinks. From 641215a70c8aa3ff7def5644ee7cf0afb4502809 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Sat, 15 Jan 2022 21:47:58 +0900 Subject: [PATCH 08/12] Update underground.py example of reidentifyByIntervals --- src/underground.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/underground.py b/src/underground.py index a77700e..1a95d63 100644 --- a/src/underground.py +++ b/src/underground.py @@ -104,6 +104,45 @@ def reidentify(): next_time = waituntil - time.perf_counter() or 0 time.sleep(next_time) +def reidentifyInSecretBase(): + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + imgpath = "./trainer/secretbase/eye.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + blinks, observed_intervals, offset_time = rngtool.tracking_blink(player_eye, 870, 680, 85, 90, size=6) + reidentified_rng = rngtool.reidentifyByIntervals(Xorshift(*state), observed_intervals, npc=0) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(diff, waituntil-offset_time) + reidentified_rng.advances(max(diff,0)) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + #timecounter reset + advances = 0 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + + while True: + advances += 1 + r = reidentified_rng.next() + waituntil += 1.017 + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + print(f"advances:{advances}, blink:{hex(r&0xF)}") + if __name__ == "__main__": #firstspecify() - reidentify() \ No newline at end of file + reidentifyInSecretBase() \ No newline at end of file From be872c4cd72ae3c0cdf9af62120c72dbdb166d76 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Tue, 18 Jan 2022 03:44:31 +0900 Subject: [PATCH 09/12] eye image added --- cresselia/eye.png | Bin 0 -> 368 bytes memo.md | 6 +++++- trainer/fullmoon/eye.png | Bin 0 -> 1097 bytes trainer/lake/eye.png | Bin 0 -> 1326 bytes 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 cresselia/eye.png create mode 100644 trainer/fullmoon/eye.png create mode 100644 trainer/lake/eye.png diff --git a/cresselia/eye.png b/cresselia/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..453d494ca7833f7d39c376fa9061c917fb60ec25 GIT binary patch literal 368 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 kb12sIBR3O7|F Date: Tue, 18 Jan 2022 03:44:57 +0900 Subject: [PATCH 10/12] Update underground.py --- src/underground.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/underground.py b/src/underground.py index 1a95d63..fcb0c3a 100644 --- a/src/underground.py +++ b/src/underground.py @@ -112,7 +112,7 @@ def reidentifyInSecretBase(): if player_eye is None: print("path is wrong") return - blinks, observed_intervals, offset_time = rngtool.tracking_blink(player_eye, 870, 680, 85, 90, size=6) + blinks, observed_intervals, offset_time = rngtool.tracking_blink(player_eye, 870, 680, 85, 90, size=7) reidentified_rng = rngtool.reidentifyByIntervals(Xorshift(*state), observed_intervals, npc=0) if reidentified_rng is None: print("couldn't reidentify state.") From e741278d1a9e8426a84c9bae7f9b0cfbe9444be8 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Tue, 18 Jan 2022 03:46:21 +0900 Subject: [PATCH 11/12] simultaneous tracking (player and pokemon) support added --- src/rngtool.py | 136 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 117 insertions(+), 19 deletions(-) diff --git a/src/rngtool.py b/src/rngtool.py index 4cfffa0..0d95155 100644 --- a/src/rngtool.py +++ b/src/rngtool.py @@ -7,6 +7,7 @@ import time import cv2 from xorshift import Xorshift import calc +from collections import Counter IDLE = 0xFF SINGLE = 0xF0 @@ -20,7 +21,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40)->Tuple[ """measuring the type and interval of player's blinks Returns: - blinks:List[int],intervals:list[int],offset_time:float: [description] + blinks:List[int], intervals:list[int], offset_time:float """ eye = img @@ -40,7 +41,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40)->Tuple[ offset_time = 0 - # 瞬きの観測 + # observe blinks while len(blinks)Tuple[ if 0.01Tuple[ cv2.destroyAllWindows() return (blinks, intervals, offset_time) -def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, size = 60)->Tuple[List[int],List[int],float]: - """measuring the type and interval of pokemon's blinks +def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.85, size = 60)->Tuple[List[int],List[int],float]: + """measuring the interval of pokemon's blinks Returns: intervals:list[int],offset_time:float: [description] @@ -106,7 +107,7 @@ def tracking_poke_blink(img, roi_x, roi_y, roi_w, roi_h, size = 60)->Tuple[List[ prev_time = time.perf_counter() - # 瞬きの観測 + # observe blinks while len(intervals)Tuple[List[ if (roi==prev_roi).all(): continue prev_roi = roi - cv2.imshow("",roi) + cv2.imshow("",cv2.resize(roi, (roi_w*2, roi_h*2))) cv2.waitKey(1) res = cv2.matchTemplate(roi,eye,cv2.TM_CCOEFF_NORMED) _, match, _, _ = cv2.minMaxLoc(res) - if 0.4Tuple[List[ video.release() return intervals +def simultaneous_tracking(plimg, plroi:Tuple[int,int,int,int], pkimg, pkroi:Tuple[int,int,int,int], plth=0.88, pkth=0.999185, size=8)->Tuple[List[int],List[int],float]: + """measuring type/intervals of player's blinks and the interval of pokemon's blinks + note: this methods is very unstable. it not recommended to use. + Returns: + intervals:list[int],offset_time:float: [description] + """ + video = cv2.VideoCapture(0,cv2.CAP_DSHOW) + video.set(cv2.CAP_PROP_FRAME_WIDTH,1920) + video.set(cv2.CAP_PROP_FRAME_HEIGHT,1080) + video.set(cv2.CAP_PROP_BUFFERSIZE,1) + + pl_state = IDLE + pk_state = IDLE + blinks = [] + intervals = [] + pl_prev = time.perf_counter() + pk_prev = time.perf_counter() + + prev_roi = None + debug_txt = "" + + offset_time = 0 + + blinkcounter = 0 + + # observe blinks + while len(blinks)0.3: + blinks[-1] = 1 + debug_txt = debug_txt+"d" + pl_state = DOUBLE + elif pl_state==DOUBLE: + pass + + if pl_state!=IDLE and time_counter - pl_prev>0.7: + pl_state = IDLE + print(debug_txt, len(blinks)) + + if pk_state==IDLE: + #poke eye + roi_x,roi_y,roi_w,roi_h = pkroi + roi = cv2.cvtColor(frame[roi_y:roi_y+roi_h,roi_x:roi_x+roi_w],cv2.COLOR_RGB2GRAY) + + res = cv2.matchTemplate(roi,pkimg,cv2.TM_CCORR_NORMED)#CCORR might be better? + _, match, _, _ = cv2.minMaxLoc(res) + cv2.imshow("pk",roi) + cv2.waitKey(1) + if 0.40.7: + pk_state = IDLE + + cv2.destroyAllWindows() + print(intervals) + return (blinks, intervals, offset_time) + def recov(blinks:List[int],rawintervals:List[int])->Xorshift: """ Recover the xorshift from the type and interval of blinks. @@ -165,7 +260,7 @@ def recov(blinks:List[int],rawintervals:List[int])->Xorshift: return result def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: - """reidentify Xorshift state by type of observed blinks. + """reidentify Xorshift state by the type of observed blinks. Args: rng (Xorshift): identified rng @@ -223,13 +318,13 @@ def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_ return None -def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: +def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, th = 0, search_max=10**6, search_min=0)->Xorshift: """reidentify Xorshift state by intervals of observed blinks. This method is faster than "reidentifyByBlinks" in most cases since it can be reidentified by less blinking. Args: rng (Xorshift): [description] - rawintervals (List[int]): list of intervals of blinks. 6 or more is recommended. + rawintervals (List[int]): list of intervals of blinks. 7 or more are recommended. npc (int, optional): [description]. Defaults to 0. search_max ([type], optional): [description]. Defaults to 10**6. search_min (int, optional): [description]. Defaults to 0. @@ -248,9 +343,6 @@ def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_ blinkrands = [(i, int((r&0b1110)==0)) for i,r in list(enumerate(identify_rng.getNextRandSequence(search_max)))[d::1+npc]] #prepare - - - expected_blinks_lst = [] expected_blinks = 0 lastblink_idx = -1 @@ -280,15 +372,21 @@ def reidentifyByIntervals(rng:Xorshift, rawintervals:List[int], npc = 0, search_ #search result = Xorshift(*rng.getState()) + distlst = [] for idx, blinks in expected_blinks_lst: - if search_blinks==blinks and search_min <= idx: - print(f"found at advances:{idx}, d={d}") + #check by hamming distance + distance = bin(search_blinks^blinks).count("1") + distlst.append(distance) + isSame = distance<=th + if isSame and search_min <= idx: + print(f"found at advances:{idx}, d={d}, hamming={distance}") result.getNextRandSequence(idx) return result + c = Counter(distlst) + print(sorted(c.items())) return None - def recovByMunchlax(rawintervals:List[float])->Xorshift: """Recover the xorshift from the interval of Munchlax blinks. @@ -299,8 +397,8 @@ def recovByMunchlax(rawintervals:List[float])->Xorshift: Xorshift: [description] """ advances = len(rawintervals) - intervals = [interval+0.048 for interval in rawintervals]#観測結果のずれを補正 - intervals = intervals[1:]#最初の観測結果はノイズなのでそれ以降を使う + intervals = [interval+0.048 for interval in rawintervals]#Corrects for delays in observation results + intervals = intervals[1:]#The first observation is noise, so we use the one after that. states = calc.reverseStatesByMunchlax(intervals) prng = Xorshift(*states) From b7dc42761c8fed32ab61288e93ae025a86107563 Mon Sep 17 00:00:00 2001 From: niart120 <38847256+niart120@users.noreply.github.com> Date: Tue, 18 Jan 2022 03:46:48 +0900 Subject: [PATCH 12/12] Create cresselia.py --- src/cresselia.py | 187 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/cresselia.py diff --git a/src/cresselia.py b/src/cresselia.py new file mode 100644 index 0000000..5cb5b36 --- /dev/null +++ b/src/cresselia.py @@ -0,0 +1,187 @@ +""" +this program is experimental. +""" + +import rngtool +import calc +import cv2 +import time +from xorshift import Xorshift +import heapq + +imgpath = "./trainer/fullmoon/eye.png" + +def firstspecify(): + imgpath = "./trainer/secretbase/eye.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + blinks, intervals, offset_time = rngtool.tracking_blink(player_eye, 870, 680, 85, 90) + prng = rngtool.recov(blinks, intervals, ) + + waituntil = time.perf_counter() + diff = round(waituntil-offset_time) + prng.getNextRandSequence(diff) + + state = prng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + +def reidentify(): + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + plimgpath = "./trainer/fullmoon/eye.png" + plimg = cv2.imread(plimgpath, cv2.IMREAD_GRAYSCALE) + plroi = (925, 500, 35, 35) + + pkimgpath = "./cresselia/eye.png" + pkimg = cv2.imread(pkimgpath, cv2.IMREAD_GRAYSCALE) + pkroi = (805, 475, 20, 30) + blinks, observed_intervals, offset_time = rngtool.simultaneous_tracking(plimg, plroi, pkimg, pkroi, pkth = 0.999185, size = 8) + + reidentified_rng = rngtool.reidentifyByIntervals(Xorshift(*state), observed_intervals, th=2, search_max=10**5) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(diff, waituntil-offset_time) + reidentified_rng.advances(max(diff,0)) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + #timecounter reset + advances = 0 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + + while True: + advances += 1 + r = reidentified_rng.next() + + waituntil += 1.017 + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + print(f"advances:{advances}, blink:{hex(r&0xF)}") + +def reidentifyInSecretBase(): + """reidentify xorshift internal state in the cresselia's room + note: this function is a bit unreliable since it is difficult to track the blinks of cresselia. + + """ + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + imgpath = "./trainer/secretbase/eye.png" + player_eye = cv2.imread(imgpath, cv2.IMREAD_GRAYSCALE) + if player_eye is None: + print("path is wrong") + return + blinks, observed_intervals, offset_time = rngtool.tracking_blink(player_eye, 870, 680, 85, 90, size=7) + reidentified_rng = rngtool.reidentifyByIntervals(Xorshift(*state), observed_intervals, npc=0) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(diff, waituntil-offset_time) + reidentified_rng.advances(max(diff,0)) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + #timecounter reset + advances = 0 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + + while True: + advances += 1 + r = reidentified_rng.next() + waituntil += 1.017 + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + print(f"advances:{advances}, blink:{hex(r&0xF)}") + +def cresselia_timeline(): + print("input xorshift state(state[0] state[1] state[2] state[3])") + state = [int(x,0) for x in input().split()] + plimgpath = "./trainer/fullmoon/eye.png" + plimg = cv2.imread(plimgpath, cv2.IMREAD_GRAYSCALE) + plroi = (925, 500, 35, 35) + + pkimgpath = "./cresselia/eye.png" + pkimg = cv2.imread(pkimgpath, cv2.IMREAD_GRAYSCALE) + pkroi = (805, 475, 20, 30) + blinks, observed_intervals, offset_time = rngtool.simultaneous_tracking(plimg, plroi, pkimg, pkroi, pkth = 0.999185, size = 4) + + reidentified_rng = rngtool.reidentifyByIntervals(Xorshift(*state), observed_intervals, th=1, search_max=1*10**3, search_min=0) + if reidentified_rng is None: + print("couldn't reidentify state.") + return + + waituntil = time.perf_counter() + diff = int(-(-(waituntil-offset_time)//1)) + print(diff, waituntil-offset_time) + reidentified_rng.advances(max(diff,0)) + + state = reidentified_rng.getState() + print("state(64bit 64bit)") + print(hex(state[0]<<32|state[1]), hex(state[2]<<32|state[3])) + print("state(32bit 32bit 32bit 32bit)") + print(*[hex(s) for s in state]) + + advances = 1 + waituntil = time.perf_counter() + time.sleep(diff - (waituntil - offset_time)) + #timeline prepare + queue = [] + blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + #blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + heapq.heappush(queue, (waituntil+blink_int,1)) + + #_ = reidentified_rng.next() + heapq.heappush(queue, (waituntil+1.017,0)) + + while queue: + advances += 1 + w, q = heapq.heappop(queue) + next_time = w - time.perf_counter() or 0 + if next_time>0: + time.sleep(next_time) + + if q==0: + r = reidentified_rng.next() + print(f"advances:{advances}, blink:{hex(r&0xF)}") + heapq.heappush(queue, (w+1.017, 0)) + else: + blink_int = reidentified_rng.range(3.0, 12.0) + 0.285 + #blink_int = reidentified_rng.rangefloat(3,12) + 0.285 + + heapq.heappush(queue, (w+blink_int, 1)) + print(f"advances:{advances}, interval:{blink_int}") + +if __name__ == "__main__": + #note: + #1. specify internal state with firstspecify() (secretbase is better place) + #2. search target on pokefinder + #3. advance rng (fullmoon island exterior is fast, about +250/s) + #4. enter the cresselia's room 2000 advances before the target, and reidentify state with cresselia_timeline() + #5. + + #firstspecify() + #reidentifyInSecretBase() + cresselia_timeline()