装备合成系统(最大限度地合成目标装备)

题目

下图是一个装备系统的合成图谱,箭头指向的是合成之后的装备,每合成一个装备需要消耗一些金币(标注在矩形框里面),箭头上的数字表示合成所需的材料数量。比如,要合成n个装备A,需要消耗3n个装备B、1n个装备C、4n个装备D,而且还需要消耗26n金币(装备B和装备D的合成与此类似)。
为了简单起见,下面题目的装备图谱都是一棵多叉树,而且玩家最初只拥有指定数量的叶子节点的装备,也就是图中的装备C、装备E、装备F和装备G。
注意,下面的图谱只是一个例子,作答的时候不要局限于这个图谱。

在这里插入图片描述
已知玩家拥有一些初级装备(叶子节点的装备)和n个金币,并且所有装备的合成都需要消耗金币,玩家需要合成尽可能多的某个装备(记为装备X),请用C#语言计算出玩家最多可以合成出多少个装备X。

为了规范输入输出,下面给出代码的基本结构,作答的时候不要修改Run函数的函数原型。

public class Exam
{
public class MaterialData
{
public ItemData item; //合成所需的物品
public int count; //合成所需的该物品的数量
}

public class ItemData
{
public int id; //物品 ID
public int count;//当前拥有的物品数量
public int costGold;//合成该物品所需的金币
public List materialList; //合成该物品所需的材料
}

///
/// 计算用 totalGold 金币最多可以合成的 item 装备的数量
///
/// 要合成的装备
/// 拥有的金币
/// 可合成的 item 装备的最大数量
public int Run(ItemData item, int totalGold)
{
return 0;
}
}

刚开始做这题的时候因为作答时间断断续续的,然后逻辑也断断续续的,写了一个demo就测试一下,今天下午再做测试时发现问题很大,然后做出了修改。

下面开始作答

Get题目的重点:
1.图谱只是一个例子,作答的时候不要局限于这个图谱。(说明装备和子材料的基础属性都是未知的,抽象的,其中materialList处可无限套娃)

2.作答的时候不要修改Run函数的函数原型

3.根据题目要求可知:将随意给Run()传入金币和ItemData即物品的id、当前数量、合成一个所需的金币、合成该物品所需的材料列表,返回合成后的目标装备数量。

解题逻辑:先把所有材料遍历存储,再把原有的子材料合成目标装备,然后逐个合成目标装备,每个的合成操作都是消耗金币和材料的,金币或材料不足时停止合成,输出结果。

代码实现

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleRun
{
    class Program
    {
        public class Exam
        {
            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; //合成该物品所需的材料
            }

            /// <summary>
            /// 计算用 totalGold 金币最多可以合成的 item 装备的数量
            /// </summary>
            /// <param name="item">要合成的装备</param>
            /// <param name="totalGold">拥有的金币</param>
            /// <returns>可合成的 item 装备的最大数量</returns>
            public int Run(ItemData item, int totalGold)
            {
                Gold = totalGold;//存储金币
                Material(item);//开始遍历材料
                while (SubMaterial(item) == true) ;//合成装备
                return item.count;//返回结果
            }
            Dictionary<int, ItemData> MaterialDic = new Dictionary<int, ItemData>();//存储材料,Key为存放所需的材料ID
            int Gold;//拥有的金币
            /// <summary>
            /// 程序入口
            /// </summary>
            /// <param name="args"></param>
            static void Main(string[] args)
            {
                //目标装备
                MaterialData materialData2 = new MaterialData { };//合成目标装备所需材料id为2的数据
                MaterialData materialData3 = new MaterialData { };//合成目标装备所需材料id为3的数据
                ItemData Dt = new ItemData { };//需要合成的装备
                List<MaterialData> materialList = new List<MaterialData>();//目标装备的合成所需材料列表
                List<MaterialData> materialList2 = new List<MaterialData>();//材料id为2的合成所需材料列表
                List<MaterialData> materialList3 = new List<MaterialData>();//材料id为3的合成所需材料列表
                //初始化装备的信息
                Dt.id = 1;
                Dt.costGold = 10;
                Dt.materialList = materialList;
                //合成目标装备所需的材料
                materialData2.count = 2;
                materialData2.item = new ItemData { };
                materialData2.item.id = 2;
                materialData2.item.count = 10;
                materialData2.item.costGold = 6;
                materialData2.item.materialList = materialList2;
                materialList.Add(materialData2);//合成目标装备需要材料2

                materialData3.count = 3;
                materialData3.item = new ItemData { };
                materialData3.item.id = 3;
                materialData3.item.count = 33;
                materialData3.item.costGold = 6;
                materialData3.item.materialList = materialList3;
                materialList.Add(materialData3);//合成目标装备需要材料3
                materialList2.Add(materialData3);//合成材料2也是需要材料3
                Exam exam = new Exam();
                int count = exam.Run(Dt, 72);//合成装备
                Console.WriteLine("您最终合成了{0}个装备!", count);
                Console.ReadKey();
            }
            /// <summary>
            /// 遍历存储所有材料
            /// </summary>
            public void Material(ItemData item)
            {
                foreach (var i in item.materialList)
                {
                    //存储材料
                    MaterialDic[i.item.id] = i.item;
                    //当materialList不为空时,说明当前材料还有其他子材料,故继续遍历存储
                    if (!i.item.materialList.Any())
                    {
                        Material(i.item);//继续遍历存储
                    }
                }
            }
            /// <summary>
            /// 逐个合成,当金币或材料不足返回停止合成
            /// </summary>
            public bool SubMaterial(ItemData item)
            {
                //遍历合成所需的材料表
                foreach (var i in item.materialList)
                {
                    //当前材料数量少于合成所需数量时,合成材料
                    if (MaterialDic[i.item.id].count < i.count)
                    {
                        //判读该材料有无所需合成材料的列表
                        if (i.item.materialList.Any())
                        {
                            //进行多次合成,直到材料足够合成一个上级材料
                            for (int j = i.item.count; j < i.count; j++)
                            {
                                SubMaterial(i.item);
                            }
                        }
                        else
                        {
                            //当前材料不可被合成
                            return false;
                        }
                        //该材料拥有的数量还小于需求数量,返回
                        if (i.item.count < i.count)
                        {
                            return false;
                        }
                    }
                }
                //当前材料满足合成上级装备,消耗材料和金币
                if (Gold >= item.costGold)
                {
                    foreach (var i in item.materialList)
                    {
                        i.item.count -= i.count;
                        //当消耗需求表的最后一个材料时,消耗金币,上级材料的数量+1
                        if (i == item.materialList.Last())
                        {
                            Gold -= item.costGold;
                            item.count += 1;
                        }
                    }
                }
                else
                {
                    //金币不足
                    return false;
                }
                return true;//合成了一个材料或装备
            }
        }
    }
}

测试
我在初始化的代码中设
合成目标装备:需要10金币,id为2的材料2个,id为3的材料3个
合成id为2的材料需要金币6个;id为3的材料为3个
当前拥有:金币72,id为2的材料10个,id为3的材料33个
在这里插入图片描述
当把金币设为100时
得到的结果:id为2的材料剩余0,id为3的材料剩余0,金币剩余6.
在这里插入图片描述
当把金币设为233时
得到的结果:id为2的材料剩余0,id为3的材料剩余0,金币剩余139.
结果还是合成7个装备

还有对材料数量等更改的测试也没有发现bug哦,这里就不一一举例了。
在这里插入图片描述

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Unity中使用UGUI实现装备合成树的步骤如下: 1. 设计装备合成树的结构:装备合成树是一个有层级关系的树形结构,每个节点代表一个装备,节点之间通过合成关系连接。可以使用脚本或者数据结构来定义装备节点和合成关系。 2. 创建UI界面:在Unity中创建一个Canvas对象,并添加需要的UI元素,比如按钮、文本等,用来显示装备合成树。 3. 绘制节点:使用UGUI提供的Button或者Image等UI组件,绘制每个装备节点的图标,并设置对应的合成信息和按钮事件等。 4. 布局节点:根据装备合成树的结构,将装备节点按照层级和位置进行布局,可以使用UGUI中的Layout组件来实现自动布局。 5. 添加交互:为每个装备节点的按钮添加事件监听,当点击某个装备节点时,根据节点的合成信息刷新树的显示内容,比如显示合成材料和合成结果等。 6. 更新合成树:当成功合成某个装备后,需要更新装备合成树的结构和显示内容,可以使用脚本来实现树的动态更新。 7. 状态管理:根据游戏逻辑和玩家行为,需要考虑装备合成树节点的状态管理,比如显示已拥有的装备节点和未解锁的装备节点等。 8. 界面优化:为了提升用户体验,可以考虑添加特效、动画和过渡效果等,使装备合成树的界面更加活跃和吸引人。 通过上述步骤,在Unity中使用UGUI可以实现一个功能完善的装备合成树界面,为玩家提供更好的游戏体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值