-
04/04 게임 알고리즘 시험자료구조/수업과제 2021. 4. 1. 00:45
'꿈의 나라'라는 머드 게임 구현연습
로그인 기능 구현
로그인 시 아이디 입력으로 기존유저와 신규유저 판별함
기존유저는 아이디와 일치하는 비밀번호를 입력하는것으로 게임 시작
신규유저는 이름과 비밀번호 성별등을 입력받아 회원가입유저 로그인 정보는 user_data.json에 저장
인벤토리 기능 구현
아이템을 버리고 줍는 기능을 구현아이템은 user_info.json에 저장
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { class Program { static void Main(string[] args) { new App(); } } }
App.cs
namespace Exam01 { public class App { public App() { new Login(); new GameLauncher(); } } }
GameManager.csusing System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace Exam01 { public class GameManager { private static GameManager instance; public UserData userData; public Dictionary<int, TextResourceData> dicTexts; public Dictionary<int, UserData> dicUsers; public Dictionary<int, UserInfo> dicUserInfos; public const string TEXT_DATA_PATH = "./text_data.json"; public const string USER_DATA_PATH = "./user_data.json"; public const string USER_INFO_PATH = "./user_info.json"; public GameManager() { LoadTextData(TEXT_DATA_PATH); LoadUserData(USER_DATA_PATH); LoadUserInfo(USER_INFO_PATH); } public static GameManager GetInstance() { if(GameManager.instance == null) { instance = new GameManager(); } return instance; } private void LoadTextData(string path) { string json = File.ReadAllText(path); TextResourceData[] texts = JsonConvert.DeserializeObject<TextResourceData[]>(json); dicTexts = texts.ToDictionary(x => x.id); } private void LoadUserData(string path) { if(File.Exists(path)) { string json = File.ReadAllText(path); UserData[] users = JsonConvert.DeserializeObject<UserData[]>(json); dicUsers = users.ToDictionary(x => x.no); } else { dicUsers = new Dictionary<int, UserData>(); } } private void LoadUserInfo(string path) { if (File.Exists(path)) { string json = File.ReadAllText(path); UserInfo[] users = JsonConvert.DeserializeObject<UserInfo[]>(json); dicUserInfos = users.ToDictionary(x => x.no); } else { dicUserInfos = new Dictionary<int, UserInfo>(); } } } }
TextResourceData.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { public class TextResourceData { public int id; public string text; } }
GameLauncher.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; namespace Exam01 { public class GameLauncher { UserInfo userInfo; List<Item> ItemsInTheGround = new List<Item>(); public GameLauncher() { ItemsInTheGround.Add(new Item("막대기")); Console.WriteLine(GameManager.GetInstance().dicTexts[10].text); ExplainMap(); Thread thread1 = new Thread(UserInfoSave); thread1.Start(); Thread thread2 = new Thread(PrintTick); thread2.Start(); //파일 내 유저 인포 데이터가 없으면 튜토리얼 시작 if(!File.Exists(GameManager.USER_INFO_PATH) || !GameManager.GetInstance().dicUserInfos.ContainsKey(GameManager.GetInstance().userData.no)) { userInfo = new UserInfo(GameManager.GetInstance().userData.no, GameManager.GetInstance().userData.name + "님의 방"); Console.WriteLine("초기 아이템 지급"); userInfo.inventory.items.Add(new Item("교복모자")); userInfo.inventory.items.Add(new Item("교복바지")); userInfo.inventory.items.Add(new Item("대걸레")); userInfo.inventory.items.Add(new Item("학교 졸업뱃지")); userInfo.inventory.items.Add(new Item("책가방")); userInfo.inventory.items.Add(new Item("실내화")); userInfo.inventory.items.Add(new Item("칠판지우개")); userInfo.inventory.items.Add(new Item("교복허리끈")); userInfo.inventory.items.Add(new Item("교복웃옷")); GameManager.GetInstance().dicUserInfos.Add(GameManager.GetInstance().userData.no , userInfo); string json = JsonConvert.SerializeObject(GameManager.GetInstance().dicUserInfos.Values.ToArray()); File.WriteAllText(GameManager.USER_INFO_PATH,json); } else { userInfo = GameManager.GetInstance().dicUserInfos[GameManager.GetInstance().userData.no]; } while(true) { var command = Console.ReadLine().Split(' '); if(command.Length == 1) { switch(command[0]) { case "동": case "서": case "남": case "북": case "위": case "아래": Console.WriteLine("{0}쪽으로 갑니다", command[0]); break; case "나가": break; case "꿈깨": ExitGame(); break; case "저장": SaveInfo(); Console.WriteLine("당신의 현재 상태를 저장합니다."); break; case "소지품": PrintInventory(); break; case "도움": case "도움말": Console.WriteLine(GameManager.GetInstance().dicTexts[11].text); break; default: Console.WriteLine("{0}::그런 명령은 없습니다.", command[0]); break; } } else if(command.Length > 1) { switch (command[command.Length-1]) { case "집다": PickUpItem(command[0]); break; case "버리다": DesertItem(command[0]); break; default: Console.WriteLine("{0}::그런 명령은 없습니다.", command[command.Length - 1]); break; } } PrintHpMpMvInfo(); } } private void PrintInventory() { Console.WriteLine("\n물건의 무게 [{0}/{1}] 물건의 부피[{2}/{3}]", userInfo.inventory.weight, userInfo.inventory.capacity, userInfo.inventory.volume, userInfo.inventory.capacity); Console.WriteLine("\t\t 당신이 가지고 있는 물건들"); foreach(Item item in userInfo.inventory.items) { Console.WriteLine(" {0}개 :: {1}", item.count, item.name); } } private void UserInfoSave() { while(true) { Thread.Sleep(20000); GameManager.GetInstance().dicUserInfos[GameManager.GetInstance().userData.no] = userInfo; string json = JsonConvert.SerializeObject(GameManager.GetInstance().dicUserInfos.Values.ToArray()); File.WriteAllText(GameManager.USER_INFO_PATH, json); PrintHpMpMvInfo(); } } private void SaveInfo() { GameManager.GetInstance().dicUserInfos[GameManager.GetInstance().userData.no] = userInfo; string json = JsonConvert.SerializeObject(GameManager.GetInstance().dicUserInfos.Values.ToArray()); File.WriteAllText(GameManager.USER_INFO_PATH, json); } private void ExitGame() { SaveInfo(); Console.WriteLine("꿈의 나라 여행이 즐거우셨는지 모르겠네요.꾸벅~\n너무 많은 여행은 피곤하겠죠 ? 조금씩만 하도록 하세용~~\n그럼 이만.\n 안암동에서 씨알."); Console.WriteLine("BYE"); Environment.Exit(0); } private void PickUpItem(string itemName) { Item pickUpItem = ItemsInTheGround.Find(x => x.name == itemName); if (pickUpItem != null) { userInfo.inventory.items.Add(pickUpItem); ItemsInTheGround.Remove(pickUpItem); Console.WriteLine("당신이 {0}을 집었습니다.", itemName); } else { Console.WriteLine("그런 물건은 없는데요?"); } } private void DesertItem(string itemName) { Item desertItem = userInfo.inventory.items.Find(x => x.name == itemName); if (desertItem != null) { ItemsInTheGround.Add(desertItem); userInfo.inventory.items.Remove(desertItem); Console.WriteLine("당신이 {0}을 버렸습니다.", itemName); } else { Console.WriteLine("그런 물건은 없는데요?"); } } private void PrintHpMpMvInfo() { Console.WriteLine("[HP {0}, MP {1}, MV {2}]", userInfo.hp, userInfo.mp, userInfo.mv); } private void ExplainMap() { Console.WriteLine("───━ {0}님의 방 ━───", GameManager.GetInstance().userData.name); Console.WriteLine("\n침대가 저만치 놓여있고, 그 주변에 여기 저기 물건들이 흩어져 있다. \n정신없이 널려져 있는 물건들을 보니 정리를 꽤나 안하는 모양이다.\n밖으로 나가는 길이 보이기는 하는데 어디로 가는 길인지는 모르겠다."); } private void PrintTick() { while(true) { Thread.Sleep(60000); Console.WriteLine("\n#### [틱방송]=========<<< 틱이 다가옵니다 >>>========= ####\n"); PrintHpMpMvInfo(); Thread.Sleep(5000); Console.WriteLine("밥 줘~~~ 밥 줘~~~~ 밥 줘~~~~~ 밥 줘~~~~~~ 밥 줘~~~~~~~"); Console.WriteLine("물 줘~~~ 물 줘~~~~ 물 줘~~~~~ 물 줘~~~~~~ 물 줘~~~~~~~"); Console.WriteLine("\n#### [틱방송]=========<<< 틱이 지나갔어요 >>>========= ####\n"); PrintHpMpMvInfo(); } } } }
UserData.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { public class UserData { public int no; public string id; public string name; public string pass; public string gender; public int tribe; } }
UserInfo.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { public class UserInfo { public int no; public string position; public int hp; public int mp; public int mv; public Inventory inventory; public UserInfo (int no , string position, int hp = 84, int mp = 44, int mv = 82) { this.no = no; this.position = position; this.hp = hp; this.mp = mp; this.mv = mv; inventory = new Inventory(94); } } }
Inventory.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { public class Inventory { public List<Item> items; public int capacity; public int volume; public int weight; public Inventory(int capacity) { this.capacity = capacity; items = new List<Item>(); } } }
Item.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Exam01 { public class Item { public int itemNum; public string name; public int count; public int volume; public int weight; public Item(string name, int count = 1, int volume = 1, int weight = 1) { this.name = name; this.count = count; this.volume = volume; this.weight = weight; } } }
Login.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace Exam01 { public class Login { public Login() { UserData user = null; string userId = ""; //초기화면 출력 Console.WriteLine(GameManager.GetInstance().dicTexts[1].text); Console.WriteLine("\n[Enter]를 누르세요.\n"); while (true) { if ((ConsoleKey)Console.ReadKey().KeyChar == ConsoleKey.Enter) { break; } } Console.WriteLine(GameManager.GetInstance().dicTexts[2].text); //아이디 입력 bool flag = true; while (true) { if(flag) { while (true) { Console.WriteLine("\n당신의 아이디는 ?"); userId = Console.ReadLine(); if (userId != null && userId.Length < 9) { break; } Console.WriteLine("아이디의 길이가 8자가 넘네요??\n정말 당신 아이디 맞아요 ? 그러지 말구 정확히 입력해 주세요. ^^; "); } Console.WriteLine("당신의 아이디가 '{0}' 맞습니까? [Y/n] ", userId); } flag = false; string yesOrNo = Console.ReadLine().Trim().ToLower(); if ("y"== yesOrNo || "예" == yesOrNo || "yes" == yesOrNo ) { break; } else if("n" == yesOrNo || "아니오" == yesOrNo || "no" == yesOrNo) { flag = true; continue; } if(!flag) { Console.WriteLine("(예 / 아니오)(YES / NO)(Y / N) 중 하나로 대답해주세요.."); } } IEnumerable<UserData> searchUser = GameManager.GetInstance().dicUsers.Values.Where(x => x.id == userId); if (searchUser.Count() != 0) { //기존유저 GameManager.GetInstance().userData = user = searchUser.First(); Console.WriteLine("어머 안녕하세요~~ {0}님 또 오셨군요.", user.name); Console.WriteLine("\n암호를 입력해주십시요. "); while (true) { if (user.pass == Console.ReadLine()) { break; } Console.WriteLine("\n암호가 틀린데요?? 다시한번 입력해 주세요. "); } } else { user = new UserData(); user.id = userId; Console.WriteLine("어머 처음 오셨네요~~ 환영해요~~"); Console.WriteLine("\n당신은 꿈의나라에서 누구라 불립니까?[중단: 끝]"); while (true) { var name = Console.ReadLine(); if (name.Length < 9) { if (GameManager.GetInstance().dicUsers.Values.Where(x => x.name == name).Count() != 0) { Console.WriteLine("\n이미 사용중인 이름이군요. 다른 이름을 넣어주세요."); continue; } else { Console.WriteLine("\n새로운 이름이군요.이 이름을 원하십니까 ? (Y / n)"); var yesOrNo = Console.ReadLine(); if ("y" == yesOrNo || "예" == yesOrNo || "yes" == yesOrNo) { user.name = name; break; } else if ("n" == yesOrNo || "아니오" == yesOrNo || "no" == yesOrNo) { Console.WriteLine("\n그러면 다시 이름을 입력하세요. "); } else { Console.WriteLine("\n(예 / 아니오)(YES / NO)(Y / N) 중 하나로 대답해주세요.."); } } } else if (name == "끝") { Console.WriteLine("BYE"); Environment.Exit(0); } else { Console.WriteLine("사용자의 이름은 8자를 넘을 수 없습니다."); } } user.no = GameManager.GetInstance().dicUsers.Count == 0 ? 1 : GameManager.GetInstance().dicUsers.Values.OrderBy(x => x.no).Last().no + 1; while (true) { Console.WriteLine("\n암호를 입력해주십시요. "); var tmpPass1 = Console.ReadLine(); Console.WriteLine("\n확인을 위해 다시한번 암호를 입력해주십시요. "); var tmpPass2 = Console.ReadLine(); if (tmpPass1 == tmpPass2) { user.pass = tmpPass1; break; } Console.WriteLine("\n먼저 입력하신 암호와 다르군요.\n암호를 다시 정하시죠. "); } Console.WriteLine("\n당신의 성별은 무엇입니까? (남[M]/여[F]) "); while (true) { var tmp = Console.ReadLine(); if (tmp == "남" || tmp == "여" || tmp == "M" || tmp == "F") { switch (tmp) { case "남": case "M": tmp = "M"; break; case "여": case "F": tmp = "F"; break; } user.gender = tmp; break; } else { Console.WriteLine("\n성별이 어떻게 된다고요 ?? (남[M] / 여[F])"); } } Console.WriteLine("꿈의 나라에는 다음과 같은 아홉 신족이 있습니다.\n== 천신(1) / 지신(2) / 마신(3) / 용신(4) / 호신(5) / 수신(6) / 화신(7) / 광신(8) / 사신(9) ==\n당신은 어느 신족에 속하십니까 ? (해당 번호를 입력하세요) "); while (true) { var tmp = int.Parse(Console.ReadLine()); if (tmp > 0 && tmp < 10) { user.tribe = tmp; break; } else { Console.WriteLine("\n그런 신족은 없는데요 ? 다시한번 입력해주세요(1 - 9) "); } } GameManager.GetInstance().dicUsers.Add(user.no, user); string json = JsonConvert.SerializeObject(GameManager.GetInstance().dicUsers.Values.ToArray()); File.WriteAllText(GameManager.USER_DATA_PATH, json); } GameManager.GetInstance().userData = user; } } }