바둑, 오목 보드(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(클래스 다이어그램)