Support multiple seed pools

This commit is contained in:
Pyrex 2024-02-09 21:05:24 -08:00
parent ae1955b7c4
commit 94a410a587
19 changed files with 56006 additions and 140 deletions

2
.gitignore vendored
View File

@ -0,0 +1,2 @@
*.pyc
__pycache__/

169
main.p8
View File

@ -85,86 +85,91 @@ __gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
a45b403c0aa0360f5944347b0018170a1312011307511c2075829964331301088305c86241754c071719a68aa302a962944fa20393c3e726a6308b36804a7013
505043247423215f30f77413244003620624034405a12c02347070330103b0d524535c21cbd1187013311316c161583180b01250f8a92308652817329c220125
51c2746157071abd696554091183b5453222346324005c7a502274729035031320a54610a134145270606923d2624887d45601017bcf92a570c08002538065a3
7722d440060430371f7796b901314fc00040caa73b9d670a016c26305a67795c32f67a3c48bd372e664136e003442a036e6a48009d460a8413333005a15c1221
25feb24a024641a930649018e06af40613c6df323df0922136c0b3a628a9704887eb465f103eb312113a71d6132681ec5314660112a592500a7332050b110022
2133bf841ad2e08531151212008b1b93269808f6e7084bf509645c4d17e5381030d09a21374097e7205833281b4968b2d257805070cb23f660123a8961d02217
99c4a3543235608e61c082461387e3a08112422243124c95b80527b4c70297bb53111112ae012101701d57021a33baa5320a75220703e67316450a470811222f
2407132570675cad8466b089c6ae8b1cd63445254321211112211225171902cc2f52b3431a96e0621a0b320810118847210217302c829172a9142e81471a1222
151012109139251e01535f3f60d066309689f475500ac31f0c51550fb2c040636116072bb95c3c20623312d15802729e11a7863610235565041e05d811102790
2303bb6766a35d19634125255536468126950ed0511d2004a869600b03606008402c423631430234c82143b431911ad813080730a56952dff8d930c0710f9c59
1560411e195885ab12a47046a513355330834851127111b0b01223b425a03700713fd455012919b962ea2204803297512905048b60e0070b10db28d95d041334
6413616371255f16bc72123662020571218053d29a0a08d5614cb03218e4202307a3331121072003208b5216380484d071152504157a34646b93320421067bfd
71328140448aa00003916fb823a42960baf06050bbbc50802215d3247720e254ada00e824740640b1d220134900a865163575c651d12fb3a5142e10402804018
d34432745132241ea1144102343936850621e24e38478403732882714b6095a00a8bc12563fb29a95124622b191e132d71031028233188cff2b6054c5a500220
06461bb07141bd203519449c4a7b81059519e186332206a601080782219753433271d3f7a60bb0325500dcd0320a4f425263a0635103119131a6c114220d483c
22692c1f36d0a4e4b650a574d52035129d6043a71416f190d044201e640d9361a28795850d841420008330235203565132f09c1062b314c01100130214826079
4433210066db20e7d4243c00363044503221a9a248028275163032437db731156197323b110083556bc6882b62120145932723c410141720502110607096341b
040253269c334a9ad729304c593a6541c8512542d252305530103c61142f64d7d884937139a6082c8af4436d472012b2a520dc2401b055ce7472750d2a334f50
02c529bd7c0950635919c19f7b339d700061121604392031118b4550112932e89603008cd0fb931925c5c25b110a43460d23941436924a202077044914a618d2
411e3341031101c5e0f0127719125212545515771b9b1db33070001903110033333c01032c3265162f30010b00d3232022416e5a6625a391e0736112b0030131
a33e106330c444a849058741a02733922393921f0230f2e645234d441b84f20ae452222723d363f2c0a0230136181d550c1054542190004072371d4e13069153
0b905062ea1b1831348050161007723cbf05e0122080c4030533b1396114221153345021058405d139924e92ad06010105e0452a8c0b703116f0342005c66451
62110200c314070a144300ca63855bc1be01cb9326008aeb0a2bc12e0fcb2120d13c806494815a00b2a2048007195e54f49f9a1bda72163953e4b55516013e01
17a030e8e9009dc461a41017a8de92072403ff12724200356739323429133a3131030ae919a118c38268a569e604609027e6d12511e1d1005f235661d08a6642
0101913aeb58522a65c9ab7108b412d5315940519305310d5e83a39a0621605902354212014ab3ce24e0276205201da9d25322db8158e0e533501c733deb2b65
82032123367845157b8203031329616024114326763031c67207e61b1489f1114603909b3c320200775856471002965c31007f4393c033910433505033001c59
84070b4404312f550d8caa4271887618b24c141401141266c2277005a2483e931a24844542112793c3321009f7657185617119015e7030049021154661a246d5
66a51123ec45154031a14727580101433190b05309382063244766e0c0226217503bc02064936f032241d81650511057171f2150044f213b2e0015a38c243680
ab3010b466481db267510761c2073003b10640243926b0d90ad4600429f4134323130114132d435c4793621a6823fa402629e1806045135b3f5818112091025a
1cf83438cf042533381708106085ca79020210f55003c06020c49848d20503c6363f7c9c22b32c7b3b1878752222a40235c1c2b14211647f20fd51b5b067c267
2604670f173da221902fc232269007651016f335274e02e3117ca6b341230d75011062b2318619531730a6117d0373b36509292c054189450968133141c11625
19883316235530007105f02314791a01789012050c740b010649696124b1d9032b0c0720002a065c9005105f018d4038a177510069544180311c470624701819
7059d63554287564a047bd9950e732c14f54a6000529070b24850d07200bd70c41b910c31d47a516d353e06f179262831975015958350d3673088f55721440f3
7026505f3ad2527235bafc335b0098035d138016c174031131100f445e48359829326a09225332136c105f455032720f3d44419d36a1992113032eec61831447
772809a792545913677b4371a877796c6889264a50119462f21f812291e2014390815078140047a9947008e0c04056628323530064650372a61457c623857aa9
53a9204033200112353841122a6e302401a32f15432d4013abf436474330056605c404c203724428e5674062403d34112f18010bd0e592916c903dc856037950
0963008c803f0293932a5e51c20b072148c512262b43313104d25024589451b058802c1841a0b8270b5e26631812671c11c112d10e036b54265454171427a062
7542720a0601caaf273804730a30522111a952078e747641627573704c2a5400e01056145a2e32f78676232d26450b251e0122e41f23405c958804600d104554
91625709a60196f0c064058d9e08493d8235ba39651a2270531a2488a78f8b64a2231744a5d602a151e3570080513385731e0e111381713211d0a3b419c6a5b3
21960bf53736235130011060a60b6130cf0740d02623371061122b0b534203b0e25ea1142535276f95a104a1215e30d9a986f06cc1a102940f2650208b0cd047
12478de7de3090c730504d10602c021027703a2ca90517d200a010910530952ae7016861d4771215c179b4415d75011800242382101763d38100140010653204
7336e0035a17802eb329002522210400747e76730e6c90450450e3a13da5620322c2222b0132a810451c9c25f7030278f24830113651ea14360862331d411164
f4d3295a634022c3aba1357001210e97a22e92278142a024f428351f32101f756a317403268d31755712811374d5122834b921b3c40d10241fee0a126a645818
25a1d55000186c218507281030124af1277320570775768c19d3472120ed02354318d105e4006d5009e5ff413b83e92008b04a28028075bf3ac3e4f850c13962
4f5f50ea324fb344364186a4353a218a0b92031555100b3220b223cd363370400077d3317921a42e21618b4b80641e904b11703b8153b0620ab00247d001403a
ba700a3b007243401f64164418a02304d6b03e394d601060f751614681301c8487413905019331570124d500c91833315f025be0707208e706a4a37409bb540c
40000c320db304c953f1176063aa48613172e632832a049452806011b07054d23e09b340d032110c557a0c29247e191298c4770d43044224115053864571060e
00766473701905322a148177154ce13230963323000062502063e891168081a7911003750054042a745834a70b80d1147ad551a37c14465a54fa1da3a42c1430
0b02d04505c8f103471874735968bb1cd203743347342fd27240c1b613504750648c426c016021707720c683d21133a05c241204591407134403ae02b36c8c51
4251261327004c729e0c3b328012e5011d6b854332683d0910a0002639144b901b0300211a613433c05b4630153bf3e30b23172d2023440a059c01b3275426f0
23383a370375496c0760039d00f8d25101f4809032302198261111202ace6ac100543264641289340f1634390cac2f204ad300548641a5086d11333409b44840
0d3111694b3d464b62e17460311442855d05cd3704923e9d0770707c0132109b399428a8146012d7a5043207d64e03fd1126742b016745603500113043464471
777326217676060195001268be8381430c862a1c2b0265a4234a69635140318597cb49370643550c2a314e33781b490095f73245600a00de12041497c80550a4
701604144259018e4314582680b0bb8a28b4061216010d3063521c666031d4460d1412012e2547030e2389252b19e9da341623912035220923220d61f5d10673
575950d15619fb7355715a214d604411ab425c28017fa0069204b0663402432027a2205515603021b5012178664215329112a53b219206035f3c10116e562c1b
810f50bb51811900008920109036a46044a566fa5c3d75f2930d101b41033e6e718450e5f32d36072531f1022065d01546295b20f09900200b200f125f060105
320bd2021354bd12376d4391020cb46909a21392d066d219e072259f0c554057d6f02b893514531a4a873080f05063001516435231229200a15d50aab311e82b
2f4c3353942ab36526425316135b3894161e224530243321900532352125720229f25b6e63272685339f70b62724ac734dfb9539aa81104f7c43c6125303a0b0
26c576b4123535e13346510610016436b311015422250811770250d4a3f86291acde02513d9541811164981402046f2351d5331390f538664452a09411464591
1923e750019b705151701c1633b06eb064015121181cb6b1414b1120e03d715118259963471fa8151bb5a2502492222a910611365306ee6fa1a43015d227e65b
407033404721f0c019292341e5e8206104601ed1574d21e8ca05171a04320ed862140210590a090430985c1289011804206a049a71f054016463335440135936
02c6202303351c50f3406fb0a1004610142f161400b481df8b740f3617bafb033c64f26562057017c58400d5a13a2320210631b361f2a1029211268166226207
013285caa12003604001110f152c7671a80f8e743406d0505156083235037931dd020107a700781e2bf6dc081266341019e61cee2698eb259d0759c481710139
255c14601869861492306742b03a2f060513a1211130042a0575301102220c20d30a5458c01554312484223950410b463035e232a58773710174065266239d2a
c9311100fc009820e4509a50ca603c90a3a009a0d5b00dd055f027215d21a531e531d6319831e8317931277132a5120a007276821161320416d14631d331e862
7462511341324319b5779502eb05d82194423941818023885111644669aa2a169110a1561bb28201632467214103762f4812302241975603a9799117a3111c31
54224678216131332299517613113822a1a81b2191451b9d4a12444e2146331121146b18a623a1212143b4414461930716662c10145931ca52421046d1d46453
e285625e10d0416a445310369c1d2d7a2210b4211365372a523145221379e432bc1f2343132211370354624605c7135214298212a65197288711ef6c10155410
2c023d63b2113522c6311131a711c2a23d1225273cc7c29b131364b26426e319811152a15f72b15a1c968691342059612724f532114262315793231026100223
e71b1831203ac658400341618db534033046726b64398c48116104050184601409453c11302421261347612b1131431a21385ba8204483115178622001227391
12161520248c8131276695811852091625941e250592543263163b098e7033340202485337d4c474719812a1e151946ff9354a543261203d82811352d0750ff4
62e13078413345221a4093473d592e235275d2f067b11349521811063506406626048503b21f19932271e447917243136a9118433c0c1b1b00126c523d552811
b3b090a138154420832f1c2b359214132417364e4b602d7684137112b0190343a05954d117631421672111324410805550316535815351443515515512135301
85032431522303a45b403c0aa0360f5944347b0018170a1312011307511c2075829964331301088305c86241754c071719a68aa302a962944fa20393c3e726a6
308b36804a7013505043247423215f30f77413244003620624034405a12c02347070330103b0d524535c21cbd1187013311316c161583180b01250f8a9230865
2817329c22012551c2746157071abd696554091183b5453222346324005c7a502274729035031320a54610a134145270606923d2624887d45601017bcf92a570
c08002538065a37722d440060430371f7796b901314fc00040caa73b9d670a016c26305a67795c32f67a3c48bd372e664136e003442a036e6a48009d460a8413
333005a15c122125feb24a024641a930649018e06af40613c6df323df0922136c0b3a628a9704887eb465f103eb312113a71d6132681ec5314660112a592500a
7332050b1100222133bf841ad2e08531151212008b1b93269808f6e7084bf509645c4d17e5381030d09a21374097e7205833281b4968b2d257805070cb23f660
123a8961d0221799c4a3543235608e61c082461387e3a08112422243124c95b80527b4c70297bb53111112ae012101701d57021a33baa5320a75220703e67316
450a470811222f2407132570675cad8466b089c6ae8b1cd63445254321211112211225171902cc2f52b3431a96e0621a0b320810118847210217302c829172a9
142e81471a1222151012109139251e01535f3f60d066309689f475500ac31f0c51550fb2c040636116072bb95c3c20623312d15802729e11a786361023556504
1e05d8111027902303bb6766a35d19634125255536468126950ed0511d2004a869600b03606008402c423631430234c82143b431911ad813080730a56952dff8
d930c0710f9c591560411e195885ab12a47046a513355330834851127111b0b01223b425a03700713fd455012919b962ea2204803297512905048b60e0070b10
db28d95d0413346413616371255f16bc72123662020571218053d29a0a08d5614cb03218e4202307a3331121072003208b5216380484d071152504157a34646b
93320421067bfd71328140448aa00003916fb823a42960baf06050bbbc50802215d3247720e254ada00e824740640b1d220134900a865163575c651d12fb3a51
42e10402804018d34432745132241ea1144102343936850621e24e38478403732882714b6095a00a8bc12563fb29a95124622b191e132d71031028233188cff2
b6054c5a50022006461bb07141bd203519449c4a7b81059519e186332206a601080782219753433271d3f7a60bb0325500dcd0320a4f425263a0635103119131
a6c114220d483c22692c1f36d0a4e4b650a574d52035129d6043a71416f190d044201e640d9361a28795850d841420008330235203565132f09c1062b314c011
001302148260794433210066db20e7d4243c00363044503221a9a248028275163032437db731156197323b110083556bc6882b62120145932723c41014172050
2110607096341b040253269c334a9ad729304c593a6541c8512542d252305530103c61142f64d7d884937139a6082c8af4436d472012b2a520dc2401b055ce74
72750d2a334f5002c529bd7c0950635919c19f7b339d700061121604392031118b4550112932e89603008cd0fb931925c5c25b110a43460d23941436924a2020
77044914a618d2411e3341031101c5e0f0127719125212545515771b9b1db33070001903110033333c01032c3265162f30010b00d3232022416e5a6625a391e0
736112b0030131a33e106330c444a849058741a02733922393921f0230f2e645234d441b84f20ae452222723d363f2c0a0230136181d550c1054542190004072
371d4e130691530b905062ea1b1831348050161007723cbf05e0122080c4030533b1396114221153345021058405d139924e92ad06010105e0452a8c0b703116
f0342005c6645162110200c314070a144300ca63855bc1be01cb9326008aeb0a2bc12e0fcb2120d13c806494815a00b2a2048007195e54f49f9a1bda72163953
e4b55516013e0117a030e8e9009dc461a41017a8de92072403ff12724200356739323429133a3131030ae919a118c38268a569e604609027e6d12511e1d1005f
235661d08a66420101913aeb58522a65c9ab7108b412d5315940519305310d5e83a39a0621605902354212014ab3ce24e0276205201da9d25322db8158e0e533
501c733deb2b6582032123367845157b8203031329616024114326763031c67207e61b1489f1114603909b3c320200775856471002965c31007f4393c0339104
33505033001c5984070b4404312f550d8caa4271887618b24c141401141266c2277005a2483e931a24844542112793c3321009f7657185617119015e70300490
21154661a246d566a51123ec45154031a14727580101433190b05309382063244766e0c0226217503bc02064936f032241d81650511057171f2150044f213b2e
0015a38c243680ab3010b466481db267510761c2073003b10640243926b0d90ad4600429f4134323130114132d435c4793621a6823fa402629e1806045135b3f
5818112091025a1cf83438cf042533381708106085ca79020210f55003c06020c49848d20503c6363f7c9c22b32c7b3b1878752222a40235c1c2b14211647f20
fd51b5b067c2672604670f173da221902fc232269007651016f335274e02e3117ca6b341230d75011062b2318619531730a6117d0373b36509292c0541894509
68133141c1162519883316235530007105f02314791a01789012050c740b010649696124b1d9032b0c0720002a065c9005105f018d4038a17751006954418031
1c4706247018197059d63554287564a047bd9950e732c14f54a6000529070b24850d07200bd70c41b910c31d47a516d353e06f179262831975015958350d3673
088f55721440f37026505f3ad2527235bafc335b0098035d138016c174031131100f445e48359829326a09225332136c105f455032720f3d44419d36a1992113
032eec61831447772809a792545913677b4371a877796c6889264a50119462f21f812291e2014390815078140047a9947008e0c04056628323530064650372a6
1457c623857aa953a9204033200112353841122a6e302401a32f15432d4013abf436474330056605c404c203724428e5674062403d34112f18010bd0e592916c
903dc8560379500963008c803f0293932a5e51c20b072148c512262b43313104d25024589451b058802c1841a0b8270b5e26631812671c11c112d10e036b5426
5454171427a0627542720a0601caaf273804730a30522111a952078e747641627573704c2a5400e01056145a2e32f78676232d26450b251e0122e41f23405c95
8804600d10455491625709a60196f0c064058d9e08493d8235ba39651a2270531a2488a78f8b64a2231744a5d602a151e3570080513385731e0e111381713211
d0a3b419c6a5b321960bf53736235130011060a60b6130cf0740d02623371061122b0b534203b0e25ea1142535276f95a104a1215e30d9a986f06cc1a102940f
2650208b0cd04712478de7de3090c730504d10602c021027703a2ca90517d200a010910530952ae7016861d4771215c179b4415d75011800242382101763d381
001400106532047336e0035a17802eb329002522210400747e76730e6c90450450e3a13da5620322c2222b0132a810451c9c25f7030278f24830113651ea1436
0862331d411164f4d3295a634022c3aba1357001210e97a22e92278142a024f428351f32101f756a317403268d31755712811374d5122834b921b3c40d10241f
ee0a126a64581825a1d55000186c218507281030124af1277320570775768c19d3472120ed02354318d105e4006d5009e5ff413b83e92008b04a28028075bf3a
c3e4f850c139624f5f50ea324fb344364186a4353a218a0b92031555100b3220b223cd363370400077d3317921a42e21618b4b80641e904b11703b8153b0620a
b00247d001403aba700a3b007243401f64164418a02304d6b03e394d601060f751614681301c8487413905019331570124d500c91833315f025be0707208e706
a4a37409bb540c40000c320db304c953f1176063aa48613172e632832a049452806011b07054d23e09b340d032110c557a0c29247e191298c4770d4304422411
5053864571060e00766473701905322a148177154ce13230963323000062502063e891168081a7911003750054042a745834a70b80d1147ad551a37c14465a54
fa1da3a42c14300b02d04505c8f103471874735968bb1cd203743347342fd27240c1b613504750648c426c016021707720c683d21133a05c2412045914071344
03ae02b36c8c514251261327004c729e0c3b328012e5011d6b854332683d0910a0002639144b901b0300211a613433c05b4630153bf3e30b23172d2023440a05
9c01b3275426f023383a370375496c0760039d00f8d25101f4809032302198261111202ace6ac100543264641289340f1634390cac2f204ad300548641a5086d
11333409b448400d3111694b3d464b62e17460311442855d05cd3704923e9d0770707c0132109b399428a8146012d7a5043207d64e03fd1126742b0167456035
00113043464471777326217676060195001268be8381430c862a1c2b0265a4234a69635140318597cb49370643550c2a314e33781b490095f73245600a00de12
041497c80550a4701604144259018e4314582680b0bb8a28b4061216010d3063521c666031d4460d1412012e2547030e2389252b19e9da341623912035220923
220d61f5d10673575950d15619fb7355715a214d604411ab425c28017fa0069204b0663402432027a2205515603021b5012178664215329112a53b219206035f
__map__
12272711306328d47551b51b4c8610acf67a11171810339055e1331841200028a2611a977291bc0633572201044ba2d638db0dc860213021c3d112540c847a3d2b88693720504c31e4c2a055431ea47602f804e4f405ea10be68d639ab9642a1a0f9744232be8b125319405159f512649d3402d0f79b242cc8070585421956f1
0584116d681c448868019160838b3092e51133c11263b7e4a313b74352a3a46110ad32d144b302e26975019463487231002d09c89c9840767c1233002a63a4119274ca950163625513502e12302efaa1f0da9bd420612524a1633109a700f00006686083c205503d7474030070402a080b771442d79631632280e071b7d0fbb7
412f13543919c4033e083182299b4330060551235013a835620e5a550325022a2d7b6250b34740163bde22730861f407910271937553c120b5c744206292856e00177230131e46015d219b307ea03d1374224f339b0332ac1d305462d2072b67cc2b2c719fd41b6d7055c4034638560aa482d0b4174a44155203a5f26b03e1c4
050a061bb02125530606752302412b605a53d7031508303520ee7358104b094101782e0da82aa965130b220f5118784700058771bb09c1848a84e32894119c8c830111590f933415202a40e60104443520d85821d00105399c0423922c8a8c60c600a333716c6097531112330c7bb050227f550833742371ac8e2e2312dd34e0
95107d34612049251a3deb6208401203151a43a27a118cf1a03f760708847432034f246608904943930431780a3ed102d070346a8180e40001b5fba3451b167353e0ab21fec20653f18161b035200815132041a5511b50c80cb8ec658516319143950f05932c71460162439bb00c35530113be243271389c083c73c731106070
335009dd0051113622908990265b11472516044a777d4707da0a9053504030942690db86053408221540300221a1b223d201403440048d1f484031617635e060621524e87647400b86740349c001590791270282f1305f32609b70132269a2e523f29108033096e310074312114a134e52922a29092b23421793346149671bd4
91176025541256501109144457253663a3041a394b173931169515f337ae26330c801902d2354d51a0d502f19a68088df41a38841f83044202165400107b081e045b2d911211a8712289a63102323b2a767022341116b34c639c0304052bc382e21905427000630d0344c8516c4665925034920b9e82e6539039736e02064780
1142321b12b421352743f871c100440b6f531b020113e6371140020437a921126a05779678c4402151412281754c4778ca02ac432553e12607330d3b1af86533a032400724969268734f760a27f45001fc40174422188a161d2b20289007145394e66022a840575b320200f8407e833275018515844490ad0274093119b1a801
0367323f2135ad8338806974bdcf944424070b0100c95446014320023a08347f77b21f31872f09139552112c417007140f63fcb520a41120160295260120027224b5b87554902044101506154406128150c06446423260ca5002317a18f37405043057165158a6084708c515050021be292a811208283572c826a2810977302e
c94a55ff919502b2a33442144b74715544716219300212f37011e813c08fd56608a386131e44f220902515151bc569b305210218c1e545826c4d34323500a9431391130198127276500440b220a1422b6b58b6a6367635e10b61808b7002313e52053a146635275f70118a2339ba62046d760b5000d3bd0012687814013f87a2
a306831030325632662132df101a5135900a7f1b3300e00860033081ec4010c00204b14440037253060c2451d45409e76d349560b2593b336532459905b00864008c262420078270533013221a930d612db04c05a42fb620419293885f24e59110d0005c320075cd4841a019089c63f521d6b8c92babf6430b48030084324d00
25af206b02e0300bf8854a07666b0423108028201456180b4216287129020549401639a610ba03231030662131c41543d3b070208d0a12323071431b689680b02410030f304bfb6684a31fc6017605041745581335b0749863260429ad11e061ed6e25a287895137ef20b21260418041d2a04408aa5b960a230a1b522000b325
e270a090811741436d45572801621c4496bd57895524875309220b5187209a1b20519b253842509224b56812a2910935501f1d040a008a2460155508248600254795b5b16ea19227d1778a7880d91843084837f450a85c0013035505588001e0718000312c7340025143107c3f1e39c5515151621712018f7700112d81170956
13020005794534d3241ab897b0d1bd287c0020012b01f0008d4b05418a400af2271362259c660a090391020222c0df12e86b3440000584050c5637072006bf05e801b465c2621967083d0b0398115119a8a3035b04210310cba70b9aa852730f100d307b00062fb003b20767442823f233303082432338c029c70e761c381418
0802150300df070980c19b3745ea37f075717622a530a08765450627000082080a0054706b6695b73832b009290054e7001c98404c2be41203aa5d07675526e306a49c50e220e7350148d085070623116528350f05003090f21400007d0047c035240273124800700339218809070000b43005252e00371000840c048e01ea20
84000d5530c12756ac1d93d0d5c060c70004d0106720b8c800b0d8e0038000504108d78577810481533ba0f0c804000c07005205760000b85002f76081e1020f00d0d01e9a14224e1e4078186105860002404003070950000090001f430910009b0300290de050d6d02077c01400f00400048d00e050060c500c87060000020d
00c0006540d290002100586000a0d00d00b14a00000a00f044f9002800600003a0400af00b0409580d040070670c0005000009e805000000200000070000080678000300600009000b00d06000000f0d77e0000000000400c000009610d00000000000a050000000000000080000a0d0000a60d805000000080000026000b000
00000060c0e000000000000080500004000009e0000306000000000000000000000706700000000050d0600000906000b00000900c0000000000030d00c0050000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
c30111e665c2b118f005bb151891000098020109634a06445a66afc5d3572f39d001b11430e3e61748055e3fd2637052131f2002560d516492b5020f990002b002f021f560105023b02d203145db2173d6341920c04b96902a31290d662d910e2752f9c05504756d0fb298534135a1a47803080f05360051613425132229001a
d505aa3b118eb2f2c4333549a23b566224356131b5834961e12254034233120950235312522720922fb5e63672625833f9076b7242ca37d4bf5993aa1801f4c7346c2135300a0b625c674b2153531e33641560011046633b111045225280117720054d3a8f2619caed2015d3591418114689412040f632155d3331095f836644
250a491164541991327e0510b907151507c161330be60b4610151281c16b1b14b411020ed317158152993674f18a51b15b2a05422922a2196011633560eef61a4a03512d726eb50407330474120f0c919232145e8e02164006e11d75d4128eac5071a14023e08d2641200195a090400389c5219810814002a640a9170f451046
36334504319563206c02323053c1053f04f60b1a00640141f26141004b18fdb847f06371abbf30c3462f56265007715c48005d1aa332021260133b162f1a202911621866222670102358ac1a023006041011f051c267178af0e84743600d051565802353309713dd2010707a0087e1b26fcd8021664301916ec1ee6289be52d9
70954c1817109352c5410681966841290376240ba3f26050311a12110340a2505703112022c0023da045850c514513424822930514b06403532e235a783717104760256632d9a212272711306328d47551b51b4c8610acf67a11171810339055e1331841200028a2611a977291bc0633572201044ba2d638db0dc860213021c3
d112540c847a3d2b88693720504c31e4c2a055431ea47602f804e4f405ea10be68d639ab9642a1a0f9744232be8b125319405159f512649d3402d0f79b242cc8070585421956f10584116d681c448868019160838b3092e51133c11263b7e4a313b74352a3a46110ad32d144b302e26975019463487231002d09c89c9840767c
1233002a63a4119274ca950163625513502e12302efaa1f0da9bd420612524a1633109a700f00006686083c205503d7474030070402a080b771442d79631632280e071b7d0fbb7412f13543919c4033e083182299b4330060551235013a835620e5a550325022a2d7b6250b34740163bde22730861f407910271937553c120b5
c744206292856e00177230131e46015d219b307ea03d1374224f339b0332ac1d305462d2072b67cc2b2c719fd41b6d7055c4034638560aa482d0b4174a44155203a5f26b03e1c4050a061bb02125530606752302412b605a53d7031508303520ee7358104b094101782e0da82aa965130b220f5118784700058771bb09c1848a
84e32894119c8c830111590f933415202a40e60104443520d85821d00105399c0423922c8a8c60c600a333716c6097531112330c7bb050227f550833742371ac8e2e2312dd34e095107d34612049251a3deb6208401203151a43a27a118cf1a03f760708847432034f246608904943930431780a3ed102d070346a8180e40001
b5fba3451b167353e0ab21fec20653f18161b035200815132041a5511b50c80cb8ec658516319143950f05932c71460162439bb00c35530113be243271389c083c73c731106070335009dd0051113622908990265b11472516044a777d4707da0a9053504030942690db86053408221540300221a1b223d201403440048d1f48
4031617635e060621524e87647400b86740349c001590791270282f1305f32609b70132269a2e523f29108033096e310074312114a134e52922a29092b23421793346149671bd491176025541256501109144457253663a3041a394b173931169515f337ae26330c801902d2354d51a0d502f19a68088df41a38841f83044202
165400107b081e045b2d911211a8712289a63102323b2a767022341116b34c639c0304052bc382e21905427000630d0344c8516c4665925034920b9e82e6539039736e020647801142321b12b421352743f871c100440b6f531b020113e6371140020437a921126a05779678c4402151412281754c4778ca02ac432553e12607
330d3b1af86533a032400724969268734f760a27f45001fc40174422188a161d2b20289007145394e66022a840575b320200f8407e833275018515844490ad0274093119b1a8010367323f2135ad8338806974bdcf944424070b0100c95446014320023a08347f77b21f31872f09139552112c417007140f63fcb520a4112016
0295260120027224b5b87554902044101506154406128150c06446423260ca5002317a18f37405043057165158a6084708c515050021be292a811208283572c826a2810977302ec94a55ff919502b2a33442144b74715544716219300212f37011e813c08fd56608a386131e44f220902515151bc569b305210218c1e545826c
4d34323500a9431391130198127276500440b220a1422b6b58b6a6367635e10b61808b7002313e52053a146635275f70118a2339ba62046d760b5000d3bd0012687814013f87a2a306831030325632662132df101a5135900a7f1b3300e00860033081ec4010c00204b14440037253060c2451d45409e76d349560b2593b3365
32459905b00864008c262420078270533013221a930d612db04c05a42fb620419293885f24e59110d0005c320075cd4841a019089c63f521d6b8c92babf6430b48030084324d0025af206b02e0300bf8854a07666b0423108028201456180b4216287129020549401639a610ba03231030662131c41543d3b070208d0a123230
71431b689680b02410030f304bfb6684a31fc6017605041745581335b0749863260429ad11e061ed6e25a287895137ef20b21260418041d2a04408aa5b960a230a1b522000b325e270a090811741436d45572801621c4496bd57895524875309220b5187209a1b20519b253842509224b56812a2910935501f1d040a008a2460
155508248600254795b5b16ea19227d1778a7880d91843084837f450a85c0013035505588001e0718000312c7340025143107c3f1e39c5515151621712018f7700112d8117095613020005794534d3241ab897b0d1bd287c0020012b01f0008d4b05418a400af2271362259c660a090391020222c0df12e86b3440000584050c
5637072006bf05e801b465c2621967083d0b0398115119a8a3035b04210310cba70b9aa852730f100d307b00062fb003b20767442823f233303082432338c029c70e761c3814180802150300df070980c19b3745ea37f075717622a530a08765450627000082080a0054706b6695b73832b009290054e7001c98404c2be41203
aa5d07675526e306a49c50e220e7350148d085070623116528350f05003090f21400007d0047c035240273124800700339218809070000b43005252e00371000840c048e01ea2084000d5530c12756ac1d93d0d5c060c70004d0106720b8c800b0d8e0038000504108d78577810481533ba0f0c804000c07005205760000b850
02f76081e1020f00d0d01e9a14224e1e4078186105860002404003070950000090001f430910009b0300290de050d6d02077c01400f00400048d00e050060c500c87060000020d00c0006540d290002100586000a0d00d00b14a00000a00f044f9002800600003a0400af00b0409580d040070670c0005000009e80500000020
0000070000080678000300600009000b00d06000000f0d77e0000000000400c000009610d00000000000a050000000000000080000a0d0000a60d805000000080000026000b00000000060c0e000000000000080500004000009e0000306000000000000000000000706700000000050d0600000906000b00000900c00000000
00030d00c0050000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@ -1,16 +1,16 @@
progression={
-- level 1
-- ruleset:new(5,1,9,0),
ruleset:new(5,1,9,0), -- by test: always winnable
-- level 2
-- ruleset:new(5,2,9,0),
ruleset:new(5,2,9,0), -- by test: always winnable
-- level 3
-- ruleset:new(7,2,9,8),
ruleset:new(7,2,9,8), -- by test: always winnable
-- level 4 (first challenging)
-- ruleset:new(9,3,9,16),
-- level 5
-- ruleset:new(9,3,11,18),
ruleset:new(9,3,9,16, "l4"),
-- level 5
ruleset:new(9,3,11,18, "l5"),
-- fortune's foundation
ruleset:new(11,4,13,22,"seeds_ff")
ruleset:new(11,4,13,22,"ff")
-- harder than fortune's foundation
-- ruleset:new(11,5,10,25)
}

