언어 자료구조 알고리즘/프로그래밍 실습

[C#] 상속과 다형성 실습 - 학생, 학사학생, 마법학생, 운동학생

언제나휴일 2019. 8. 9. 15:07
반응형

실습) 다음 시나리오에 맞게 프로그램을 작성하시오.

시나리오
프로그램이 시작하면서 학사 학생과 운동 학생, 마법 학생을 한 명씩 생성
학생을 생성 후 전체 학생에게 강의=>자습=>잠자기=>휴식하기=>음료마시기=>노래하기 순으로 진행
(각 단계마다 학생 정보를 출력)
자습하기에서는 해당 학생이 학사 학생이면 독서도 지시함
휴식하기에서는 해당 학생이 마법 학생이면 여행도 지시함
노래하기에서는 해당 학생이 운동 학생이면 춤추게 지시함 
학생
멤버 필드로 이름, 주민번호, 체력, 지력, 스트레스가 있음
번호: 순차적 부여, 변하지 않음
이름: 생성 시 전달
지력:100(최소 0, 최대 200)
체력: 100 (최소 0, 최대 200)
스트레스: 0 (최소 0, 최대 100)
연속으로 공부한 횟수: 0 (0,5), 공부를 하면 1 증가, 그 외의 행위를 하면 0으로 리셋, scnt로 부름 

 

 

학사 학생
멤버 필드로 더미 뇌가 있음
더미 뇌는 생성 시 0 이며 공부한 회수가 5의 배수가 될 때마다 1씩 증가
공부하다.
체력 5소모, 지력: scnt+더미 뇌 증가, 스트레스: 2감소
강의를 받다.
체력 3소모, 지력: scnt 증가, 스트레스: scnt증가
잠자다.
체력 10회복, 스트레스: 5감소     *scnt는 연속 공부한 회수
휴식하다.
체력 3회복, 스트레스: 25감소
음료 섭취
체력 5회복, 지력:  10감소 , 스트레스: 2증가
노래하다.
체력 10 소모, 지력: 5-scnt감소, 스트레스: 5-scnt증가
독서하다.
더미 뇌 1증가, 스트레스: 5감소

 

 

마법 학생마법 학생은 내부적으로 지팡이가 있다.
지팡이는 생성 시 0이며 마법 여행 시 1씩 증가
공부하다.
체력 3소모, 지력: scnt 증가, 스트레스: 3증가
강의를 받다.
체력 2소모, 지력: scnt 증가, 스트레스: 5증가
잠자다.
체력 10회복, 스트레스: 5감소
휴식하다.
체력 3회복, 스트레스: 25감소
음료 섭취
체력 5+지팡이 회복, 지력:  10-지팡이 감소, 스트레스: 2감소
노래하다.
체력 10-지팡이 소모, 지력: 5감소, 스트레스: 5감소
마법 여행을 가다.
지팡이 1증가

 

 

운동 학생
운동 학생은 내부적으로 air가 있다.
air는 생성 시 0 이며 춤을 추면 1 증가
공부하다.
체력 2소모, 지력: scnt/2 증가,
air 3 감소, air*3만큼 스트레스 감소
강의를 받다.
체력 1소모, 지력: scnt/2 증가,
air :5 감소, air*3만큼 스트레스 감소
잠자다.
체력 10회복, 스트레스: 5감소
휴식하다.
체력 8회복, 스트레스: 25감소
음료 섭취
체력 5 회복, 지력:  3 감소, 스트레스: 2감소
노래하다.
체력 5소모, 지력: 2증가, 스트레스: 5감소
춤을 추다.
체력 5소모, 지력: 3증가, air 1증가

*2019년 공주대에서

 

실습 결과

StuValue.cs

namespace 학사_마법_운동
{
    /// <summary>
    /// 학생 값을 정의한 정적 클래스
    /// </summary>
    internal static class StuValue
    {
        /// <summary>
        /// 최소 HP:0
        /// </summary>
        internal const int MIN_HP=0;
        /// <summary>
        /// 최대 HP:200
        /// </summary>
        internal const int MAX_HP = 200;
        /// <summary>
        /// 디폴트 HP:100
        /// </summary>
        internal const int DEF_HP = 100;

        /// <summary>
        /// 최소 IQ:0
        /// </summary>
        internal const int MIN_IQ = 0;
        /// <summary>
        /// 최대 IQ:200
        /// </summary>
        internal const int MAX_IQ = 200;
        /// <summary>
        /// 디폴트 IQ:100
        /// </summary>
        internal const int DEF_IQ = 100;

        /// <summary>
        /// 최소 스트레스:0
        /// </summary>
        internal const int MIN_STRESS = 0;
        /// <summary>
        /// 최대 스트레스:100
        /// </summary>
        internal const int MAX_STRESS = 100;
        /// <summary>
        /// 디폴트 스트레스:0
        /// </summary>
        internal const int DEF_STRESS = 0;

        /// <summary>
        /// 최소 연속으로 공부한 횟수:0
        /// </summary>
        internal const int MIN_SCNT = 0;
        /// <summary>
        /// 최대 연속으로 공부한 횟수:5
        /// </summary>
        internal const int MAX_SCNT = 5;
        /// <summary>
        /// 디폴트 연속으로 공부한 횟수:0
        /// </summary>
        internal const int DEF_SCNT = 0;
    }
}

Student.cs

using System;
namespace 학사_마법_운동
{
    /// <summary>
    /// 학생 클래스 - 추상 클래스
    /// </summary>
    internal abstract class Student
    {
        string name;//이름(생성 시 전달)
        readonly int no;//주민번호(순차적 부여)
        int hp;//체력: 100 (최소 0, 최대 200)
        /// <summary>
        /// 체력 속성 - 가져오기
        /// </summary>
        public int Hp
        {
            get
            {
                return hp;
            }
            protected set
            {
                if(value<StuValue.MIN_HP)
                {
                    value = StuValue.MIN_HP;
                }
                if(value> StuValue.MAX_HP)
                {
                    value = StuValue.MAX_HP;
                }
                hp = value;
            }
        }

        int iq;//지력
        /// <summary>
        /// 지력 속성 - 가져오기
        /// </summary>
        public int IQ
        {
            get
            {
                return iq;
            }
            protected set
            {
                if(value<StuValue.MIN_IQ)
                {
                    value = StuValue.MIN_IQ;
                }
                if(value>StuValue.MAX_IQ)
                {
                    value = StuValue.MAX_IQ;
                }
                iq = value;
            }
        }
        int stress;//스트레스
        /// <summary>
        /// 스트레스 속성 - 가져오기
        /// </summary>
        public int Stress
        {
            get
            {
                return stress;
            }
            protected set
            {
                if(value<StuValue.MIN_STRESS)
                {
                    value = StuValue.MIN_STRESS;
                }
                if(value>StuValue.MAX_STRESS)
                {
                    value = StuValue.MAX_STRESS;
                }
                stress = value;
            }
        }
        int scnt;//연속으로 공부한 횟수
        /// <summary>
        /// 연속으로 공부한 횟수 속성 - 가져오기
        /// </summary>
        protected int Scnt
        {
            get
            {
                return scnt;
            }
            private set
            {
                if(value>StuValue.MAX_SCNT)
                {
                    value = StuValue.MAX_SCNT;
                }
                scnt = value;
            }            
        }
        static int lastno;//가장 최근에 부여한 주민번호
        /// <summary>
        /// 학생 생성자
        /// </summary>
        /// <param name="name">학생 이름</param>
        internal Student(string name)
        {
            this.name = name;
            iq = StuValue.DEF_IQ;
            hp = StuValue.DEF_HP;
            stress = StuValue.DEF_STRESS;
            scnt = StuValue.DEF_SCNT;
            lastno++;
            no = lastno;
        }
        //internal abstract Anything(); 파생 클래스에서 반드시 재정의하세요.
        /// <summary>
        /// 음료를 마시다.
        /// </summary>
        internal virtual void Drink()
        {
            Console.WriteLine("{0} 마시다.", this);
            scnt = 0;
        }       
        /// <summary>
        /// 잠을 자다.
        /// </summary>
        internal virtual void Sleep()//파생 클래스에서 재정의 할 수 있어요.
        {
            Console.WriteLine("{0} 잠자다.", this);
            scnt = 0;
        }
        /// <summary>
        /// 공부하다.
        /// </summary>
        internal virtual void Study()
        {
            Console.WriteLine("{0} 공부하다.", this);
            Scnt= scnt+1;
        }
        /// <summary>
        /// 노래하다.
        /// </summary>
        internal virtual void Sing()
        {
            Console.WriteLine("{0} 노래하다.", this);
            scnt = 0;
        }
        /// <summary>
        /// 강의를 받다.
        /// </summary>
        internal virtual void ListenLecture()
        {
            Console.WriteLine("{0} 강의받다.", this);
            Scnt= scnt + 1;
        }
        /// <summary>
        /// 휴식하다.
        /// </summary>
        internal virtual void Relax()
        {
            Console.WriteLine("{0} 휴식하다.", this);
            scnt = 0;
        }
        /// <summary>
        /// ToString 메서드 재정의
        /// </summary>
        /// <returns>번호와 이름</returns>
        public override string ToString()
        {
            return string.Format("<{0},{1}>",no,name);
        }
    }
}

SStudent.cs

using System;

namespace 학사_마법_운동
{
    /// <summary>
    /// 학사 학생 - 학생 클래스에서 파생
    /// </summary>
    internal class SStudent : Student
    {
        int dummy;//더미 뇌는 생성 시 0 이며 공부한 횟수가 5의 배수가 될 때마다 1씩 증가
        int study_cnt;//공부한 횟수
        public SStudent(string name):base(name)
        {        
        }

        internal override void Drink()
        {
            //음료 섭취
            //체력 5회복, 지력: 10감소 , 스트레스: 2증가
            base.Drink();
            Hp += 5;
            IQ -= 10;
            Stress += 2;
        }
        internal override void ListenLecture()
        {
            //강의를 받다.
            //체력 3소모, 지력: scnt 증가, 스트레스: scnt증가
            base.ListenLecture();
            Hp -= 3;
            IQ += Scnt;
            Stress += Scnt;
        }
        internal override void Relax()
        {
            //휴식하다.
            //체력 3회복, 스트레스: 25감소
            base.Relax();
            Hp += 3;
            Stress -= 25;
        }
        internal override void Sing()
        {
            //노래하다.
            //체력 10 소모, 지력: 5 - scnt감소, 스트레스: 5 - scnt증가
            base.Sing();
            Hp -= 10;
            IQ -= 5 - Scnt;
            Stress += 5 - Scnt;
        }
        internal override void Sleep()
        {
            //잠자다.
            //체력 10회복, 스트레스: 5감소
            base.Sleep();
            Hp += 10;
            Stress -= 5;
        }
        internal override void Study()
        {
            //공부하다.
            //체력 5소모, 지력: scnt + 더미 뇌 증가, 스트레스: 2감소
            base.Study();
            Hp -= 5;
            IQ += Scnt + dummy;
            Stress -= 2;
            study_cnt++;
            if(study_cnt %5 == 0)
            {
                dummy++;
            }
        }
        /// <summary>
        /// 책을 읽다.
        /// </summary>
        internal void Reading()
        {
            //독서하다.
            //더미 뇌 1증가, 스트레스: 5감소
            Console.WriteLine("{0} 독서하다.", this);
            dummy++;
            Stress -= 5;            
        }
    }
}

