跳到主要内容

合成规则:让结果可计算、可复现

先暂时忘掉苹果图片。棋盘只是一组整数:0 表示空格,正数表示物品等级。一次操作输入两个格子编号,输出是否成功和升级后的等级。

只要相同输入能得到相同结果,你就可以在没有 Unity 画面的情况下检查规则。

独立纯 C# 示例​

下面代码不依赖 Unity API,可放入普通 C# 工程检查,也可作为 Unity 项目的规则类。它只演示同级合成;固定奖励 10 分,不包含生成物品、移动空格或撤销。

using System;

public sealed class MergeBoard
{
private readonly int[] cells;
private readonly int maxLevel;
public long Score { get; private set; }
public int CellCount => cells.Length;

public MergeBoard(int[] initialCells, int maxLevel)
{
if (initialCells == null || initialCells.Length == 0)
throw new ArgumentException("需要非空棋盘");
if (maxLevel < 1)
throw new ArgumentOutOfRangeException(nameof(maxLevel));
foreach (int level in initialCells)
if (level < 0 || level > maxLevel)
throw new ArgumentException("棋盘中存在非法等级");
cells = (int[])initialCells.Clone();
this.maxLevel = maxLevel;
}

public int GetLevel(int index) => cells[index];
public int[] CopyCells() => (int[])cells.Clone();

public bool TryMerge(int source, int target, out int newLevel)
{
newLevel = 0;
if (source < 0 || source >= cells.Length ||
target < 0 || target >= cells.Length || source == target)
return false;

int level = cells[source];
if (level == 0 || level != cells[target] || level >= maxLevel)
return false;

// 在写状态前计算可能失败的值,避免只改了一半。
long nextScore = checked(Score + 10);
newLevel = level + 1;
cells[source] = 0;
cells[target] = newLevel;
Score = nextScore;
return true;
}
}

构造时复制数组,避免外部代码直接改动内部状态。正常无效操作返回 false,棋盘不变;分数极端溢出会在状态写入前抛错。GetLevel 是读取接口,调用方应提供合法索引,错误索引会抛异常。

这份代码没有存档恢复入口。增加恢复时,应在独立工厂或明确构造入口验证分数与格式,不能从外部任意写 Score。

用具体结果验收​

初始状态操作结果
[1,1,0,0]0 → 1[0,2,0,0],加 10 分
[1,2,0,0]0 → 1拒绝,完全不变
[0,1,0,0]0 → 1拒绝,完全不变
[1,0,0,0]0 → 0拒绝,同格不能合成
[最高级,最高级]0 → 1拒绝,不越过等级上限
任意合法棋盘越界编号拒绝,不改变分数

还要对成功后的同一源目标重复调用一次:源格已空,不应再次加分。这说明状态本身能阻止一类重复处理;跨网络的请求重试仍需要服务端幂等机制。

规则确定后,才连接表现​

如果先删除源物品,再检查目标是否合法,就可能出现半完成状态。和后端事务一样,先校验,提前完成可能失败的计算,再集中提交。

让 AI 增加功能时守住什么​

如果要加“移动到空格”,请它新增明确的命令结果,而不是让“合成失败”顺手变成移动。如果要加撤销,先定义完整快照还是操作日志,并说明广告奖励是否可撤销。

请基于上述规则增加测试用例,重点覆盖状态不变、等级边界、重复调用和数组所有权。不要把动画或 GameObject 引入规则类。

下一站:输入、显示与反馈怎样连接。