Talk:希顶模组

此后如竟没有炬火,我便是唯一的光。
QWERTY 52 38在话题“符文水晶制造物品”中的最新留言:昨天23:57

符文水晶制造物品

符文水晶由符文石和紫水晶合成。

我们可以投入一个符文水晶序列,暂定序列长度为3,每个序列对应一个可由制造器生产的物品。在已定义序列外的所有序列对应一个废熔块(clinker )。

我们投入完一个序列(也可以可选打开gui,把当前可合成的方块显示在左侧,类似于工作台,单击后填充到序列框中,如果按shift自动填充完一组)后会显示当前对应的物品,同时显示这个物品当前的价值,价值就是我们需要投入多少组符文水晶序列。这时我们可以按shift自动填充完成一组。

按下确认键后,我们得到产物,同时更新价值和污染。

序列安排规则:第一位代表分类,第二位代表语义倾向,第三位代表比较任意的修正(参考联觉)。

  • 孢子花是  植物 - 挂在上面 - 产生像土一样的碎屑
  • 海绵是  软状物 - 和水有关 - 可以把水干燥

技术地

数据结构

1.污染表: 实际上需要计算污染值的是游戏里已经加载的区块,单独记录在一张表里(保存在世界文件,而不是区块文件),未加载区块就作为边界条件(不需要存储,执行扩散的时候考虑到就可以了)。

可以考虑保存到一个字典。

2.制造器: 制造器是方块,其方块实体里保存其制造过的物品的能量值(字典,映射物品ID和能量值)。

能量值实际上和制造器方块绑定,每个制造器里储存这个制造器里历史上制造过的物品(不需要记录全部物品,这样可以节省空间)。当能量值落回本底值后可以清除这个物品对应的能量值字典元素,以节省空间。

3.游戏参数: 下面的数据保存在模组配置文件json里

  • 本底污染值(bP):16,确保污染值不会降到更低的水平。
  • 本底能量值(bE):16,制造器能量的上限。
  • 净化速度(pP)和(pE):定义每个游戏刻(tick)减去的污染和增加的能量。
  • 扩散速度(pD):定义污染进一步扩散到相邻区块的速度。
  • 物品价格表: 存储各类物品的基础价值,以便根据物品类型等属性查找价格。
  • 物品序列对应表。

游戏机制

1.制造物品过程 通过物品ID从物品价格表中查找该物品的基础价值, 计算当前需要消耗的价值。

  • 价值 = floor(P/E)*基础价值

根据所在区块的污染值及当前能量值更新该区块的污染,并更新制造器该物品的能量值。

  • P += 消耗的符文水晶数(实际上是价值*3)
  • E = P_old*E/P

如果物品制造成功,则记录该物品及其能量在制造器的历史中。

2.污染扩散过程 每隔n刻执行一遍下面的操作:

  • 遍历污染表,求当前区块和四个邻域区块(权=扩散速度(pD))的加权平均值,更新为新值,注意考虑未加载区块的边界条件。

3.净化过程 每隔n刻执行一遍下面的操作:

  • 遍历污染表,利用净化速度(pP)逐渐降低每个区块的污染,实现对本底污染值(bP)的约束。

4.能量补充 每隔n刻执行一遍下面的操作:

  • 遍历当前强加载区块下的制造器方块实体,利用净化速度(pE)来增加能量值,确保每个制造器的能量值不超过本底能量值(bE)。

python demo

import math
import tkinter as tk

bP, bE = 16, 16  # 本底污染和能量
P = [[bP for _ in range(10)] for _ in range(10)]  # 污染地图
E = [[1, 1, bE], [5, 5, bE], [3, 3, bE]]  # 制造器的坐标和能量
pP, pE = 0.1, 0.06  # 净化速度
pD = 0.5  # 扩散速度
current_iteration = 0  # 当前迭代计数

