add gui, egg guide, and reorganize project

This commit is contained in:
Lincoln-LM 2022-01-02 05:05:42 -07:00
parent 5e42f324b8
commit 2308fef44a
24 changed files with 436 additions and 87 deletions

BIN
Nursery.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

BIN
Repel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

View File

@ -1,7 +0,0 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./munchlax/eye.png",
"view": [470, 430, 50, 60],
"reidentify": ""
}

View File

@ -1,7 +0,0 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./trainer/cave/eye.png",
"view": [610, 330, 30, 30],
"reidentify": "0x37a35d28 0x488e6831 0xb7f56519 0x79a3b387"
}

View File

@ -1,7 +0,0 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./munchlax/eye.png",
"view": [470, 430, 50, 60],
"reidentify": ""
}

View File

@ -1,7 +1,7 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./trainer/ruins/eye.png",
"image": "./images/cave/eye.png",
"view": [610, 330, 30, 30],
"reidentify": ""
"thresh": 0.9
}

View File

@ -0,0 +1,12 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./images/munchlax/eye.png",
"view": [
470,
430,
50,
60
],
"thresh": 0.9
}

12
configs/config_room.json Normal file
View File

@ -0,0 +1,12 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "images\\home\\eye.png",
"view": [
610,
347,
30,
30
],
"thresh": 0.9
}

View File

@ -0,0 +1,7 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./images/spear_pillar/eye.png",
"view": [625, 338, 17, 19],
"thresh": 0.75
}

View File

@ -1,7 +1,7 @@
{
"MonitorWindow": true,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./trainer/ruins/eye.png",
"image": "./images/ruins/eye.png",
"view": [610, 330, 30, 30],
"reidentify": ""
"thresh": 0.9
}

28
egg.md Normal file
View File

@ -0,0 +1,28 @@
## Preface
- Set up Project_Xs
- Make sure you know how to find your state with blinks either manually or via screen capture
- You must have masuda method and/or shiny charm to rng for shininess
- Include gender ratio in pokefinder or you will not get correct results
## Steps
1. Set up pokefinder according to your parents information and your filters
2. Remove at least one parent from nursery/have your two parents ready to enter the nursery
3. Stand 1 tile away from being able to talk to the nursery lady (as seen below)
![](./Nursery.png)
4. Use a super repel
5. Take 21 total steps going up one square then down one square
- You should end directly in front of the nursery lady
6. Deposit parents into daycare
7. Fly to your house and enter your room
8. Take steps in your room until the repel text comes up
- Make sure that you are facing down when the repel expires
- If you are not facing down, then turn to face down and activate the "Theres a time and place for everything but not now" text box by using a key item
![](./Repel.png)
9. If the repel text is open then hover over "No"
10. Find your current state/advances with blinks
11. Find a target in pokefinder
12. As you approach your target advance, hold the down arrow
13. When you reach the target, hold A to close the text box and take a step
14. Head back to the daycare to collect your egg!
- If there is no egg/the egg is not shiny, make sure that your parents info is correct in pokefinder and if so then find the advance you actually hit
- If the advance you hit was near your target, account for the delay for your next attempt

View File

Before

Width:  |  Height:  |  Size: 427 B

After

Width:  |  Height:  |  Size: 427 B

BIN
images/home/eye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 674 B

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
images/spear_pillar/eye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

View File

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 993 B

View File

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 791 B

338
src/player_blink_gui.py Normal file
View File

