호텔 예약 콘솔 프로그램 - 2

이찬호·2023년 7월 21일
0

프로젝트

목록 보기
2/4

어제 작성하던 콘솔프로그램에 기능을 추가해보자.
오늘은 3개의 페이지를 추가해볼 것이다. 어제 1,2번 페이지가 있던 것을 기억해보자.
1. 랜덤 머니 지급, 2. 호텔의 방 정보 보기
오늘 추가할 페이지는
3. 호텔 방 예약하기
4. 예약한 방 목록 보기
5. 예약한 방 목록 체크인 날짜 순으로 보기이다.
먼저 대략적인 구성을 해보자
3. 호텔 방 예약하기

  • 2번 페이지에서 보여준 것처럼 방들의 목록을 보여주며 시작하자.
  • 방들의 목록을 보고 번호를 선택하여 날짜를 입력하고 해당 날짜에 예약이 되어있지 않다면 예약을 하고, 아니라면 예약이 불가능하다는 메시지를 출력하자.
  • 만약 예약을 하는데 방의 가격만큼 현재 돈이 없다면 돈이 없다는 메시지를 출력하자.

이제 방들의 목록을 보여주려는데, 어제는 임시로 그저 프린트문을 나열하여 구현하였다. 하지만 예약을 받기 위해 방들의 정보를 데이터로 저장하여 관리하는 것이 필요해졌다. 먼저 방들의 정보를 데이터로 만들어보자. 어떻게 해야할까? 여러 방들을 공장처럼 찍어내는 기능이 필요하다는 생각이 든다면 아주 좋다. 바로 클래스이다!

class room {
	class room {
    let roomnuber : Int // 호텔방의 번호
    let price : Int // 호텔방의 가격
    init(roomnumber : Int, price : Int) {
        self.roomnuber = roomnumber
        self.price = price
    }
}
var room101 = room(roomnumber: 101, price: 10000)
var room102 = room(roomnumber: 102, price: 30000)
var room201 = room(roomnumber: 201, price: 40000)
var roomList : [room] = [room101, room102, room201]

이런식으로 room이라는 클래스를 선언하면 여러 방들을 만들고 관리가 수월해진다!
roomList라는 배열을 만들어 room형태의 객체들을 저장하도록 만들어주었다.

이제 다음은 어제 만들었던 switch문의 case 2 부분도 고쳐줘야 한다. 출력을 하기 위해 여러 방법이 있지만 간단하게 반복출력 할 수 있는 for문을 이용해서 출력을 해보자.

//중략...
case 2 :
        for i in 0..<roomList.count{
        print("\(i+1). \(roomList[i].roomnuber)호 1박 \(roomList[i].price)원")
    }
    //결과
    //1. 101호 10000원
    //2. 102호 30000원
    //3. 201호 40000원
        print("돌아가려면 아무키나 입력하세요")
        var temp = getInt() //키를 입력받기전 화면을 유지하기 위한 장치
        
//중략...

for문의 내용은 roomList배열의 크기만큼 탐색하며 각각의 요소들의 roomnuber와 price를 출력하는 것이다.
여기서 문득 3번 페이지에도 저 코드를 써야한다는 것이 생각나지 않는가? 나는 보통 반복되는 작업 -> 함수이다. 물론 두줄짜리코드라 함수를 만드는게 더 귀찮을 수 있지만 습관을 들이다보면 익숙해져 나중에 도움이 될 것이다.

func showRoomList() {
    for i in 0..<roomList.count{
        print("\(i+1). \(roomList[i].roomnuber)호 1박 \(roomList[i].price)원")
    }
}
//case 2 부분 코드 수정
case 2 :
        showroomList()
        print("돌아가려면 아무키나 입력하세요")
        var temp = getInt() //키를 입력받기전 화면을 유지하기 위한 장치

함수의 장점은 깔끔한 점도 있지만, 복잡한 프로그래밍을 하게 되면 여러 파일로 나누어서 관리하게 되는 데, 이때는 Main파일을 이용해서 프로그램을 실행할 것이다. 이러한 습관을 들여논다면 Main파일은 눈으로 보기에 깔끔하며, 여러 파일을 관리하기 수월해 질 것이다!

이제 3번 페이지로 넘어가보자. 먼저 기존 스위치문에 case 3를 추가해주면 된다. 우리가 가장먼저 방들의 리스트를 보여주기로 했으니 아~~~주 간편하게 showroomList()를 하면 된다. 얼마나 편리한가!

case 3 :
	showroomList()
    print("예약할 방을 선택하십시오.")
    var index = getInt() // 예약할 방을 선택

여기까진.. 수월했으나 날짜라는 데이터를 어떻게 처리할지 고민하던 과정에서 해답을 아직 찾지 못하였다... 이부분은 좀 더 고민해보고 조언을 구하여 이후 로직을 바꿔주는 과정을 포스팅하도록 하겠다. 일단 임시로 당일 날짜만 선택하여 1일씩 예약할 수 있도록 구현해보자!
날짜를 하루 단위로 처리하기 위해 room 클래스에 bookingdays 라는 요소를 추가하였다. 이때 이 요소는 String타입을 요소로 같는 배열로 선언했다.

class room {
	let roomnuber : Int
    let price : Int
    var bookingdays : [String] = [] //예약 날짜를 저장하는 String 배열
    init(roomnumber : Int, price : Int) {
        self.roomnuber = roomnumber
        self.price = price
    }
}

이제 그러면 case 3 로 돌아가서 다시 로직을 만들어주자

func getString () -> String {
    var value : String
    if let x = readLine() {
        value = x
    }
    else {
        value = ""
    }
    return value
}

func bookingroom(index : Int) {
    if index < roomList.count && index != -1 { //(1)
        print("예약날짜를 입력하세요 ex)2023-07-21")
        var date = getString()
        if !roomList[index].bookingdays.contains(date){ //(2)
            if money >= roomList[index].price{ //(3)
                roomList[index].bookingdays.append(date)
                print("날짜 : \(date)")
                print("호실 : \(roomList[index].roomnuber)호 예약완료!")
            }
            else{
                print("소지금액이 부족합니다.")
            }
        }
        else {
            print("해당 날짜에 이미 예약되어있는 방입니다.")
        }
        
    }
}
case 3 :
	showroomList()
    print("예약할 방을 선택하십시오.")
    var index = getInt() -1  // 예약할 방을 선택, 방 순서는 1부터 시작하지만 
    						//roomList의 인덱스는 0부터 시작하기에 1을 빼준다.
    bookingroom(index : index)

이번엔 조금 길지만 차분하게 살펴보자. getString()은 getInt()과 같은 원리의 메서드이다. 이번엔 우리가 예약날짜로 String을 입력받기 위해 만든 것이다.
그 다음은 bookingroom()이다. 우리가 스위치문 case 3에서 index라는 숫자를 입력받은 것을 기억하는가? bookingroom()은 그 index값을 인자로 받는 메서드이다. 가장 먼저 나오는 if문은 index값이 roomList에 없는 인덱스 값을 입력했을 때 실행되지 않게 하기 위한 if문이다. (1)
그 다음 if문은 해당 index값을 가지는 roomList 요소의 bookingdays 배열에 우리가 입력받은 date값이 존재하는 지를 체크한다. (2)
마지막 if문은 소지금액이 예약하려는 방의 가격보다 많으면 예약이 가능하고 아니라면 돈이 부족하다는 메시지를 출력하는 if문이다. (3)
마지막 if문의 조건까지 만족한다면 bookingdays의 배열에 append를 이용하여 date를 추가해주고 결과를 알려준다.
이렇게 함수를 완성했다면 case3 에는 bookingroom() 한번 사용해주면 끝이다!

함수들이 여러개 생기고 클래스도 선언하여 사용하면 파일들을 나누어 관리하는 것이 유지보수에 있어 좀더 수월하다. 기존에 코드를 작성하던 파일을 main.swift, 새롭게 우리가 클래스와 메서드를 선언한 코드들을 room.swift라는 파일을 만들어 나누면 이렇게 메인 페이지가 깔끔해진다.

이제 4번 페이지를 만들어보자!

//Room파일에 작성
func showbookingList () {
    for i in 0..<roomList.count{
        for k in 0..<roomList[i].bookingdays.count{
            print("호실 : \(roomList[i].roomnuber)호 예약날짜 : \(roomList[i].bookingdays[k])")
        }
    }
}
//main파일에 작성
case 4 :
	showbookingList()

showbookingList()는 먼저 roomList의 크기만큼 순회하며, 각 요소의 bookingdays에 있는 요소들을 출력해주는 메서드이다. 이후 각 결과를 출력해주는 간단한 함수이다.
끝이다!

실행화면

5번페이지는 현재단계에서 날짜데이터에 대한 문제가 해결되지 않았기에 이후 데이터처리에 따라 코드를 크게 변경할 가능성이 있다고 판단된다. 따라서 날짜데이터 문제가 해결된다면 이후 체크인 날짜별로 정렬하여 보여주는 기능을 구현하도록 하겠다.

profile
안녕하세요

1개의 댓글

comment-user-thumbnail
2023년 7월 21일

덕분에 좋은 정보 얻어갑니다, 감사합니다.

답글 달기