Notice
Recent Posts
Recent Comments
Link
먼지나는 블로그
객체지향 본문
using System;
namespace CSharp
{
class Program
{
enum ClassType
{
None = 0,
Knight = 1,
Archer = 2,
Mage = 3
}
enum MonsterType
{
None = 0,
Slime = 1,
Orc = 2,
Skeleton = 3
}
struct Monster
{
public int hp;
public int attack;
}
struct Player
{
public int hp;
public int attack;
}
static ClassType ChoiceClass()
{
Console.WriteLine("직업을 선택하세요!");
Console.WriteLine("[1] 기사");
Console.WriteLine("[2] 궁수");
Console.WriteLine("[3] 마법사");
ClassType choice = ClassType.None;
string input = Console.ReadLine();
switch (input)
{
case "1":
choice = ClassType.Knight;
break;
case "2":
choice = ClassType.Archer;
break;
case "3":
choice = ClassType.Mage;
break;
}
return choice;
}
static void CreatePlayer(ClassType choice, out Player player)
{
switch (choice)
{
case ClassType.Knight:
player.hp = 100;
player.attack = 10;
break;
case ClassType.Archer:
player.hp = 75;
player.attack = 12;
break;
case ClassType.Mage:
player.hp = 50;
player.attack = 15;
break;
default:
player.hp = 0;
player.attack = 0;
break;
}
}
static void CreateRandomMonster(out Monster monster)
{
//랜덤으로 1~3 몬스터 중 하나를 리스폰
Random rand = new Random();
int randMonter = rand.Next(1, 4);
switch (randMonter)
{
case (int)MonsterType.Slime:
Console.WriteLine("슬라임이 스폰되었습니다!");
monster.hp = 20;
monster.attack = 2;
break;
case (int)MonsterType.Orc:
Console.WriteLine("오크가 스폰되었습니다!");
monster.hp = 40;
monster.attack = 4;
break;
case (int)MonsterType.Skeleton:
Console.WriteLine("스켈레톤이 스폰되었습니다!");
monster.hp = 30;
monster.attack = 3;
break;
default:
monster.hp = 0;
monster.attack = 0;
break;
}
}
static void Fight(ref Player player, ref Monster monster)
{
while (true)
{
//플레이어가 몬스터 공격
monster.hp -= player.attack;
if (monster.hp <= 0)
{
Console.WriteLine("승리했습니다!");
Console.WriteLine($"남은 체력 : {player.hp}");
break;
}
//몬스터 반격
player.hp -= monster.attack;
if (player.hp <= 0)
{
Console.WriteLine("패배했습니다!");
Console.WriteLine($"남은 체력 : {player.hp}");
break;
}
}
}
static void EnterField(ref Player player)
{
while (true)
{
Console.WriteLine("필드에 접속했습니다!");
//몬스터 생성
Monster monster;
CreateRandomMonster(out monster);
Console.WriteLine("[1] 전투모드로 돌입");
Console.WriteLine("[2] 일정 확률로 마을로 도망");
string input = Console.ReadLine();
if (input == "1")
{
Fight(ref player, ref monster);
}
else if (input == "2")
{
//33%
Random rand = new Random();
int randValue = rand.Next(0, 101);
if (randValue <= 33)
{
Console.WriteLine("도망치는데 성공했습니다!");
break;
}
else
{
Fight(ref player, ref monster);
}
}
}
//[1] 전투모드로 돌입
//[2] 일정 확률로 마을로 도망
}
static void EnterGame(ref Player player)
{
while(true)
{
Console.WriteLine("마을에 접속했습니다");
Console.WriteLine("[1] 필드로 가기");
Console.WriteLine("[2] 로비로 돌아가기");
string input = Console.ReadLine();
if (input == "1")
{
EnterField(ref player);
}
else if (input == "2")
{
break;
}
switch (input)
{
case "1":
break;
case "2":
break;
}
}
}
static void Main(string[] args)
{
while (true)
{
ClassType choice = ChoiceClass();
if (choice == ClassType.None)
continue;
//캐릭터 생성
Player player;
CreatePlayer(choice, out player);
//기사(100/10) 궁수(75/12) 법사(50/15)
//Console.WriteLine($"Hp{player.hp} Attack{player.attack}");
EnterGame(ref player);
}
}
}
}
앞서 작성했던 TextRPG 코드
함수 기반으로 이루어진 코드로 간단한 프로그램을
코딩할 땐 직관적으로 볼 수 있는 장점이 있지만
프로그램이 커질수록 유지보수가 힘든 큰 단점이 있다
또한 함수의 호출 순서가 바뀔 경우 로직이
꼬이게 되는 상황이 발생할 수 있다
따라서 오늘은 함수 기반이 아닌
객체지향 코드를 작성해보고자 한다
1. 클래스와 구조체
using System;
namespace CSharp
{
class Knight
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
struct Mage
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Mage Move");
}
public void Attack()
{
Console.WriteLine("Mage Attack");
}
}
class Program
{
//객체(OOP Object Oriented Programming
//knight
//속성 : hp, attack, pos
//기능 : Move, Attack, Die
static void Main(string[] args)
{
Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;
knight.Move();
knight.Attack();
}
}
}
같은 내용이 들어가있는 Knight클래스와
Mage구조체는 가장 큰 차이점이 존재한다
바로 Knight 클래스의 경우 참조하는 반면
Mage 구조체는 그저 카피한 값에 불과하다
using System;
namespace CSharp
{
//객체(OOP Object Oriented Programming
//knight
//속성 : hp, attack, pos
//기능 : Move, Attack, Die
//ref 참조
class Knight
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
// 카피
struct Mage
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Mage Move");
}
public void Attack()
{
Console.WriteLine("Mage Attack");
}
}
class Program
{
static void KillMage(Mage mage)
{
mage.hp = 0;
}
static void KillKnight(Knight knight)
{
knight.hp = 0;
}
static void Main(string[] args)
{
Mage mage;
mage.hp = 100;
mage.attack = 50;
KillMage(mage);
Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;
KillKnight(knight);
}
}
}
따라서 위의 코드를 디버깅을 통해
각 knight와 mage의 hp값이 mage는 그대로 100
knight는 0의 값이 저장된다는 것을 볼 수 있다
using System;
namespace CSharp
{
//객체(OOP Object Oriented Programming
//knight
//속성 : hp, attack, pos
//기능 : Move, Attack, Die
class Knight
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
struct Mage
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Mage Move");
}
public void Attack()
{
Console.WriteLine("Mage Attack");
}
}
class Program
{
static void KillMage(Mage mage)
{
mage.hp = 0;
}
static void KillKnight(Knight knight)
{
knight.hp = 0;
}
static void Main(string[] args)
{
Mage mage;
mage.hp = 100;
mage.attack = 50;
KillMage(mage);
Mage mage2 = mage;
mage.hp = 0;
Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;
KillKnight(knight);
Knight knight2 = new Knight();
knight2.hp = 100;
knight2.attack = 10;
}
}
}
mage와 mage2 knight와 knight2는
서로 다른 존재로 인식된다
하지만 매번 new로 생성하기엔 불편한 부분이
있기 때문에 이런 점을 해결하기 위한 것이
바로 딥카피를 이용하는 것이다
using System;
namespace CSharp
{
//객체(OOP Object Oriented Programming
//knight
//속성 : hp, attack, pos
//기능 : Move, Attack, Die
class Knight
{
public int hp;
public int attack;
public Knight Clone()
{
Knight knight2 = new Knight();
knight2.hp = hp;
knight2.attack = attack;
return knight2;
}
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
struct Mage
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Mage Move");
}
public void Attack()
{
Console.WriteLine("Mage Attack");
}
}
class Program
{
static void KillMage(Mage mage)
{
mage.hp = 0;
}
static void KillKnight(Knight knight)
{
knight.hp = 0;
}
static void Main(string[] args)
{
Mage mage;
mage.hp = 100;
mage.attack = 50;
KillMage(mage);
Mage mage2 = mage;
mage.hp = 0;
Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;
KillKnight(knight);
}
}
}
knight2를 knight클래스 내에
클론 함수 내에서 생성하였다