@ -0,0 +1,338 @@
import json
import signal
import sys
import time
import tkinter as tk
import tkinter.filedialog as fd
import threading
from tkinter import ttk
from os import listdir
from os.path import isfile, join
import rngtool
import cv2
import time
import json
import os.path
from PIL import Image, ImageTk
from xorshift import Xorshift
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.previewing = False
self.monitoring = False
self.reidentifying = False
self.config_json = {}
self.default_config = {
"MonitorWindow": True,
"WindowPrefix": "SysDVR-Client [PID ",
"image": "./images/cave/eye.png",
"view": [0, 0, 0, 0],
"thresh": 0.9
}
self.pack()
self.create_widgets()
signal.signal(signal.SIGINT, self.signal_handler)
def update_configs(self,event=None):
self.config_jsons = [f for f in listdir("configs") if isfile(join("configs", f))]
self.config_combobox['values'] = self.config_jsons
def create_widgets(self):
self.master.title("Player Blink")
self.progress = ttk.Label(self,text="0/0")
self.progress.grid(column=0,row=0)
self.config_combobox = ttk.Combobox(self, state="readonly", values=[])
self.config_combobox.grid(column=1,row=0)
self.config_combobox.bind("<<ComboboxSelected>>", self.config_combobox_onchange)
self.config_combobox.bind("<Button-1>", self.update_configs)
self.update_configs()
self.new_config_button = ttk.Button(self,text="+",command=self.new_config,width=2)
self.new_config_button.grid(column=2,row=0)
self.eye_display = ttk.Label(self)
self.eye_display.grid(column=1,row=1)
self.monitor_display_buffer = ttk.Label(self)
self.monitor_display_buffer.grid(column=1,row=2,rowspan=64)
self.monitor_display = ttk.Label(self)
self.monitor_display.grid(column=1,row=2,rowspan=64)
self.monitor_blink_button = ttk.Button(self, text="Monitor Blinks", command=self.monitor_blinks)
self.monitor_blink_button.grid(column=3,row=0)
self.reidentify_button = ttk.Button(self, text="Reidentify", command=self.reidentify)
self.reidentify_button.grid(column=4,row=0,columnspan=2)
self.preview_button = ttk.Button(self, text="Preview", command=self.preview)
self.preview_button.grid(column=6,row=0)
self.stop_tracking_button = ttk.Button(self, text="Stop Tracking", command=self.stop_tracking)
self.stop_tracking_button.grid(column=7,row=0)
x = y = w = h = 0
th = 0.9
ttk.Label(self,text="X").grid(column=4,row=1)
ttk.Label(self,text="Y").grid(column=4,row=2)
ttk.Label(self,text="W").grid(column=4,row=3)
ttk.Label(self,text="H").grid(column=4,row=4)
ttk.Label(self,text="Th").grid(column=4,row=5)
self.pos_x = tk.Spinbox(self, from_= 0, to = 99999, width = 5)
self.pos_x.grid(column=5,row=1)
self.pos_y = tk.Spinbox(self, from_= 0, to = 99999, width = 5)
self.pos_y.grid(column=5,row=2)
self.pos_w = tk.Spinbox(self, from_= 0, to = 99999, width = 5)
self.pos_w.grid(column=5,row=3)
self.pos_h = tk.Spinbox(self, from_= 0, to = 99999, width = 5)
self.pos_h.grid(column=5,row=4)
self.pos_th = tk.Spinbox(self, from_= 0, to = 1, width = 5, increment=0.1)
self.pos_th.grid(column=5,row=5)
self.save_button = ttk.Button(self, text="Select Eye",command=self.new_eye)
self.save_button.grid(column=4,row=6,columnspan=2)
self.new_eye_button = ttk.Button(self, text="Save Config",command=self.save_config)
self.new_eye_button.grid(column=4,row=7,columnspan=2)
self.s0_1_2_3 = tk.Text(self, width=10, height=4)
self.s0_1_2_3.grid(column=0,row=2,rowspan=4)
self.s01_23 = tk.Text(self, width=20, height=2)
self.s01_23.grid(column=0,row=6,rowspan=4)
self.advances = 0
self.adv = ttk.Label(self,text=self.advances)
self.adv.grid(column=0,row=10)
self.pos_x.delete(0, tk.END)
self.pos_x.insert(0, x)
self.pos_y.delete(0, tk.END)
self.pos_y.insert(0, y)
self.pos_w.delete(0, tk.END)
self.pos_w.insert(0, w)
self.pos_h.delete(0, tk.END)
self.pos_h.insert(0, h)
self.pos_th.delete(0, tk.END)
self.pos_th.insert(0, th)
self.after_task()
def new_config(self):
with fd.asksaveasfile(initialdir="./configs/", filetypes=[("JSON", ".json")]) as f:
json.dump(self.default_config,f,indent=4)
self.config_combobox.set(os.path.basename(f.name))
self.config_combobox_onchange()
def new_eye(self):
self.config_json["image"] = os.path.relpath(fd.askopenfilename(initialdir="./images/", filetypes=[("Image", ".png")]))
self.player_eye = cv2.imread(self.config_json["image"], cv2.IMREAD_GRAYSCALE)
self.player_eye_tk = self.cv_image_to_tk(self.player_eye)
self.eye_display['image'] = self.player_eye_tk
def save_config(self):
json.dump(self.config_json,open(join("configs",self.config_combobox.get()),"w"),indent=4)
def cv_image_to_tk(self, image):
split = cv2.split(image)
if len(split) == 3:
b,g,r = split
image = cv2.merge((r,g,b))
im = Image.fromarray(image)
return ImageTk.PhotoImage(image=im)
def config_combobox_onchange(self, event=None):
self.config_json = json.load(open(join("configs",self.config_combobox.get())))
x,y,w,h = self.config_json["view"]
self.pos_x.delete(0, tk.END)
self.pos_x.insert(0, x)
self.pos_y.delete(0, tk.END)
self.pos_y.insert(0, y)
self.pos_w.delete(0, tk.END)
self.pos_w.insert(0, w)
self.pos_h.delete(0, tk.END)
self.pos_h.insert(0, h)
self.pos_th.delete(0, tk.END)
self.pos_th.insert(0, self.config_json["thresh"])
self.player_eye = cv2.imread(self.config_json["image"], cv2.IMREAD_GRAYSCALE)
self.player_eye_tk = self.cv_image_to_tk(self.player_eye)
self.eye_display['image'] = self.player_eye_tk
def stop_tracking(self):
self.tracking = False
def monitor_blinks(self):
if not self.monitoring:
self.monitor_blink_button['text'] = "Stop Monitoring"
self.monitoring = True
self.monitoring_thread=threading.Thread(target=self.monitoring_work)
self.monitoring_thread.daemon = True
self.monitoring_thread.start()
else:
self.monitor_blink_button['text'] = "Monitor Blinks"
self.monitoring = False
def reidentify(self):
if not self.reidentifying:
self.reidentify_button['text'] = "Stop Reidentifying"
self.reidentifying = True
self.reidentifying_thread=threading.Thread(target=self.reidentifying_work)
self.reidentifying_thread.daemon = True
self.reidentifying_thread.start()
else:
self.reidentify_button['text'] = "Reidentify"
self.reidentifying = False
def monitoring_work(self):
self.tracking = False
blinks, intervals, offset_time = rngtool.tracking_blink(self.player_eye, *self.config_json["view"], MonitorWindow=self.config_json["MonitorWindow"], WindowPrefix=self.config_json["WindowPrefix"], tk_window=self, th=self.config_json["thresh"])
prng = rngtool.recov(blinks, intervals)
self.monitor_blink_button['text'] = "Monitor Blinks"
self.monitoring = False
self.preview()
waituntil = time.perf_counter()
diff = round(waituntil-offset_time)
prng.getNextRandSequence(diff)
state = prng.getState()
s0 = f"{state[0]:08X}"
s1 = f"{state[1]:08X}"
s2 = f"{state[2]:08X}"
s3 = f"{state[3]:08X}"
s01 = s0+s1
s23 = s2+s3
print(s01,s23)
print(s0,s1,s2,s3)
self.s0_1_2_3.delete(1.0, tk.END)
self.s01_23.delete(1.0, tk.END)
self.s0_1_2_3.insert(1.0,s0+"\n"+s1+"\n"+s2+"\n"+s3)
self.s01_23.insert(1.0,s01+"\n"+s23)
self.advances = 0
self.tracking = True
while self.tracking:
self.advances += 1
r = prng.next()
waituntil += 1.018
print(f"advances:{self.advances}, blinks:{hex(r&0xF)}")
next_time = waituntil - time.perf_counter() or 0
time.sleep(next_time)
def reidentifying_work(self):
self.tracking = False
state = [int(x,16) for x in self.s0_1_2_3.get(1.0,tk.END).split("\n")[:4]]
s0 = f"{state[0]:08X}"
s1 = f"{state[1]:08X}"
s2 = f"{state[2]:08X}"
s3 = f"{state[3]:08X}"
s01 = s0+s1
s23 = s2+s3
print(s01,s23)
print(s0,s1,s2,s3)
self.s0_1_2_3.delete(1.0, tk.END)
self.s01_23.delete(1.0, tk.END)
self.s0_1_2_3.insert(1.0,s0+"\n"+s1+"\n"+s2+"\n"+s3)
self.s01_23.insert(1.0,s01+"\n"+s23)
print([hex(x) for x in state])
observed_blinks, _, offset_time = rngtool.tracking_blink(self.player_eye, *self.config_json["view"], MonitorWindow=self.config_json["MonitorWindow"], WindowPrefix=self.config_json["WindowPrefix"], tk_window=self, th=self.config_json["thresh"], size=20)
reidentified_rng, adv = rngtool.reidentifyByBlinks(Xorshift(*state), observed_blinks, return_advance=True, npc=1)
self.reidentify_button['text'] = "Reidentify"
self.reidentifying = False
self.preview()
waituntil = time.perf_counter()
diff = round(waituntil-offset_time)+1
reidentified_rng.getNextRandSequence(diff)
state = reidentified_rng.getState()
self.advances = adv+diff
self.tracking = True
while self.tracking:
self.advances += 1
r = reidentified_rng.next()
waituntil += 1.018
print(f"advances:{self.advances}, blinks:{hex(r&0xF)}")
next_time = waituntil - time.perf_counter() or 0
time.sleep(next_time)
def preview(self):
if not self.previewing:
self.preview_button['text'] = "Stop Preview"
self.previewing = True
self.previewing_thread=threading.Thread(target=self.previewing_work)
self.previewing_thread.daemon = True
self.previewing_thread.start()
else:
self.preview_button['text'] = "Preview"
self.previewing = False
def previewing_work(self):
last_frame_tk = None
if self.config_json["MonitorWindow"]:
from windowcapture import WindowCapture
video = WindowCapture(self.config_json["WindowPrefix"])
else:
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)
while self.previewing:
eye = self.player_eye
w, h = eye.shape[::-1]
roi_x, roi_y, roi_w, roi_h = self.config_json["view"]
_, frame = video.read()
roi = cv2.cvtColor(frame[roi_y:roi_y+roi_h,roi_x:roi_x+roi_w],cv2.COLOR_RGB2GRAY)
res = cv2.matchTemplate(roi,eye,cv2.TM_CCOEFF_NORMED)
_, match, _, max_loc = cv2.minMaxLoc(res)
cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), (0,0,255), 2)
if 0.01<match<self.config_json["thresh"]:
cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), 255, 2)
else:
max_loc = (max_loc[0] + roi_x,max_loc[1] + roi_y)
bottom_right = (max_loc[0] + w, max_loc[1] + h)
cv2.rectangle(frame,max_loc, bottom_right, 255, 2)
frame_tk = self.cv_image_to_tk(frame)
self.monitor_tk_buffer = last_frame_tk
self.monitor_display_buffer['image'] = self.monitor_tk_buffer
self.monitor_tk = frame_tk
self.monitor_display['image'] = self.monitor_tk
last_frame_tk = frame_tk
self.monitor_tk_buffer = None
self.monitor_tk = None
def after_task(self):
self.config_json["view"] = [int(self.pos_x.get()),int(self.pos_y.get()),int(self.pos_w.get()),int(self.pos_h.get())]
self.config_json["thresh"] = float(self.pos_th.get())
self.adv['text'] = self.advances
self.after(100,self.after_task)
def signal_handler(self, signal, frame):
sys.exit(0)
root = tk.Tk()
app = Application(master=root)
app.mainloop()

View File

@ -1,52 +0,0 @@
import time
import cv2
import json
config = json.load(open("config.json"))
if config["MonitorWindow"]:
from windowcapture import WindowCapture
video = WindowCapture(config["WindowPrefix"])
else:
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)
roi_y = 0
roi_x = 0
roi_h = 10
roi_w = 10
UP = 2490368
DOWN = 2621440
LEFT = 2424832
RIGHT = 2555904
print("use up/down/left/right to move box, 8/4/6/2 to expand/shrink box, q to close")
while True:
_,frame = video.read()
time_counter = time.perf_counter()
cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), 255, 2)
cv2.imshow("view", frame)
keypress = cv2.waitKeyEx(1)
if keypress == ord('q'):
video.release()
cv2.destroyAllWindows()
exit()
elif keypress == UP:
roi_y -= 10
elif keypress == DOWN:
roi_y += 10
elif keypress == LEFT:
roi_x -= 10
elif keypress == RIGHT:
roi_x += 10
elif keypress == ord('8'):
roi_h -= 10
elif keypress == ord('2'):
roi_h += 10
elif keypress == ord('4'):
roi_w -= 10
elif keypress == ord('6'):
roi_w += 10
if keypress != ord('q') and keypress != -1:
print([roi_x,roi_y,roi_w,roi_h])