def make(index):  # 一次制造过程
    global P, E
    price = getPrice(index)
    xy = (E[index][0], E[index][1])

    cP = P[xy[0]][xy[1]]
    cE = E[index][2]
    
    make_info = f"迭代: {current_iteration}, 点({xy[0]}, {xy[1]}) 污染: {cP:.2f}, 能量: {cE:.2f}, 价值: {price}"

    if(price<=256):
        _P = P[xy[0]][xy[1]]
        P[xy[0]][xy[1]] += price
        if P[xy[0]][xy[1]] > 0:
            E[index][2] = _P * E[index][2] / P[xy[0]][xy[1]]
        
    return make_info

def getPrice(index):
    xy = (E[index][0], E[index][1])
    return max(math.floor(P[xy[0]][xy[1]] / E[index][2]), 0) * 3

def purify(dtime=1):  # 净化污染和能量
    global P, E
    for x in range(len(P)):
        for y in range(len(P[x])):
            P[x][y] = max(P[x][y] - dtime * pP, bP)  # 确保不低于bP
    
    for e in E:
        e[2] = min(e[2] + dtime * pE, bE)

def diff(dtime=1):  # 污染扩散
    global P
    new_P = [row[:] for row in P]
    for x in range(10):
        for y in range(10):
            x1, x2 = max(x-1, 0), min(x+1, 9)
            y1, y2 = max(y-1, 0), min(y+1, 9)
            new_P[x][y] = (P[x][y] +
                           P[x1][y] * pD +
                           P[x2][y] * pD +
                           P[x][y1] * pD +
                           P[x][y2] * pD) / (1 + 4 * pD)

    P[:] = new_P  

def update_display(window, make_info):  # 在tk窗口中显示污染和能量
    for widget in window.winfo_children():
        widget.destroy()  # 清空窗口内容

    pollution_label = tk.Label(window, text="污染:")
    pollution_label.pack()

    # 绘制灰度图
    canvas = tk.Canvas(window, width=200, height=200)
    canvas.pack()

    # 渲染灰度值,min 固定为 0,max 固定为 255
    for x in range(10):
        for y in range(10):
            # 计算灰度值
            # 这里将污染值归一化到 [0, 255]
            gray_value = int(255-min(255, max(0, P[x][y])))  # 污染值范围限制在0到255之间
            color = f'#{gray_value:02x}{gray_value:02x}{gray_value:02x}'  # 转换为颜色格式
            canvas.create_rectangle(y * 20, x * 20, (y + 1) * 20, (x + 1) * 20, fill=color, outline='')  # 绘制方块

    energy_text = "能量:\n" + "\n".join([f"点({e[0]}, {e[1]}): {e[2]:.2f}" for e in E])
    energy_label = tk.Label(window, text=energy_text)
    energy_label.pack()

    # 添加当前迭代数的标签
    iteration_label = tk.Label(window, text=f"当前迭代数: {current_iteration}")
    iteration_label.pack()

    make_label = tk.Label(window, text=make_info)
    make_label.pack()

def run_simulation_step(window):  
    global current_iteration
    if current_iteration >= 1000:
        return  

    diff()  # 先扩散
    purify()  # 后净化
    
    make_info = ""   
    if current_iteration in range(30, 1000):
        make_info += make(1) + "\n"
    if current_iteration in range(0, 1000):
        make_info += make(0) + "\n"   

    update_display(window, make_info)  # 更新窗口内容
    current_iteration += 1

def on_key_press(event):  # 处理按键事件
    run_simulation_step(root)  # 用户按键时执行下一步

root = tk.Tk()
root.title("污染和能量模拟")

root.bind("<Key>", on_key_press)  # 绑定按键事件

# 启动主事件循环
root.mainloop()

雨音浅夏留言2025年1月16日 (四) 05:06 (CST)回复

以上内容已加入开发计划。预计会在完成新的开凿符文石机制完成之后着手处理。--QWERTY_52_38 讨论 贡献 2025年1月23日 (四) 23:57 (CST)回复