EasyCastleUNITY

JSON 파일을 통한 데이터 읽기 및 대리자 복습 본문

C#프로그래밍

JSON 파일을 통한 데이터 읽기 및 대리자 복습

EasyCastleT 2023. 7. 29. 21:54

item_data. xlsx
monster._data. xlsx
hero_data.xlsx
프로그램 흐름 이러한 순서로 작성함

-------------------------------------------------------------------------------

정보들을 저장하는 클래스 

ItemData 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class ItemData
    {
        public int id;
        public string name;
        public int damage;
    }
}

HeroData

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class HeroData
    {
        public int id;
        public string name;
        public int damage;
        public int maxHp;
        
    }
}

MonsterData

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class MonsterData
    {
        public int id;
        public string name;
        public int item_id;
        public int maxHp;
        public int damage;
    }
}

---------------------------------------------------------------------------------------------------------------------

변하는 정보 저장하는 클래스

ItemInfo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class ItemInfo
    {
        //저장 객체,변화하는 정보 저장 

        //멤버
        public int id;
        public int damage;
        //생성자 
        public ItemInfo(int id, int damage)
        {
            this.id = id;
            this.damage = damage;
        }
    }
}

HeroInfo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class HeroInfo
    {
        //멤버
        public int id;
        public int damage;
        //생성자 
        public HeroInfo(int id, int damage)
        {
            this.id = id;
            this.damage = damage;
        }
    }
}

MonsterInfo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class MonsterInfo
    {
        //저장 객체, 변화하는 정보 저장 

        public int id;
        public int item_id;
        public int damage;

        public MonsterInfo(int id,int item_id, int damage)
        {
            this.id = id;
            this.item_id = item_id;
            this.damage = damage;
        }
    }
}

-----------------------------------------------------------------------------------------------------------------------

객체를 생성하는 클래스 

Item

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class Item
    {
        private ItemInfo info;
        //속성 info 정보의 없는 이름을 받아옴
        public string Name
        {
            get { ItemData data = DataManager.instance.GetItemData(info.id);
                return data.name;
            }
        }
        //생성자
        public Item(ItemInfo info)
        {
            this.info = info;
            Console.WriteLine("{0} 생성, 공격력:{1}",this.Name,this.info.damage);
        }

        public ItemInfo GetItemInfo()
        {
            return this.info;
        }

        public int GetItemId()
        {
            return this.info.id;
        }

        public int GetItemDamage()
        {
            return this.info.damage;
        }
    }
}

Hero

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class Hero
    {
        HeroInfo info;
        HeroData data;
        private int maxHp;
        private int hp;
        private Inventory bag; //영웅의 인벤토리 
        private Item equipItem;
        public Hero(HeroInfo info)
        {
            this.info = info;
            this.data = DataManager.instance.GetHeroData(this.info.id);
            this.maxHp = this.data.maxHp;
            this.hp = this.maxHp;

            Console.WriteLine("영웅: {0} 생성 , 공격력: {1} 체력: {2}/{3}",
                data.name, info.damage, this.hp, this.maxHp);
        }

        public void SetBag(Inventory bag)
        {
            this.bag = bag;
            Console.WriteLine("{0} 칸 짜리 가방을 영웅 {1}가(이) 장착했습니다",
                bag.GetCapacity(), data.name);
        }
        //영웅이 아이템을 인벤토리에 저장 
        public void SetItem(Item item)
        {
            this.bag.AddItem(item);
            Console.WriteLine("{0} 아이템을 영웅 {1} 이(가) 습득했습니다.", item.Name,this.data.name);
        }
        //아이템 장착 메서드, 인벤토리에서 찾아서 장착 
        public void Equip(int id) //id로 검색해서 장착 
        {
            if (bag.Exist(id) == true)
            {
                equipItem = bag.GetItemByInven(id);
                info.damage += equipItem.GetItemDamage();
                Console.WriteLine("영웅 {0}이 {1}을(를) 장착했습니다. 현재 공격력: {2}"
                    , data.name, equipItem.Name,info.damage);
            }
            else Console.WriteLine("아이템이 없습니다");
        }
        //아이템 장착 해제 메서드, 해제 되면 다시 인벤토리로 들어감 
        public void UnEquip()
        {
            this.bag.AddItem(equipItem);
            info.damage -= this.equipItem.GetItemDamage();
            Console.WriteLine("영웅 {0}이 {1}을(를) 장착 해제 했습니다. 현재 공격력: {2}",
               data.name, equipItem.Name, info.damage);
            this.equipItem = null;
           
        }
        //영웅 공격
        public void Attack(Monster monster)
        {
            Console.WriteLine("영웅 {0}은 몬스터 {1}을 공격했다. {2} Damage!"
                ,data.name,monster.Name,info.damage);
            monster.HitDamage(this.info.damage);
        }
        //이름 받아오기
        public string GetHeroName()
        {
            return this.data.name;
        }
        //가방 반환
        public Inventory GetBag()
        {
            return this.bag;
        }
    }
}

Monster

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LearnDotnet
{
    public class Monster
    {
        //멤버
        private MonsterInfo info;
        private int maxHp;
        private int hp;
        private MonsterData data;
        public Action onDie; //대리자 
        public string Name
        {
            get { return data.name; }
        }
        //생성자
        public Monster(MonsterInfo info)
        {
            this.info = info;
            data = DataManager.instance.GetMonsterData(this.info.id);
            this.maxHp = data.maxHp;
            this.hp = this.maxHp;

            Console.WriteLine("몬스터 {0} 생성 , 체력 : {1}/{2}", this.Name, this.hp, this.maxHp);
        }
        //받은 데미지 계산 메서드 
        public void HitDamage(int damage)
        {
            this.hp -= damage;
            if(this.hp <= 0)
            {
                this.hp = 0;
            }
            Console.WriteLine("몬스터 {0}, 체력 : {1}/{2}",
                this.Name, this.hp, this.maxHp);
            if(this.hp <= 0)
            {
                this.Die();
            }
        }
        //죽음 메서드
        private void Die()
        {
            Console.WriteLine("몬스터 {0}가(이) 죽었습니다!", this.Name);
            this.onDie(); //대리자 호출 
        }

        public int GetMonsterItemId()
        {
            return this.info.item_id;
        }
    }
}

----------------------------------------------------------------------------------------------------------------------

Hero 객체가 주체적으로 아이템을 저장하는 클래스 

Inventory 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace LearnDotnet
{
    public class Inventory
    {
        List<Item> items = new List<Item>();
        private int capacity;
        //생성자
        public Inventory(int capacity)
        {
            this.capacity = capacity;
        }
        //멤버 메서드 

        //인벤토리의 아이템 저장하는 메서드 
        public void AddItem(Item item)
        {
            items.Add(item);
           // Console.WriteLine("{0} 아이템이 가방에 들어갔습니다", item.Name);
        }
        //인벤토리의 현재 찾는 아이템이 있는지 없는지 확인하는 메서드
        public bool Exist(int id) //item의 id로 확인 
        {
            for(int i = 0; i < items.Count; i++)
            {
                if (items[i].GetItemId() == id)
                {
                   // Console.WriteLine("찾았다");
                    return true;
                }
            }
            return false;
        }
        //인벤토리에서 아이템 찾아서 꺼내기 
        public Item GetItemByInven(int id) //item의 id로 확인 
        {
            Item foundItem = null;
            for(int i=0; i<items.Count; i++)
            {
                if(items[i].GetItemId() == id)
                {
                    foundItem =  items[i];
                    items.Remove(items[i]); //꺼낸 아이템 리스트에서 삭제 
                    break; //반복문 탈출 
                }
            }
            return foundItem;
        }
        //인벤토리 현재 저장 현황 출력 
        public void PrintAllInvenItem()
        {
            Console.WriteLine("-----인벤토리-----");
            for (int i=0; i < items.Count; i++)
            {
                Console.WriteLine("{0}",items[i].Name);
            }
            Console.WriteLine("------------------");

        }
        //인벤토리의 용량 반환하는 메서드
        public int GetCapacity()
        {
            return this.capacity;
        }
        //현재 인벤토리 내의 모든 아이템 종목 반환하는 함수 
        public List<Item> GetItems()
        {
            return this.items;
        }
        
        
    }
}

-------------------------------------------------------------------------------------------------------------------------

데이터를 관리하는 클래스

DataManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;

namespace LearnDotnet
{
    //싱글톤 패턴 이용, 언제 어디서나 접근 가능 
    public class DataManager
    {
        public static readonly DataManager instance = new DataManager();
        //item정보를 저장하는 사전
        Dictionary<int, ItemData> itemDic = new Dictionary<int, ItemData>();
        //monster 정보를 저장하는 사전 
        Dictionary<int, MonsterData> monsterDic = new Dictionary<int, MonsterData>();
        //hero 정보를 저장하는 사전 
        Dictionary<int, HeroData> heroDic = new Dictionary<int, HeroData>();
        //json 파일을 통해 받아온 정보를 저장할 Item배열
        ItemData[] itemDatas;
        //json 파일을 통해 받아온 정보를 저장한 Monster 배열
        MonsterData[] monsterDatas;
        //jsom 파일을 통하 밷아온 정보를 저장할 Hero 배열
        HeroData[] heroDatas;

        //생성자, 싱글톤 패턴이기에 생성자에 접근 할 수 없도록 private 한정자 사용 
        private DataManager()
        {

        }
        //아이템의 정보를 json파일에서 읽어오는 메서드 
        public void LoadItemData()
        {
            //현재 경로의 해당 이름의 파일을 받아와 문자열로 저장 
            string json = File.ReadAllText("./item_data.json");
            //역직렬화를 하면 ItemData 객체들을 요소로 하는 배열 객체가 나온다.
            itemDatas = JsonConvert.DeserializeObject<ItemData[]>(json);
            //순회 하면서 itemData를 item사전에 저장 
            foreach(ItemData itemData in itemDatas)
            {
                itemDic.Add(itemData.id, itemData); //키값과 데이터 저장 
            }
          //  Console.WriteLine(json);

        }
        //몬스터의 정보를 json 파일에서 읽어오는 메서드
        public void LoadMonsterData()
        {
            //현재 경로의 해당 이름의 파일을 받아와 문자열로 저장 
            string json = File.ReadAllText("./monster_data.json");
            //역직렬화를 하면 MonsteData 객체들을 요소로 하는 배열 객체가 나온다. 
            //json 파일의 구조가 그렇기 때문 
            monsterDatas = JsonConvert.DeserializeObject<MonsterData[]>(json);
            //순회 하면서 monsterData를 monster 사전에 저장 
            //우리가 사용하기 편하기 위해 
            foreach(MonsterData monsterData in monsterDatas)
            {
                monsterDic.Add(monsterData.id, monsterData);
            }
            //Console.WriteLine(json);

        }

        //영웅의 정보를 json 파일에서 읽어오는 메서드 
        public void LoadHeroData()
        {
            //현재 경로의 해당 이름의 파일을 받아와 문자열로 저장 
            string json = File.ReadAllText("./hero_data.json");
            //역직렬화를 하면 HeroData 객체들을 요소로 하는 배열 객체가 나온다.
            //json 파일의 구조가 그렇기 때문
            heroDatas = JsonConvert.DeserializeObject<HeroData[]>(json);
            //순회 하면서 heroDaTAS를 hero 사전에 저장 
            //사용하기 편하기 위해
            foreach(HeroData heroData in heroDatas)
            {
                heroDic.Add(heroData.id, heroData);
            }
            //Console.WriteLine(json);
        }
        //키 값을 통해 ItemData를 반환하는 메서드
        public ItemData GetItemData(int id)
        {
            return this.itemDic[id];
        }
        //키 값을 통해 MonsterData를 반환하는 메서드 
        public MonsterData GetMonsterData(int id)
        {
            return this.monsterDic[id];

        }
        //키 값을 통해 HeroData를 반환하는 메서드
        public HeroData GetHeroData(int id)
        {
            return this.heroDic[id];
        }

    }
}

---------------------------------------------------------------------------------------------------------------------------

Game 클래스 , 실질적인 실행 부분 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Data;

namespace LearnDotnet
{
    public class Game
    {
        public Hero hero;
        private Monster monster;

        public Game()
        {

        }

        public void Start()
        {
            Console.WriteLine("게임이 시작되었습니다");
            this.hero = this.CreateHero(10001); //영웅 Richard 생성 
            this.monster = this.CreateMonster(1004); //몬스터 뱀파이어 생성 
            this.monster.onDie = () => { //몬스터가 죽었다는 것을 받아옴, 대리자 실행
                //드롭 아이템 생성 
                int itemId = this.monster.GetMonsterItemId();
                Item dropItem = this.CreateItem(itemId);
                Console.WriteLine("{0}이 {1}을 드롭했다!", monster.Name, dropItem.Name);
                this.hero.SetItem(dropItem); //드롭 아이템 습득
            };
            Inventory bag = new Inventory(5); //5칸 짜리 인벤토리 생성 
            hero.SetBag(bag); //영웅이 가방 장착 
            Console.WriteLine("초기 아이템을 2개 지급 합니다");
            Item item1 = this.CreateItem(100); //장검 아이템 생성 
            Item item2 = this.CreateItem(101); //단검 아이템 생성 
            hero.SetItem(item1); //장검 저장 
            hero.SetItem(item2); //단검 저장 
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 
            hero.Equip(100); //영웅이 장검을 장착 
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 
            Console.WriteLine("영웅{0} 6번 공격!", this.hero.GetHeroName());
            for(int i=0; i<6; i++)
            {
                hero.Attack(monster); //영웅 몬스터 공격 
            }
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 
            hero.UnEquip(); //장착 해제
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 
            hero.Equip(104); //망치 장착 
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 
            hero.UnEquip(); //장착 해제
            bag.PrintAllInvenItem(); //인벤토리 현황 출력 


            //Inventory inven = hero.GetBag();
            //List<Item> items = inven.GetItems();
            //this.SaveItems(items);




        }
        //영웅 생성 메서드 
        private Hero CreateHero(int id)
        {
            HeroData data = DataManager.instance.GetHeroData(id);
            HeroInfo info = new HeroInfo(data.id, data.damage);
            return new Hero(info);
        }
        //몬스터 생성 메서드 
        private Monster CreateMonster(int id)
        {
            MonsterData data = DataManager.instance.GetMonsterData(id);
            MonsterInfo info = new MonsterInfo(data.id, data.item_id, data.damage);
            return new Monster(info);
        }
        //아이템 생성 매서드 
        private Item CreateItem(int id)
        {
            ItemData data = DataManager.instance.GetItemData(id);
            ItemInfo info = new ItemInfo(data.id, data.damage);
            return new Item(info);
        }

        //public void SaveItems(List<Item> items)
        //{
        //    List<ItemInfo> itemInfos = new List<ItemInfo>();
        //    foreach (Item item in items)
        //    {
        //        itemInfos.Add(item.GetItemInfo());
        //    }
        //    InfoManager.instance.gameInfo.itemInfos = itemInfos;
        //    //직렬화
        //    string json = JsonConvert.SerializeObject(InfoManager.instance.gameInfo);
        //    File.WriteAllText("./game_info.json", json);
        //    Console.WriteLine("파일 저장 완료");
        //}
    }
}

실행

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Data;

namespace LearnDotnet
{
    public class App
    {
        //멤버
        private Game game;
       
        //생성자
        public App()
        {
           
            //-------------------------게임 준비------------------------
            DataManager.instance.LoadItemData();
            DataManager.instance.LoadMonsterData();
            DataManager.instance.LoadHeroData();
            //---------------------------------------------------------


            //----------게임 시작----------------
            this.game = new Game();
            this.game.Start();
            
        }

       
    }
}

item_data.json
0.00MB
monster_data.json
0.00MB
hero_data.json
0.00MB