Seed Finding by Java [2]
一、對(duì)之前專(zhuān)欄的補(bǔ)充
首先是build.gradle這個(gè)文件,之前專(zhuān)欄里的這一句?:url "https://maven-snapshots.seedfinding.com" 是多余的,這個(gè)是很早之前的url了,最新的就是:url "https://maven.seedfinding.com" 這一句,所以可以刪掉。
其次還有兩個(gè)庫(kù)之前忘記導(dǎo)入了,一個(gè)是mc_noise,一個(gè)是latticg。mc_noise是一個(gè)用來(lái)模擬Minecraft中使用的Perlin Noise(柏林噪聲)等noise,但是我既不會(huì)用也沒(méi)用過(guò),具體如何使用也不是很懂。latticg反轉(zhuǎn)Java的Java.util.Random類(lèi)可能的內(nèi)部種子,給定其輸出信息,以各種隨機(jī)調(diào)用的不等式系統(tǒng)的形式。該算法的工作原理是將問(wèn)題簡(jiǎn)化為在格中找到某些向量,然后使用格的簡(jiǎn)化版本通過(guò)分枝定界算法來(lái)解決。說(shuō)人話就是比如這個(gè)區(qū)塊符合某個(gè)條件,可以通過(guò)一些辦法來(lái)得到可能的種子,我用的很少,只用來(lái)研究如何篩眼,因此不會(huì)介紹如何使用,因?yàn)槲叶囊膊欢唷?/p>
最終的build.gradle文件如下:

可以看我GitHub上的build文件,直接復(fù)制粘貼就好
還有上期專(zhuān)欄說(shuō)的隨機(jī)篩種,其實(shí)就是創(chuàng)建一個(gè)Java隨機(jī)然后用nextLong()方法隨機(jī)一個(gè)long類(lèi)型的值當(dāng)中種子就好,如圖所示,當(dāng)然我沒(méi)有對(duì)這個(gè)seed做什么,只是打印

上面的是無(wú)限循壞隨機(jī),如果想控制數(shù)量的話可以用for循環(huán),比如10個(gè)

隨機(jī)篩就是這樣,不再贅述。之前說(shuō)的列表篩會(huì)在本專(zhuān)欄后面教學(xué),因?yàn)楸容^重要所以就單獨(dú)說(shuō)

這是上期專(zhuān)欄中用VillageGenerator篩村莊黑曜石的示例代碼,請(qǐng)看obsidian += item.getCount()這一句。為什么是+=呢,因?yàn)橐粋€(gè)村莊里的箱子有很多,我們遍歷了每一個(gè)chest,每當(dāng)有obsidian時(shí)都加上這個(gè)箱子里obsidian的數(shù)量。提這個(gè)的原因是后面我會(huì)講寶藏的掠奪,然而它是一個(gè)單箱結(jié)構(gòu),也就是說(shuō)只有一個(gè)箱子,不用+=,防止弄混
那么補(bǔ)充到此結(jié)束,接下來(lái)進(jìn)入正題
二、寶藏

