下边写的多叉树图谱物品合成有问题吗?各位大佬看看哪里有问题
using System.Collections.Generic;
namespace Test
{
public class MaterialData
{
public ItemData item; //合成所需的物品
public int count; //合成所需的该物品的数量
}
public class ItemData
{
public int id; //物品 ID
public int count; //当前拥有的物品数量
public int costGold; //合成该物品所需的金币
public List<MaterialData> materialList; //合成该物品所需的材料
}
public class Exam
{
private static Exam instance = new Exam();
public static Exam Instance
{
get
{
return instance;
}
set
{
value = instance;
}
}
/// <summary>
/// 计算用 totalGold 金币最多可以合成的 item 装备的数量
/// </summary>
/// <param name="item">要合成的装备</param>
/// <param name="totalGold">拥有的金币</param>
/// <returns>可合成的 item 装备的最大数量</returns>
public int Run(ItemData item, int totalGold)
{
//因为有当前拥有物品数量的限制,首先根据又有的物品数量求出,当前最多可以合成多少个所需物品
//且MaterialData里持有ItemData,ItemData持有MaterialData,所以使用递归来完成当前拥有的物品数量
//Todo 递归获取到数量
int Count = GetMaxCount(item);
//获取到最多能合成的物品数量后,在来计算合成一个该物品所需要的金币
int singlePrice = GetSinglePrice(item);
//获取到合成所需的价格之后,使用总的金币数量来计算,最多能合成几个该物品
int num = GetMaxNumByPrice(singlePrice, totalGold);
//计算完当前金币所能合成的物品数量后,需要跟当前库存里最多能生成物品数量做比较,得到最终能够合成物品的最大数量
int maxNum = GetMaxNum(Count, num);
return maxNum;
}
/// <summary>
/// 获取该物品库存数量
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int GetMaxCount(ItemData item)
{
//首先要获取物体合成的所需材料的数量即,materialList的数量,根据合成所需的材料的数量,来判断当前能合成多少物品
//如果当前合成的物品不需要合成材料,就直接返回当前所拥有的物品的数量
if (item.materialList.Count == 0) return item.count;
//如果所需要的合成材料的数量不等于0,则说明该物品有一个或一个以上的合成材料
//此时需要遍历所需材料列表来确认合成的数量
int materialNum, canSynthesisNum = 0;
foreach (var material in item.materialList)
{
//因为materialList里有ItemData,所以要获取到ItemData的数量
materialNum = GetMaxCount(material.item);
//计算出ItemData的数量后,除去合成材料所需要的ItemData的数量,就能计算出Material的数量
canSynthesisNum = materialNum / material.count;
}
return canSynthesisNum;
}
/// <summary>
/// 获取单个物品消耗金币
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int GetSinglePrice(ItemData item)
{
//计算单个物体的价格时,首先去判断所需材料列表有没有物体,没有物体就直接返回该物体的单价costGold
if (item.materialList.Count == 0) return item.costGold;
//如果有合成材料,计算合成物品价格时需要将合成材料所消耗的金币也计算进去,所以还是需要计算,能够合成物体的数量
//因为ItemData和materiallist有相互依赖,对materiallist进行遍历,遍历期间递归计算每一个合成材料所需要的金币
int materialPrice = 0;
foreach (var material in item.materialList)
{
//此处合成所需材料,数量可能是多个,所以此处还要乘上合成数量
materialPrice += GetSinglePrice(material.item) * material.count;
}
//程序运行到此处时,合成物体所需材料消耗的金币就计算完成,但是合成物体时也要花费金币,此处将合成物体消耗金币相加即可
materialPrice += item.costGold;
return materialPrice;
}
/// <summary>
/// 通过当前金币获取能够购买的物品数量,不考虑库存的问题
/// </summary>
/// <param name="price">物品单价</param>
/// <param name="totalGold">总金币</param>
/// <returns></returns>
public int GetMaxNumByPrice(int price, int totalGold)
{
//此处还需要判断是否满足购买条件,即总金币大于0,或者物品单价要低于总金币才能购买
if (totalGold <= 0 || price > totalGold) return 0;
return totalGold / price;
}
/// <summary>
/// 获取最大合成物品数量
/// </summary>
/// <param name="count">库存数量</param>
/// <param name="num">所持金币最大合成数量</param>
/// <returns></returns>
public int GetMaxNum(int count, int num)
{
return count <= num ? count : num;
}
}
}
using System;
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
ItemData A = new ItemData()
{
id = 1,
count = 2,
costGold = 10,
materialList = new List<MaterialData>()
};
ItemData B = new ItemData()
{
id = 2,
count = 10,
costGold = 20,
materialList = new List<MaterialData>()
};
MaterialData C = new MaterialData
{
item = new ItemData
{
id = 1,
count = 10,
costGold = 10,
materialList = new List<MaterialData>()
},
count = 2
};
B.materialList.Add(C);
int result = Exam.Instance.Run(B, 100);
Console.WriteLine(result);
Console.ReadLine();
}
}
}