분명 작은 게임 하나..였는데 이것저것 넣다가 스케일이 제법 커져버린 다이스게임이다.
학생의 이름을 정하고, 그 학생이 학교를 가는데까지의 과정이 큰 틀이다.
등등..여러가지가 있다.
원래 클래스를 교통수단과 학생클래스만 만들어서 나머지는 main에 다 꾸겨서 넣었더니,
코드가 엄청 길어져서 짜기도, 읽기도 힘들어서 클래스를 나누었더니…11개의 클래스가 나왔다.
미리 말하는거지만 코드가 완전하지는 못하다. 아직 객체지향을 배우고있기도 해서 클래스 응용을 그렇게 잘하지 못한다. 더 배우면 잘 되겠지
코드 다 짜는데 총 3~4시간은 걸린듯.. 머리통 굴리면서 구조 바꾸는데 2/3 이상 소요됨
전체 구조를 대략 이렇다.

*사진은 gpt가 그려줬다. (확실히 일을 잘 해)
자자 우선 코드를 하나씩 보겠다.
package com.oop7;
import java.util.Scanner;
public class GoingToSchoolMenu {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("학생 이름을 입력하세요 : ");
String name = scan.nextLine();
Student student = new Student(name, 5_000);
Rice rice = new Rice("카레라이스", 3_000);
Bus bus = new Bus(1_000);
Subway subway = new Subway(1_400);
Taxi taxi = new Taxi();
Dice dice = new Dice();
Turn turn = new Turn(0, 5);
Game game = new Game();
game.startGame(dice, rice, bus, subway, taxi, student, turn);
}
}
메인클래스에서는 각 클래스들의 호출과 초기값 지정 및 게임 실행을 담당하도록 했다.
package com.oop7;
public class Student {
private final String NAME;
private int money;
public Student(String name, int money){
this.NAME = name;
this.money = money;
}
// 버스 결제
public void busPay(Bus bus){
int fair = bus.getPRICE();
if (money < fair) {
System.out.println("잔액이 부족합니다.");
} else {
money -= fair;
System.out.println(fair + "원 결제가 완료되었습니다.");
System.out.println("남은 잔액은 " + money + "원 입니다.");
}
}
// 지하철 결제
public void subwayPay(Subway subway){
int fair = subway.getPRICE();
if (money < fair) {
System.out.println("잔액이 부족합니다.");
} else {
money -= fair;
System.out.println(fair + "원 결제가 완료되었습니다.");
System.out.println("남은 잔액은 " + money + "원 입니다.");
}
}
// 택시결제
public void taxiPay(Taxi taxi){
int fair = taxi.getPRICE();
if (money < fair) {
System.out.println("잔액이 부족합니다.");
} else {
money -= fair;
System.out.println(fair + "원 결제가 완료되었습니다.");
System.out.println("남은 잔액은 " + money + "원 입니다.");
}
}
public int getMoney() {
return money;
}
public String getName() {
return NAME;
}
}
처음에는 결제를 이동수단 클래스에서 하게 시켰으나..양방향으로 정보를 주고받아야해서, 학생클래스에서 진행하도록 구조를 수정했었다.
package com.oop7;
public class Bus {
private final int PRICE;
public Bus(int price){
this.PRICE = price;
}
public int getPRICE() {
return PRICE;
}
}
package com.oop7;
public class Subway {
private final int PRICE;
public Subway(int price){
this.PRICE = price;
}
public int getPRICE() {
return PRICE;
}
}
package com.oop7;
import java.util.Random;
public class Taxi {
private Random random = new Random();
private int price;
public Taxi(){
this.price = random.nextInt(1001) + 2000;
}
public int getPRICE() {
return price;
}
}
학생클래스에서 계산을 맡으니 간소화된 코드들.
package com.oop7;
import java.util.Random;
public class Dice {
private Random random = new Random();
public int diceRoll(){
int dice = random.nextInt(20) + 1;
System.out.println("D20 : " + dice);
return dice;
}
}
다이스를 굴리고, 결과값을 print로 출력까지 하게했다. (이벤트에 일일이 출력하면 손이 너무 많이 감..)
아 추가로
package com.oop7;
public class Rice {
private String menu;
private int price;
public Rice(String menu, int price) {
this.menu = menu;
this.price = price;
}
void buy(Student student) {
int studentMoney = student.getMoney();
if (student.getMoney() < price) {
System.out.println("잔액이 부족합니다.");
} else {
studentMoney -= price;
System.out.println(price + "원 결제가 완료되었습니다.");
System.out.println("남은 잔액은 " + studentMoney + "원 입니다.");
}
}
}
게임을 시작하면 먼저 밥먹을거냐에 대한 다이스를 돌리기에..
package com.oop7;
public class Turn {
private int yourTurn;
private final int TURN_DEADLINE;
public Turn(int yourTurn, int TURN_DEADLINE){
this.yourTurn = yourTurn;
this.TURN_DEADLINE = TURN_DEADLINE;
}
public int leftTurn(){
return TURN_DEADLINE - yourTurn;
}
public void addYourTurn(int yourTurn) {
this.yourTurn += yourTurn;
}
public void nextTurn(int yourTurn){
System.out.println("===============");
System.out.println("턴 " + yourTurn);
System.out.println("===============");
}
public int getYourTurn() {
return yourTurn;
}
}
턴을 담당하는 클래스. TURN_DEADLINE에 도달하면 게임 오버되는 형식이다. 게임오버 조건문은 game클래스에 있다.
package com.oop7;
import static com.oop7.Events.*;
public class Game {
private boolean gameOver = false;
public void startGame(
Dice dice,
Rice rice,
Bus bus,
Subway subway,
Taxi taxi,
Student student,
Turn turn
) {
int yourTurn = turn.getYourTurn();
System.out.println("당신은 학교를 갑니다.");
yourTurn = hungryEvent(dice, rice, student, turn);
// 턴검사
System.out.println("당신은 어떤 교통수단이 최적의 수단인지 잘 모른다.");
yourTurn = movementEvent(dice, bus, subway, taxi, student, turn);
if (yourTurn == -1) {
gameOver = true;
} else {
while (!gameOver) {
System.out.println("System : 이벤트 시나리오 발생 ( 환승체크 ) ");
int event = dice.diceRoll();
if (event <= 7) {
yourTurn = transferEvent(dice, bus, subway, taxi, student, turn);
if(turn.leftTurn() == 0){
gameOver = true;
break;
}
}else {
break;
}
}
}
int leftTurn = turn.leftTurn();
if(leftTurn > 0){
System.out.println("당신은 무사히 학교에 도착했다!");
}else if (leftTurn == -1) {
System.out.println("택시를 타고 빠르게 도착했다!");
}else if (leftTurn <= 0){
System.out.println("당신은 결국 지각하고 말았다!");
}
}
}
이벤트 클래스의 함수들을 호출하고, 게임의 결과를 반환하는 역할의 클래스다.
그리고…
package com.oop7;
public class Events {
static int hungryEvent(
Dice dice,
Rice rice,
Student student,
Turn turn
) {
int yourTurn = turn.getYourTurn();
int event = 0;
turn.nextTurn(yourTurn);
System.out.println("System : 이벤트 시나리오 발생 ( 배고픔 ) ");
System.out.println("System : 10이하시 밥을 먹음 (턴 소모 1, 돈 -3000 )");
System.out.println("System : 10초과시 바로 학교로 이동함 (턴 소모 X)");
event = dice.diceRoll();
if (event <= 10) {
System.out.println("이런 지금 너무 배가 고프다! 지금당장 밥을 먹어야한다.");
rice.buy(student);
System.out.println("밥을 야무지게 먹었다.");
turn.addYourTurn(1);
} else {
System.out.println("배가 고프긴한데, 참을만 해서 그냥 가기로 했다.");
}
System.out.println("현재 남은 턴 : " + turn.leftTurn());
return yourTurn;
}
static int movementEvent(
Dice dice,
Bus bus,
Subway subway,
Taxi taxi,
Student student,
Turn turn
) {
int yourTurn = turn.getYourTurn();
int event = dice.diceRoll();
turn.nextTurn(yourTurn);
System.out.println("System : 이벤트 시나리오 발생 ( 이동수단 ) ");
System.out.println("System : 3이하시 가까운 역까지 걸어감 (턴 소모 2)");
System.out.println("System : 3초과 11이하시 버스를 탐 (턴 소모 1, 돈 -1000 )");
System.out.println("System : 11초과 19이하시 지하철을 탐 (턴 소모 1, 돈 -1000)");
System.out.println("System : 20이 뜰 시 택시를 탐 ( 돈 -2000 ~ 3000, 즉시도착 )");
System.out.println("D20 : " + event);
if (event <= 3) {
System.out.println("무슨 바람이 분건지, 갑자기 운동이 하고싶어진 당신은 다음 환승장까지 걸어가기로 했다.");
turn.addYourTurn(2);
transferEvent(dice, bus, subway, taxi, student, turn);
} else if (event <= 11) {
System.out.println("당신은 버스를 타기로 했다.");
student.busPay(bus);
turn.addYourTurn(1);
} else if (event <= 19) {
System.out.println("당신은 지하철을 타기로 했다.");
student.subwayPay(subway);
turn.addYourTurn(1);
} else {
System.out.println("당신은 빠르게 가고싶어서 택시를 불렀다.");
if (student.getMoney() < taxi.getPRICE()) {
System.out.println("그러나 당신에게는 돈이 없다!! \n 하는 수 없이 버스와 지하철 중에 선택해야한다.");
event = dice.diceRoll();
if (event <= 10) {
System.out.println("당신은 버스를 타기로 했다.");
student.busPay(bus);
turn.addYourTurn(1);
} else {
System.out.println("당신은 지하철을 타기로 했다.");
student.subwayPay(subway);
turn.addYourTurn(1);
}
} else {
System.out.println("당신은 택시를 타고 빠르게 이동했다.");
student.taxiPay(taxi);
yourTurn = -1;
}
}
System.out.println("현재 남은 턴 : " + turn.leftTurn());
return yourTurn;
}
static int transferEvent(
Dice dice,
Bus bus,
Subway subway,
Taxi taxi,
Student student,
Turn turn
) {
int event = 0;
int yourTurn = turn.getYourTurn();
turn.nextTurn(yourTurn);
System.out.println("System : 아무래도 환승을 해야할 것 같다.");
System.out.println("System : 3초과 11이하시 버스를 탐 (턴 소모 1, 돈 -1000 )");
System.out.println("System : 11초과 19이하시 지하철을 탐 (턴 소모 1, 돈 -1400)");
System.out.println("System : 20이 뜰 시 택시를 탐 ( 돈 -2000 ~ 3000, 즉시도착 )");
event = dice.diceRoll();
int result = 0;
if (event > 3 && event <= 11) {
System.out.println("당신은 버스를 타기로 했다.");
result = 1;
turn.addYourTurn(1);
} else if (event <= 19) {
System.out.println("당신은 지하철을 타기로 했다.");
result = 2;
turn.addYourTurn(1);
} else {
System.out.println("당신은 빠르게 가고싶어서 택시를 불렀다.");
if (student.getMoney() < 3000) {
System.out.println("그러나 당신에게는 돈이 없다!! \n 하는 수 없이 버스와 지하철 중에 선택해야한다.");
event = dice.diceRoll();
if (event <= 10) {
System.out.println("당신은 버스를 타기로 했다.");
turn.addYourTurn(1);
} else {
System.out.println("당신은 지하철을 타기로 했다.");
turn.addYourTurn(1);
}
} else {
System.out.println("당신은 택시를 타고 빠르게 이동했다.");
student.taxiPay(taxi);
turn.addYourTurn(1);
}
}
System.out.println("System : 이벤트 시나리오 발생 ( 환승체크? ) ");
event = dice.diceRoll();
if (event <= 5) {
System.out.println("이런!! 실수로 환승카드를 찍지 않았다!! 돈이 더 들겠군..");
if (result == 1) {
student.busPay(bus);
} else {
student.subwayPay(subway);
}
}
return turn.getYourTurn();
}
static int transferCheckEvent(
Dice dice,
Bus bus,
Subway subway,
Taxi taxi,
Student student,
Turn turn
) {
int event = dice.diceRoll();
System.out.println("System : 이벤트 시나리오 발생 ( 환승 ) ");
System.out.println("당신은 길을 가다가 문뜬 이 길이 잘못 된 길이 아닐까 의문을 가지기 시작한다.");
System.out.println("D20을 굴려서 10 이하면 환승한다.");
System.out.println("D20 : " + event);
if (event <= 10) {
transferEvent(dice, bus, subway, taxi, student, turn);
} else {
System.out.println("아무래도 길을 잘 찾아온 것 같다.");
}
System.out.println("현재 남은 턴 : " + turn.leftTurn());
return turn.getYourTurn();
}
}
얘가 제일 길다. 연산이 많다기보단..print가 많다 ㅋㅋ..
이벤트 클래스의 함수들은 static으로 짰다.
(원래 Main 클래스에서 static으로 짠거 그대로 옮긴것)
수정해서 이정도지, 수정안했으면 Main클래스 코드줄이 거진 500줄이 넘었다.
다이스 굴리는것 까진 간단했는데, 다이스 결과에 따라 나오는 값이 다르게 설정하는게 겁나 귀찮았다.