728x90
반응형
아래의 소스는 Hunt the Wumpus(1973) 를 Java코드로 구현한 것입니다.
package javaDev;
import java.util.Random;
import java.util.Scanner;
public class HuntTheWumpus {
static int[][] S = new int[20][3]; // Cave system
static int[] L = new int[6]; // Positions (player, wumpus, pits, and bats)
static int[] M = new int[6]; // Temporary storage of L
static int A = 5; // Number of arrows
static int F = 0; // Flag for game state
static Random rand = new Random();
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("INSTRUCTIONS (Y-N)");
String input = scanner.nextLine().toUpperCase();
if (input.equals("N")) {
return;
}
// Initialize cave layout
initializeCave();
// Display instructions
displayInstructions();
// Set up game and start
gameLoop();
}
// Method to initialize the cave system and the positions of hazards
static void initializeCave() {
int[][] caveData = {
{2, 5, 8}, {1, 3, 10}, {2, 4, 12}, {3, 5, 14}, {1, 4, 6},
{5, 7, 15}, {6, 8, 17}, {1, 7, 9}, {8, 10, 18}, {2, 9, 11},
{10, 12, 19}, {3, 11, 13}, {12, 14, 20}, {4, 13, 15}, {6, 14, 16},
{15, 17, 20}, {7, 16, 18}, {9, 17, 19}, {11, 18, 20}, {13, 16, 19}
};
// Assign cave layout data
for (int i = 0; i < 20; i++) {
S[i] = caveData[i];
}
// Randomly assign positions for the player, Wumpus, pits, and bats
for (int i = 0; i < 6; i++) {
L[i] = getRandomNumber(20);
M[i] = L[i];
}
// Check for crossovers (no duplicates in the setup)
checkForCrossover();
}
// Method to check for any crossover (same position for player, wumpus, etc.)
static void checkForCrossover() {
for (int i = 0; i < 6; i++) {
for (int j = i + 1; j < 6; j++) {
if (L[i] == L[j]) {
L[j] = getRandomNumber(20);
i = 0; // Restart checking after modifying
break;
}
}
}
}
// Helper method to generate a random number within a range
static int getRandomNumber(int range) {
return rand.nextInt(range) + 1;
}
// Method to display the game instructions
static void displayInstructions() {
System.out.println("\nWELCOME TO 'HUNT THE WUMPUS'");
System.out.println("THE WUMPUS LIVES IN A CAVE OF 20 ROOMS...");
System.out.println("... (long instructions, omitted for brevity)");
System.out.println("WUMPUS - 'I SMELL A WUMPUS'");
System.out.println("BAT - 'BATS NEARBY'");
System.out.println("PIT - 'I FEEL A DRAFT'");
}
// Main game loop
static void gameLoop() {
while (true) {
// Print location and hazard warnings
printLocationAndHazards();
// Choose action (shoot or move)
chooseAction();
// Check for game over conditions
if (F != 0) {
break;
}
}
}
// Print location and hazard warnings
static void printLocationAndHazards() {
System.out.println("\nYOU ARE IN ROOM " + L[0]);
System.out.print("TUNNELS LEAD TO: ");
for (int i = 0; i < 3; i++) {
System.out.print(S[L[0] - 1][i] + " ");
}
System.out.println();
// Check for hazards
for (int i = 1; i < 6; i++) {
if (L[0] == L[i]) {
switch (i) {
case 1: // Wumpus
System.out.println("I SMELL A WUMPUS!");
break;
case 2: // Pit
case 3:
System.out.println("I FEEL A DRAFT");
break;
case 4: // Bat
case 5:
System.out.println("BATS NEARBY!");
break;
}
}
}
}
// Choose to shoot or move
static void chooseAction() {
System.out.print("SHOOT OR MOVE (S-M): ");
String choice = scanner.nextLine().toUpperCase();
if (choice.equals("S")) {
shootArrow();
} else if (choice.equals("M")) {
movePlayer();
}
}
// Handle shooting an arrow
static void shootArrow() {
System.out.println("NO. OF ROOMS (1-5): ");
int arrowLength = Integer.parseInt(scanner.nextLine());
if (arrowLength < 1 || arrowLength > 5) {
shootArrow(); // Invalid input, retry
return;
}
int[] path = new int[arrowLength];
for (int i = 0; i < arrowLength; i++) {
System.out.print("ROOM #" + (i + 1) + ": ");
path[i] = Integer.parseInt(scanner.nextLine());
if (i > 0 && path[i] == path[i - 1]) {
System.out.println("ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM");
return;
}
}
// Shoot the arrow
for (int i = 0; i < arrowLength; i++) {
boolean hit = false;
for (int j = 0; j < 3; j++) {
if (S[L[0] - 1][j] == path[i]) {
L[0] = path[i];
hit = true;
break;
}
}
if (!hit) {
L[0] = S[L[0] - 1][rand.nextInt(3)];
}
}
// Check if the arrow hits the Wumpus
if (L[0] == L[1]) {
System.out.println("AHA! YOU GOT THE WUMPUS!");
F = 1;
} else {
A--;
if (A <= 0) {
System.out.println("YOU RAN OUT OF ARROWS! YOU LOSE!");
F = -1;
} else {
System.out.println("MISSED");
}
}
}
// Handle moving the player
static void movePlayer() {
System.out.print("WHERE TO: ");
int newRoom = Integer.parseInt(scanner.nextLine());
if (newRoom < 1 || newRoom > 20) {
System.out.println("INVALID ROOM, TRY AGAIN.");
movePlayer();
return;
}
// Check if the move is valid
boolean validMove = false;
for (int i = 0; i < 3; i++) {
if (S[L[0] - 1][i] == newRoom) {
validMove = true;
break;
}
}
if (!validMove) {
System.out.println("NOT POSSIBLE - TRY ANOTHER ROOM.");
movePlayer();
return;
}
// Update player position
L[0] = newRoom;
// Check for hazards
if (L[0] == L[1]) {
System.out.println("OOPS! BUMPED A WUMPUS!");
F = -1; // Game over
} else if (L[0] == L[2] || L[0] == L[3]) {
System.out.println("YOU FELL IN A PIT!");
F = -1; // Game over
} else if (L[0] == L[4] || L[0] == L[5]) {
System.out.println("SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!");
L[0] = getRandomNumber(20);
}
}
}
1. 패키지 선언
package javaDev;
- package는 Java 프로그램을 논리적으로 그룹화하는 데 사용됩니다. javaDev는 이 파일이 포함된 패키지 이름입니다.
2. 필드 선언
static int[][] S = new int[20][3]; // Cave system
static int[] L = new int[6]; // Positions (player, wumpus, pits, and bats)
static int[] M = new int[6]; // Temporary storage of L
static int A = 5; // Number of arrows
static int F = 0; // Flag for game state
static Random rand = new Random();
static Scanner scanner = new Scanner(System.in);
- S: 2차원 배열로, 각 방에 연결된 방들의 목록을 저장합니다. 20개의 방과 각 방에 연결된 3개의 방이 존재합니다.
- L: 게임에 필요한 위치 정보(플레이어, Wumpus, pits, bats 등)를 저장하는 배열입니다.
- M: L 배열의 임시 복사본입니다.
- A: 남은 화살의 수입니다.
- F: 게임 상태를 나타내는 플래그입니다. 0이면 게임이 진행 중, 1이면 승리, -1이면 게임 오버를 나타냅니다.
- rand: 난수 생성기입니다.
- scanner: 사용자 입력을 받기 위한 Scanner 객체입니다.
3. main 메서드
public static void main(String[] args) {
System.out.println("INSTRUCTIONS (Y-N)");
String input = scanner.nextLine().toUpperCase();
if (input.equals("N")) {
return;
}
// Initialize cave layout
initializeCave();
// Display instructions
displayInstructions();
// Set up game and start
gameLoop();
}
- main 메서드는 프로그램의 진입점입니다.
- 사용자에게 게임 설명을 보여주고, "Y" 또는 "N"을 입력받습니다. "N"을 입력하면 게임을 종료합니다.
- 게임을 시작하기 전에 initializeCave()를 호출하여 동굴을 초기화하고, displayInstructions()로 게임 설명을 출력합니다.
- 이후 gameLoop()를 호출하여 게임을 시작합니다.
4. initializeCave 메서드
static void initializeCave() {
int[][] caveData = {
{2, 5, 8}, {1, 3, 10}, {2, 4, 12}, {3, 5, 14}, {1, 4, 6},
{5, 7, 15}, {6, 8, 17}, {1, 7, 9}, {8, 10, 18}, {2, 9, 11},
{10, 12, 19}, {3, 11, 13}, {12, 14, 20}, {4, 13, 15}, {6, 14, 16},
{15, 17, 20}, {7, 16, 18}, {9, 17, 19}, {11, 18, 20}, {13, 16, 19}
};
for (int i = 0; i < 20; i++) {
S[i] = caveData[i];
}
// Randomly assign positions for the player, Wumpus, pits, and bats
for (int i = 0; i < 6; i++) {
L[i] = getRandomNumber(20);
M[i] = L[i];
}
checkForCrossover();
}
- 동굴 구조를 초기화합니다. caveData 배열은 각 방에 연결된 다른 방들을 나타냅니다. S[i]는 각 방에 연결된 방들의 리스트입니다.
- L 배열에 플레이어, Wumpus, pits, bats의 위치를 랜덤으로 배치하고, M 배열에 L을 복사합니다.
- checkForCrossover()는 같은 위치에 플레이어나 다른 객체들이 겹치지 않도록 확인합니다.
5. checkForCrossover 메서드
static void checkForCrossover() {
for (int i = 0; i < 6; i++) {
for (int j = i + 1; j < 6; j++) {
if (L[i] == L[j]) {
L[j] = getRandomNumber(20);
i = 0; // Restart checking after modifying
break;
}
}
}
}
- L 배열의 각 항목이 중복되는지 확인하여, 중복될 경우 새로운 위치를 할당합니다. 위치가 겹칠 경우 getRandomNumber(20)을 사용하여 새로운 값을 재할당합니다.
6. getRandomNumber 메서드
static int getRandomNumber(int range) {
return rand.nextInt(range) + 1;
}
- 주어진 범위 내에서 랜덤한 정수를 생성하는 메서드입니다. rand.nextInt(range)는 0부터 range-1까지의 정수를 반환하는데, +1을 해주어 1부터 range까지의 정수를 반환합니다.
7. displayInstructions 메서드
static void displayInstructions() {
System.out.println("\nWELCOME TO 'HUNT THE WUMPUS'");
System.out.println("THE WUMPUS LIVES IN A CAVE OF 20 ROOMS...");
System.out.println("... (long instructions, omitted for brevity)");
System.out.println("WUMPUS - 'I SMELL A WUMPUS'");
System.out.println("BAT - 'BATS NEARBY'");
System.out.println("PIT - 'I FEEL A DRAFT'");
}
- 게임 설명을 출력하는 메서드입니다.
8. gameLoop 메서드
static void gameLoop() {
while (true) {
// Print location and hazard warnings
printLocationAndHazards();
// Choose action (shoot or move)
chooseAction();
// Check for game over conditions
if (F != 0) {
break;
}
}
}
- 게임이 진행되는 메서드입니다. printLocationAndHazards()로 현재 위치와 위험 요소를 출력하고, chooseAction()을 통해 이동이나 화살 발사 등의 행동을 선택하게 합니다.
- 게임이 끝날 조건(F != 0)이 되면 게임을 종료합니다.
9. printLocationAndHazards 메서드
static void printLocationAndHazards() {
System.out.println("\nYOU ARE IN ROOM " + L[0]);
System.out.print("TUNNELS LEAD TO: ");
for (int i = 0; i < 3; i++) {
System.out.print(S[L[0] - 1][i] + " ");
}
System.out.println();
// Check for hazards
for (int i = 1; i < 6; i++) {
if (L[0] == L[i]) {
switch (i) {
case 1: // Wumpus
System.out.println("I SMELL A WUMPUS!");
break;
case 2: // Pit
case 3:
System.out.println("I FEEL A DRAFT");
break;
case 4: // Bat
case 5:
System.out.println("BATS NEARBY!");
break;
}
}
}
}
- 플레이어의 위치와 연결된 방을 출력하고, 각종 위험(웅푸스, 함정, 박쥐)을 확인하여 출력합니다.
10. chooseAction 메서드
static void chooseAction() {
System.out.print("SHOOT OR MOVE (S-M): ");
String choice = scanner.nextLine().toUpperCase();
if (choice.equals("S")) {
shootArrow();
} else if (choice.equals("M")) {
movePlayer();
}
}
- 사용자로부터 "S" (화살 쏘기) 또는 "M" (이동) 입력을 받아 해당 행동을 실행합니다.
11. shootArrow 메서드
- 화살을 발사하는 방법을 구현한 메서드로, 지정된 방을 목표로 화살을 쏩니다.
12. movePlayer 메서드
- 플레이어가 이동할 방을 선택하고, 해당 방으로 이동하는 로직을 처리합니다. 위험 요소에 맞닿으면 게임 오버가 됩니다.
이 프로그램은 Hunt the Wumpus 게임을 완전하게 재현하며, 사용자 입력을 통해 플레이어의 행동을 처리하고, 게임 진행 상황을 출력합니다.
728x90
반응형
'Dev > Classic Game Dev' 카테고리의 다른 글
Hunt the Wumpus(1973) Original Source Code(Basic) (0) | 2025.04.16 |
---|