...

[JAVA]객체지향 개념을 고려한 숫자야구 게임의 구현 본문

언어/JAVA 자바

[JAVA]객체지향 개념을 고려한 숫자야구 게임의 구현

gi2 2022. 6. 8. 14:08
https://github.com/jwpark1211/mathBaseball_final

 

 숫자 야구 게임의 메커니즘 

 1. 처음 user는 player가 한 명인지, 두 명인지 결정한다.

2. 플레이어가 한 명이면 컴퓨터를 대상으로, 두명이면 유저 두명이 서로 게임을 진행한다. 

3. 플레이어가 한 명인 경우엔 컴퓨터가 가진 숫자를 유저가 일방적으로 맞추는 형태이다.

4. 플레이어가 두 명인 경우엔 서로 숫자를 가지고 번갈아가며 서로의 숫자를 맞추는 형태이다. 

 

 


[1] Game 객체를 생성하고 gameStart 메소드를 호출한다. 

몇 명이 플레이 할 지를 결정하면, roundFactory를 호출하여 round 객체를 새로 생성한다. 

public class Game {

    private Scanner sc = new Scanner(System.in);
    private RoundFactory roundFactory = new RoundFactory();
    private Round round  = roundFactory.createP1Round(); //default

    public void gameStart(){
        String choice = "";

        System.out.print("몇 명이 play 합니까? (1명= p1, 2명 = p2)");
        choice=sc.nextLine();

        if(choice.equalsIgnoreCase("p1"))
            round = roundFactory.createP1Round();
        else if(choice.equalsIgnoreCase("p2"))
            round = roundFactory.createP2Round();
        else
            System.out.println("잘못된 입력입니다.");

        round.Play();
    }
}

 

[2] RoundFactory는 round의 성격에 맞게 의존성을 주입해준다. (round는 인터페이스이고, round_p1/p2는 상속 객체이다)

플레이어가 한 명인 경우엔 Defense만 가능한 유저, Attack만 가능한 유저를 round_p1의 유저로 넣고 객체를 생성한다.

플레이어가 두 명인 경우엔 multi 가 가능한 유저 두 명을 넣고 round_p2의 객체를 생성한다. 

public class RoundFactory {

    public Round_p1 createP1Round(){ return new Round_p1(OnlyDefenseUser(),OnlyAttackUser());}

    public Round_p2 createP2Round() { return new Round_p2(MultiUser(),MultiUser());}
    //===================================================================================//

    private User OnlyAttackUser(){
        return new User(new Attack());
    }

    private User OnlyDefenseUser(){
        return new User(new Defense());
    }

    private User MultiUser(){ return new User(new AttackAndDefense());}

}

[3] User는 Behavior 객체(인터페이스)를 가지고 있고, 생성자를 통해 의존성을 주입받는다. behavior.go를 호출하면 필요한 행동에 맞춰 행동이 실행된다. 이 때 dto는 data transfer object, dso는 data save object이다. 

public class User {

    private Behavior behavior;
    private DSO dso = new DSO();

    public User(Behavior behavior) {
        this.behavior = behavior;
    }

    public void play(DTO dto){
        behavior.Go(dto,dso);
    }

}
public class DTO {
    private int[]attackNumber = new int[4];
    private List<String> attackHistory = new ArrayList<>();
    private String result = "";
    private List<String> resultHistory = new ArrayList<>();

    public int[] getAttackNumber() {
        return attackNumber;
    }

    public String getResult() {
        return result;
    }

    public void setAttackNumber(int[] attackNumber) {
        this.attackNumber = attackNumber;
        attackHistory.add(Arrays.toString(attackNumber));
    }

    public void setResult(String result) {
        this.result = result;
        resultHistory.add(result);
    }

    public void printGameHistory(){
        for(int i=0;i<attackHistory.size();i++){
            System.out.print(attackHistory.get(i) + " : ");
            System.out.println(resultHistory.get(i));
        }
    }

}
public class DSO {
    private int[]defenseNumber = new int[4];

    public int[] getDefenseNumber() {
        return defenseNumber;
    }

    public void setDefenseNumber(int[] defenseNumber) {
        this.defenseNumber = defenseNumber;
    }
}

[4] round는 user 객체를 주입받은 후 게임을 play 한다. 새로운 dto 객체를 생성하여 두 유저 사이에 커뮤니케이션이 가능하도록 한다. 4S가 되면 그동안의 게임 히스토리를 반환한 후 게임을 종료한다.

public class Round_p1 implements Round{
    private User computer;
    private User user;