View File

@ -16,7 +16,7 @@ def randrange(r,mi,ma):
t = (r & 0x7fffff) / 8388607.0
return t * mi + (1.0 - t) * ma
def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, MonitorWindow = False, WindowPrefix = "SysDVR-Client [PID ")->Tuple[List[int],List[int],float]:
def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, MonitorWindow = False, WindowPrefix = "SysDVR-Client [PID ", tk_window = None)->Tuple[List[int],List[int],float]:
"""measuring the type and interval of player's blinks
Returns:
@ -24,6 +24,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor
"""
eye = img
last_frame_tk = None
if MonitorWindow:
from windowcapture import WindowCapture
@ -47,6 +48,12 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor
# 瞬きの観測
while len(blinks)<size or state!=IDLE:
if tk_window != None:
if not tk_window.monitoring and not tk_window.reidentifying:
tk_window.progress['text'] = "0/0"
tk_window.monitor_tk_buffer = None
tk_window.monitor_tk = None
exit()
_, frame = video.read()
time_counter = time.perf_counter()
roi = cv2.cvtColor(frame[roi_y:roi_y+roi_h,roi_x:roi_x+roi_w],cv2.COLOR_RGB2GRAY)
@ -57,6 +64,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor
res = cv2.matchTemplate(roi,eye,cv2.TM_CCOEFF_NORMED)
_, match, _, max_loc = cv2.minMaxLoc(res)
cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), (0,0,255), 2)
if 0.01<match<th:
cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), 255, 2)
if state==IDLE:
@ -64,9 +72,11 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor
interval = (time_counter - prev_time)/1.018
interval_round = round(interval)
intervals.append(interval_round)
print(f"Adv Since Last: {round((time_counter - prev_time)/1.018)} {(time_counter - prev_time)}")
print(f"Adv Since Last: {round((time_counter - prev_time)/1.018)} {(time_counter - prev_time)/1.018}")
print("blink logged")
print(f"Intervals {len(intervals)}/{size}")
if tk_window != None:
tk_window.progress['text'] = f"{len(intervals)}/{size}"
if len(intervals)==size:
offset_time = time_counter
@ -89,16 +99,28 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor
max_loc = (max_loc[0] + roi_x,max_loc[1] + roi_y)
bottom_right = (max_loc[0] + w, max_loc[1] + h)
cv2.rectangle(frame,max_loc, bottom_right, 255, 2)
cv2.imshow("view", frame)
keypress = cv2.waitKey(1)
if keypress == ord('q'):
cv2.destroyAllWindows()
exit()
if tk_window == None:
cv2.imshow("view", frame)
keypress = cv2.waitKey(1)
if keypress == ord('q'):
cv2.destroyAllWindows()
exit()
else:
frame_tk = tk_window.cv_image_to_tk(frame)
tk_window.monitor_tk_buffer = last_frame_tk
tk_window.monitor_display_buffer['image'] = tk_window.monitor_tk_buffer
tk_window.monitor_tk = frame_tk
tk_window.monitor_display['image'] = tk_window.monitor_tk
last_frame_tk = frame_tk
if state!=IDLE and time_counter - prev_time>0.7:
state = IDLE
# print(debug_txt)
cv2.destroyAllWindows()
if tk_window == None:
cv2.destroyAllWindows()
else:
tk_window.progress['text'] = "0/0"
frame_tk = None
last_frame_tk = None
return (blinks, intervals, offset_time)
def tracking_blink_manual(size = 40, reidentify = False)->Tuple[List[int],List[int],float]:
@ -237,7 +259,7 @@ def recov(blinks:List[int],rawintervals:List[int])->Xorshift:
result.getNextRandSequence(advanced_frame)
return result
def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift:
def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0, return_advance=False)->Xorshift:
if search_max<search_min:
search_min, search_max = search_max, search_min
search_range = search_max - search_min
@ -279,10 +301,13 @@ def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_
if search_blinks==blinks and search_min <= idx:
print(f"found at advances:{idx}, d={d}")
result.getNextRandSequence(idx)
if return_advance:
return result, idx
return result
return None
def recovByMunchlax(rawintervals:List[float])->Xorshift:
"""Recover the xorshift from the interval of Munchlax blinks.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB