개발자 성장 일지

2022.03.16 복습 뱀 게임

NEWDODORIPYO 2022. 3. 16. 17:10

오늘은 지난 시간 공부했던 내용들을 복습 삼아 뱀 주사위 게임을 만들어보았습니다 

 

뱀 주사위 게임 설계

복습 삼아 만드는 것이기에 간단하게 진행하신다고 하시네요

(간단 너무 좋아 😘)

 

설계도는 그렸으니 만들어야 할 것들을 정리해보겠습니다 

 

Class Player , Class Tile 가 먼저 필요할 것 같습니다 이 2가지를 먼저 설계하는 이유는 이 두 가지는 리턴 타입이 될 수 있고 파라미터가 될 수 있고 자료구조가 될 수 있기 때문에 먼저 설계해야 합니다 

 

그 후 Interface PlayerService를 만들고 그 안에는 getNextPlyer 가있고 return 타입으로는 Plyer를 가질 것 같습니다 

Interface TileService는 getTile(idx) 를가질것 같습니다 이렇게 설계 순서도 정해보았습니다 이런 식으로 타입들을 미리 정해두면 나중에 작업을 나누어서 진행했을 때 굉장히 편리하다고 합니다 그래서 오늘은 뼈대는 같이 잡고 UI , Player , Tile를 따로따로 팀원을 정해서 만들고 합쳐보는 수업으로 진행되었습니다 그리고 오늘은 Lombok를 안 쓰고 만들었습니다 

 

패키지 구성 

패키지는 이렇게 나누었습니다 

 

UI 

public class GameUI {

    private PlayerService playerService;
    private TileService tileService;
    private Scanner scanner;

