最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Carpet編程入坑跳坑指北

2019-07-19 01:49 作者:祿存天璣  | 我要投稿

作者:祿存

前言

歡迎來TIS論壇,享受極致的 Markdown 渲染體驗(yàn):https://forum.tis.world/topic/132/carpet編程入坑跳坑指北

首先感謝各位能抽時(shí)間看這一篇文章。最近抽了兩天時(shí)間研究了一下 Carpet 這個(gè)腳本語(yǔ)言,這里來和大家分享一下自己的心得體會(huì)。

我最早了解到 Carpet 是因?yàn)?gnembon 的宣傳視頻。但是了解了也沒去多看。后來因?yàn)橥米訖C(jī)研究生物 AI 的時(shí)候說到了 Carpet 端,就去研究了一下。花了一個(gè)晚上實(shí)現(xiàn)了寬度優(yōu)先搜索,又花了一個(gè)下午實(shí)現(xiàn)了 A*尋路算法,算是有了點(diǎn)心得體會(huì),來和大家分享一下。

基本介紹

Carpet 是一個(gè)用 Java 編寫的,擁有較多功能的,基于原版 Minecraft 系統(tǒng)的函數(shù)式編程腳本。大體可以用“萬物皆函數(shù)”概括,與 Java 的“萬物皆對(duì)象”相映成趣。

Carpet 的運(yùn)行效率不如Forge,但編寫起來更加簡(jiǎn)單,修改也容易得多。

這里講到的所有內(nèi)容都可以在官方的手冊(cè) https://gnembon.github.io/scarpet/ 找到。

在讀這篇文章之前,最好就對(duì)編程有所了解。

語(yǔ)法技巧

首先是各種特殊用法和注意要點(diǎn):?

  • 對(duì)列表的一些奇妙操作,這個(gè)后面集中講;

  • null?的設(shè)定是比任何對(duì)象都小的:在參與比較大小時(shí),除了與自身相比為?true,否則總是?false;

  • global_?前綴可以聲明全局變量,運(yùn)行完畢后也會(huì)被保存;

  • 和 Java 一樣,|| &&?是“短路”的,也就是只會(huì)在必要條件下檢測(cè)后一項(xiàng),例如官方的示例;

  • 函數(shù)只能傳值,例如:delete(list) -> list = l(); a = l(1,2,3); delete(a); print(a);?的輸出是?[1, 2, 3]。

列表,以及字符串

  • 列表是基于 Java 的?ArrayList?的,字符串是基于?String。運(yùn)行效率如何自己掂量著看;

  • 列表可以同時(shí)存放不同類型的值,這點(diǎn)跟 Python 有點(diǎn)類似;

  • 列表進(jìn)行?+ - * /?的時(shí)候,如果后一個(gè)是數(shù)字,就對(duì)列表內(nèi)的每一個(gè)對(duì)象進(jìn)行一次操作;如果也是列表并且長(zhǎng)度一樣,就會(huì)將對(duì)象一一對(duì)應(yīng)加起來,形成一個(gè)新的對(duì)象;如果前后列表長(zhǎng)度不一樣會(huì)報(bào)錯(cuò)。

  • 另外,l(l(1,2), l(2,3)) + l(l(1,2), l(2,3))?以及?l(l(1,2), l(2,3)) + l(1,2)都是可以的;

  • 列表進(jìn)行?+=?時(shí)自動(dòng)往最后面添加后一個(gè)操作數(shù);

  • 列表用?element(<list>, <index>)?取出對(duì)象的時(shí)候,-1 代表最后一個(gè),-2是倒數(shù)第二個(gè);下標(biāo)如果溢出就重新從0開始計(jì)數(shù);

  • 字符串在使用?+=?+?的時(shí)候都會(huì)自動(dòng)將后一個(gè)對(duì)象轉(zhuǎn)換為字符串然后拼接;

  • ~?在對(duì)列表使用時(shí),會(huì)在列表中查找后一個(gè)對(duì)象。查到了返回下標(biāo),查不到返回?null;對(duì)字符串使用時(shí)會(huì)將后一個(gè)對(duì)象轉(zhuǎn)換成字符串,作為正則表達(dá)式進(jìn)行匹配。返回匹配到的字符串或者?null;

  • 對(duì)字符串使用?-?時(shí),會(huì)將后一個(gè)對(duì)象轉(zhuǎn)換成字符串,并返回一個(gè)去除了所有該字符串的新字符串,不進(jìn)行正則匹配,例如?'ababa' - 'aba'?返回?b。