structureSeed之類(lèi)的東西不必多說(shuō),至于為什么要先聲明一個(gè)空的CPos變量呢,首先,寶藏與廢棄礦井和除要塞外其他結(jié)構(gòu)的生成是不一樣的,它們會(huì)在每一個(gè)區(qū)塊都嘗試生成,所以使用getInRegion()方法時(shí)輸入的regionX和regionZ應(yīng)為區(qū)塊坐標(biāo)(可以當(dāng)作它們的region大小為一個(gè)區(qū)塊),很明顯我們要用for循環(huán)來(lái)循環(huán)生成區(qū)塊坐標(biāo)x和z,這里我們遍歷區(qū)塊的x坐標(biāo)-16到16,z坐標(biāo)-16到16,如果它不為null(空),則判斷它是否能在這個(gè)區(qū)塊生成,即是否符合群系,如果符合,就把一開(kāi)始的空變量重新賦值成這個(gè)坐標(biāo),這就是為什么要先聲明空變量。再用getLootAtPos方法得到這個(gè)寶藏的戰(zhàn)利品,indexed為false是因?yàn)椴灰屗笖?shù)化(有點(diǎn)難說(shuō)明,總之記住基本都是false就好),然而這個(gè)方法得到的數(shù)據(jù)類(lèi)型是List<ChestContent>,也就是一個(gè)箱子列表,顯而易見(jiàn)的這個(gè)列表只有一個(gè)元素,因?yàn)閷毑厥菃蜗浣Y(jié)構(gòu),所以在它后面加上get(0),即得到第一個(gè)元素(也只有一個(gè)),如果你indexed填的是true那么它會(huì)報(bào)錯(cuò),因?yàn)樗笖?shù)化了。然后得到箱子里鐵錠(iron ingot)的數(shù)量,如果小于7就return,檢查下一個(gè)種子(至于為什么是7,SpeedRun玩家太清楚了)。寶藏會(huì)生成在區(qū)塊里(9,9)的位置,所以再具體說(shuō)明寶藏箱的坐標(biāo),用BPos(方塊坐標(biāo))

最后再得到出生點(diǎn)的坐標(biāo),用distanceTo這個(gè)方法得到出生點(diǎn)離寶藏的距離(兩個(gè)坐標(biāo)都要是方塊坐標(biāo)BPos),如果大于50就return。50格內(nèi)則打印出seed、寶藏坐標(biāo)、鐵錠數(shù)量

在main方法的for循環(huán)里調(diào)用treasure這個(gè)方法,運(yùn)行

輸出了兩個(gè)種子,停止運(yùn)行進(jìn)游戲查看是否正確

用我堪比p神的技術(shù)20秒找到寶藏,確實(shí)有10鐵

寶藏就在腳下,秒找!確實(shí)有8鐵
最后補(bǔ)充,其實(shí)這樣是有漏洞的,在給空變量重新賦值的時(shí)候:比如說(shuō)區(qū)塊(-10,-12)有一個(gè)寶藏,且在出生點(diǎn)50格內(nèi),但是因?yàn)橘x值完之后還會(huì)繼續(xù)循壞,在區(qū)塊(10,8)又有一個(gè)寶藏,重新賦值,但它在出生點(diǎn)50格外了,所以會(huì)被認(rèn)為是不符合要求的種子;你可能會(huì)說(shuō)得到第一個(gè)之后終止循環(huán)就好了,但如果第一個(gè)50格外第二個(gè)50格內(nèi)呢?具體解決辦法會(huì)在以后寫(xiě)如何篩rsg種的時(shí)候介紹
三、群系

如何在給定的坐標(biāo)得到一定距離內(nèi)想要的群系呢?首先,加載主世界群系(OverworldBiomeSource),再聲明一個(gè)群系列表,里面添加你想要的如何群系,我隨便寫(xiě)了三個(gè),河流、深海、海洋,再創(chuàng)建Java隨機(jī)數(shù)(JRand,但它其實(shí)是篩種庫(kù)里的一個(gè)類(lèi)),填入?yún)?shù)seed,用locateBiome方法得到離(0,0)這個(gè)坐標(biāo)(可以隨意改,y也是)16格(也可以改)內(nèi)的河流或深海或海洋的坐標(biāo),如果都沒(méi)有則return,最后打印種子和坐標(biāo)。運(yùn)行后你會(huì)發(fā)現(xiàn)速度很快,停止運(yùn)行后隨便挑一個(gè)種子查看即可
四、1.17.1滿眼種村莊20黑
首先進(jìn)篩種群:956255985,下載群文件所有滿眼種1171Unique.txt,把它放到篩種文件夾,再創(chuàng)建一個(gè)文本文檔用來(lái)輸出種子,比如:

20obsidian就是我創(chuàng)建的文本文檔
因?yàn)檫@部分代碼過(guò)長(zhǎng),所以我打算下一期單獨(dú)講,具體代碼可以看我GitHub
GitHub:https://github.com/Xinyuuu7/Example
感謝支持!