MStudent.cs

using System;

namespace 학사_마법_운동
{
    /// <summary>
    /// 마법 학생 - 학생 클래스에서 파생
    /// </summary>
    internal class MStudent : Student
    {
        int stick;//지팡이
        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="name">학생 이름</param>
        public MStudent(string name):base(name)
        {            
        }
        /// <summary>
        /// 음료를 마시다.
        /// </summary>
        internal override void Drink()
        {
            //음료 섭취
            //체력 5 + 지팡이 회복, 지력: 10 - 지팡이 감소, 스트레스: 2감소
            base.Drink();
            Hp += 5 + stick;
            IQ -= 10 - stick;
            Stress -= 2;
        }
        /// <summary>
        /// 강의받다.
        /// </summary>
        internal override void ListenLecture()
        {
            //강의를 받다.
            //체력 2소모, 지력: scnt 증가, 스트레스: 5증가
            base.ListenLecture();
            Hp -= 2;
            IQ += Scnt;
            Stress += 5;
        }
        /// <summary>
        /// 휴식하다.
        /// </summary>
        internal override void Relax()
        {
            //휴식하다.
            //체력 3회복, 스트레스: 25감소
            base.Relax();
            Hp += 3;
            Stress -= 25;
        }
        /// <summary>
        /// 노래하다.
        /// </summary>
        internal override void Sing()
        {
            //노래하다.
            //체력 10 - 지팡이 소모, 지력: 5감소, 스트레스: 5감소
            base.Sing();
            Hp -= 10 - stick;
            IQ -= 5;
            Stress -= 5;
        }
        /// <summary>
        /// 잠을 자다.
        /// </summary>
        internal override void Sleep()
        {
            //잠자다.
            //체력 10회복, 스트레스: 5감소
            base.Sleep();
            Hp += 10;
            Stress -= 5;
        }
        /// <summary>
        /// 공부하다.
        /// </summary>
        internal override void Study()
        {
            //공부하다.
            //체력 3소모, 지력: scnt 증가, 스트레스: 3증가
            base.Study();
            Stress -= 3;
            IQ += Scnt;
            Stress += 3;
        }

        /// <summary>
        /// 여행가다.
        /// </summary>
        internal void Travel()
        {
            //마법 여행을 가다.
            //지팡이 1증가
            Console.WriteLine("{0} 여행 가다.", this);
            stick++;
        }
    }
}

PStudent.cs

using System;

namespace 학사_마법_운동
{
    /// <summary>
    /// 운동 학생 - 학생 클래스에서 파생
    /// </summary>
    internal class PStudent : Student
    {
        int air;
        public PStudent(string name):base(name)
        {            
        }

        internal override void Drink()
        {
            //음료 섭취
            //체력 5 회복, 지력: 3 감소, 스트레스: 2감소
            base.Drink();
            Hp += 5;
            IQ -= 3;
            Stress -= 2;
        }
        internal override void Relax()
        {
            //휴식하다.
            //체력 8회복, 스트레스: 25감소
            base.Relax();
            Hp += 8;
            Stress -= 25;
        }
        internal override void ListenLecture()
        {
            //강의를 받다.
            //체력 1소모, 지력: scnt / 2 증가,
            //air :5 감소, air*3만큼 스트레스 감소
            base.ListenLecture();
            Hp -= 1;
            IQ += Scnt / 2;
            air -= 5;
            Stress -= air * 3;
        }
        internal override void Sing()
        {
            //노래하다.
            //체력 5소모, 지력: 2증가, 스트레스: 5감소
            base.Sing();
            Hp -= 5;
            IQ += 2;
            Stress -= 5;
        }
        internal override void Sleep()
        {
            //잠자다.
            //체력 10회복, 스트레스: 5감소
            base.Sleep();
            Hp += 10;
            Stress -= 5;
        }
        internal override void Study()
        {
            //공부하다.
            //체력 2소모, 지력: scnt / 2 증가,
            //air 3 감소, air*3만큼 스트레스 감소
            base.Study();
            Hp -= 2;
            IQ += Scnt / 2;
            air -= 3;
            Stress -= air * 3;
        }
        /// <summary>
        /// 춤을 추다.
        /// </summary>
        internal void Dance()
        {
            //춤을 추다.
            //체력 5소모, 지력: 3증가, air 1증가
            Console.WriteLine("{0} 춤을 추다.", this);
            Hp -= 5;
            IQ += 3;
            air++;
        }
    }
}

Application.cs

using System;

namespace 학사_마법_운동
{
    /// <summary>
    /// 응용 클래스 - 학사, 마법, 운동 학생 테스트 용도
    /// </summary>
    internal class Application
    {
        Student[] stues = new Student[3];
        /// <summary>
        /// 실행하다.
        /// </summary>
        internal void Run()
        {
            //프로그램이 시작하면서 학사 학생과 운동 학생, 마법 학생을 한 명씩 생성           
            stues[0] = new SStudent("공부잘");
            stues[1] = new MStudent("휘리릭");
            stues[2] = new PStudent("빨라요");

            //학생을 생성 후 전체 학생에게 강의=>자습 => 잠자기 => 휴식하기 => 음료마시기 => 노래하기 순으로 진행
            //(각 단계마다 학생 정보를 출력)
            StartLecture();
            SelfStudy();
            TurnOff();
            TeaTime();
            Party();
            GoToNoRaeRoom();
        }

        private void GoToNoRaeRoom()
        {
            //노래하기
            //노래하기에서는 해당 학생이 운동 학생이면 춤추게 지시함
            for (int i = 0; i<stues.Length;i++)
            {
                stues[i].Sing();
                PStudent ps = stues[i] as PStudent;
                if(ps!=null)
                {
                    ps.Dance();
                }
                ViewStuInfo(stues[i]);                
            }
        }

        private void ViewStuInfo(Student student)
        {
            Console.WriteLine("=== {0} === ", student);
            Console.WriteLine("   지력:{0}, 체력:{1} 스트레스:{2}", student.IQ, student.Hp, student.Stress);
        }

        private void Party()
        {
            //음료마시기
            for (int i = 0; i < stues.Length; i++)
            {
                stues[i].Drink();
                ViewStuInfo(stues[i]);
            }
        }

        private void TeaTime()
        {
            //휴식하기
            //휴식하기에서는 해당 학생이 마법 학생이면 여행도 지시함
            for (int i = 0; i < stues.Length; i++)
            {
                stues[i].Relax();
                MStudent ms = stues[i] as MStudent;
                if(ms != null)
                {
                    ms.Travel();
                }
                ViewStuInfo(stues[i]);
            }
        }

        private void TurnOff()
        {
            //잠자기
            for (int i = 0; i < stues.Length; i++)
            {
                stues[i].Sleep();
                ViewStuInfo(stues[i]);
            }
        }

        private void SelfStudy()
        {
            //자습
            //자습하기에서는 해당 학생이 학사 학생이면 독서도 지시함
            for (int i = 0; i < stues.Length; i++)
            {
                stues[i].Study();
                SStudent ss = stues[i] as SStudent;
                if(ss != null)
                {
                    ss.Reading();
                }
                ViewStuInfo(stues[i]);
            }
        }

        private void StartLecture()
        {
            //강의
            for (int i = 0; i < stues.Length; i++)
            {
                stues[i].ListenLecture();
                ViewStuInfo(stues[i]);
            }
        }
    }
}

Program.cs

namespace 학사_마법_운동
{
    class Program
    {
        static void Main(string[] args)
        {            
            Application app = new Application();
            app.Run();
        }
    }
}

실행 화면

*버그는 각자가 잡아 보시길...*

반응형