'C#'에 해당되는 글 39건

  1. 2019.04.04 ItemData구현
  2. 2019.04.04 Hash란?
  3. 2019.04.03 Dictionary를 이용한 Inventory구현 및 Json사용
  4. 2019.04.02 Inventory구현 (창고이동, 제작, 목록 등등)
  5. 2019.04.01 멀티스레딩 + SetCursorPosition에서 생긴 문제 [해결]
  6. 2019.04.01 Inventory를 다시 Array로 되돌리기
  7. 2019.04.01 제너릭 클래스, 상속을 이용하여 Inventory 만들기
  8. 2019.04.01 List를 이용하여 Inventory 만들기

ItemData구현

C#/수업내용 2019. 4. 4. 15:07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
 
namespace Study_0404
{
    public class App
    {
        private string[] arrDataName = { "weapon_data.json""armor_data.json""stat_data.json""char_stat_data.json" };
        public Dictionary<int, ItemData> dicWeaponItem;
        public Dictionary<int, ItemData> dicArmorItem;
        public List<Item> inventory;
 
        public App()
        {
            dicWeaponItem = new Dictionary<int, ItemData>();
            dicArmorItem = new Dictionary<int, ItemData>();
            inventory = new List<Item>();
        }
 
 
        public void Start()
        {
            this.LoadAllData();
            for(int index=0; index<6; index++)
            {
                inventory.Add(this.CreateItem(index, 0));
                inventory.Add(this.CreateItem(index, 1));
 
            }
            for(int index = 0; index < inventory.Count; index++)
            {
                Console.WriteLine("pointer id : {0}", index);
                if(inventory[index].info.type == 0)
                {
                    Console.WriteLine("{0}.{1} Lv.{2} Dmg.{3}", inventory[index].info.id, dicWeaponItem[inventory[index].info.id].name, dicWeaponItem[inventory[index].info.id].level, inventory[index].info.damage);
                }
                if(inventory[index].info.type == 1)
                {
 
                    Console.WriteLine("{0}.{1} Lv.{2} Arm.{3}", inventory[index].info.id, dicArmorItem[inventory[index].info.id].name, dicArmorItem[inventory[index].info.id].level, inventory[index].info.armor);
                }
            }
        }
 
        //data load method
        public void LoadAllData() 
        {
            for(int i = 0; i<this.arrDataName.Length; i++)
            {
                var fileName = this.arrDataName[i];
                string path = string.Format("./Data/{0}", arrDataName[i]);
            }
            string weaponDataPath = "./Data/weapon_data.json";
            bool isExist = true;
            if (isExist)
            {
                var weapon = File.ReadAllText(weaponDataPath);
                var weaponJson = JsonConvert.DeserializeObject<ItemData[]>(weapon);
                foreach (var data in weaponJson)
                {
                    var itemData = new ItemData(data.id, data.type, data.name, data.level, data.damage_min, data.damage_max);
                    dicWeaponItem.Add(itemData.id, itemData);
                }
            }
            string armorDataPath = "./Data/armor_data.json";
            isExist = File.Exists(armorDataPath);
            if (isExist)
            {
                var armor = File.ReadAllText(armorDataPath);
                var armorJson = JsonConvert.DeserializeObject<ItemData[]>(armor);
                foreach(var data in armorJson)
                {
                    var itemData = new ItemData(data.id, data.type, data.name, data.level, data.armor_min, data.armor_max);
                    dicArmorItem.Add(itemData.id, itemData);
                }
            }            
 
        }
 
