鱗目界域-龍論壇

游態龍的錫安山。龍的力量、智慧、野性、與優雅

您尚未登录。 (登录 | 注册)

公告

mb 爪機版     |    論壇指南     |    Discord     |    QQ群

《龙魂志》第一期
《龙魂志》第二期

Tips:欢迎来到龙之里

#76 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-04-02 13:31:19

回应:

@shiningdracon 寫道: 我沒看出你這句話是對哪一部分有疑問

只是我對「偶然」的小調侃罷了 [臉紅笑]

最后修改: Sherixs (2026-04-02 13:31:47)

#77 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-04-02 13:24:51

回应:

@Sherixs 寫道: 就拿對龍有害的毒物來說吧,龍族的數量少,作爲一種對其他龍的威懾,即便有哪條龍知道解藥,也不一定會分享給其他龍.如果龍之間的領地性很強,相互的交流少的話,那更不利於解藥方法的傳播,最終可能大部分龍會受影響.

這相當於預設了一個更具體的情景。然而同樣可以預設另一種情景,比如龍的領地不固定,而是像一些鴉科、鷹科那樣鬆散的結構,與其它龍也不是零交流。
只是考慮到過於具體的預設討論價值不大,所以我在主樓並沒有預設這樣具體的情景,而只是做宏觀上的比較。
何況即使是在你這個預設下,主樓也已經把“技術的發展與傳承”考慮在內了。無尾的知識傳承是優勢,但在中世紀還不足以對龍構成威脅。

@Sherixs 寫道: 而且我覺得人類既然還是能逃過像黑死病這樣的大災難,保存種族的生存天賦算是點滿了

那麼就拿黑死病舉例子好了。

黑死病造成的後果是人口銳減,大量農田無人耕種,村莊荒廢,城市衰退。勞動力的短缺和統治者鎮壓能力的下降使得領主不再能輕易控制農民。領主、教會等舊的社會統治勢力逐漸衰落,農民的人身依附變弱,爲後續商業與手工業的興起埋下伏筆。

僅僅是六、七年的時間便造成了這樣的後果。那麼想象一下,如果疫情持續時間更久,會發生什麼。

而且龍本身作爲一種天災式的存在,除了可以讓人口銳減土地荒廢以外,還可以進一步破壞道路、海港,令長途貿易中斷。城市因供給不足而退化。襲擊行政機構,官員、士兵、神職人員大量死亡,行政能力和徵兵能力下降。各地區回到本地自給的狀態。學校和修道院運轉困難,抄寫、保存、傳授知識的能力下降。社會重新高度鄉村化,分工下降,交換減少,知識傳播變慢。

龍可以讓這一狀態持續上百年。等三、四代之後無尾不會剩下多少知識傳承。

@Sherixs 寫道: 

@shiningdracon 寫道: 由於一系列的偶然

難說這算不算無魔世界觀

我沒看出你這句話是對哪一部分有疑問。是對“無尾直到近代才由於一系列的偶然開啓了工業文明”這句話有疑問嗎?這是歷史吧。


有 1 位朋友喜欢这篇文章:Sherixs

#78 聲稱自己是龍但是恐高會不會是一件很丟臉的事情 » 2026-04-01 14:54:07

回应:

