Computer programming/java

java로 만드는 BoxOffice 영화 예매 프로그램: 예매 좌석 구현

대학원생(노예) 2021. 12. 22. 01:25

이전글

2021.12.19 - [개발 공부/java] - java로 만드는 BoxOffice 영화 예매 프로그램: API 구현

2021.12.19 - [개발 공부/java] - java로 만드는 BoxOffice 영화 예매 프로그램: OPEN API

2021.12.17 - [개발 공부/java] - java로 만드는 BoxOffice 영화 예매 프로그램: 회원관리 구현

2021.12.17 - [개발 공부/java] - java로 만드는 BoxOffice 영화 예매 프로그램: 준비 단계

 

 

서론

    이번 포스트에서는 API를 통해 얻은 일별 박스오피스 정보로 영화를 선택하고 영화 좌석을 골라 티켓을 예매하는 코드를 구현해보겠다.

 

 

서론

- 개발환경은 이전 페이지와 동일하다.

 

 

소스코드

class MenuManager {
    // 상수 설정
    // 요청(Request) 요청 변수
    private static final String REQUEST_URL = "http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json";
    private static final String AUTH_KEY = "영화진흥위원회 인증키";

    // 일자 포맷
    private static final SimpleDateFormat DATE_FMT = new SimpleDateFormat("yyyyMMdd");

    // Map -> QueryString
    public static String makeQueryString(Map<String, String> paramMap) {
        final StringBuilder sb = new StringBuilder();

        paramMap.forEach((key, value) -> {
            if (sb.length() > 0) {
                sb.append('&');
            }
            sb.append(key).append('=').append(value);
        });

        return sb.toString();
    }

    public static void chooseMovie() {
        List<String> movieNameList = new ArrayList<>();
        // 변수설정
        // 하루전 날짜
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, -1); // 당일은 안됨

        // 변수 설정
        // 요청(Request) 인터페이스 Map
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("key", AUTH_KEY);                        // 발급받은 인증키
        paramMap.put("targetDt", DATE_FMT.format(cal.getTime()));  // 조회하고자 하는 날짜
        paramMap.put("itemPerPage", "3");                            // 결과 ROW 의 개수( 최대 10개 )
        paramMap.put("multiMovieYn", "");                             // Y:다양성 영화, N:상업영화, Default:전체
        paramMap.put("repNationCd", "");                             // K:한국영화, F:외국영화, Default:전체

        try {
            // Request URL 연결 객체 생성
            URL requestURL = new URL(REQUEST_URL + "?" + makeQueryString(paramMap));
            HttpURLConnection conn = (HttpURLConnection) requestURL.openConnection();

            // GET 방식으로 요청
            conn.setRequestMethod("GET");
            conn.setDoInput(true);

            // 응답(Response) 구조 작성
            // Stream -> JSONObject
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String readline;
            StringBuilder response = new StringBuilder();

            while ((readline = br.readLine()) != null) {
                response.append(readline);
            }

            JSONParser parser = new JSONParser();
            JSONObject responseBody = (JSONObject) parser.parse(response.toString());

            // 데이터 추출
            JSONObject boxOfficeResult = (JSONObject) responseBody.get("boxOfficeResult");

            // 박스오피스 상위 랭킹 3 출력
            JSONArray dailyBoxOfficeList = (JSONArray) boxOfficeResult.get("dailyBoxOfficeList");
            for (Object o : dailyBoxOfficeList) {
                JSONObject boxOffice = (JSONObject) o;
                System.out.printf("  %s - %s \n", boxOffice.get("rnum"), boxOffice.get("movieNm"));
                //boxOffice.get("movieCd")
                movieNameList.add((String) boxOffice.get("movieNm"));
            }
            System.out.println("종료: exit\n");

        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("명령어) ");
            String command = scanner.nextLine();

            switch (command) {
                case "1":
                    String movieRankedOne = movieNameList.get(0);
                    Seat.reserve(movieRankedOne);
                    break;
                case "2":
                    String movieRankedTwo = movieNameList.get(1);
                    Seat.reserve(movieRankedTwo);
                    break;
                case "3":
                    String movieRankedThree = movieNameList.get(2);
                    Seat.reserve(movieRankedThree);
                    break;
                case "exit":
                    break;
                default:
                    System.out.println("잘못입력하셨습니다. 다시 입력해주세요");
                    continue;
            }
            break;
        }
    }
}

- API로 얻은 일별 박스오피스 목록을 통해 박스오피스 순위 1, 2, 3등 중 한 가지를 고른다.

 

class Seat {
    static Map<String, Integer[][]> map = new HashMap<>();
    static List<String> userTicketList = new ArrayList<>();
    public static void reserve(String movie) { // ex: movie = 이터널스
        Integer[][] seats = map.getOrDefault(movie, new Integer[5][5]);     // 2차원 배열을 이용
        String strColumn;   // 열이름
        char inputColumn;
        int rowNum;         // 행번호
        Scanner sc = new Scanner(System.in);
        boolean isRun = true;   // 반복 flag
        do {
            System.out.println();
            System.out.println(movie);
            System.out.println("──────────────────SCREEN──────────────────");
            System.out.println();
            System.out.print("       ");
            for (int i = 0; i < seats.length; i++) {
                System.out.print(" [ " + (i + 1) + " ] ");
            }
            System.out.println();
            for (int i = 0; i < seats.length; i++) {
                System.out.println();
                System.out.print(" [ " + (char) (i + 65) + " ] ");
                for (int j = 0; j < seats[i].length; j++) {
                    if (seats[i][j] == null) {
                        System.out.print(" [ □ ] ");
                    } else if (seats[i][j] == 0) {
                        System.out.print(" [ □ ] ");
                    } else {
                        System.out.print(" [ ■ ] ");
                    }
                }
                System.out.println();
            }
            System.out.print("──────────────────────────────────────────\n");
            System.out.println("(예약종료는 exit)");
            System.out.print("예약하실 좌석의 열을 입력(A~E) : ");

            strColumn = sc.next();
            if (strColumn.equals("exit")) {
                System.out.println("종료되었습니다");
                break;
            }

            inputColumn = strColumn.trim().charAt(0);
            System.out.println("입력한 열 : " + inputColumn);
            if (inputColumn < 65 || inputColumn > 69) {
                System.out.println("선택할 수 없는 좌석입니다");
                continue;
            }
            int column = inputColumn - 65;
            System.out.print("예약하실 좌석의 행 번호를 입력(1~5) : ");
            rowNum = sc.nextInt();

            if (rowNum < 1 || rowNum > 5) {
                System.out.println("선택할 수 없는 행 번호입니다");
                continue;
            }
            System.out.println("선택하신 좌석은 : " + inputColumn + " 열이고 " + rowNum + " 행입니다");
            System.out.print("예약 완료 하시겠습니까 ? (Yes / No) : ");
            String s = sc.next();
            if (s.equals("y") || s.equals("Y") || s.equals("Yes") || s.equals("yes") || s.equals("YES")) {
                if (seats[column][rowNum - 1] == null) {
                    seats[column][rowNum - 1] = 1;
                    System.out.println("예약이 완료되었습니다\n");
                } else if (seats[column][rowNum - 1] == 0) {
                    seats[column][rowNum - 1] = 1;
                    System.out.println("예약이 완료되었습니다\n");
                } else {
                    System.out.print("\n이미 예약된 좌석입니다.\n");
                }
            } else if (s.equals("n") || s.equals("N") || s.equals("no") || s.equals("No") || s.equals("NO")) {
                System.out.println("취소되었습니다");
                isRun = false;
            } else {
                System.out.println("잘못 입력하셨습니다.");
            }
            userTicketList.add(movie + " " + inputColumn + "열 " + rowNum + "번" );
        }
        while (isRun);

        map.put(movie, seats);
    }
}

 

 

결과화면

영화 선택 결과 화면

- 영화 좌석 선택

 

마치며...

   OPEN API를 활용하여 일별 박스오피스 정보로 영화 예매 프로그램을 만들어볼 수 있었다. 프로젝트를 만들면서 API를 활용하는 방법에 대해 알아볼 수 있는 좋은 기회였다.