        public Item CreateItem(int id, int type)
        {
            Random rand = new Random();
            if(type == 0)
            {
                int damageOrArmor = rand.Next(dicWeaponItem[id].damage_min, dicWeaponItem[id].damage_max);
                ItemInfo info = new ItemInfo(id, type, damageOrArmor);
                return new Item(info);
            }
            else if(type == 1)
            {
                int damageOrArmor = rand.Next(dicArmorItem[id].armor_min, dicArmorItem[id].armor_max);
                ItemInfo info = new ItemInfo(id, type, damageOrArmor);
                return new Item(info);
            }
            return default(Item);
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Study_0404
{
    public class Item
    {
        public ItemInfo info;
        public Item(ItemInfo info)
        {
            this.info = info;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Study_0404
{
    public class ItemData
    {
        public int id;
        public int type;
        public string name;
        public int level;
        public int damage_min;
        public int damage_max;
        public int armor_min;
        public int armor_max;
 
        public ItemData(int id, int type, string name, int level, int min, int max)
        {
            if(type==0)
            {
                this.id = id;
                this.type = type;
                this.name = name;
                this.level = level;
                this.damage_min = min;
                this.damage_max = max;
            }
            else if(type==1)
            {
                this.id = id;
                this.type = type;
                this.name = name;
                this.level = level;
                this.armor_min = min;
                this.armor_max = max;
 
            }
        }
    }
}
 
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Study_0404
{
    public class ItemInfo
    {
        public int id;
        public int type;
        public int damage;
        public int armor;
        public ItemInfo(int id, int type, int damageOrArmor)
        {
            if (type == 0)
            {
                this.id = id;
                this.type = type;
                this.damage = damageOrArmor;
            }
            else if (type == 1)
            {
                this.id = id;
                this.type = type;
                this.armor = damageOrArmor;
            }
 
        }
    }
}
 
cs


:

Hash란?

C#/과제 2019. 4. 4. 00:34

Hash

해시는 Hashtable, Hashmap, SHA, MD와같이 알고리즘, 암호학에 사용된다.

해시함수를 통하여 어떠한 데이터를 고정길이의 데이터로 매핑한다. 원 데이터 값은 Key, 매핑 후의 값은 HashValue, 이 과정들을 Hashing이라한다.


Collision

Hashing은 Key를 고유의 계산식을 통하여 HashValue를 만드는 것이라고 하였다.

그럼 충돌은 무엇이고, 왜 일어날까?

충돌은 각각 다른 A, B의 Key를 Hashing했을 때, 둘 다 같은 HashValue를 가진 경우를 충돌했다고 한다.

서로 같은 HashValue를 들고 Bucket(저장공간)에 접근을 했다면, 충돌이 일어난 주소에는 누구를 저장해야할까?


위의 그림을 예시로 생각해보자.

그림이 마치 배열을 연상하게끔 하는데, 배열로 보면 {1,2,3,4,5,6,7}은 Index, 그 옆은 값을 저장하는 공간이고, 홍길동과 임꺽정은 포인터다.

배열에서는 각각의 값마다 고유의 Index를 가지고 정해진 양의 데이터를 정해진 공간에 저장하므로 같은 Index의 공간에 서로 저장하려고 하는 

저런 경우가 없지만, Hash는 Hash Function의 고유 계산식을 통해 값을 산출하는 방식이므로 위처럼 동일한 값이 나올 수 있다.

그래서 Key 홍길동의 HashValue는 3, Key 임꺽정의 HashValue는 3이라고 가정했을 때, 서로는 같은 곳을 차지하려하고 있다.

그렇게 동일 값이 나오면 어떻게 해야할까?


Collision Resolve

충돌을 해결하는 방법에는 첫번째로 chaining이 있다.

위처럼 같은 HashValue를 가질 경우, Bucket에 Linked-List를 이용하여 값을 연달아 저장하는 방식이다.

3번 Bucket에는 Linked-List가 있고, 첫번째는 길동이집주소가, 두번째에는 꺽정이집주소가 저장되는 것이다.


또, open addressing방식이 있다. 이는 chaining처럼 bucket에 Linked-List를 이용하여 여러 값을 넣는 것과는 달리 이는 한 bucket에 하나만 들어갈 수 있다.

linear probing(선형 탐색)은 꺽정이가 늦게 왔다고 가정했을 때, 3번 bucket에는 길동이가 먼저 차지했다. 그렇다면 꺽정이는 다음 방인

4번 bucket으로 가서 자리가 있는지 확인을 하고, 비어있다면 그 곳을 차지한다. 혹여나 4번 bucket에도 누군가 자리를 차지했다면 5번으로 간다.

즉 한칸씩 옆으로 가서 확인하고 자리를 차지하는 방식이다. (무조건 한칸씩이 아닌, 정해진 폭만큼 이동한다.(2칸씩일 수도 있다.))

quadratic probing(제곱 탐색)은 linear probing처럼 옆칸으로 가지만, 정해진 폭만큼이 아닌 제곱의 폭만큼 이동한다.

3번 bucket이 길동이가 차지하고 있어서 4번을 갔더니 거기도 누군가 차지하고 있었다. 그럼 4(2의 제곱)만큼 떨어진 7번 bucket으로 간다.

거기도 꽉차있으면 9(3의 제곱)만큼 떨어진 12번 bucket으로 간다. 거기도 꽉차있으면 16(4의 제곱)만큼 떨어진 19번 bucket으로 간다.

이를 제곱 탐색이라고 한다.

double hasing(더블 해싱)은 해시함수를 2개를 쓰는 방법인데, 1번 해시함수는 HashValue를 만든다. 그리고 2번 해시함수는 충돌시 이동하는 폭을 정한다. 단 이 방법은 1번 해시함수에서 나온 해시값과 2번 해시함수에서 나온 해시값은 서로소여야만하는 조건이 있다.


이 외에도 많은 collision resolve 방법이 있다.



Hash Function

해시함수는 해시값을 쉽게 계산해내고, 해시의 문제점인 Collision(충돌)을 최소화시키고, 그 충돌을 해결하고, 각 공간에 균일하게 값을 분포시키는 역할을 한다.

이 해시함수들은 각각 다른 고유의 계산식을 가지고 있어서 같은 Key를 Hashing하더라도 다른 HashValue가 도출된다.

Division Method(나눗셈법), Multiplication Method(2진수 연산에 최적화된 함수), Universal Hasing(다수의 해시함수를 두고 무작위로 골라 해싱) 등 여러 방법이 있다.

최적화된 해시함수는 임의의 Key가 특정한 HashValue로 치우치지 않고, 고루고루 분포되게 하는 함수가 최적의 함수이다.




참조

Hash Tables and Hash Functions (Computer Science)

https://www.youtube.com/watch?v=KyUTuwz_b7Q


What is a HashTable Data Structure - Intoduction to Hash Tables, Part 0 (Paul Programming)

https://www.youtube.com/watch?v=MfhjkfocRR0



:

Dictionary를 이용한 Inventory구현 및 Json사용

C#/수업내용 2019. 4. 3. 23:33


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
 
using Newtonsoft.Json;
 
namespace Dictionary_0403
{
    public class App
    {
        Dictionary<int, ItemData> dicItems = new Dictionary<int, ItemData>();
        public App()
        {
            var readJson = File.ReadAllText(@"weapon_data.json");
            Console.WriteLine(readJson);
            var arrItemData = JsonConvert.DeserializeObject<ItemData[]>(readJson);
            foreach(var item in arrItemData)
            {
                Console.WriteLine(item.name);
            }
        }
 
        public void Start()
        {
            Dictionary<stringstring> dicPeople = new Dictionary<stringstring>();
            dicPeople.Add("940915-1111111""홍길동");
            dicPeople.Add("950915-1111111""임꺽정");
 
            var name = dicPeople["940915-1111111"];
            Console.WriteLine("name = {0}", name);
 
            var hasKey = dicPeople.ContainsKey("940915-1111111");
            if(hasKey)
            {
                name = dicPeople["940915-1111111"];
                dicPeople.Remove("940915-1111111");
                Console.WriteLine("{0}", name);
            }
            else
            {
                Console.WriteLine("해당키의 값은 없습니다.");
            }
 
            foreach(KeyValuePair<stringstring> pair in dicPeople)
            {
                Console.WriteLine("{0} : {1}", pair.Key, pair.Value);
            }
        }
 
        public void Start2()
        {
            var item = new ItemData(0"혈마검"701822.3f, 2231.8f);
            dicItems.Add(item.id, item);
            item = new ItemData(1"카를레이의 주장"701735.5f, 2085.8f);
            dicItems.Add(item.id, item);
            item = new ItemData(2"지존의 손잡이 칼"70321.0f, 321.0f);
            dicItems.Add(item.id, item);
            item = new ItemData(3"은장도"701735.5f, 2085.8f);
            dicItems.Add(item.id, item);
            item = new ItemData(4"손잡이 칼"70321.0f, 325.5f);
            dicItems.Add(item.id, item);
            item = new ItemData(5"그린스톤 경의 부채"701735.5f, 2085.8f);
            dicItems.Add(item.id, item);
            foreach(KeyValuePair<int, ItemData> pair in dicItems)
            {
                Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지: {3}~{4}", pair.Value.id, pair.Value.name, pair.Value.maxLevel, pair.Value.damageMin, pair.Value.damageMax);
            }
 
            var firstItem = this.CreateItem(0);
            var secondItem = this.CreateItem(1);
            var thirdItem = this.CreateItem(2);
            var fourthItem = this.CreateItem(3);
            var fifthtItem = this.CreateItem(4);
            var sixthtItem = this.CreateItem(5);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", firstItem.itemInfo.id, dicItems[firstItem.itemInfo.id].name, dicItems[firstItem.itemInfo.id].maxLevel, firstItem.itemInfo.damage);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", secondItem.itemInfo.id, dicItems[secondItem.itemInfo.id].name, dicItems[secondItem.itemInfo.id].maxLevel, secondItem.itemInfo.damage);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", thirdItem.itemInfo.id, dicItems[thirdItem.itemInfo.id].name, dicItems[thirdItem.itemInfo.id].maxLevel, thirdItem.itemInfo.damage);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", fourthItem.itemInfo.id, dicItems[fourthItem.itemInfo.id].name, dicItems[fourthItem.itemInfo.id].maxLevel, fourthItem.itemInfo.damage);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", fifthtItem.itemInfo.id, dicItems[fifthtItem.itemInfo.id].name, dicItems[fifthtItem.itemInfo.id].maxLevel, fifthtItem.itemInfo.damage);
            Console.WriteLine("\n\n{0}. {1}\n 레벨:{2}, 데미지:{3}", sixthtItem.itemInfo.id, dicItems[sixthtItem.itemInfo.id].name, dicItems[sixthtItem.itemInfo.id].maxLevel, sixthtItem.itemInfo.damage);
        }
 
        public Item CreateItem(int id)
        {
            double damage = this.GetRandomNumber(dicItems[id].damageMin, dicItems[id].damageMax);
            ItemInfo info = new ItemInfo(id, dicItems[id].maxLevel, (float)damage);
            return new Item(info);
        }
        public double GetRandomNumber(double minimum, double maximum)
        {
            Random rand = new Random();
            return rand.NextDouble() * (maximum - minimum) + minimum;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Dictionary_0403
{
    public class Item
    {
        public ItemInfo itemInfo;
 
        public Item(ItemInfo itemInfo)
        {
            this.itemInfo = itemInfo;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Dictionary_0403
{
    public class ItemData
    {
        public int id;
        public string name;
        public int maxLevel;
        public float damageMin;
        public float damageMax;
 
        public ItemData(int id, string name, int maxLevel, float damageMin, float damageMax)
        {
            this.id = id;
            this.name = name;
            this.maxLevel = maxLevel;
            this.damageMin = damageMin;
            this.damageMax = damageMax;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Dictionary_0403
{
    public class ItemInfo
    {
        public int id;
        public int level;
        public float damage;
 
        public ItemInfo(int id, int level, float damage)
        {
            this.id = id;
            this.level = level;
            this.damage = damage;
        }
    }
}
 
cs



Json형식의 파일을 역직렬화하여 Item객체를 생성하였다.

역직렬화 하는데 Newtonsoft.Json 패키지를 사용하였다.

:

Inventory구현 (창고이동, 제작, 목록 등등)

C#/수업내용 2019. 4. 2. 17:45


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericInventory
{
    class App
    {
        public App()
        {
            Console.WriteLine("App 생성자");
        }
        public void StartApp()
        {
            Inventory<HerbItem> herbInventory = new Inventory<HerbItem>();
            Inventory<MagicItem> magicInventory = new Inventory<MagicItem>();
            Inventory<Item> guildWarehouse = new Inventory<Item>();
            ConsoleKey menuKey = ConsoleKey.D1;
            string inputName;
 
            while(menuKey != ConsoleKey.D7)
            {
                Console.WriteLine("1.아이템제작 2.아이템목록 3.아이템검색 4.아이템버리기 5.창고이동 6.아이템변경");
                menuKey = Console.ReadKey().Key;
                switch(menuKey)
                {
                    case ConsoleKey.D1:
                        Console.WriteLine("제작하실 아이템 종류와 품목을 선택하세요");
                        Console.WriteLine("약초 : 평온초 / 은엽수 / 뱀뿌리 / 마법초 / 무덤이끼");
                        Console.WriteLine("마부 : 가속의 서약 / 원소의 격류 / 치명적인 항해");
                        inputName = Console.ReadLine();
                        switch(inputName)
                        {
                            case "평온초":
                                herbInventory.AddItem(new HerbItem(inputName));
                                break;
                            case "은엽수":
                                herbInventory.AddItem(new HerbItem(inputName));
                                break;
                            case "뱀뿌리":
                                herbInventory.AddItem(new HerbItem(inputName));
                                break;
                            case "마법초":
                                herbInventory.AddItem(new HerbItem(inputName));
                                break;
                            case "무덤이끼":
                                herbInventory.AddItem(new HerbItem(inputName));
                                break;
                            case "가속의 서약":
                                magicInventory.AddItem(new MagicItem(inputName));
                                break;
                            case "원소의 격류":
                                magicInventory.AddItem(new MagicItem(inputName));
                                break;
                            case "치명적인 항해":
                                magicInventory.AddItem(new MagicItem(inputName));
                                break;
                            default:
                                Console.WriteLine("제작할 수 없는 아이템입니다.");
                                break;
                        }
                        break;
                    case ConsoleKey.D2:
                        Console.WriteLine("허브가방");
                        herbInventory.PrintItemList();
                        Console.WriteLine("\n마부가방");
                        magicInventory.PrintItemList();
                        break;
                    case ConsoleKey.D3:
                        Console.WriteLine("찾을 아이템 이름을 입력하세요");
                        inputName = Console.ReadLine();
                        var herbTemp = herbInventory.SearchItem(inputName);
                        var magicTemp = magicInventory.SearchItem(inputName);
                        if(herbTemp!=null)
                        {
                            Console.WriteLine("{0}이 가방에 {1}개 있습니다", herbTemp.itemName, herbTemp.itemCount);
                        }
                        else if(magicTemp!=null)
                        {
                            Console.WriteLine("{0}이 가방에 {1}개 있습니다.", magicTemp.itemName, magicTemp.itemCount);
                        }
                        else
                        {
                            Console.WriteLine("가방에 존재하지 않는 아이템입니다.");
                        }
                        break;
                    case ConsoleKey.D4:
                        Console.WriteLine("버릴 아이템 이름을 입력하세요");
                        inputName = Console.ReadLine();
                        var herbSuccess = herbInventory.RemoveItem(inputName);
                        var magicSuccess = magicInventory.RemoveItem(inputName);
                        if(herbSuccess == true || magicSuccess)
                        {
                            Console.WriteLine("{0}를 버렸습니다.", inputName);
                        }
                        else if(herbSuccess == false && magicSuccess == false)
                        {
                            Console.WriteLine("{0}이 가방에 없습니다.", inputName);
                        }
                        break;
                    case ConsoleKey.D5:
                        Console.Write("1.창고에서 가져오기 2.창고에 넣기");
                        var key = Console.ReadKey().Key;
                        bool moveSuccess;
                        switch(key)
                        {
                            case ConsoleKey.D1:
                                moveSuccess = guildWarehouse.MoveWareToInven(ref guildWarehouse.items, ref herbInventory.items, ref magicInventory.items);
                                break;
                            case ConsoleKey.D2:
                                moveSuccess = guildWarehouse.MoveInvenToWare(ref guildWarehouse.items, ref herbInventory.items, ref magicInventory.items);
                                break;
                            default:
                                Console.WriteLine("잘못입력하셨습니다");
                                break;
                        } 
                        break;
                    case ConsoleKey.D6:
                        Console.WriteLine("변경할 아이템의 이름을 입력하세요");
                        string toChangeItem = Console.ReadLine();
                        Console.WriteLine("무슨 아이템으로 변경할까요?");
                        string changeItem = Console.ReadLine();
                        if(herbInventory.UpdateItem(ref herbInventory.items, new HerbItem(changeItem), toChangeItem) == false &&
                        magicInventory.UpdateItem(ref magicInventory.items, new MagicItem(changeItem), toChangeItem) == false)
                        {
                            Console.WriteLine("변경하실 수 있는 아이템이 없습니다.");
                        }
                        else
                        {
                            Console.WriteLine("변경이 완료되었습니다!");
                        }
                        break;
                }
            }
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericInventory
{
    public class HerbItem : Item
    {
        public HerbItem(string name)
        {
            this.itemType = 2;
            this.itemCount = 1;
            this.itemName = name;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericInventory
{
    public class Item
    {
        public int itemType;
        public string itemName;
        public int itemCount;
 
        public Item()
        {
        }
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericInventory
{
    public class MagicItem : Item
    {
        public MagicItem(string name)
        {
            this.itemType = 1;
            this.itemCount = 1;
            this.itemName = name;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericInventory
{
    public class Inventory<T> where T : Item
    {
        public List<T> items = new List<T>();
 
        public Inventory()
        {
            Console.WriteLine("인벤토리가 생성되었습니다.");
        }
 
        public void AddItem(T item)
        {
            int addCount = 0;
            foreach (var search in items)
            {
                if (item.itemName == search.itemName)
                {
                    search.itemCount++;
                    addCount = 1;
                    Console.WriteLine("{0}가 가방에 추가되었습니다.", item.itemName);
                    break;
                }
            }
            if (addCount != 1)
            {
                items.Add(item);
                Console.WriteLine("{0}가 가방에 추가되었습니다.", item.itemName);
            }
        }
 
        public bool RemoveItem(string name)
        {
            int removeCount = 0;
            foreach (var search in items)
            {
                if (name == search.itemName)
                {
                    if (search.itemCount != 1)
                    {
                        search.itemCount--;
                        return true;
                    }
                    else if (search.itemCount == 1)
                    {
                        items.RemoveAt(removeCount);
                        return true;
                    }
                }
                removeCount++;
            }
            return false;
        }
 
        public void PrintItemList()
        {
            foreach (var count in items)
            {
                Console.WriteLine("{0}, {1}개", count.itemName, count.itemCount);
            }
        }
 
        public T SearchItem(string name)
        {
            foreach (var search in items)
            {
                if (search.itemName == name)
                {
                    return search;
                }
            }
            return default(T);
        }
 
        public bool UpdateItem(ref List<T> item, T items, string toChangeItem)
        {
            int countUpdate = 0;
            for (int index = 0; index < item.Count; index++)
            {
                if (toChangeItem == item[index].itemName)
                {
                    for (int indexTemp = 0; indexTemp < item.Count; indexTemp++)
                    {
                        if (item[indexTemp].itemName == items.itemName)
                        {
                            item[indexTemp].itemCount++;
                            item.RemoveAt(index);
                            countUpdate = 1;
                            return true;
                        }
                    }
                    if (countUpdate != 1)
                    {
                        item[index] = items;
                        countUpdate = 1;
                        return true;
                    }
                }
            }
            return false;
        }
 
        public bool MoveWareToInven(ref List<Item> warehouse, ref List<HerbItem> herbInventory, ref List<MagicItem> magicInventory)
        {
            int takeItemCount = 0;
            int index = 0;
            Console.WriteLine("무엇을 가져오시겠습니까?");
            Console.WriteLine("창고의 아이템 목록");
            foreach(var item in warehouse)
            {
                Console.Write("{0} {1}개\t", item.itemName, item.itemCount);
            }
            string takeItemName = Console.ReadLine();
            foreach(var item in warehouse)
            {
                if(item.itemName == takeItemName)
                {
                    takeItemCount = 1;
                    break;
                }
                index++;
            }
 
            if(takeItemCount != 1 && takeItemName != "평온초" && takeItemName != "은엽수" && takeItemName != "뱀뿌리" && takeItemName != "마법초" &&
                takeItemName != "무덤이끼" && takeItemName != "가속의 서약" && takeItemName != "원소의 격류" && takeItemName != "치명적인 항해")
            {
                Console.WriteLine("창고에 존재하지 않는 아이템입니다.");
                return false;
            }
            else
            {
                if(takeItemName == "평온초" || takeItemName == "은엽수" || takeItemName == "뱀뿌리" || takeItemName == "마법초" || takeItemName == "무덤이끼")
                {
                    foreach(var search in herbInventory)
                    {
                        if(search.itemName == takeItemName)
                        {
                            search.itemCount++;
                            warehouse.RemoveAt(index);
                            return true;
                        }
                    }
                    herbInventory.Add(new HerbItem(takeItemName));
                    warehouse.RemoveAt(index);
                    return true;
                }
                else if(takeItemName == "가속의 서약" || takeItemName == "원소의 격류" || takeItemName == "치명적인 항해")
                {
                    foreach(var search in magicInventory)
                    {
                        if(search.itemName == takeItemName)
                        {
                            search.itemCount++;
                            warehouse.RemoveAt(index);
                            return true;
                        }
                    }
                    magicInventory.Add(new MagicItem(takeItemName));
                    warehouse.RemoveAt(index);
                    return true;
                }
            }
            return false;
        }
 
        public bool MoveInvenToWare(ref List<Item> warehouse, ref List<HerbItem> herbInventory, ref List<MagicItem> magicInventory)
        {
            int takeItemCount = 0;
            int index = 0;
            Console.WriteLine("무엇을 넣으시겠습니까?");
            Console.WriteLine("자신의 아이템 목록");
            foreach (var item in herbInventory)
            {
                Console.Write("{0} {1}개\t", item.itemName, item.itemCount);
            }
            foreach (var item in magicInventory)
            {
                Console.Write("{0} {1}개\t", item.itemName, item.itemCount);
            }
            string takeItemName = Console.ReadLine();
            foreach (var item in herbInventory)
            {
                if (item.itemName == takeItemName)
                {
                    takeItemCount = 1;
                    break;
                }
                index++;
            }
            if(takeItemCount != 1)
            {
                index = 0;
                foreach(var item in magicInventory)
                {
                    if(item.itemName == takeItemName)
                    {
                        takeItemCount = 1;
                        break;
                    }
                    index++;
                }
            }
 
            if (takeItemCount != 1 && takeItemName != "평온초" && takeItemName != "은엽수" && takeItemName != "뱀뿌리" && takeItemName != "마법초" &&
                takeItemName != "무덤이끼" && takeItemName != "가속의 서약" && takeItemName != "원소의 격류" && takeItemName != "치명적인 항해")
            {
                Console.WriteLine("인벤토리에 존재하지 않는 아이템입니다.");
                return false;
            }
            else
            {
                if (takeItemName == "평온초" || takeItemName == "은엽수" || takeItemName == "뱀뿌리" || takeItemName == "마법초" || takeItemName == "무덤이끼")
                {
                    foreach (var search in warehouse)
                    {
                        if (search.itemName == takeItemName)
                        {
                            search.itemCount++;
                            herbInventory.RemoveAt(index);
                            return true;
                        }
                    }
                    warehouse.Add(new HerbItem(takeItemName));
                    herbInventory.RemoveAt(index);
                    return true;
                }
                else if (takeItemName == "가속의 서약" || takeItemName == "원소의 격류" || takeItemName == "치명적인 항해")
                {
                    foreach (var search in warehouse)
                    {
                        if (search.itemName == takeItemName)
                        {
                            search.itemCount++;
                            magicInventory.RemoveAt(index);
                            return true;
                        }
                    }
                    warehouse.Add(new MagicItem(takeItemName));
                    magicInventory.RemoveAt(index);
                    return true;
                }
            }
            return false;
        }
    }
}
 
cs


:

멀티스레딩 + SetCursorPosition에서 생긴 문제 [해결]

C#/Problems 2019. 4. 1. 17:37

구상은 (x,y)좌표를 기반으로 (0,0)에서는 출력하는 스레드가 활동을 하고,

(0,20)에서는 입력받는 스레드가 활동을 하는 것을 구상했다.


(0,0)에서 메뉴를 출력한 후에 (0,20)에서 입력받고 다시 (0,0)으로 올라가서 그에 대한 답을 출력하는 방식으로 코딩을 했는데

자꾸 위의 사진처럼 (0,0)이 끝난 뒤에 (0,20)으로 내려가지 않고 저 자리에서 입력을 1회 해야했다.

이처럼 aaaaa의 좌표에서 1회 입력을 해야만 ddddd가 있는 (0,20)좌표로 커서가 이동했다.

무엇이 문제일까 계속 만져보고 SetCursorPosition을 따로 메서드에 지정하여 lock도 걸어보았지만 똑같았다.

또, 이렇게 멋대로 커서가 왔다갔다하면서 출력이 늘어질 때도 있었다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        public void SetCursor(int x, int y) //커서 좌표 지정 lock하여 한번에 1스레드만 이용가능
        {
            lock(lockObject)
            {
                Console.SetCursorPosition(x, y);
            }
        }
        public void StartOutputThread() //아웃풋 스레드 생성 및 실행
        {
            this.SetCursor(00);
            ThreadStart outputThreadStart = new ThreadStart(this.MenuOutput);
            Thread outputThread = new Thread(outputThreadStart);
            outputThread.Start();
        }
        public void StartInputThread() //인풋 스레드 생성 및 실행
        {
            this.SetCursor(020);
            ThreadStart inputThreadStart = new ThreadStart(this.Input);
            Thread inputThread = new Thread(inputThreadStart);
            inputThread.Start();
        }
cs

(스레드와 직접적으로 관련된 메서드 부분)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void SetCursor(int x, int y) //커서 좌표 지정 lock하여 한번에 1스레드만 이용가능
        {
            lock(lockObject)
            {
                Console.SetCursorPosition(x, y);
            }
        }
        public void StartOutputThread() //아웃풋 스레드 생성 및 실행
        {
            this.SetCursor(00);
            ThreadStart outputThreadStart = new ThreadStart(this.MenuOutput);
            Thread outputThread = new Thread(outputThreadStart);
            outputThread.Priority = ThreadPriority.Highest;
            outputThread.Start();
        }
        public void StartInputThread() //인풋 스레드 생성 및 실행
        {
            this.SetCursor(020);
            ThreadStart inputThreadStart = new ThreadStart(this.Input);
            Thread inputThread = new Thread(inputThreadStart);
            inputThread.Priority = ThreadPriority.Lowest;
            inputThread.Start();
        }
 
cs

아웃풋 스레드와 인풋 스레드 간의 우선순위때문에 그러는 것 같아서

아웃풋 스레드에게 최우선순위를 주고, 인풋 스레드에게 최하 우선순위를 주었지만, 똑같은 현상이 반복되었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        public void SetCursor(int x, int y) //커서 좌표 지정 lock하여 한번에 1스레드만 이용가능
        {
            lock(lockObject)
            {
                Console.SetCursorPosition(x, y);
            }
        }
        public void StartOutputThread() //아웃풋 스레드 생성 및 실행
        {
            this.SetCursor(00);
            ThreadStart outputThreadStart = new ThreadStart(this.MenuOutput);
            Thread outputThread = new Thread(outputThreadStart);
            outputThread.Start();
            this.StartInputThread();
        }
        public void StartInputThread() //인풋 스레드 생성 및 실행
        {
            this.SetCursor(020);
            ThreadStart inputThreadStart = new ThreadStart(this.Input);
            Thread inputThread = new Thread(inputThreadStart);
            inputThread.Start();
        }
 
cs
호출을 연쇄적으로 하게끔 아웃풋스레드 메서드에서 인풋스레드 메서드를 호출해봤으나 똑같았다.

키포인트는 제어권인거 같은데 풀 수가 없었다.

그렇게 이것저것 해보고 조언도 구해서 결국 답을 찾았다.

제어권 문제가 정답이었고, 그의 해답은 async, await에 있었다.

해결을 위해 async, await을 공부하는 중에 "그렇다면 스레드가 활동 중일 때 안 놓으면 되지않나?" 싶어서 Thread.Join();을 사용해봤다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        public void SetCursor(int x, int y) //커서 좌표 지정 lock하여 한번에 1스레드만 이용가능
        {
            lock(lockObject)
            {
                Console.SetCursorPosition(x, y);
            }
        }
        public async void StartOutputThread() //아웃풋 스레드 생성 및 실행
        {
            this.SetCursor(00);
            ThreadStart outputThreadStart = new ThreadStart(this.MenuOutput);
            Thread outputThread = new Thread(outputThreadStart);
            outputThread.Start();
            outputThread.Join();
        }
        public async void StartInputThread() //인풋 스레드 생성 및 실행
        {
            this.SetCursor(020);
            ThreadStart inputThreadStart = new ThreadStart(this.Input);
            Thread inputThread = new Thread(inputThreadStart);
            inputThread.Start();
            inputThread.Join();
        }
cs

바로 outputThread.Join(); inputThread.Join(); 부분이다.

Thread의 Join 메서드는 사용한 스레드의 작업이 완료될때까지 호출자를 차단한다.

즉 App.cs에서 StartOuputThread() 메서드를 호출했는데, 원래는 outputThread.Start();가 실행되고 작업이 완료되기 전에 App.cs로 돌아가 StartInputThread(); 메서드를 호출하여 인풋스레드를 실행하는 것이다.   

하지만 위처럼 아웃풋 스레드를 실행하고, Join메서드를 사용해주면 작업이 완료되기 전에 호출자가 제어권을 가져갈 수 없다.

그렇게 해결을 했다.



이제 이 코드에 async, await, task를 사용해서 구현해봐야겠다.




-async await 공부중... 공부하고 코드 적용 후 업데이트 할 예정-

'C# > Problems' 카테고리의 다른 글

암호화하여 직렬화, 복호화하여 역직렬화 [문제해결중]  (0) 2019.04.10
하는중  (0) 2019.04.01
공부할 것과 정리중인 것  (0) 2019.03.28
공부중  (0) 2019.03.27
Console.Read() 의 형변환 [해결]  (0) 2019.03.25
:

Inventory를 다시 Array로 되돌리기

C#/수업내용 2019. 4. 1. 16:08


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class Inventory
    {
        //Item형식의 값을 저장할 공간 
        private Item[] items = new Item[10];
        public int inventoryCount = 10;
 
        //기본 생성자 
        public Inventory()
        {
            Console.WriteLine("Inventory클래스의 생성자");
            Console.WriteLine("items.Length: {0}", items.Length);
        }
 
        //넣고 (매개변수로 Item인스턴스를 받아 배열에 넣는다)
        public void AddItem(Item item)
        {
            //배열의 방에 현재 위치에 있는지 확인후 없으면 다음방에 넣는다.
            //Item, Item, null, null,null, null,null, null,null, null
            //Item, Item, Item, Item,Item, Item,Item, Item,Item, Item
            //더이상 넣을수 없습니다.
            for(int index=0; index<items.Length; index++)
            {
                if (this.GetItemCount() == inventoryCount)
                {
                    Console.WriteLine("인벤토리가 꽉찼습니다.");
                    break;
                }
                else if(items[index] == null)
                {
                    items[index] = item;
                    Console.WriteLine("{0}의 제작이 완료되었습니다.", item.name);
                    break;
                }
            }
 
 
        }
 
        //뺀다 
        public void GetItemByName(string searchName)
        {
            //배열안에 있는 요소들중에 serachName 문자열과 비교해서 같은거 찾음
            //찾은거 반환, 못찾으면? null반환 
            //같은게 있다면? 하나만 가져오자 
            //돌도끼, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //반환값 : 돌도끼
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, 장검,null, null,null, null,null, null
            //돌도끼, 장검, null, null, null, ,null, null,null, null,null, null
            //손도끼, 돌도끼, null, null,null, null,null, null,null, null
            int index = 0;
            var readKey = ConsoleKey.D0;
            foreach (Item checkInventory in items)
            {
                if (checkInventory.name == searchName)
                {
                    Console.WriteLine("{0}가 인벤토리에 있습니다. 버리시겠습니까?(1.버린다 2.넣어둔다)", searchName);
                    readKey = Console.ReadKey().Key;
                    break;
                }
                index++;
            }
            if (readKey == ConsoleKey.D1)
            {
                items[index] = null;
                for(index=0; index<items.Length-1; index++)
                {
                    if (items[index] == null)
                    {
                        var temp = items[index + 1];
                        items[index + 1= items[index];
                        items[index] = temp;
                    }
                }
                Console.WriteLine("인벤토리를 정렬하였습니다.");
                Console.WriteLine("{0}을 버렸습니다.", searchName);
            }
        }
 
        public void ResizeArr(string inputSize)
        {
            int parseSize;
            Int32.TryParse(inputSize.ToString(), out parseSize);
            if(parseSize>10)
            {
                Console.WriteLine("값을 잘못 입력하셨습니다.");
            }
            else
            {
                Array.Resize(ref items, items.Length+parseSize);
                Console.Write("가방이 {0}칸 늘어났습니다.", parseSize);
                inventoryCount += parseSize;
            }
        }
 
        //목록출력
        public void GetItemList()
        {
            foreach (Item itemList in items)
            {
                if (itemList == null)
                {
                    break;
                }
                Console.Write("{0}  ", itemList.name);
            }
        }
 
        //인벤토리에 있는 아이템 갯수 가져오기 
        public int GetItemCount()
        {
            //배열안에 있는 값이 null이 아닐경우 카운트 해서 반환함 
            int cnt = 0;
            foreach (var item in items)
            {
                if (item != null)
                {
                    cnt++;
                }
            }
            return cnt;
        }
    }
}
cs




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class App
    {
        public App()
        {
            this.Start();
        }
        public void Start()
        {
            Inventory inventory = new Inventory() { };
 
            var inputKey = ConsoleKey.D0;
            while (inputKey != ConsoleKey.D5)
            {
                Console.WriteLine("\n1.아이템제작 2.인벤토리 3.아이템검색 4.가방늘리기 5.종료하기");
                inputKey = Console.ReadKey().Key;
                string inputItemName;
                switch(inputKey)
                {
                    case ConsoleKey.D1:
                        Console.Write("제작하실 아이템을 입력하세요 : ");
                        inputItemName = Console.ReadLine();
                        inventory.AddItem(new Item(inputItemName));
                        break;
                    case ConsoleKey.D2:
                        inventory.GetItemList();
                        break;
                    case ConsoleKey.D3:
                        Console.Write("검색하실 아이템 이름을 입력하세요 : ");
                        inputItemName = Console.ReadLine();
                        inventory.GetItemByName(inputItemName);
                        break;
                    case ConsoleKey.D4:
                        Console.Write("얼마나 늘리시겠습니까? (1회 최대 10칸) : ");
                        var inputSize = Console.ReadLine();
                        inventory.ResizeArr(inputSize);
                        break;
                    case ConsoleKey.D5:
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
 
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    public class Item
    {
        public string name;
 
        public Item(string name)
        {
            this.name = name;
        }
    }
}
cs


:

제너릭 클래스, 상속을 이용하여 Inventory 만들기

C#/수업내용 2019. 4. 1. 15:37


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    public class HerbItem : Item
    {
        public HerbItem(string name)
        {
            this.name = name;
        }
    }
}
 

cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    public class MagicalItem : Item
    {
        public MagicalItem(string name)
        {
            this.name = name;
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    public class Item
    {
        public string name;
 
        public Item()
        {
        }
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class Inventory<T>
    {
        //Item형식의 값을 저장할 공간 
        private List<Item> items = new List<Item>();
        public int inventoryCount = 10;
 
        //기본 생성자 
        public Inventory()
        {
            Console.WriteLine("Inventory클래스의 생성자");
            Console.WriteLine("items.Length: {0}", items.Count);
        }
 
        //넣고 (매개변수로 Item인스턴스를 받아 배열에 넣는다)
        public void AddItem(Item item)
        {
            //배열의 방에 현재 위치에 있는지 확인후 없으면 다음방에 넣는다.
            //Item, Item, null, null,null, null,null, null,null, null
            //Item, Item, Item, Item,Item, Item,Item, Item,Item, Item
            //더이상 넣을수 없습니다.
            if (this.GetItemCount() == inventoryCount)
            {
                Console.WriteLine("인벤토리가 꽉찼습니다.");
            }
            else
            {
                items.Add(item);
                Console.WriteLine("{0}의 제작이 완료되었습니다.", item.name);
            }
 
 
        }
 
        //뺀다 
        public void GetItemByName(string searchName)
        {
            //배열안에 있는 요소들중에 serachName 문자열과 비교해서 같은거 찾음
            //찾은거 반환, 못찾으면? null반환 
            //같은게 있다면? 하나만 가져오자 
            //돌도끼, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //반환값 : 돌도끼
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, 장검,null, null,null, null,null, null
            //돌도끼, 장검, null, null, null, ,null, null,null, null,null, null
            //손도끼, 돌도끼, null, null,null, null,null, null,null, null
            int index = 0;
            var readKey = ConsoleKey.D0;
            foreach (Item checkInventory in items)
            {
                if (checkInventory.name == searchName)
                {
                    Console.WriteLine("{0}가 인벤토리에 있습니다. 버리시겠습니까?(1.버린다 2.넣어둔다)", searchName);
                    readKey = Console.ReadKey().Key;
                    break;
                }
                index++;
            }
            if (readKey == ConsoleKey.D1)
            {
                items.RemoveAt(index);
                Console.WriteLine("{0}을 버렸습니다.", searchName);
            }
        }
 
        //목록출력
        public void GetItemList()
        {
            foreach (Item itemList in items)
            {
                if (itemList == null)
                {
                    break;
                }
                Console.Write("{0}  ", itemList.name);
            }
        }
 
        //인벤토리에 있는 아이템 갯수 가져오기 
        public int GetItemCount()
        {
            //배열안에 있는 값이 null이 아닐경우 카운트 해서 반환함 
            int cnt = 0;
            foreach (var item in items)
            {
                if (item != null)
                {
                    cnt++;
                }
            }
            return cnt;
        }
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class App
    {
        public App()
        {
            this.Start();
        }
        public void Start()
        {
            Inventory<HerbItem> herbInventory = new Inventory<HerbItem>(); //허브인벤토리
            Inventory<MagicalItem> magicInventory = new Inventory<MagicalItem>(); //마부인벤토리
 
            var inputKey = ConsoleKey.D0;
            while (inputKey != ConsoleKey.D4)
            {
                Console.WriteLine("\n1.아이템제작 2.인벤토리 3.아이템검색 4.종료하기");
                inputKey = Console.ReadKey().Key;
                string inputItemName;
                switch(inputKey)
                {
                    case ConsoleKey.D1:
                        Console.WriteLine("제작하실 아이템 종류와 품목을 선택하세요");
                        Console.WriteLine("약초 : 평온초 / 은엽수 / 뱀뿌리 / 마법초 / 무덤이끼");
                        Console.WriteLine("마부 : 가속의 서약 / 원소의 격류 / 치명적인 항해");
                        inputItemName = Console.ReadLine();
                        switch(inputItemName)
                        {
                            case "평온초":
                                herbInventory.AddItem(new HerbItem(inputItemName));
                                break;
                            case "은엽수":
                                herbInventory.AddItem(new HerbItem(inputItemName));
                                break;
                            case "뱀뿌리":
                                herbInventory.AddItem(new HerbItem(inputItemName));
                                break;
                            case "마법초":
                                herbInventory.AddItem(new HerbItem(inputItemName));
                                break;
                            case "무덤이끼":
                                herbInventory.AddItem(new HerbItem(inputItemName));
                                break;
                            case "가속의 서약":
                                magicInventory.AddItem(new MagicalItem(inputItemName));
                                break;
                            case "원소의 격류":
                                magicInventory.AddItem(new MagicalItem(inputItemName));
                                break;
                            case "치명적인 항해":
                                magicInventory.AddItem(new MagicalItem(inputItemName));
                                break;
                            default:
                                Console.WriteLine("제작할 수 없는 아이템입니다.");
                                break;
                        }
                        break;
                    case ConsoleKey.D2:
                        Console.Write("약초 가방 : ");
                        herbInventory.GetItemList();
                        Console.Write("\n마부 가방 : ");
                        magicInventory.GetItemList();
                        break;
                    case ConsoleKey.D3:
                        Console.Write("검색하실 아이템 이름을 입력하세요 : ");
                        inputItemName = Console.ReadLine();
                        herbInventory.GetItemByName(inputItemName);
                        magicInventory.GetItemByName(inputItemName);
                        break;
                    case ConsoleKey.D4:
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
 
cs


:

List를 이용하여 Inventory 만들기

C#/수업내용 2019. 4. 1. 14:56

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class Inventory
    {
        //Item형식의 값을 저장할 공간 
        private List<Item> items = new List<Item>();
        public int inventoryCount = 10;
 
        //기본 생성자 
        public Inventory()
        {
            Console.WriteLine("Inventory클래스의 생성자");
            Console.WriteLine("items.Length: {0}", items.Count);
        }
 
        //넣고 (매개변수로 Item인스턴스를 받아 배열에 넣는다)
        public void AddItem(Item item)
        {
            //배열의 방에 현재 위치에 있는지 확인후 없으면 다음방에 넣는다.
            //Item, Item, null, null,null, null,null, null,null, null
            //Item, Item, Item, Item,Item, Item,Item, Item,Item, Item
            //더이상 넣을수 없습니다.
            if (this.GetItemCount() == inventoryCount)
            {
                Console.WriteLine("인벤토리가 꽉찼습니다.");
            }
            else
            {
                items.Add(item);
                Console.WriteLine("{0}의 제작이 완료되었습니다.", item.name);
            }
 
 
        }
 
        //뺀다 
        public void GetItemByName(string searchName)
        {
            //배열안에 있는 요소들중에 serachName 문자열과 비교해서 같은거 찾음
            //찾은거 반환, 못찾으면? null반환 
            //같은게 있다면? 하나만 가져오자 
            //돌도끼, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //반환값 : 돌도끼
            //null, 돌도끼, null, null,null, null,null, null,null, null
            //null, 돌도끼, null, 장검,null, null,null, null,null, null
            //돌도끼, 장검, null, null, null, ,null, null,null, null,null, null
            //손도끼, 돌도끼, null, null,null, null,null, null,null, null
            int index = 0;
            var readKey = ConsoleKey.D0;
            foreach (Item checkInventory in items)
            {
                if (checkInventory.name == searchName)
                {
                    Console.WriteLine("{0}가 인벤토리에 있습니다. 버리시겠습니까?(1.버린다 2.넣어둔다)", searchName);
                    readKey = Console.ReadKey().Key;
                    break;
                }
                index++;
            }
            if (readKey == ConsoleKey.D1)
            {
                items.RemoveAt(index);
                Console.WriteLine("{0}을 버렸습니다.", searchName);
            }
        }
 
        //목록출력
        public void GetItemList()
        {
            foreach (Item itemList in items)
            {
                if (itemList == null)
                {
                    break;
                }
                Console.Write("{0}  ", itemList.name);
            }
        }
 
        //인벤토리에 있는 아이템 갯수 가져오기 
        public int GetItemCount()
        {
            //배열안에 있는 값이 null이 아닐경우 카운트 해서 반환함 
            int cnt = 0;
            foreach (var item in items)
            {
                if (item != null)
                {
                    cnt++;
                }
            }
            return cnt;
        }
    }
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    class App
    {
        public App()
        {
            this.Start();
        }
        public void Start()
        {
            Inventory inventory = new Inventory();
            var inputKey = ConsoleKey.D0;
            while (inputKey != ConsoleKey.D4)
            {
                Console.WriteLine("\n1.아이템제작 2.인벤토리 3.아이템검색 4.종료하기");
                inputKey = Console.ReadKey().Key;
                string inputItemName;
                switch(inputKey)
                {
                    case ConsoleKey.D1:
                        Console.Write("제작하실 아이템 이름을 입력하세요 : ");
                        inputItemName = Console.ReadLine();
                        inventory.AddItem(new Item(inputItemName));
                        break;
                    case ConsoleKey.D2:
                        inventory.GetItemList();
                        break;
                    case ConsoleKey.D3:
                        Console.Write("검색하실 아이템 이름을 입력하세요 : ");
                        inputItemName = Console.ReadLine();
                        inventory.GetItemByName(inputItemName);
                        break;
                    case ConsoleKey.D4:
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ArrayInventory
{
    public class Item
    {
        public string name;
 
        public Item(string name) //매개변수로  이름을 받아 멤버변수에 저장함
        {
            this.name = name;
        }
    }
}
cs


'C# > 수업내용' 카테고리의 다른 글

Inventory를 다시 Array로 되돌리기  (0) 2019.04.01
제너릭 클래스, 상속을 이용하여 Inventory 만들기  (0) 2019.04.01
Array를 이용하여 Inventory 만들기  (0) 2019.04.01
공부할것  (0) 2019.03.29
2. for, foreach, while  (0) 2019.03.27
: