언어 자료구조 알고리즘/Escort C#

[C#] 프로젝트 구현 - 학생 이동

언제나휴일 2016. 5. 3. 13:38
반응형

7.4 프로젝트 구현

 

학생 이동


학생 이동 시퀀스 다이어그램

[그림] 학생 이동 시퀀스 다이어그램


 이제 학생 이동에 대한 MoveStudent 메서드를 구현해 봅시다. 시퀀스 다이어그램을 보면 학생 이동 기능에서는 먼저 캠퍼스에 있는 모든 학생 정보를 보여주고 사용자가 이동할 학생 번호를 입력한 후에 장소를 선택하면 해당 장소로 보내기로 되어 있습니다. 그런데 현재 약속된 시퀀스 다이어그램에서는 선택된 학생이 캠퍼스에도 여전히 존재하게 되어 있네요. 이에 선택된 장소에 학생을 보내기 전에 캠퍼스에세 나오게 하는 메서드(OutStudent) Campus 클래스에 추가하기로 할게요. 여러분들은 시퀀스 다이어그램에도 수정하시기 바랍니다.

 

class Campus

{

    ... 중략 ...

    internal void OutStudent(Student student)

    {

        throw new NotImplementedException();

    }

}

 

 캠퍼스 생활의 MoveStudent는 시퀀스 다이어그램를 보면서 작성해 봅시다. 먼저, 모든 학생 정보를 출력하고 이동할 학생과 장소를 선택해서 선택된 장소로 보내면 되겠죠.

 

class CampusLife

{

    ... 중략 ...

    private void MoveStudent()

    {

        ViewStuInfoInCampus(); //모든 학생 정보 출력

        Console.WriteLine("이동할 학생 번호를 입력하세요.");

        int num = EHLib.GetNum();

 

        Student student = campus[num]; //입력한 번호의 학생 참조

 

        if (student == null) //입력한 번호의 학생이 없을

        {

            Console.WriteLine("잘못 선택하였습니다. ");

            return;

        }

        Place place = SelectPlace(); //장소 선택

 

        if (place == null) //잘못 선택하였을

        {

            Console.WriteLine("잘못 선택하였습니다.");

            return;

        }

        campus.OutStudent(student); //캠퍼스에서 학생이 나간다.

        place.InStudent(student); //선택된 장소로 학생이 들어간다.

    }

}

 

 이제 캠퍼스에 있는 학생 정보를 출력하는 메서드인 ViewStuInfoInCampus를 구현해 봅시다. 여기에서는 단순히 캠퍼스에 있는 학생 수를 얻어와서 차례대로 학생 정보를 얻어와 화면에 출력하면 되겠죠.

 

class CampusLife

{

    ... 중략 ...

    private void ViewStuInfoInCampus()

    {

        int scnt = campus.StuCount;

        for (int i = 0; i < scnt; i++)

        {

            Console.WriteLine(campus.GetStuInfo(i));

        }

    }

}

 

 캠퍼스의 StuCount 속성은 학생들을 보관하는 배열에 보관된 요소 개수를 반환하면 될 것입니다. 그리고 캠퍼스에 i번째 요소 정보를 문자열로 반환하는 GetStuInfo에서는 학생의 ToString 메서드를 호출하여 얻은 문자열을 그대로 반환하면 되겠죠.

 

class Campus

{

    ... 중략 ...

    internal int StuCount

    {

        get

        {

            return FindEmptyIndex();

        }

    }

 

    internal string GetStuInfo(int nth)

    {

        if ((nth >= 0) && (nth < FindEmptyIndex() ) )

        {

           return students[nth].ToString();

        }

 

        return "해당 학생 정보 없음";

    }

}

 

 이번에는 Campus의 특정 번호의 학생을 반환하는 인덱서를 구현해 보기로 합시다. 여기에서는 차례대로 학생의 번호가 입력된 번호와 같은지 확인해서 해당 학생 개체를 반환하면 될 것입니다.

 

class Campus

{

    ... 중략 ...

    internal Student this[int snum]

    {

        get

        {

            for (int i = 0; i < students.Length; i++)

            {

                if (students[i].Num == snum)

                {

                    return students[i];

                }

            }

            return null;

        }

    }

}

 

 그리고 Student 클래스의 ToString 메서드를 재정의하여 학생 번호와 이름을 문자열로 반환하게 작성합시다.

 

class Student

{

    ... 중략 ...

    public override string ToString()

    {

       return string.Format("번호:{0} 이름:{1}", Num, Name);

    }

}

 

 장소를 선택하는 SelectPlace에서는 캠퍼스 생활의 places 배열에 있는 각 장소 정보를 화면에 출력하여 사용자에게 특정 장소를 선택하게 하여 선택한 장소를 반환하면 되겠죠.

 

class CampusLife

{

    ... 중략 ...

    private Place SelectPlace()

    {

        for (int i = 0; i < places.Length; i++)

        {

            Console.WriteLine("{0}:{1}", i + 1, places[i].ToString());

        }

 

        Console.WriteLine("장소를 선택하세요.");

        int num = EHLib.GetNum();

 

        if ((num > 0) && (num <= places.Length))

        {

            return places[num - 1];

        }

        return null;

   }

}

 

 그리고 각 장소의 ToString을 재정의해 주어야겠지요.

 

class Dormitory:Place

{

     ... 중략 ...

    public override string ToString()

    {

       return "기숙사";

    }

}

  

 이번에는 Campus 클래스에서 특정 학생을 빼내는 OutStudent 메서드를 구현합시다. 먼저, 입력된 학생을 찾아야 할 것입니다. 그리고 찾은 위치에 맨 뒤에 있는 학생을 옮기고 맨 뒤를 null로 바꿔주면 되겠네요. 정확히 이해하기 위해 필요하시면 논리적인 그림을 그려보시기 바랍니다.

 

class Campus

{

    ... 중략 ...

    internal void OutStudent(Student student)

    {

        int index = FindStudent(student);

        if (index == -1)

        {

            return;

        }

        students[index] = students[students.Length - 1];

        students[students.Length - 1] = null;

    }

    private int FindStudent(Student student)

    {

        for (int i = 0; i < students.Length; i++)

        {

            if (students[i] == student)

            {

                return i;

            }

        }

        return -1;

    }

}

  

 그리고 학생이 특정 장소로 이동했을 때 수행되는 Place 클래스의 InStudent 메서드를 구현해 봅시다. 먼저, 학생들을 보관하기 위한 배열을 생성하는 코드를 생성자에 추가해야겠지요. 그리고 InStudent 메서드에서는 처음으로 발견되는 빈자리를 찾아 해당 위치에 입력된 학생 개체를 보관하면 될 것입니다. 캠퍼스에서도 같은 방법으로 구현했기 때문에 크게 어렵지 않을 것입니다.

 

abstract class Place

{

    ... 중략 ...

    Student[] students = null;

    internal Place()

    {

        students = new Student[GameRule.MaxStudents];

    }

    internal void InStudent(Student student)

    {

        int empty_index = FindEmptyIndex();

        students[empty_index] = student;

    }

    private int FindEmptyIndex()

    {

        int i;

        for (i = 0; i < students.Length; i++)

        {

            if (students[i] == null)

            {

                break;

            }

        }

        return i;

    }

}

 

 이상으로 학생 이동에 관련된 MoveStudent 메서드에 대한 구현을 마쳤습니다.


너와 나의 연결고리 "공감"

 

반응형