    public Round_p1(User computer, User user) {
        this.computer = computer;
        this.user = user;
    }

    @Override
    public void Play() {
        DTO dto = new DTO();

        while(true){
            computer.play(dto);//defense
            if(dto.getResult().equalsIgnoreCase("4S"))
                break;
            System.out.println("Attack!!");
            user.play(dto);//attack
        }

        System.out.println("==AttackHistory==");
        dto.printGameHistory();

    }
}
public class Round_p2 implements Round{
    private User userA;
    private User userB;

    public Round_p2(User userA, User userB) {
        this.userA = userA;
        this.userB = userB;
    }

    @Override
    public void Play() {
        DTO dtoA = new DTO();
        DTO dtoB = new DTO();

        userB.play(dtoA);
        userA.play(dtoB);


        while(true){

            System.out.println("UserA Attack!!");
            userA.play(dtoA); //attack
            userB.play(dtoA); //defense
            if(dtoA.getResult().equalsIgnoreCase("4S")) {
                System.out.println("** UserA Win **");
                break;
            }

            System.out.println("UserB Attack!!");
            userB.play(dtoB); //attack
            userA.play(dtoB); //defense
            if(dtoB.getResult().equalsIgnoreCase("4S")){
                System.out.println("** UserB Win **");
                break;
            }

        }

        System.out.println("==UserA Attack History==");
        dtoA.printGameHistory();

        System.out.println("==UserB Attack History==");
        dtoB.printGameHistory();

    }
}

+++++++) behavior 알고리즘 

public class Attack implements Behavior {

    private Scanner sc = new Scanner(System.in);

    @Override
    public void Go(DTO dto, DSO dso) {
        makeInputNumber(dto);
    }

    //======================<inner method>==========================//
    private void makeInputNumber(DTO dto){
        int temp[] = new int[4];

        System.out.print("숫자를 입력해주세요 : ");
        String numberS = sc.nextLine();
        if(numberS.length()!= 4){
            System.out.print("잘못된 입력입니다. 숫자를 다시 입력해주세요 : ");
            numberS = sc.nextLine();
        }
        String temp_S[] = numberS.split("");

        for (int i = 0; i < 4; i++) {
            temp[i] = Integer.parseInt(temp_S[i]);
        }

        dto.setAttackNumber(temp);
    }
}
public class Defense implements Behavior {

    private int count = 0;

    @Override
    public void Go(DTO dto, DSO dso) {
        if(count == 0)
            makeRandomNumber(dso);
        else
            judge(dto,dso);
        count++;
    }

    //=======================<inner method>==========================//

    private void makeRandomNumber(DSO dso){
        int temp[] = new int[4];

        for (int i = 0; i < 4; i++) {
            temp[i] = (int) (Math.random() * 10);
            for (int j = 0; j < i; j++) {
                if (temp[i] == temp[j])
                    i--;
            }
        }

        for(int i=0;i<4;i++){
            System.out.print(temp[i]);
        }
        System.out.println();
        dso.setDefenseNumber(temp);
    }

    private void judge(DTO dto, DSO dso){
        int countS =0 ; int countB = 0;

        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                if(dso.getDefenseNumber()[i]==dto.getAttackNumber()[j]){
                    if(i==j)
                        countS++;
                    else
                        countB++;
                }
            }
        }
        String result = makeResult(countS,countB);
        System.out.println(result);
        dto.setResult(result);
    }

    private String makeResult (int countS, int countB){
        if(countS!=0 && countB!=0)
            return countS+"S"+countB+"B";
        else if(countS==0 && countB!=0)
            return countB+"B";
        else if(countS!=0 && countB == 0)
            return countS+"S";
        else
            return "OUT";
    }
}
public class AttackAndDefense implements Behavior {

    private static int count=0;
    private Attack attack = new Attack();
    private Defense defense = new Defense();

    @Override
    public void Go(DTO dto, DSO dso) {
        if(count==0||count==1)
            defense.Go(dto, dso);
        else{
            if(count%2==0)
                attack.Go(dto, dso);
            else
                defense.Go(dto,dso);        }
        count++;
    }

}

'언어 > JAVA 자바' 카테고리의 다른 글

JAVA 파라미터에 오는 점 세개 문법 !  (0) 2022.04.16
JAVA 접근 제한자 정리  (0) 2022.04.14
[JAVA] Final 이란?  (0) 2022.03.03
[JAVA] Static이란?  (0) 2022.02.28
[JAVA] Scanner의 next() / nextLine() 차이점  (0) 2022.02.18
Comments