관리 메뉴

클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지

상속 18 - 단원 마무리 및 Open Challenge 문제 풀기 <물고기 잡기 게임 만들기> 본문

프로그래밍 언어/자바

상속 18 - 단원 마무리 및 Open Challenge 문제 풀기 <물고기 잡기 게임 만들기>

huenuri 2024. 12. 2. 06:59

상속 단원을 마무리하며 도전 문제를 풀어보려고 한다. 문제가 정말 어려워서 지금 내 수준에서는 혼자서는 절대로 풀 수 없는 문제였다. 풀이를 참고하며 풀어볼 예정이다.


 

 

 

 

 

단원 마무리하기

 


 

 

 

 

 

Bear의 Fish 먹기 게임 만들기

 

 

 

 


 

 

 

 

 

문제 풀기

 

GameObject 클래스

 

 

 

 

 

Bear 클래스

 

 

 

 

 

fish 클래스

 

 

 

 

 

Game 클래스

 

 

이제 클래스별로 설명을 해보겠다.


 

 

 

 

코드 분석하기

 

1. Game 클래스

이 클래스는 게임의 전체 로직을 관리한다.

멤버 변수

  • MAX_X, MAX_Y : 게임 맵의 크기를 나타낸다.
  • map : 2D 배열로 게임의 상태를 저장. 기본 값은 '-'
  • : 게임 오브젝트를 담는 배열(Bear와 Fish)
  • state : 게임 상태를 나타낸다.
    • 0 : 게임 진행 중
    • 1 : Bear가 승리
    • 2 : Fish가 승리 (Fish는 자동으로 도망치지 않으므로 사실상 구현되지 않음)

메서드

  1. Game() (생성자)
    • 초기 맵을 모두 '-'로 초기화
    • Bear(0, 0)과 Fish(5, 5)를 초기화하여 배열 m에 추가
  2. run()
    • 게임의 메인 루프를 담당
    • 게임이 끝날 때까지 Bear와 Fish를 움직이고 상태를 업데이트
    • 맵을 지우고(clear) 새로 그린다(update, draw).
  3. update()
    • map에 Bear와 Fish의 현재 위치를 반영
    • Fish를 먼저 그려, Bear가 Fish와 겹칠 때 Fish가 사라지도록 설정
  4. clear()
    • 맵에서 Bear와 Fish의 현재 위치를 '-'로 초기화
  5. draw()
    • map 배열을 출력하여 현재 게임 상태를 화면에 표시
  6. doesEnd()
    • Bear와 Fish의 위치가 동일하면(collide 메서드) 게임 종료

 

 

 

 

2. GameObject 클래스

추상 클래스로, Bear와 Fish의 공통 동작(추상화)을 정의한다.

멤버 변수

  • x, y: 현재 위치
  • distance: 한 번 움직일 때의 이동 거리

메서드

  1. collide(GameObject p)
    • 두 객체의 위치가 동일하면 충돌(true)을 반환
    • Bear가 Fish와 충돌하면 게임이 종료된다.
  2. move() (추상 메서드)
    • Bear와 Fish의 이동 로직을 정의
    • 서브 클래스에서 구현해야 한다.
  3. getShape() (추상 메서드)
    • Bear와 Fish의 모양(문자)을 반환
    • 서브 클래스에서 구현해야 한다.

 

 

3. Bear 클래스

 

Bear 클래스는 GameObject를 상속받아 Bear의 동작을 구현한다. 사용자 입력에 따라 이동하며, 맵에서 Bear의 현재 위치와 모양을 갱신한다.

멤버 변수

  • scanner
    • 사용자 입력을 받기 위한 Scanner 객체

생성자

public GameObject(int startX, int startY, int distance)
  • 부모 클래스의 생성자를 호출(super)하여 Bear의 초기 위치와 이동 거리를 설정
  • Scanner 객체를 초기화

 

메서드

  1. move()
    • 사용자 입력(a, s, d, f)에 따라 Bear의 위치를 변경한다.
    • 입력에 따른 동작:
      • 'a': 왼쪽으로 이동. x 좌표를 감소
      • 'f': 오른쪽으로 이동. x 좌표를 증가
      • 'd': 위로 이동. y 좌표를 감소
      • 's': 아래로 이동. y 좌표를 증가
    • 맵의 경계 확인
      • Bear가 맵의 크기를 초과하지 않도록 x와 y를 제한한다.
      • 맵 범위를 초과할 경우, 좌표를 맵의 경계로 고정
@Override
public void move() {
    System.out.print("왼쪽(a), 아래(s), 위(d), 오른쪽(f) >> ");
    char c = scanner.next().charAt(0);
    switch(c) {
        case 'a': x--; if(x < 0) x = 0; break; // 왼쪽
        case 'f': x++; if(x >= Game.MAX_X) x = Game.MAX_X - 1; break; // 오른쪽
        case 'd': y--; if(y < 0) y = 0; break; // 위
        case 's': y++; if(y >= Game.MAX_Y) y = Game.MAX_Y - 1; break; // 아래
    }
}

 

 

2. getShape()

  • Bear의 모양을 나타내는 문자인 'B'를 반환
@Override
public char getShape() {
    return 'B';
}

 

 

 

4. Fish 클래스

기본 구조

  1. Fish 클래스는 GameObject를 상속받아 난수 기반으로 이동하는 물고기 객체를 정의한다.
  2. Fish는 맵에서 '@'로 표시된다.

 

주요 메서드

1. move()

  • 난수를 사용해 물고기가 무작위로 이동
    • x와 y 좌표 각각에 대해
      • n == 0: Positive 방향(오른쪽/아래)
      • n == 1: Negative 방향(왼쪽/위)
      • n == 2~4: 정지
  • 맵 경계를 초과하지 않도록 제한
    • x < 0 → x = 0, x >= MAX_X → x = MAX_X - 1
    • y < 0 → y = 0, y >= MAX_Y → y = MAX_Y - 1

2. getShape()

  • Fish의 모양 '@' 반환
  • 게임 맵에서 물고기의 위치를 나타낸다.

 

동작 예시

  1. 초기 위치: (5, 5)
  2. 난수 결과:
    • n = 0 (오른쪽 이동) → (6, 5)
    • n = 1 (위 이동) → (6, 4).
  3. 결과:
    • 맵에서 물고기의 위치는 '@'로 표시

 

 

 

 

코드 실행해보기

 

 

이게 게임 첫 시작 화면이다.

 

 

 

 

s를 두 번 누르니 아래로 두 칸 내려갔다. 그런 다음 한참 동안 물고기를 쫓기 시작했다. 아마 5분 이상한 것 같다.

 

 

 

 

 

그리고 드디어 물고기를 잡았다. 다 실행하고 나니 무척 재미있었다.


 

 

 

 

 

 

학습을 마치고

도전 문제는 코드를 읽고 대략 이해하는데 목표를 두었다. 공부할 시간이 부족해서 코드를 일일이 분석해보지 않았지만 나중데 시간날 때 다시 한번 찬찬히 읽고 분석해보려고 한다.

간단한 게임이라도 직접 만들어보면 정말 재미있고 프로그래밍을 할 맛이 난다. 이제 연습문제만 남아있는데 문제가 얼마나 많은지 30문제나 된다. 한 문제당 난이도도 꽤 있고 말이다. 그래도 난 지금까지 앞선 단원에서도 모든 문제를 가능하면 다 풀고 넘어갔듯이 이번에도 그래볼 생각이다.

 

오늘 하루 이 연습문제를 다 푸는데 학습 목표를 세웠다.