* amount 숫자 증가 X - 수업 이후 해결
1. App.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class App
{
// 생성자
public App()
{
Game game = new Game();
game.Start();
}
}
}
2. Game.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
namespace Study08
{
public class Game
{
// 필드
public List<Monster> monsters;
private Inventory inven;
// 생성자
public Game()
{
this.inven = new Inventory();
this.monsters = new List<Monster>();
this.LoadDatas();
if (!this.IsNewbie())
{
this.LoadInfos();
}
}
public void Start()
{
Console.WriteLine("Start");
this.CreateMonster(100);
this.CreateMonster(101);
this.CreateMonster(102);
foreach (var monster in this.monsters)
{
//MonsterData data = DataManager.instance.GetMonsterData(monster.Id);
//Console.WriteLine(data.name);
Console.WriteLine("{0}, {1}", monster.Id, monster.Name);
}
Monster target = this.monsters[0];
// Action 대리자
target.dieAction = () =>
{
this.monsters.Remove(target); // List에서 제거
Console.WriteLine(this.monsters.Count); // 2
MonsterData data = DataManager.instance.GetMonsterData(target.Id);
Item item = this.DropItem(data.drop_item0, data.drop_item1, data.drop_item2);
this.inven.Add(item);
Console.WriteLine("아이템 수: {0}", this.inven.Count);
this.Save();
};
target.onHit += (sender, args) =>
{
Console.WriteLine("{0}%", args.per); // 남은 체력 %
};
Console.WriteLine(target);
target.Hit(14);
target.Hit(16);
}
public Item DropItem(params int[] arr)
{
IEnumerable<int> ids = arr.Where(x => x != 0);
Random rand = new Random();
var idx = rand.Next(0, ids.Count()); // 0, 1
foreach (var id in arr)
{
Console.WriteLine("=>{0}", id);
}
int randItemIdx = arr[idx];
Console.WriteLine(randItemIdx);
ItemData data = DataManager.instance.GetItemData(randItemIdx);
return this.CreateItem(data.id);
}
private Item CreateItem(int id)
{
ItemInfo info = new ItemInfo(id);
return new Item(info);
}
private void LoadInfos()
{
var itemInfosJson = File.ReadAllText("./item_infos.json");
// 역직렬화
var itemInfos = JsonConvert.DeserializeObject<ItemInfo[]>(itemInfosJson);
Console.WriteLine(itemInfos);
foreach (var info in itemInfos)
{
var item = new Item(info);
this.inven.Add(item);
}
Console.WriteLine("인벤토리 아이템 갯수 : {0}", this.inven.Count);
}
private bool IsNewbie()
{
var exists = File.Exists("./item_infos.json");
if (exists)
Console.WriteLine("기존 유저");
else
Console.WriteLine("신규 유저");
return !exists;
}
private void LoadDatas()
{
DataManager.instance.LoadMonsterDatas();
DataManager.instance.LoadItemDatas();
}
private void CreateMonster(int id)
{
Monster mon = new Monster(id);
this.monsters.Add(mon);
}
public void Save()
{
// 직렬화: 객체 -> 문자열
// List<Item> -> [{"id": 100 }]
var json = JsonConvert.SerializeObject(this.inven.GetItems());
Console.WriteLine( json);
// 파일로 저장
File.WriteAllText("./item_infos.json", json);
Console.WriteLine("인벤토리 아이템들 저장 완료");
}
}
}
// 저장할 때는 시점이 저장됨
3. DataManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Linq;
namespace Study08
{
// 싱글톤 클래스
// sealed: 봉인 키워드 -> 상속 불가
public sealed class DataManager
{
// static: 정적 키워드, 프로그램 시작해서 끝날 때까지 값 유지 -> 형식으로 접근해야 함
// readonly: 읽기 전용 필드 생성
public static readonly DataManager instance = new DataManager();
private Dictionary<int, MonsterData> dicMonsters;
private Dictionary<int, ItemData> dicItems;
// private 생성자
private DataManager()
{
}
// 인스턴스 메서드
public void LoadItemDatas()
{
string json = File.ReadAllText("./item_data.json");
// 역직렬화
var arr = JsonConvert.DeserializeObject<ItemData[]>(json);
this.dicItems = arr.ToDictionary(x => x.id);
Console.WriteLine("item_data가 로드되었습니다. {0}", this.dicItems.Count);
}
public void LoadMonsterDatas()
{
Console.WriteLine("LoadData");
string json = File.ReadAllText("./monster_data.json");
Console.WriteLine(json);
// 역직렬화 : 문자열 -> 객체
// 몬스터 데이터 배열을 반환
MonsterData[] arrMonsterDatas = JsonConvert.DeserializeObject<MonsterData[]>(json);
// Linq 사용
// 내부 람다의 의미는 배열에 담긴 객체의 속성 중 key를 어떤 것으로 할 것인가?
this.dicMonsters = arrMonsterDatas.ToDictionary(x => x.id);
// Linq 사용 X
////this.dicMonsters = new Dictionary<int, MonsterData>();
//// 배열에 담긴 MonsterData 객체 사전에 옮긴다
//foreach (MonsterData data in arrMonsterDatas)
//{
// this.dicMonsters.Add(data.id, data);
//}
// 확인
foreach (KeyValuePair<int, MonsterData> pair in this.dicMonsters)
{
// id, monsterdata 인스턴스 출력됨
Console.WriteLine("key: {0}, value: {1}", pair.Key, pair.Value);
}
}
public MonsterData GetMonsterData(int id)
{
return this.dicMonsters[id];
}
public ItemData GetItemData(int id)
{
return this.dicItems[id];
}
}
}
4. MonsterData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class MonsterData
{
public int id;
public string name;
public float max_hp;
public int drop_item0; // item_data 테이블의 id
public int drop_item1;
public int drop_item2;
}
}
5. Monster.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class Monster
{
public class HitEventArgs : EventArgs
{
public float per;
}
public int Id
{
get;
private set;
}
public string Name
{
get
{
MonsterData data = DataManager.instance.GetMonsterData(this.Id);
return data.name;
}
}
private float hp; // 현재 체력
private float maxHp; // 최대 체력
public Action dieAction;
public EventHandler<HitEventArgs> onHit;
// 생성자
public Monster(int id)
{
this.Id = id;
MonsterData data = DataManager.instance.GetMonsterData(this.Id);
this.maxHp = data.max_hp;
this.hp = this.maxHp;
Console.WriteLine("몬스터 (id: {0})가 생성되었습니다.", this.Id);
Console.WriteLine("체력 {0}/{1}", this.hp, this.maxHp);
}
public bool IsDie()
{
return this.hp <= 0;
}
public void Hit(int damage)
{
if (this.IsDie()) return;
this.hp -= damage;
if (this.hp <= 0)
this.hp = 0;
var args = new HitEventArgs();
args.per = this.hp / this.maxHp * 100.0f;
this.onHit(this, args);
//this.onHit(this, new HitEventArgs() { per = this.hp / this.maxHp });
Console.WriteLine("{0}이(가) {1} 피해를 입었습니다. (체력 {2}/{3})", this.Name, damage, this.hp, this.maxHp);
if(this.hp <= 0)
{
this.Die();
}
}
private void Die()
{
Console.WriteLine("id: {0}, name: {1}이(가) 죽었습니다.", this.Id, this.Name);
this.DieAction();
}
public void DieAction()
{
this.dieAction();
}
}
}
6. ItemData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class ItemData
{
public int id;
public string name;
public float damage;
}
}
7. Item.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class Item
{
private ItemInfo info; // 저장 객체
public int Id
{
get
{
return this.info.id;
}
}
public int Amount
{
get
{
return this.info.amount;
}
set
{
this.info.amount = value;
}
}
// 생성자
public Item(ItemInfo info)
{
this.info = info;
this.info.amount = Amount;
}
}
}
8. ItemInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class ItemInfo
{
// 저장 객체를 public으로 정의
public int id;
public int amount;
// 생성자
public ItemInfo(int id, int amount = 1)
{
this.id = id;
this.amount = amount;
}
}
}
9. Inventory.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study08
{
public class Inventory
{
private List<Item> items;
public int Count
{
get
{
return this.items.Count;
}
}
// 생성자
public Inventory()
{
this.items = new List<Item>();
}
public void Add(Item item)
{
// 아래와 같은 기능
//Item sameItem = null;
//for (int i = 0; i < this.items.Count; i++)
//{
// if (this.items[i].Id == item.Id)
// {
// sameItem = this.items[i];
// break;
// }
//}
var sameItem = this.items.Find(x => x.Id == item.Id);
if (sameItem != null)
{
sameItem.Amount++;
}
else {
this.items.Add(item);
}
}
public void Remove(Item item)
{
this.items.Remove(item);
}
public List<Item> GetItems()
{
return this.items;
}
}
}
'C# > 수업 내용' 카테고리의 다른 글
[C#] 알고리즘 문제 (0) | 2022.07.06 |
---|---|
Json 연습 2 - 캐릭터, 경험치 데이터 (1) | 2022.06.21 |
대리자 연습 (0) | 2022.06.16 |
2차원 배열 맵타일 (0) | 2022.06.15 |
2048 왼쪽 이동 (0) | 2022.06.15 |