공부/자바(JAVA)

바둑, 오목 보드(Baduk, Omok Board) - GUI

도도-도윤 2017. 10. 22. 19:56

바둑, 오목 보드(Baduk, Omok Board) - GUI


바둑, 오목 보드를 구현하였습니다.

바둑판을 설계하는 원리를 소개하겠습니다.



1. 바둑 판 크기

바둑판은 크게 19줄 바둑판, 13줄 바둑판, 9줄 바둑판이 있습니다.


* 19줄 바둑판

19줄 바둑판은 가장 일반적인 형태의 바둑판으로, 일반적인 대국이나 공식 기전 등에 쓰인다.

줄 수는 가로와 세로 19줄씩, 착점은 361개이다.


 19줄 바둑판


* 13줄 바둑판

13줄 바둑판은 좀 더 간소한 대국을 위한 바둑판이다. 줄 수는 가로와 세로 13줄씩, 착점은 169개이다.




 13줄 바둑판


* 9줄 바둑판

9줄 바둑판은 간소한 대국이나 바둑 교육 및 연습 등의 용도로 이용되는 바둑판이다. 착점이 적기 때문에 대국이 빨리 끝난다는 특징이 있다.

줄 수는 가로와 세로 9줄씩, 착점은 81개이다.

다음은 9줄 바둑판에서의 대국 예이다. 6호반 공제일 경우 일본식 룰에서는 흑 29집 - 백 32.5집(26집 + 덤 6.5집)으로 백의 3집반승이 되고, 중국식 룰에서는 흑 42집(29집 + 흑돌 13개) - 백 45.5집(26집 + 백돌 13개 + 덤 6.5집)으로 백의 3집반승이 된다.




 9줄 바둑판


(기타)

* 17줄 바둑판

고대 역사 속에서 사용되었던 바둑판이다.

티베트 전통 바둑에서도 17줄 바둑판을 사용한다.

줄 수는 가로와 세로 17줄씩, 착점은 289개이다.




 17줄 바둑판


* 15줄 바둑판

현재는 일본의 오목인 렌주 대국에서 공식적으로 사용되는 바둑판이다. 기존의 19줄 바둑판은 흑이 유리하고 13줄 바둑판은 백이 유리하다는 비판에 따라 채택된 규격이다. 줄 수는 가로와 세로 15줄씩, 착점은 225개이다




 15줄 바둑판


* 11줄 바둑판

바투에서 13줄 바둑판과 함께 사용되는 바둑판이다. 줄 수는 가로와 세로 11줄씩, 착점은 121개이다.


* 7줄 바둑판

9줄 바둑판에서 두 줄이 줄어든 바둑판으로, 용도는 9줄 바둑판과 같다. 줄 수는 가로와 세로 7줄씩, 착점은 49개이다.


* 4줄 바둑판

4줄 바둑판은 중화민국 출신의 프로 기사 장쉬 9단이 4줄 묘수풀이 퍼즐용으로 고안한 바둑판이다. 판이 너무 작아서 일반적인 대국에는 적합하지 않다. 줄 수는 가로와 세로 4줄씩, 착점은 16개이다.




 4줄 바둑판




2. 바둑/오목 알의 종류




검은색 - 알

흰색 - 알


바둑알의 종류는 크게 두 개 알로 구성됩니다.

검은색 알 1개, 흰색 알 1개로 구성됩니다.


게임 사용자를 생각해보면,

1:1(사용자 : 사용자), 1:Com(사용자 : 컴퓨터), Com:Com(컴퓨터:컴퓨터) 경기를 생각해볼 수 있겠습니다.



3. 알의 변화


  한 명은 흰색 알을, 다른 한 명은 검정색 알을 놓게 됩니다.

 1텀씩 번갈아가면서, 흰 알, 검은 알, 흰 알, 검은 알 순서로 게임이 진행됩니다.



4. 보드판




 보드판의 조각 1개


"보드판의 조각"을 반복해서 보드판을 구성합니다.

예를 들면,





더블클릭을 하시면 이미지를 수정할 수 있습니다





















이런 형태로 보드판의 조각을 이용해서 보드판을 구성합니다.

수학적인 표현으로서, 행렬(Matrix)이 이러한 형태를 가장 잘 표현하고 있습니다.



5. 영상

보드판에 알이 놓여지는 영상입니다. 자바 스윙(Swing)으로 구현하였습니다.


 


 시연 영상



6. 소스코드


/*
 *   GUI.java
 *   Created By: Dodo
 *   2017. 10. 22
 */

 package Window;


 import java.awt.BorderLayout;
 import java.awt.EventQueue;

 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.border.EmptyBorder;

 import Board.DrawBoard;


 public class GUI extends JFrame {

       private JPanel contentPane;
       private JPanel contentBoard;
       private DrawBoard drawBoard;
 
       /**
       * Launch the application.
       */
       public static void main(String[] args) {
              EventQueue.invokeLater(new Runnable() {
                    public void run() {
                           try {
                               GUI frame = new GUI();
                               frame.setVisible(true);
                           } catch (Exception e) {
                               e.printStackTrace();
                           }
                     }
              }); 
       }

        /**
        * Create the frame.
        */


       public GUI() {
             setTitle("Baduk/Omok Board - 프로그램");
             initComponents();
             createObjects();
        }
 
       public void initComponents() {

             setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             setBounds(100, 100, 750, 680);

             contentPane = new JPanel();
             contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
             setContentPane(contentPane);
             contentPane.setLayout(null);

             //contentPane.add(contentBoard);
       }
 
       public void createObjects() {
             drawBoard = new DrawBoard();
             drawBoard.setPath( System.getProperty("user.dir") );
             drawBoard.setBoardSize( 19 );
             drawBoard.createBoard();
  
             this.contentBoard =  drawBoard.getContent();
             contentPane.add(contentBoard);
             this.contentBoard.repaint();
       }
}

 GUI.java



/*
 *   BadukType.java
 *   Created By: Dodo(Rabbit.white@daum.net)
 *   2017. 10. 22
 */


 package Board;

 public enum BadukType{
        WHITE, BLACK
 }

 BadukType.java



/*
 *   DrawBoard.java
 *   Created By: Dodo(Rabbit.white@daum.net)
 *   2017. 10. 22
 */


 package Board;


 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;

 import javax.swing.ImageIcon;
 import javax.swing.JButton;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;


 public class DrawBoard implements ActionListener {
 
         private int x;
         private int y;
 
         public final int STD_19 = 19;
         public final int STD_13 = 13;
         public final int STD_9 = 9;
 
         public final int ETC_17 = 17;
         public final int ETC_15 = 15;
         public final int ETC_11 = 11;
         public final int ETC_7 = 7;
         public final int ETC_4 = 4;
 
         private Dimension dim;

         private int size;
         private JButton[][] btnBaduk;
         private boolean[][] baduk;
         private BadukType type;
         private JPanel contentBoard;
         private String path;
 
         public DrawBoard( ) {
  
               dim = new Dimension();
               contentBoard = new JPanel();
               contentBoard.setBackground(Color.ORANGE);
               contentBoard.setBounds(10, 35, 0, 0);
               contentBoard.setLayout(null);
  
               this.type = BadukType.WHITE;
               this.size = 0;
  
        }
 
        public void setBoardSize( int size ) {
  
                switch ( size )
                {
                     case STD_19:
                         dim.setSize(560, 560);
                         break;
    
                     case STD_13:
                         dim.setSize(400, 400);
                         break;
    
                     case STD_9:
                         dim.setSize(290, 290);
                         break;
    
                    case ETC_17:
                         dim.setSize(510, 510);
                         break;
    
                    case ETC_15:
                         dim.setSize(455, 455);
                         break;
    
                    case ETC_11:
                         dim.setSize(345, 345);
                         break;
    
                    case ETC_7:
                         dim.setSize(235, 235);
                         break;
    
                    case ETC_4:
                         dim.setSize(155, 155);
                         break;
               }
  
               this.size = size;
  
          }
 
          public int getBoardSize() {
               return this.size;
          }
 
          public void createBoard() {
  
               btnBaduk = new JButton[ (int) ( getBoardSize() + 1) ] [ (int) ( getBoardSize() + 1) ];
               baduk = new boolean[ (int) ( getBoardSize() + 1) ] [ (int) ( getBoardSize() + 1) ];
  
               for ( int i = 0; i <= getBoardSize(); i++) {
   
                    for ( int j = 0; j <= getBoardSize(); j++) {
    
                           // 바둑알 놓기
                           btnBaduk[i][j] = new JButton("");
                           btnBaduk[i][j].setBounds( 23 + ( i * 27 ), 19 + ( j * 27 ), 5, 5 );
                           btnBaduk[i][j].setBackground(new Color(153, 51, 0));
                           btnBaduk[i][j].setBorderPainted(false);
                           //btnBaduk[i][j].setContentAreaFilled(false);
                           //btnBaduk[i][j].setFocusPainted(false);
                           //btnBaduk[i][j].setOpaque(false);
                           btnBaduk[i][j].setActionCommand( i + "," + j );
                           btnBaduk[i][j].addActionListener( this );
    
                           contentBoard.add(btnBaduk[i][j]);
    
                           baduk[i][j] = false;
    
                           if ( i < getBoardSize() && j < getBoardSize() )
                           {
                                    JLabel baduk = new JLabel("");
                                    baduk.setBounds( 23 + ( i * 27 ), 16 + ( j * 27 ), 40, 40 );
                                    baduk.setIcon(new ImageIcon( getPath() + "\\BoardBlank.png"));
                                    contentBoard.add(baduk);
                            } // end of if
    
                       } // end of for
    
                   } // end of for
  
             contentBoard.setBounds(12, 63, (int)dim.getWidth(), (int)dim.getHeight() );
  
        }
 
        public JPanel getContent() {
             return this.contentBoard;
        }


        public void actionPerformed(ActionEvent arg0) {
  
               String tmp = arg0.getActionCommand();
  
               int x = Integer.parseInt( tmp.substring(0, tmp.indexOf(",") ) );
               int y = Integer.parseInt( tmp.substring( tmp.indexOf(",") + 1, tmp.length() ) );
  
               // 바둑알이 놓여졌을 때, 
               if ( baduk[x][y] ) {

                        JOptionPane.showMessageDialog(null, "이미 바둑알이 놓여져 있습니다.");
                        return;
               }
  
               // 바둑알 지정
               if ( type == BadukType.WHITE ) {
                       btnBaduk[x][y].setIcon(new ImageIcon( getPath() + "\\BoardWhite.png"));
                       type = BadukType.BLACK;
               }
               else {
                       btnBaduk[x][y].setIcon(new ImageIcon( getPath() + "\\BoardBlack.png"));
                       type = BadukType.WHITE;
                }
  
                // 바둑알 위치
                btnBaduk[x][y].setBounds( btnBaduk[x][y].getX() - 13, btnBaduk[x][y].getY() - 13, 30, 30);

                // 바둑알 이동 - 비활성화
                baduk[x][y] = true;
  
        }
 
        public String getPath() {
                return this.path;
        }
 
        public void setPath(String path) {
                this.path = path;
        }
 
 }

 DrawBoard.java


JavaBaduk.zip



7. 참고 자료

바둑판, https://ko.wikipedia.org/wiki/%EB%B0%94%EB%91%91%ED%8C%90



8. UML 설계




 UML - Classes Diagram(클래스 다이어그램)


JavaBaduk.zip
0.06MB

'공부 > 자바(JAVA)' 카테고리의 다른 글

자바(Swing) - 달력 구현하기  (0) 2017.10.28
자바 Swing(스윙) 차트 - JfreeChart  (0) 2017.10.24
Jasper Reports - 보고서 구현하기  (0) 2017.10.24
RX,TX - 시리얼(Serial)  (0) 2017.10.21
DB연동 프로젝트(Java Swing)  (0) 2017.10.15