View File

@ -3,14 +3,42 @@ import struct
import zlib
def main():
# No need to store any seeds for level 2 or 3: all 5000 of the first 5000 seeds are fine
# We could use negencode_delta_4b, which is pretty uneventful
# level_1 = load_seeds("input/level_1.txt")[:5000]
# analyze(level_1)
# level_2 = load_seeds("input/level_2.txt")[:5000]
# analyze(level_2)
# level_3 = load_seeds("input/level_3.txt")[:5000]
# analyze(level_3)
level_4 = load_seeds("input/level_4.txt")[:5000]
# analyze(level_4)
level_5 = load_seeds("input/level_5.txt")[:5000]
# analyze(level_5)
ff = load_seeds("input/fortunes_foundation.txt")
# analyze(ff)
ffdata = delta_4b(ff)
# level_7 = load_seeds("input/level_7.txt")[:5000]
# analyze(level_7)
augment_map("../main.p8", "../seed_constants.lua", ffdata, {
"ffdata_start": 0,
"ffdata_end": len(ffdata),
})
level_4_data = negencode_16b(level_4)
level_5_data = negencode_delta_4b(level_5)
ff_data = delta_4b(ff)
all_data = b""
offsets = {}
for block, data in [
("l4", level_4_data),
("l5", level_5_data),
("ff", ff_data)
]:
offsets[f"{block}_start"] = len(all_data)
all_data += data
offsets[f"{block}_end"] = len(all_data)
augment_map("../main.p8", "../seed_constants.lua", all_data, offsets)
def augment_map(target, constants_file, binary, offsets):
@ -58,13 +86,21 @@ def analyze(seeds):
print("{} seeds".format(len(seeds)))
for encoding in [
naive, delta_8b, delta_3b, delta_4b, delta_5b, zlib_delta_4b, zlib_delta_8b
naive, bitfield, delta_8b, delta_2b, delta_3b, delta_4b, delta_5b, zlib_delta_4b, zlib_delta_8b,
negencode_delta_4b, negencode_16b,
]:
print("{} encoding: {} bytes".format(encoding.__name__, len(encoding(seeds))))
def naive(seeds):
return b"".join(struct.pack("<I", s) for s in seeds)
def bitfield(seeds):
mx = max(seeds)
out = bytearray((mx+7)//8)
for s in seeds:
out[s // 8] |= 1 << (s % 8)
return bytes(out)
def delta_8b(seeds):
out = b""
acc = 0
@ -110,6 +146,9 @@ def delta_4b(seeds):
def zlib_delta_4b(seeds):
return zlib.compress(delta_4b(seeds))
def delta_2b(seeds):
return delta_nb(seeds, 2)
def delta_3b(seeds):
return delta_nb(seeds, 3)
@ -151,6 +190,26 @@ def delta_nb(seeds, n):
out += bytes(chunk_bytes)
return out
def negencode_delta_4b(seeds):
mx, new = negencode(seeds)
return struct.pack("<H", mx) + delta_4b(new)
def negencode_16b(seeds):
mx, new = negencode(seeds)
out = b""
out += struct.pack("<H", mx)
for i in new:
out += struct.pack("<H", i)
return out
def negencode(seeds):
mn = 0
mx = max(seeds) + 1
everyone = set(range(mn, mx))
for i in seeds:
everyone.remove(i)
return mx, sorted(everyone)
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,8 @@
seed_constants={
ffdata_start=4096,
ffdata_end=10434
l4_start=4096,
l4_end=4138,
l5_start=4138,
l5_end=4679,
ff_start=4679,
ff_end=11017
}

View File

@ -1,25 +1,54 @@
seeds={}
add(modules,seeds)
function seeds:init()
self.seeds_ff=seed_pool:new(seed_constants.ffdata_start,seed_constants.ffdata_end)
self.l4=seed_pool:new(seed_constants.l4_start,seed_constants.l4_end,_naive_16b,true)
self.l5=seed_pool:new(seed_constants.l5_start,seed_constants.l5_end,_delta_4b,true)
self.ff=seed_pool:new(seed_constants.ff_start,seed_constants.ff_end,_delta_4b)
end
function seeds:choose(pool)
if (pool) return rnd(self[pool].seeds)
return rnd(0xffff.ffff)
if (pool) return self[pool]:choose()
return rnd(5000>>16)
end
seed_pool=klass()
function seed_pool:init(addr_start,addr_end)
function seed_pool:init(addr_start,addr_end,routine,negencode)
if (negencode) self.neg_max=(%addr_start)>>16 addr_start+=2
local seeds={}
routine(seeds,addr_start,addr_end)
self.seeds=seeds
self.is_seed={}
for s in all(seeds) do
self.is_seed[s] = true
end
end
function seed_pool:choose()
if self.neg_max then
while true do
local r = rnd(self.neg_max)
if (not self.is_seed[r]) return r
end
end
return rnd(self.seeds)
end
function _delta_4b(seeds,s,e)
local acc=0
while addr_start < addr_end do
local byte=@addr_start
while s < e do
local byte=@s
local nb0=byte>>20
local nb1=(byte&0xf)>>16
if nb0==0 then acc+=0x0.000f else acc+=nb0 add(seeds,acc) end
if nb1==0 then acc+=0x0.000f else acc+=nb1 add(seeds,acc) end
addr_start+=1
s+=1
end
end
function _naive_16b(seeds,s,e)
while s < e do
add(seeds,%s)
s+=2
end
self.seeds=seeds
end

110
simulator/level_7.txt Normal file
View File

@ -0,0 +1,110 @@
81
11
124
76
10
111
128
63
106
136
50
150
6
152
74
27
113
91
171
18
167
16
125
51
148
198
93
146
200
219
196
83
177
14
237
36
262
239
276
169
285
138
242
241
259
299
302
279
182
166
191
159
306
255
320
309
295
328
313
373
269
348
340
388
286
354
428
382
398
322
441
343
469
319
453
488
456
520
525
414
508
361
529
527
521
494
569
563
417
580
589
594
614
605
422
596
505
593
676
511
682
660
413
512
483
716
722
731
629
696

View File

@ -1,4 +1,4 @@
use std::{borrow::Borrow, fs::File, io::Write, sync::{Arc, Mutex}};
use std::{fs::File, io::Write, sync::{Arc, Mutex}};
use board::Board;
use ruleset::Ruleset;
@ -16,28 +16,7 @@ mod zobrist;
fn main() {
/*
let mut rng = PicoRng::srand(0x20000);
for _ in 0..10 {
println!("{}", rng.rnd(0x10000));
}
return;
*/
/*
let ruleset = Ruleset {
n_slots: 11,
n_suits: 5,
n_cards_per_suit: 10,
n_arcana: 25
};
*/
let ruleset = Ruleset {
n_slots: 11,
n_suits: 4,
n_cards_per_suit: 13,
n_arcana: 22
};
/*
let filename = "level_1.txt";
let ruleset = Ruleset {
n_slots: 5,
n_suits: 1,
@ -46,6 +25,16 @@ fn main() {
};
*/
/*
let filename = "level_2.txt";
let ruleset = Ruleset {
n_slots: 5,
n_suits: 2,
n_cards_per_suit: 9,
n_arcana: 0
};
*/
/*
let filename = "level_3.txt";
let ruleset = Ruleset {
n_slots: 7,
n_suits: 2,
@ -54,37 +43,61 @@ fn main() {
};
*/
/*
let filename = "level_4.txt";
let ruleset = Ruleset {
n_slots: 9,
n_suits: 3,
n_cards_per_suit: 9,
n_arcana: 16
};
*/
/*
let filename = "level_5.txt";
let ruleset = Ruleset {
n_slots: 9,
n_suits: 3,
n_cards_per_suit: 11,
n_arcana: 18
};
*/
/*
let filename = "fortunes_foundation.txt";
let ruleset = Ruleset {
n_slots: 11,
n_suits: 4,
n_cards_per_suit: 13,
n_arcana: 22
};
*/
let filename = "level_7.txt";
let ruleset = Ruleset {
n_slots: 11,
n_suits: 5,
n_cards_per_suit: 10,
n_arcana: 25
};
let setup = ruleset.compile().expect("compilation should succeed");
/*
for _ in 0..10000 {
Deal::deal(&setup, &mut rand::thread_rng());
}
*/
const THREADS: usize = 28;
let winnable_seeds_file = Arc::new(Mutex::new(File::create("winnable_seeds_multithreaded.txt").expect("should be able to create")));
let work_source: WorkSource = WorkSource::new(0);
let winnable_seeds_file = Arc::new(Mutex::new(File::create(filename).expect("should be able to create")));
let mut threads = Vec::new();
for i in 0..THREADS {
for _ in 0..THREADS {
let setup2 = setup.clone();
let source = work_source.clone();
let wsf = winnable_seeds_file.clone();
threads.push(std::thread::spawn(move || {
winnable_seeds_thread(
&setup2,
source,
|seed| {
let mut f = wsf.lock().expect("must be able to lock");
write!(f, "{}\n", seed).expect("write should succeed");
f.flush().expect("flush should succeed");
},
i as u32,
THREADS as u32
);
}));
}
@ -95,11 +108,31 @@ fn main() {
}
fn winnable_seeds_thread(setup: &ruleset::Setup, mut cb: impl FnMut(u32), start: u32, step: u32) {
#[derive(Clone)]
struct WorkSource {
seed: Arc<Mutex<Option<u32>>>
}
impl WorkSource {
fn new(seed: u32) -> Self {
return WorkSource { seed: Arc::new(Mutex::new(Some(seed))) }
}
fn take(&self) -> Option<u32> {
let mut self_seed = self.seed.lock().expect("shouldn't have panicked");
if let Some(seed) = *self_seed {
*self_seed = seed.checked_add(1);
return Some(seed);
}
return None
}
}
fn winnable_seeds_thread(setup: &ruleset::Setup, source: WorkSource, mut cb: impl FnMut(u32)) {
let mut winnable = 0;
let mut total = 0;
for seed in (start..0xffffffff).step_by(step as usize) {
while let Some(seed) = source.take() {
let mut board = Board::new(&setup);
board.deal(Deal::deal(&setup, seed));
board.display();

View File

@ -10832,3 +10832,109 @@
85247
92829
91669
97597
85443
84931
91729
88458
92969
95686
86653
88570
86989
79762
87578
90767
89826
86559
90667
89319
89598
85609
89626
89416
88794
90134
87662
97716
91243
92688
86171
96000
93473
79902
86671
87690
97877
86923
89767
86057
93557
92638
90891
90919
89823
90883
89822
89878
92881
84476
92722
92513
92716
84588
94005
98017
89836
90088
94145
90172
90995
92597
97884
90312
80182
88850
80294
81556
84840
96140
91753
80434
90974
91087
91809
94453
98024
87129
81948
82004
91271
86197
91311
90718
85323
87157
92793
92905
91977
94789
94817
85407
96224
98248
91479
88082
85631
91535
91591
85064
82200
98500
89102
98640
80518
82312
82480
89158
96308

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff