c# 강의/과제

20200428 - 상점(판매종료일/레벨제한/구매수량제한 등)

쪼혀 2020. 4. 29. 02:16

 

매일매일 페키지는 매일 자정 구매제한 초기화 개념

 


> App.cs

더보기
using Microsoft.SqlServer.Server;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace _20200428_1
{
    class App
    {
        Info info;
        public App()
        {
            DataManager dm = DataManager.GetInstance();

            this.Init();


            //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
            // test용 데이터 주입

            //ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

            this.Load();
            this.info.myDia = 2000;
            this.info.myGold = 10000000;
            this.info.myLevel = 60;

            this.info.PrintInfo();
            this.PackageList();

            // 패키지 구매 테스트
            this.BuyPackage(10000);
            this.BuyPackage(10000);
            this.BuyPackage(10001);
            this.BuyPackage(10002);
            /*  
              this.BuyPackage(10000);
              this.BuyPackage(10001);
              this.BuyPackage(10002);
              this.BuyPackage(10003);
              this.BuyPackage(10004);
              this.BuyPackage(10005);
            */

            // this.everyDayPackageCount();
            this.info.Save();
        }

        public void Init()
        {
            DataManager dm = DataManager.GetInstance();

            info = new Info();

            Console.WriteLine();
            dm.LoadDatas();
        }

        // 판매 종료일 계산
        public void convertDate(string[] getDate)
        {
            DataManager dm = DataManager.GetInstance();

            System.DateTime endDate = new System.DateTime(int.Parse(getDate[0]), int.Parse(getDate[1]), int.Parse(getDate[2]));
            TimeSpan ddayDate = endDate - DateTime.Now;

            Console.Write($"-판매종료까지: ");
            if (ddayDate.Days > 0) { Console.Write($"{ddayDate.Days}일 "); };
            Console.WriteLine($"{ ddayDate.Hours }시간 { ddayDate.Minutes }분 { ddayDate.Seconds }초 남음");

        }

        //매일매일 초기화
        public void everyDayPackageCount()
        {
            Timer timaer = null;
            int FixHours = 12;
            var now = DateTime.Now;
            var scheduledTime = new DateTime(now.Year, now.Month, now.Day, FixHours, 0, 0);
            if (scheduledTime < now)
                scheduledTime = scheduledTime.AddDays(1);

            var timeout = scheduledTime - now;

            var timer = new Timer(timeout.TotalMilliseconds);
            timer.Enabled = true;
            timer.Elapsed += OnTimeEvent;

            Console.Write($"-판매종료까지: ");
            Console.WriteLine($"{ timeout.Hours }시 { timeout.Minutes }분 { timeout.Seconds }초 남음");

        }

        public void OnTimeEvent(Object source, System.Timers.ElapsedEventArgs e)
        {
            // 해당 이벤트 발생한다면 매일 자정 이후 매일매일 패키지 구매 카운트 초기화
            Console.WriteLine(e.SignalTime);
            this.info.dicBuyedPackageData[10005] = 0;
        }

        public void BuyPackage(int buyNum)
        {
            DataManager dm = DataManager.GetInstance();
            var data = dm.GetItemDatas(buyNum);

            Console.WriteLine();
            Console.WriteLine("ㅡㅡㅡㅡㅡㅡ 구매 ㅡㅡㅡㅡㅡㅡ");
            Console.WriteLine(data.item_name);
            this.info.BuyPackage(buyNum);
        }

        public void PackageList()
        {
            DataManager dm = DataManager.GetInstance();
            Dictionary<int, ItemData> data = dm.GetAllItemDatas();
            List<int> list = new List<int>(data.Keys);

            foreach (var key in list)
            {
                var cType = dm.GetCurrencyDataById(data[key].item_type);
                var desc = string.Format(data[key].level_limit_desc, data[key].level_limit);
                string money = String.Format("{0:#,###}", data[key].price);
                string mileage = String.Format("{0:#,###}", data[key].mileage);
                string[] testdate = new string[3];

                Console.WriteLine("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
                Console.WriteLine(" *" + data[key].item_name);


                if (data[key].mileage > 0)
                {
                    Console.WriteLine($"-마일리지: {mileage}");
                }

                if (data[key].level_limit > 0) { Console.WriteLine("-" + desc); }
                Console.Write($"[{cType.name}]");
                Console.WriteLine($"-가격: {money}");
                if (data[key].everyday_package) { Console.WriteLine("★매일매일 패키지★"); }


                if (data[key].buy_end_date != "null")
                {
                    testdate = data[key].buy_end_date.Split('.');
                    this.convertDate(testdate);
                }

                if (key == 10005)
                {
                    this.everyDayPackageCount();
                }

                if (data[key].buy_limit > 0)
                {
                    Console.Write("-구매가능수량: (");
                    if (this.info.dicBuyedPackageData.ContainsKey(key))
                    {
                        this.info.count = this.info.dicBuyedPackageData[key];
                    }
                    Console.Write(this.info.count);
                    Console.WriteLine($"/{data[key].buy_limit})");
                }

            }//forEach end
        }

        public void MyinfoPrint()
        {
            Info myInfo = this.info.GetInfoData();
            Console.WriteLine("ㅡㅡㅡㅡㅡㅡㅡㅡㅡ 내 정보 ㅡㅡㅡㅡㅡㅡㅡㅡ");
            Console.WriteLine("[다이아:{0}][골드:{1}][마일리지:{2}][레벨:{3}]",
                myInfo.myDia, myInfo.myGold, myInfo.myLevel);
        }

        public void Load()
        {
            var path = "./info/info.json";
            if (File.Exists(path))
            {
                //파일 읽기 
                var json = File.ReadAllText("./info/info.json");

                //역직렬화 
                //이때 배열이 아니라는점 주의 
                this.info = JsonConvert.DeserializeObject<Info>(json);
                Console.WriteLine(this.info.myLevel);
            }
        }
    }
}

 

> DataManager.cs

더보기
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;
using Newtonsoft.Json;

namespace _20200428_1
{
    class DataManager
    {
        private static DataManager singleTone;

        private Dictionary<int, CurrencyData> dicCurrencyData;
        private Dictionary<int, ItemData> dicItemData;

        private DataManager()
        {
            this.dicCurrencyData = new Dictionary<int, CurrencyData>();
            this.dicItemData = new Dictionary<int, ItemData>();
        }

        public static DataManager GetInstance()
        {
            if (DataManager.singleTone == null)
            {
                DataManager.singleTone = new DataManager();
                return DataManager.singleTone;
            }
            else
            {
                return DataManager.singleTone;
            }
        }

        public void LoadDatas()
        {
            string json = "";
            string path = "";

            try
            {
                // 아이템 
                path = "./data/item_data.json";
                if (File.Exists(path))
                {
                    json = File.ReadAllText(path);
                    this.dicItemData = JsonConvert.DeserializeObject<ItemData[]>(json).ToDictionary(x => x.id, x => x);
                }

                // 재화
                path = "./data/currency_data.json";
                if (File.Exists(path))
                {
                    json = File.ReadAllText(path);
                    this.dicCurrencyData = Newtonsoft.Json.JsonConvert.DeserializeObject<CurrencyData[]>(json).ToDictionary(x => x.id, x => x);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("* catch");
                Console.WriteLine(e.Message);
                throw;
            }

        } //Loaddata() end

        public CurrencyData GetCurrencyDataById(int id)
        {
            return dicCurrencyData[id];
        }

        public ItemData GetItemDatas(int id)
        {
            return this.dicItemData[id];
        }

        public Dictionary<int, ItemData> GetAllItemDatas()
        {
            return this.dicItemData;
        }

    }// class end
}

 

> Info.cs

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

namespace _20200428_1
{
    class Info
    {
        public int myDia; // 소지 다이아 갯수
        public int myGold; // 소지 골드 갯수
        public int myLevel; // 현재 레벨
        public int myMileage; // 현재 누적 마일리지
        public int count;

        public Dictionary<int, int> dicBuyedPackageData; // 구매한 페키지 id, 수량 추가


        public Info()
        {
            this.dicBuyedPackageData = new Dictionary<int, int>();
        }

        public Info(int myDia, int myGold, int myLevel, int myMileage, Dictionary<int, int> dicBuyedPackageData)
        {
            this.myDia = myDia;
            this.myGold = myGold;
            this.myLevel = myLevel;
            this.myMileage = myMileage;
            this.dicBuyedPackageData = dicBuyedPackageData;
        }

        public void BuyPackage(int buyNum)
        {
            DataManager dm = DataManager.GetInstance();

            ItemData data = dm.GetItemDatas(buyNum);

            // 보유 재화 확인
            if (data.item_type == 100)
            {
                if (this.myDia >= data.price)
                {
                    // 구매가능 수량 확인
                    this.PackageBuyLimitCheck(data);
                }
                else
                {
                    Console.WriteLine("구매 다이아 부족");
                }
            }

            if (data.item_type == 101)
            {

                if (this.myGold >= data.price)
                {
                    // 구매가능 수량 확인
                    this.PackageBuyLimitCheck(data);
                }
                else
                {
                    Console.WriteLine("구매 골드 부족");
                }
            }

            this.PrintInfo();
        }

        // 수매수량, 레벨 체크
        public void PackageBuyLimitCheck(ItemData data)
        {
            if (this.dicBuyedPackageData.ContainsKey(data.id))
            {
                this.count = this.dicBuyedPackageData[data.id];
            }

            // 수량 체크
            if (data.buy_limit != 0 && data.buy_limit <= this.count) { Console.WriteLine("더이상 구매불가"); return; }

            // 레벨 체크
            if (data.level_limit != 0 && data.level_limit > this.myLevel) { Console.WriteLine("레벨부족으로 구매불가"); return; }

            if (data.item_type == 100)
            {
                Console.WriteLine("-다이아");
                this.count++;
                this.myDia -= data.price;
                this.myMileage += data.mileage;
                this.dicBuyedPackageData[data.id] = this.count;
            }

            if (data.item_type == 101)
            {
                Console.WriteLine("-골드");
                this.count++;
                this.myGold -= data.price;
                this.myMileage += data.mileage;
                this.dicBuyedPackageData[data.id] = this.count;
            }
        }

        public void PrintInfo()
        {
            DataManager dm = DataManager.GetInstance();

            Console.WriteLine($"-다이아:{this.myDia} -골드:{this.myGold} -레벨:{this.myLevel} -마일리지:{this.myMileage}");

            Console.WriteLine("ㅡㅡㅡㅡㅡ 구매 이력 ㅡㅡㅡㅡ");

            if (this.dicBuyedPackageData.Count > 0)
            {
                foreach (var item in this.dicBuyedPackageData)
                {
                    Console.WriteLine($"{item.Key } {item.Value}");
                }
            }
        }

        public void Save()
        {
            try
            {
                var json = JsonConvert.SerializeObject(this);
                File.WriteAllText("./info/info.json", json);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                throw;
            }
            Console.WriteLine("데이터 저장");
        }

        public Info GetInfoData()
        {
            return this;
        }
    }
}

 

> data파일들

더보기
namespace _20200428_1
{
    class ItemData
    {
        public int id;
        public int item_type;
        public string item_name;
        public int mileage;
        public int price;
        public int level_limit;
        public string level_limit_desc;
        public int buy_limit;
        public string buy_start_date;
        public string buy_end_date;
        public bool everyday_package;
    }
}
namespace _20200428_1
{
    class CurrencyData
    {
        public int id;
        public string name;
        public int currency_type;
        public string icon_currency;
    }
}