函數(shù)式編程和列表

抱歉,這里沒有點(diǎn)操作符,大括號(hào)和中括號(hào)也沒有

流操作?可以了解,但沒卵用

排序列表是?sort(<list>)?但是外部傳入的列表對(duì)象沒變,你需要?list = sort(list),之前應(yīng)該說過了,list.sort()?是什么?不存在的!

不過,你可以在一些作者預(yù)定義好的函數(shù)里寫語(yǔ)句,類似 Java 的 Lambda 表達(dá)式。(慘,你自己是沒法寫能傳語(yǔ)句的函數(shù)的!)例如這樣能把一個(gè)列表映射成另一個(gè)列表,里面的每一個(gè)對(duì)應(yīng)的值都是相反的:

map(list, -_)

它可以當(dāng)作 Java 里的

list.stream().map(x -> -x).toArray()

這里的下劃線_就是list里的每一個(gè)對(duì)象。

同理可得:

  • ?filter(list, _ > 0)?能得到一個(gè)只有原列表中正數(shù)的新列表。?

  • 還有高級(jí)版的排序:sort_key(list, -_)?實(shí)現(xiàn)了逆序排序。

之前提到了流操作,確實(shí)很像,然而并不一樣:根本沒有那種優(yōu)化! 例如:first(sort(list), true)?的性能比效果上等價(jià)的?min(list)?要差得多!

另外,列表只能在最后添加,不能中間插入,不能中間刪除,但是可以根據(jù)下標(biāo)截取出一個(gè)新的列表——其他的功能要自己寫! 舉個(gè)例子:

remove_by_val(list, item) -> ( ? ?

? new_list = l();

? for (list,

? ? if (item == _,

? ? ? ?put(new_list, null, _)

?? ?)

??);

??return(new_list)

);

沒錯(cuò),for?和?if?也是函數(shù),只不過能傳入語(yǔ)句。具體要看官方手冊(cè)的定義,同樣的還有?loopwhile。另外這里沒有方便的?break?和?continue,可能需要立flag或者用超大的條件判斷。

看到這里,你可能會(huì)覺得不妙:那咋取出列表的特定元素?答案是?element(<list>, <index>),element有點(diǎn)奇妙的特性,上文說過。

那關(guān)于Minecraft的功能呢???

抱歉,我沒怎么了解(笑)

不過看手冊(cè),功能還是挺全的,可以控制時(shí)間流逝速度,進(jìn)行隨機(jī)刻,搜索實(shí)體,獲取 NBT 標(biāo)簽,生成結(jié)構(gòu),執(zhí)行命令,甚至方便地檢測(cè)一片區(qū)域里的方塊……畢竟作者在技術(shù)社區(qū)混了那么久,基本上你想到的需求是一應(yīng)俱全的。(實(shí)時(shí)生物AI追蹤呢?)

不過也要小心一點(diǎn)。比起命令方塊,Carpet 的安全性要差一點(diǎn)。例如一次在聊天欄輸出超大的列表會(huì)卡死客戶端,服務(wù)端在執(zhí)行腳本的時(shí)候默認(rèn)會(huì)凍結(jié)住之類的……

Carpet編程入坑跳坑指北的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
本溪| 临城县| 绥棱县| 扶余县| 建平县| 昌黎县| 湟中县| 黔东| 碌曲县| 鲁甸县| 冕宁县| 深圳市| 淮阳县| 永安市| 托克托县| 平安县| 丰城市| 汾西县| 澄城县| 驻马店市| 台北县| 宁远县| 南安市| 衡水市| 文昌市| 射阳县| 温泉县| 石台县| 宜兰县| 卫辉市| 洞头县| 洱源县| 沛县| 曲靖市| 铁力市| 成都市| 出国| 罗源县| 玉门市| 炎陵县| 黄龙县|