    public GameUI(PlayerService playerService, TileService tileService, Scanner scanner) {
        this.playerService = playerService;
        this.tileService = tileService;
        this.scanner = scanner;
    }
    //이름을 정할 때 start나 run 등은 사용하면 안 된다 이유는 멀티 스레드(multi thread) 환경에서 쓰기 때문에 나중에 헷갈리게 된다
    public void play(){


        System.out.println("플레이어 차례입니다");
        //Player 얻어오기
        Player player = playerService.getNextPlayer();
        System.out.println(player);
        scanner.nextLine();

        //주사위 굴리기 1~6까지
        int value = (int)(Math.random()*6)+1;
        System.out.println("주사위 값은 "+value);

        //현재 위치 가져오기
        int current=player.getCurrent();

        //주사위 값과 위치 값을 더해서 이동된 값 
        Tile targetTile = tileService.getTile(current + value);
        System.out.println(targetTile);

먼저 ui로 뼈대를 잡아보았습니다 기본적인 뼈대는 완성이 되었기에 이제 각팀원들이 각자의 파트를 코딩했습니다 

 

다음은 Player 의 코딩을 진행했습니다 

Player 

Class Player 

public class Player {
    //이름
    private String name;
    //위치
    private int current;

    //생성자
    public Player(String name){
        this.name = name;
        this.current=0;
    }


    
    public int getCurrent() {

        return this.current;
    }
    //player 의 위치가 변화해야하기에
    public void setCurrent(int current) {

        this.current = current;
    }

    //toString
    @Override
    public String toString() {
        return "Player{" +
                "name='" + name + '\'' +
                ", current=" + current +
                '}';
    }
}

PlayerServiceImpl 

<Interface와 연결된 PlayerServiceImpl> 

                            //implement는 interface 상속
public class PlayerServiceImpl implements PlayerService{
   //Player의 배열 게임 참여인원
   private  Player[] players;
   //차례를 넘길때 필요한 번호
   private  int idx;


   public PlayerServiceImpl(){
       players = new Player[4];
       players[0]= new Player("철수");
       players[1]= new Player("영희");
       players[2]= new Player("영미");
       players[3]= new Player("민수");
       this.idx = 0;
   }

   //상속
    @Override
    public Player getNextPlayer() {
       return players[idx++ %4];
    }
}

Tile

public class Tile {
    //Tile 의 번호
    private int num;
   //생성자
    public Tile(int num) {

        this.num = num;
    }
    //getter
    public int getNum() {

        return num;
    }
    //toString
    @Override
    public String toString() {
        return "Tile{" +
                "num=" + num +
                '}';
    }
}

기본Tile 말고도 뱀 게임에는 특별한 타일들이 있습니다 그런 올라가거나~ 내려가는 그런 타일 말이죠 그런 타일들은 따로 Class LinkedTile로 만들었습니다 

LinkedTile

//뱀게임에서 위로 올라가거나 내려가는 특별한 Tile
public class LinkedTile extends Tile{
    //데이터베이스 위주의 설정<식별키>이 아닌 객체지향적인 설정
    //Tile 인데  target을 가지고 있는 모양
    //Tile 와 target가 연결된 구조
    //알고리즘 공부할때 자주보게됨
    private Tile target;


    //생성자
    //LinkedTile 을 만드는 방법이 2가지 이곳은 num만 받는 방법
    public LinkedTile(int num){
        //this( ) 나오는건 생성자
        this(num,null);
    }
   //생성자
    //num , Tile target 을 받는 방법
    public LinkedTile(int num, Tile target) {
        //부모 생성자
        super(num);
        //새로 생긴 생성자
        this.target = target;
    } //이러면 생성자가 많아져서 지져분해진다 그래서 보통 이럴때는 builder을 선호한다

    //setter
    public void setTarget(Tile target) {

        this.target = target;
    }
    //toString
    @Override
    public String toString() {

        return super.toString()+ "LinkedTile{" +
                "target=" + target +
                '}';
    }
}

TileServiceImpl

<Interface 와 연결된 TileServiceImpl>

public class TileServiceImpl implements TileService{

    //타일의 배열
    private Tile[] tiles;

    public TileServiceImpl(){
        //총 타일의수
        tiles = new Tile[100];

        //타일을 생성해주기위해 루프
        for (int i = 0; i < tiles.length ; i++) {
           //7의 배수면 LinkedTile를 연결
            if(i % 7 == 1){
                tiles[i]=new LinkedTile(i);
            }else {
                tiles[i]=new Tile(i);
            }
        }
    }



    @Override
    public Tile getTile(int idx) {

        return tiles[idx];
    }
}

UI 

<수정본>

import java.util.Scanner;

public class GameUI {

    private PlayerService playerService;
    private TileService tileService;
    private Scanner scanner;

    public GameUI(PlayerService playerService, TileService tileService, Scanner scanner) {
        this.playerService = playerService;
        this.tileService = tileService;
        this.scanner = scanner;
    }
    //이름을 정할 때 start나 run 등은 사용하면 안 된다 이유는 멀티 스레드(multi thread) 환경에서 쓰기 때문에 나중에 헷갈리게 된다
    public void play(){


        System.out.println("플레이어 차례입니다");
        //Player 얻어오기
        Player player = playerService.getNextPlayer();
        System.out.println(player);
        scanner.nextLine();

        //주사위 굴리기 1~6까지
        int value = (int)(Math.random()*6)+1;
        System.out.println("주사위 값은 "+value);

        //현재 위치 가져오기
        int current=player.getCurrent();

        //주사위 값과 위치 값을 더해서 이동된 값
        Tile targetTile = tileService.getTile(current + value);
        System.out.println(targetTile);

        //player의 위치가 변함
        player.setCurrent(targetTile.getNum());

        System.out.println("----------------");
        play();

    }
}

각 Interface 

PlayerService

public interface PlayerService {
    Player getNextPlayer();
}

TileService

public interface TileService {

    Tile getTile(int idx);

}

Main

public class Main {

    public static void main(String[] args) {

        GameUI gameUI = new GameUI(new PlayerServiceImpl() ,
                new TileServiceImpl() ,
                new Scanner(System.in));
        gameUI.play();

    }
}

main 에서는 만들어둔 코드들을 호출했습니다

결과도 깔끔하게 진행되고 있습니다 

하지만 강의중에는 LinkedTile을 완성하지 못했습니다 기능을 못하고 있는 상태입니다 이걸 바로 빨리 해결해 보는 것도 중요하지만 아직 봐야 할 요점이나 기능 들이 산더미이기에.... 우선 내일 강의를 위해 다른 걸 공부하러 가봐야 할 것 같습니다..... 강사님은 항상 말씀하셨죠 코딩 코드가 중요한 것이 아닙니다 지금은 이해하고 설계하는 것이 중요한 것입니다!!! 

그러니 이해하러 가보겠습니다