我就是這樣的,明明精神上非常渴望飛行,但是現實中一旦站在高處就會開始嚴重恐高…… [流汗] 
我只能將這個現象解釋爲人身帶來的壞影響,就像想走路的時候發現自己沒有腿一樣(


有 1 位朋友喜欢这篇文章:箐岚

#79 關於龍的自身散熱問題。 » 2026-03-31 18:43:49

回应:

除了散熱,感覺保暖也更重要~

飛得高一些,空氣很容易低於0度

高空風又大,翅膀就算不凍僵,持續損失熱量感覺也很麻煩    [靈感]

#80 聲稱自己是龍但是恐高會不會是一件很丟臉的事情 » 2026-03-31 16:49:59

回应:

[↑] @鏡中龍影 寫道: 身體沒有翅膀當然恐懼 [汗] …

太現實了! [大哭]

#81 關於龍的自身散熱問題。 » 2026-03-31 09:05:15

回应:


最近算了一下,發現如果能用膜翼散熱的話主要的問題是氧氣需求量和功率密度(136W/kg),不過這個模型是龍平地起飛,如果是利用高度差起飛那氧氣需求和功率密度問題都不存在了,散熱可能也用不着翅膀。
鉛筆是後來用幾何體粗略估算了身體表面積修正後的結果,沒有算軀幹外的邊邊角角。

#82 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-30 21:12:32

回应:

@shiningdracon 寫道: 你想表達的是經驗的傳承

個龍經驗.
就拿對龍有害的毒物來說吧,龍族的數量少,作爲一種對其他龍的威懾,即便有哪條龍知道解藥,也不一定會分享給其他龍.如果龍之間的領地性很強,相互的交流少的話,那更不利於解藥方法的傳播,最終可能大部分龍會受影響.如果龍族上下一心想滅絕人類那另當別論 [酷酷] 
反觀人類這邊,人口數量多,反倒提供了豐富的實驗樣品(?;而且我覺得人類既然還是能逃過像黑死病這樣的大災難,保存種族的生存天賦算是點滿了——從我知道的歷史來說,真不敢下定論說人類是脆弱的,說不定會把全部的生存技能都拿出來了(.對龍來說,人可能會像蟲子一樣難殺,何況人還是擁有智慧的,有規劃、有計謀的蟲子.

@shiningdracon 寫道: 由於一系列的偶然

難說這算不算無魔世界觀 [大喊]

#83 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-30 20:41:48

回应:

@Sherixs 寫道: 但是人類有醫生和有限的醫學系統,可以嘗試破解

在科學的方法論出現之前,無尾對毒物的處理能力只限於物理排出、稀釋、緩解症狀,可以說並沒有有效的應對手段。而科學的方法論的出現是很近代和很偶然的事情。

@Sherixs 寫道: 而龍只能依靠經驗(如果龍沒有醫生的話(?),社會動物的優勢

一切知識都源於經驗。我猜你想表達的是經驗的傳承,但這和社會性是兩個範疇的東西。比如沒法說螞蟻蜜蜂這種真社會性物種有什麼知識傳承。即使將語境僅限於無尾,這種經驗傳承也很可能變成墨守成規,反過來鎖死未來的發展。

@Sherixs 寫道: 怎麼看龍族只能算一種前期強勢的勢力,後期還得看人類

實際上給無尾中世紀的開局已經是放水放成海洋了。如果是原始社會的開局,無尾沒有機會進入定居時代。定居的出現需要可馴化的作物和牲畜,無尾真正馴化的物種只有那麼有限的幾種,而且需要漫長的時間。一直到近代還維持原始部落狀態的地方,原因之一就是因爲缺少可馴化的動植物。
舉個例子,斑馬和馬很相似,但斑馬由於性格比馬更暴躁,更不容易服從,對環境更警覺,因此一直沒能馴化。
要知道無尾維持了數十萬年的原始部落狀態,進入穩定的農耕文明也不過是數千年。在很長時間裏,生態條件並沒有提供足夠多、足夠合適的馴化對象來支撐高密度定居。可馴化物種本來就極少,可作爲勞動力和交通工具的大型哺乳動物更稀缺。
無尾直到近代才由於一系列的偶然開啓了工業文明,社會演進的漫長時間間隔本身就說明無尾社會的發展並不是線性的、必然的從部落走到工業文明。

最后修改: shiningdracon (2026-03-30 20:49:47)

#84 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-30 19:45:28

回应:

@shiningdracon 寫道: 在龍有所防備的情況下

但是人類有醫生和有限的醫學系統,可以嘗試破解,而龍只能依靠經驗(如果龍沒有醫生的話(?),社會動物的優勢 [靈感] 
比較尷尬的是不清楚中世紀的醫學會不會直接把人醫死 [生病] 
怎麼看龍族只能算一種前期強勢的勢力,後期還得看人類 [靈感]我認爲沒有被削弱過的龍族前期都是很強的:D

最后修改: Sherixs (2026-03-30 19:58:24)

#85 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-30 16:28:49

回应:

[↑] @羽落 寫道: 舉幾個例子:葡萄、百合屬植物(對於貓來說哪怕是花粉或接觸過相關植物的水也有劇毒)由於對牲畜無害,全境實行可能不現實,但哪怕一半的地區實行,龍在長時間與人類戰鬥的情況下也有很大概率碰上。如果完全沒有對應 …

嚴格來說葡萄並不屬於這一類毒物。不過這是細節。可以在假設這種天然毒物存在的前提下繼續討論。

@羽落 寫道: 由於對牲畜無害,全境實行可能不現實,但哪怕一半的地區實行,龍在長時間與人類戰鬥的情況下也有很大概率碰上。

前文所說的下毒是隱蔽設伏,引誘龍攝入毒物。然而這種大範圍部署涉及成規模的資源調動,與隱蔽矛盾。實際上和大量建造弩炮的策略一樣,在龍有所防備的情況下會失敗。

@羽落 寫道: 認同一半,如果是非當地植物大概率沒有相關知識。但同樣的,人也沒有一個樣本實驗哪些對龍有效果。

相比之下,龍有大量的實驗機會,可以針對性的給無尾下毒。

龍的戰略目標是摧毀無尾的穩定生產能力,進而瓦解其社會結構。而無尾社會依賴的耕種、放牧等食物獲取方式非常容易被龍針對。

#86 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-28 15:39:37

回应:

@shiningdracon 寫道: 毒物需要對牲畜無害,不然無法設伏。

舉幾個例子:葡萄、百合屬植物(對於貓來說哪怕是花粉或接觸過相關植物的水也有劇毒)

無尾需要預判龍的行蹤才能提前準備。

由於對牲畜無害,全境實行可能不現實,但哪怕一半的地區實行,龍在長時間與人類戰鬥的情況下也有很大概率碰上。

毒物需要對龍致命,或者短時間內能造成失能。不然龍只需要到無人區等待身體恢復,無尾很難遠距離穿越地形追殺。

如果完全沒有對應消化能力(上面說的百合屬植物)的確可以致命。

對自己有害的天然毒物,龍比無尾更熟悉。

認同一半,如果是非當地植物大概率沒有相關知識。但同樣的,人也沒有一個樣本實驗哪些對龍有效果。


有 1 位朋友喜欢这篇文章:Sherixs

#87 [中短期工程]龍族種羣擴散模擬程序 » 2026-03-28 15:26:27

回应:

@羽落 寫道: 找這些數據真是費時費力啊,ai找數據也常常劃成完全不相干的部分,並沒有節省多少時間。實在是找不動了,按初步搜索的結果全部設置爲四級營養級吧......

主要是營養級相關數據本來就很少有人去專門統計,找不到也是預料之中……

#88 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-28 15:19:20

回应:

@羽落 寫道: 或許可以考慮對特定區域的牲畜投毒,這樣就不用製備了,直接使用已有的植物。如果龍有一次注意到估計這種方法就不管用了,但如果沒注意到可能就完蛋。

幾個困難:
無尾需要預判龍的行蹤才能提前準備。
毒物需要對牲畜無害,不然無法設伏。
毒物需要對龍致命,或者短時間內能造成失能。不然龍只需要到無人區等待身體恢復,無尾很難遠距離穿越地形追殺。
對自己有害的天然毒物,龍比無尾更熟悉。

發帖時本來是想對比一下龍和無尾之間宏觀層面的優劣和劣勢,但大家似乎更關注“下毒”這個話題  [owo]

最后修改: shiningdracon (2026-03-28 16:55:19)

#89 [中短期工程]龍族種羣擴散模擬程序 » 2026-03-28 15:19:08

回应:

找這些數據真是費時費力啊,ai找數據也常常劃成完全不相干的部分,並沒有節省多少時間。實在是找不動了,按初步搜索的結果全部設置爲四級營養級吧...... [嗝屁] 
更新後的表格如下:
| 生物羣系      | NPP     | EF   | 有效可食NPP | 營養級   | 傳遞係數   | **頂掠可得能量** |
| --------- | ------- | ---- | ------- | --------- | ------ | ---------- |
| **熱帶雨林**  | 2200    | 0.20 | 440     | 第四級 | 0.001 | **0.440**  |
| **熱帶季節林** | 1600    | 0.25 | 400     | 第四級       | 0.001 | **0.400**  |
| **溫帶落葉林** | 1200    | 0.30 | 360     | 第四級       | 0.001  | **0.360**  |
| **溫帶針葉林** | 1300    | 0.18 | 234     | 第四級       | 0.001  | **0.234**  |
| **稀樹草原**  | 900     | 0.60 | 540     | 第四級       | 0.001  | **0.540**  |
| **溫帶草原**  | 600     | 0.80 | 480     | 第四級       | 0.001   | **0.480**   |
| **北方針葉林** | 800     | 0.12 | 96      | 第四級       | 0.001   | **0.096**   |
| **地中海灌叢** | 700     | 0.22 | 154     | 第四級       | 0.001  | **0.154**  |
| **苔原**    | 140     | 0.25 | 70      | 第四級       | 0.001   | **0.070**   |
| **荒漠**    | 65 | 0.25 | 26      | 第四級     | 0.001    | **0.026**   |
| **極地冰原**  | ~0      | ~0   | ~0      | —         | —      | **~0**     |
| **水**  | ~0      | ~0   | ~0      | —         | —      | **~0**     |
發現雨林對頂掠的貢獻值仍然低於草原,計劃添加每個網格的捕獵成功率來修正。但這可能又得帶一些主觀色彩來取值了。 [流淚笑]

#90 黑龍謝里斯的胡思亂想 » 2026-03-28 00:24:10

回应:

在想龍族是否需要 文字和個龍的名字
名字需要的可能性比較大,比如宣誓領地;對龍和對人都需要,更不用說幾百年的壽命都能熬死多少代人類了 [靈感] 
文字的需求就比較難推測了
1.如果龍的記性好到能記住“收藏”中所有的寶物,那似乎也沒有什麼記錄的需要.
2.龍很少遇到複雜的交流情景,也沒有人類那樣複雜的社會結構,文字的使用沒多大必要.
ps:上古卷軸的龍語做得用心了,有楔形文字的感覺 [大笑] 
怎麼有種 論文字下鄉 的即視感XD

#91 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-27 17:35:55

回应:

[↑] @鏡中龍影 寫道: 對體能因素表示質疑。如果說滑翔比較節約體力,但是滑翔有風阻,要保持速度就要有下降率,有下降率就要爬升),這10萬公里聽起來像天天都在馬拉松 …

我是從純能量角度計算的,算出來好像是12000km,因爲理想因素所以打了個折,如果考慮個體差異的話會麻煩不少,但不太可能少於5000km。
滑翔能量消耗我取的是BMR的2倍。

#92 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-27 13:22:07

回应:

[↑] @羽落 寫道: 另外補充一點,按照3m,300kg的龍來算,龍可以在4.5天內直線飛行10000km。如果有感興趣的我可以把計算過程發出來。 …

對體能因素表示質疑。
如果說滑翔比較節約體力,但是滑翔有風阻,要保持速度就要有下降率,有下降率就要爬升),這10萬公里聽起來像天天都在馬拉松

#93 [中短期工程]龍族種羣擴散模擬程序 » 2026-03-27 13:01:00

回应:

找到辦法了,可以查找通過氮同位素δ¹⁵N分析得出的平均營養級,初步搜索確認雨林中頂掠的平均營養級是4左右,但缺少可引用的學術研究資料,另外其它生物羣系的營養級可能也得用這種辦法校正。

#94 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-26 22:22:20

回应:

[↑] @shiningdracon 寫道: 對方也不知道什麼東西對龍有毒且無法被龍察覺。相比之下,你對自己的瞭解,遠比無尾對你的瞭解要多。 …

或許可以考慮對特定區域的牲畜投毒,這樣就不用製備了,直接使用已有的植物。如果龍有一次注意到估計這種方法就不管用了,但如果沒注意到可能就完蛋。
強弱方面的話,據我瞭解,人類似乎對各種植物毒素的抵抗力強於大多數肉食動物。
另外補充一點,按照3m,300kg的龍來算,龍可以在4.5天內直線飛行10000km。如果有感興趣的我可以把計算過程發出來。

#95 你是否認爲色情內容有損於龍的形象 » 2026-03-24 13:51:47

回应:

不妨在多加個內容,變成swf、nswf、r18g,這樣討論起來就更有意思了 [壞笑]

最后修改: SmallDragon (2026-03-24 13:53:01)

#96 正在聽什麼音樂? » 2026-03-23 21:53:34

回应:

Atlantis - Postiljonen
https://music.163.com/song?id=26612938

Wait - Postiljonen
https://music.163.com/song?id=478920643

完美融合了Synthwave和DreamPop風格,於空靈遼遠而又充滿律動的音色中塑造了音樂的空間感,聽者得以實現精神漫遊和共振。

#97 AI小遊戲樓 » 2026-03-23 07:07:05

回应:

要不要試試開一個 GitHub Pages?這樣就能直接在線玩了

這東西挺適合這種純前端小遊戲的,不用自己搭服務器,也不需要額外配置環境,把代碼丟上去就能跑。
而且免費,自帶版本管理,後續更新也很方便,改完代碼再 push 一下就更新了。

我之前和別人一起做過一個詭法棋遊戲,前陣子翻出來順手改成了棋譜網站,也放在 GitHub Pages 上了:https://shiningdracon.github.io/guifa/


有 1 位朋友喜欢这篇文章:龍爪翻書

#98 AI小遊戲樓 » 2026-03-21 19:47:16

回应:

翻牌配對遊戲






<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>奇幻 ANSI 翻牌配對遊戲</title>
  <style>
    :root {
      --bg: #0a0f0a;
      --panel: #101810;
      --border: #33ff66;
      --text: #b7ffbf;
      --dim: #6fcf7f;
      --accent: #00ffaa;
      --warn: #ffee55;
      --match: #66ff99;
      --danger: #ff6688;
      --shadow: rgba(0, 255, 120, 0.18);
    }

    * {
      box-sizing: border-box;
    }

    body {
      margin: 0;
      min-height: 100vh;
      background:
        radial-gradient(circle at top, #112211 0%, #081008 45%, #040804 100%);
      color: var(--text);
      font-family: "Courier New", Consolas, monospace;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 24px;
    }

    .game-shell {
      width: min(920px, 100%);
      background: var(--panel);
      border: 3px solid var(--border);
      box-shadow:
        0 0 20px var(--shadow),
        inset 0 0 12px rgba(0,255,120,0.08);
      padding: 20px;
      border-radius: 10px;
    }

    .title {
      white-space: pre-wrap;
      line-height: 1.1;
      color: var(--accent);
      font-size: 14px;
      margin: 0 0 14px 0;
      text-shadow: 0 0 6px rgba(0,255,180,0.35);
    }

    .hud {
      display: flex;
      gap: 12px;
      flex-wrap: wrap;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
    }

    .stats {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
    }

    .stat-box {
      border: 2px solid var(--border);
      padding: 8px 12px;
      min-width: 120px;
      background: rgba(0, 40, 0, 0.45);
      box-shadow: inset 0 0 8px rgba(0,255,100,0.08);
    }

    .stat-label {
      color: var(--dim);
      font-size: 12px;
      margin-bottom: 4px;
    }

    .stat-value {
      color: var(--warn);
      font-weight: bold;
      font-size: 20px;
    }

    button {
      background: #081108;
      color: var(--text);
      border: 2px solid var(--border);
      padding: 10px 16px;
      font-family: inherit;
      font-size: 15px;
      cursor: pointer;
      border-radius: 6px;
      transition: 0.15s ease;
      box-shadow: 0 0 10px rgba(0,255,120,0.08);
    }

    button:hover {
      background: #102010;
      color: #ffffff;
      transform: translateY(-1px);
    }

    .message {
      min-height: 28px;
      margin-bottom: 14px;
      color: var(--accent);
      font-size: 15px;
    }

    .board {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 12px;
    }

    .card {
      aspect-ratio: 3 / 4;
      perspective: 1000px;
      cursor: pointer;
    }

    .card-inner {
      position: relative;
      width: 100%;
      height: 100%;
      transition: transform 0.45s ease;
      transform-style: preserve-3d;
    }

    .card.flipped .card-inner,
    .card.matched .card-inner {
      transform: rotateY(180deg);
    }

    .card-face {
      position: absolute;
      inset: 0;
      border: 2px solid var(--border);
      border-radius: 8px;
      backface-visibility: hidden;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 10px;
      overflow: hidden;
      box-shadow:
        inset 0 0 12px rgba(0,255,120,0.08),
        0 0 10px rgba(0,255,120,0.08);
    }

    .card-back {
      background:
        linear-gradient(135deg, rgba(0,255,120,0.07), rgba(0,255,255,0.03)),
        #071007;
      color: var(--accent);
      font-size: 16px;
      text-align: center;
      white-space: pre-wrap;
    }

    .card-front {
      background:
        linear-gradient(180deg, rgba(30,50,30,0.7), rgba(8,16,8,0.95)),
        #0b140b;
      transform: rotateY(180deg);
      color: var(--text);
    }

    .ansi-art {
      white-space: pre;
      line-height: 1.02;
      font-size: clamp(8px, 1.1vw, 12px);
      text-align: left;
      user-select: none;
      text-shadow: 0 0 4px rgba(0,255,120,0.18);
    }

    .card.matched .card-face {
      border-color: var(--match);
      box-shadow:
        inset 0 0 14px rgba(120,255,160,0.12),
        0 0 14px rgba(120,255,160,0.22);
    }

    .footer {
      margin-top: 14px;
      color: var(--dim);
      font-size: 13px;
      line-height: 1.6;
    }

    .blink {
      animation: blink 1s step-start infinite;
    }

    @keyframes blink {
      50% { opacity: 0.2; }
    }

    @media (max-width: 700px) {
      .board {
        grid-template-columns: repeat(4, 1fr);
        gap: 8px;
      }

      .game-shell {
        padding: 14px;
      }

      .title {
        font-size: 11px;
      }

      .stat-box {
        min-width: 96px;
      }
    }
  </style>
</head>
<body>
  <div class="game-shell">
    <pre class="title">
╔══════════════════════════════════════════════╗
║   FANTASY ANSI MEMORY MATCH : DRAGON QUEST  ║
╚══════════════════════════════════════════════╝
    </pre>

    <div class="hud">
      <div class="stats">
        <div class="stat-box">
          <div class="stat-label">TIME</div>
          <div class="stat-value" id="timer">0 秒</div>
        </div>
        <div class="stat-box">
          <div class="stat-label">MATCHED</div>
          <div class="stat-value" id="matchedCount">0 / 8</div>
        </div>
        <div class="stat-box">
          <div class="stat-label">TURNS</div>
          <div class="stat-value" id="turnCount">0</div>
        </div>
      </div>
      <button id="restartBtn">重新開始</button>
    </div>

    <div class="message" id="message">請翻開兩張牌,找出相同的奇幻角色。</div>

    <div class="board" id="board"></div>

    <div class="footer">
      操作方式:用滑鼠點擊卡牌翻面。<span class="blink">█</span><br>
      主題:奇幻世界、Dragon、ANSI 復古終端機風格
    </div>
  </div>

  <script>
    const cardDesigns = [
      {
        name: "DRAGON",
        art: String.raw`
   /\_/\ 
  / o o \
 (   "   )__
 /| ___ |\  \
/_|/   \|_\_/
   /^^^\    
  /_/ \_\   
 DRAGON     
`
      },
      {
        name: "WIZARD",
        art: String.raw`
    /\
   /__\
   \  /
   /==\
  /====\
     ||
   \_==_/
    /  \
  WIZARD
`
      },
      {
        name: "KNIGHT",
        art: String.raw`
    O
   /|\
   / \
  |=+=|
  |===|
  |===|
   / \
  /___\
  KNIGHT
`
      },
      {
        name: "SLIME",
        art: String.raw`
   ______
  /      \
 /  o  o  \
|    --    |
 \  ____  /
  \______/
   SLIME
`
      },
      {
        name: "CHEST",
        art: String.raw`
  __________
 /_________/|
 |  _   _ | |
 | | | | || |
 | |_| |_|| |
 |  ___   | /
 |_/___\__|/
   CHEST
`
      },
      {
        name: "PHOENIX",
        art: String.raw`
   \  |  /
    \ | /
  ---\|/---
    /^^\
   /_/\_\
   / || \
  /  ||  \
  PHOENIX
`
      },
      {
        name: "SWORD",
        art: String.raw`
     /\
     ||
     ||
     ||
     ||
   ==||==
     ||
     ||
    /__\
    SWORD
`
      },
      {
        name: "CASTLE",
        art: String.raw`
  |>>>  <<<|
  |[]|  |[]|
  |  |__|  |
 _|  ____  |_
| | |    | | |
|_|_|____|_|_|
   CASTLE
`
      }
    ];

    const board = document.getElementById("board");
    const timerEl = document.getElementById("timer");
    const matchedCountEl = document.getElementById("matchedCount");
    const turnCountEl = document.getElementById("turnCount");
    const messageEl = document.getElementById("message");
    const restartBtn = document.getElementById("restartBtn");

    let cards = [];
    let firstCard = null;
    let secondCard = null;
    let lockBoard = false;
    let matchedPairs = 0;
    let turns = 0;
    let seconds = 0;
    let timer = null;
    let started = false;

    function shuffle(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
      return array;
    }

    function startTimer() {
      if (timer) return;
      timer = setInterval(() => {
        seconds++;
        timerEl.textContent = `${seconds} 秒`;
      }, 1000);
    }

    function stopTimer() {
      clearInterval(timer);
      timer = null;
    }

    function updateStats() {
      matchedCountEl.textContent = `${matchedPairs} / 8`;
      turnCountEl.textContent = turns;
    }

    function setMessage(text, color = "var(--accent)") {
      messageEl.textContent = text;
      messageEl.style.color = color;
    }

    function createCardElement(cardData, index) {
      const card = document.createElement("div");
      card.className = "card";
      card.dataset.name = cardData.name;
      card.dataset.index = index;

      card.innerHTML = `
        <div class="card-inner">
          <div class="card-face card-back">
<pre class="ansi-art">+--------+
| ###### |
| ##??## |
| ###### |
| FANTSY |
+--------+</pre>
          </div>
          <div class="card-face card-front">
<pre class="ansi-art">${cardData.art}</pre>
          </div>
        </div>
      `;

      card.addEventListener("click", onCardClick);
      return card;
    }

    function buildBoard() {
      board.innerHTML = "";
      const doubled = [...cardDesigns, ...cardDesigns].map((c, i) => ({
        ...c,
        uid: i + "-" + Math.random().toString(16).slice(2)
      }));

      cards = shuffle(doubled);

      cards.forEach((cardData, index) => {
        const el = createCardElement(cardData, index);
        board.appendChild(el);
      });
    }

    function resetTurnState() {
      firstCard = null;
      secondCard = null;
      lockBoard = false;
    }

    function onCardClick(e) {
      const clicked = e.currentTarget;

      if (lockBoard) return;
      if (clicked === firstCard) return;
      if (clicked.classList.contains("flipped")) return;
      if (clicked.classList.contains("matched")) return;

      if (!started) {
        started = true;
        startTimer();
      }

      clicked.classList.add("flipped");

      if (!firstCard) {
        firstCard = clicked;
        setMessage("已翻開第 1 張牌…");
        return;
      }

      secondCard = clicked;
      lockBoard = true;
      turns++;
      updateStats();

      const isMatch = firstCard.dataset.name === secondCard.dataset.name;

      if (isMatch) {
        firstCard.classList.add("matched");
        secondCard.classList.add("matched");
        matchedPairs++;
        updateStats();

        if (matchedPairs === 8) {
          stopTimer();
          setMessage(`恭喜完成!總共 ${seconds} 秒,翻牌 ${turns} 次。`, "var(--match)");
        } else {
          setMessage(`配對成功:${firstCard.dataset.name}`, "var(--match)");
        }

        resetTurnState();
      } else {
        setMessage("沒有配對成功,再試一次。", "var(--danger)");
        setTimeout(() => {
          firstCard.classList.remove("flipped");
          secondCard.classList.remove("flipped");
          resetTurnState();
        }, 850);
      }
    }

    function resetGame() {
      stopTimer();
      firstCard = null;
      secondCard = null;
      lockBoard = false;
      matchedPairs = 0;
      turns = 0;
      seconds = 0;
      started = false;

      timerEl.textContent = "0 秒";
      updateStats();
      setMessage("請翻開兩張牌,找出相同的奇幻角色。");
      buildBoard();
    }

    restartBtn.addEventListener("click", resetGame);

    resetGame();
  </script>
</body>
</html>

#99 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-21 18:03:11

回应:

[↑] @Sherixs 寫道: 在野外中毒,你都不一定搞得明白是因爲什麼中毒,也不知道應該找什麼東西解毒 [靈感] …

對方也不知道什麼東西對龍有毒且無法被龍察覺。相比之下,你對自己的瞭解,遠比無尾對你的瞭解要多。

#100 中世紀的無尾如何與一條聰明的龍戰鬥 » 2026-03-21 17:42:36

回应:

[↑] @shiningdracon 寫道: 氪石是吧在龍認知之內的,龍會有所防範。在龍認知之外的,以中世紀的技術條件很難造出來。 …

在野外中毒,你都不一定搞得明白是因爲什麼中毒,也不知道應該找什麼東西解毒 [靈感]

最后修改: Sherixs (2026-03-21 17:43:05)

论坛页尾

Powered by jQuery blueimp FluxBB