Uknow's Lab.
article thumbnail

 

앞서 포스팅했던 2048과 마찬가지로,

자바를 처음 배울 당시, Swing 파트를 배울 즈음 만들었던 프로젝트 입니다.

 

 

https://uknowblog.tistory.com/2

 

[Java] 숫자 야구 게임

어렸을 적 많이 해봤던 숫자 야구 게임. ​ 입력한 값의 숫자와 정답의 숫자의 같은 자릿수의 숫자가 같다면 Strike ​ 자릿수는 다르나 같은 숫자가 있다면 Ball 이며, ​ 3 Strike 일 경우 게임을 승

uknowblog.tistory.com

 

숫자 야구 게임은 이전에 콘솔창 버전에서는 다룬 적이 있는데요.

해당 로직을 기반으로 한 GUI 버전입니다.

 

 

 

총 10번의 기회 안에 숫자를 맞추면 됩니다.

 

프로그램엔 두 가지 자바 클래스 파일이 있는데,

실행을 담당하는 Main.java와 프로그램 내부 로직을 담당하는 Baseball.java 입니다

- Main.java

public class Main {
   public static void main(String[] args)
   {
      new Baseball();
   }
}

 

- Baseball.java

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class Baseball extends JFrame implements ActionListener, KeyListener{
   Container ct = getContentPane();
   JTextArea log;
   JTextField input;
   JButton inputb;
   JLabel strike;
   JLabel ball;
   JLabel chnum;
   int[] answer = new int[3];
   final int MAX_THROW = 10;
   int cnfThrow = 0;

   public Baseball()
   {
      Initialize();
      setTitle("Baseball Game");
      setSize(750,600);
      setVisible(true);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }

   public void Initialize()
   {
      ct.setLayout(new BorderLayout());

      //왼쪽 텍스트 에어리어
      log = new JTextArea();
      log.append("슷자 야구 게임에 오신것을 환영합니다!\n");
      ct.add(log, BorderLayout.CENTER);

      //오른쪽 상위 서브패널 (입력창 분리용)
      JPanel supersub = new JPanel();
      supersub.setLayout(new BorderLayout());
      ct.add(supersub,BorderLayout.EAST);

      //오른쪽 서브패널
      JPanel sub = new JPanel();
      sub.setLayout(new GridLayout(5,1));
      supersub.add(sub,BorderLayout.CENTER);

      //숫자 입력 패널
      JPanel pinput = new JPanel();
      pinput.setLayout(new BorderLayout());
      supersub.add(pinput,BorderLayout.NORTH);

      //입력 텍스트필드
      input = new JTextField();
      pinput.add(input,BorderLayout.CENTER);
      input.addKeyListener(this);

      //입력 버튼
      inputb = new JButton();
      inputb.setText("입력");
      inputb.addActionListener(this);
      pinput.add(inputb,BorderLayout.EAST);
      inputb.setFont(new Font("나눔고딕", Font.BOLD, 45));
      inputb.setHorizontalAlignment(SwingConstants.CENTER);
      inputb.setBackground(new Color(198,255,203));

      //스트라이크 볼 패널
      JPanel sb = new JPanel();
      sb.setLayout(new GridLayout(1,2));
      sub.add(sb);
      sb.setBackground(new Color(164,200,255));


      //남은 기회 라벨
      JLabel chance = new JLabel();
      chance.setText("남은 기회");
      chance.setFont(new Font("나눔고딕", Font.BOLD, 30));
      chance.setHorizontalAlignment(SwingConstants.CENTER);
      sub.add(chance);

      //남은 기회 횟수
      chnum = new JLabel();
      chnum.setText(MAX_THROW+"");
      chnum.setFont(new Font("나눔고딕", Font.BOLD, 45));
      chnum.setHorizontalAlignment(SwingConstants.CENTER);
      sub.add(chnum);

      sub.setBackground(new Color(213,240,251));

      strike = new JLabel();
      strike.setText("   strike");
      ball = new JLabel();
      ball.setText("   ball");
      sb.add(strike);
      sb.add(ball);
      strike.setFont(new Font("나눔고딕", Font.BOLD, 45));
      strike.setHorizontalAlignment(SwingConstants.CENTER);
      ball.setFont(new Font("나눔고딕", Font.BOLD, 45));
      ball.setHorizontalAlignment(SwingConstants.CENTER);

      //다시 시작 버튼
      JButton restart = new JButton();
      restart.setText("다시 시작");
      restart.setFont(new Font("나눔고딕", Font.BOLD, 45));
      restart.setHorizontalAlignment(SwingConstants.CENTER);
      restart.addActionListener(this);
      restart.setBackground(new Color(183,210,255));
      sub.add(restart);

      //게임 종료 버튼
      JButton exitbutton = new JButton();
      exitbutton.setText("게임 종료");
      exitbutton.setFont(new Font("나눔고딕", Font.BOLD, 45));
      exitbutton.setHorizontalAlignment(SwingConstants.CENTER);
      exitbutton.setBackground(new Color(153,191,255));
      sub.add(exitbutton);
      exitbutton.addActionListener(this);

      answermake();
   }

   public void play()
   {
      int[] input = new int[3];

      input = importText();

      int[] stbal = judge(input[0],input[1],input[2]);
      strike.setText(stbal[1]+" strike");
      ball.setText(stbal[0]+" ball");
      log.append(input[0]+" "+input[1]+" "+input[2]+"\n");

      if(stbal[1] == 3)
      {
         log.append("정답!!! 총 "+cnfThrow+"번 던지셨습니다.\n");
      }
      else
         log.append(stbal[1]+" strike "+stbal[0]+" ball 입니다\n");

      if(cnfThrow == MAX_THROW-1)
      {
         inputb.setEnabled(false);
         log.append("졌습니다. 정답은 "+answer[0]+" "+answer[1]+" "+answer[2]+" 입니다.\n");
      }
      cnfThrow++;
      chnum.setText((MAX_THROW-cnfThrow)+"");
   }

   public int[] importText()
   {
      int[] arr = new int[3];

      String temp = input.getText();

      if(temp.length() == 3)
      {
         int num = Integer.parseInt(temp);

         arr[2] = num%10;
         num /= 10;
         arr[1] = num%10;
         num /= 10;
         arr[0] = num;

         input.setText("");
      }
      else
      {
         String[] str = temp.split(" ");

         for(int i = 0; i<str.length; i++)
            arr[i] = Integer.parseInt(str[i]);

         input.setText("");
      }
      return arr;
   }

   private int[] judge(int a, int b, int c)
   {
      int[] num = {a,b,c};
      int[] stbal = {0,0};

      for(int i = 0; i<3;i++)
      {
         if(num[i] == answer[i])
            stbal[1]++;
         else
         {
            for(int k = 0; k<3;k++)
            {
               if(num[i] == answer[k])
                  stbal[0]++;
            }
         }
      }
      return stbal;
   }

   public void answermake()
   {
      Random ran = new Random();

      for(int i = 0;i<3;i++)
      {
         answer[i] = ran.nextInt(9)+1;
         for(int k = i;k>=0;k--)
         {
            if(k>0)
            {
               if(answer[i] == answer[k-1])
               {
                  answer[i] = ran.nextInt(9)+1;
                  k = i + 1;
               }
            }
         }
      }
   }

   public void restart()
   {
      inputb.setEnabled(true);
      answermake();
      chnum.setText(MAX_THROW+"");
      log.setText("슷자 야구 게임에 오신것을 환영합니다!\n");
      cnfThrow = 0;
   }

   public void actionPerformed(ActionEvent e)
   {
      String str = e.getActionCommand();

      if(str.equals("입력"))
         play();
      else if(str.equals("다시 시작"))
         restart();
      else if(str.equals("게임 종료"))
         System.exit(0);
   }


   public void keyPressed(KeyEvent e)
   {
      int a = e.getKeyCode();

      if(a == 10 && MAX_THROW > cnfThrow) // 10은 enter를 의미
         play();
   }


   public void keyReleased(KeyEvent arg0) {}
   public void keyTyped(KeyEvent arg0) {}

}

 

 

전체 소스는 아래 깃허브에서 보실 수 있습니다.

해당 프로젝트는 Eclipse에서 개발되었으며, intellij에서 원할하게 import 되지 않을 수 있습니다.

자바 소스 파일은 두 개밖에 되지 않으니, 새 프로젝트를 생성하고 파일 두개만 복붙하셔도 됩니다.

 

https://github.com/yoon6763/BaseballGame

 

GitHub - yoon6763/BaseballGame: 자바 Swing을 사용하여 제작한 숫자야구게임

자바 Swing을 사용하여 제작한 숫자야구게임. Contribute to yoon6763/BaseballGame development by creating an account on GitHub.

github.com

 

 

 

당시 Swing을 배울 땐 매번 콘솔창만 찍다가 GUI 코딩을 처음 해봐서,

신난 마음에 2048에 이어 숫자야구게임 까지 제작했었습니다.

 

intellij와 이를 기반으로 한 Jetbrains IDE들이 Swing을 기반으로 마개조해 만들었다고 하는데,

Swing을 그렇게까지 활용한 Jetbrains가 대단할 따름입니다.

 

Swing은 현재 그렇게 많이 쓰이는 기술이 아닙니다만,

저에게 있어 컴포넌트 등을 처음으로 직접 짜보고, 배치하고, 구현하고

GUI와 레이아웃 등을 이해하는데 있어서

굉장한 영향을 준 툴이자, 코딩을 하면서 재밌다고 느끼기 시작한 계기가 되었기 때문에 꽤나 뜻깊은 툴이기도 합니다.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.