2009-10-16 4 views
3

Computer Go 게임을 디자인하기 위해 간단한 Go 보드를 만들고 싶습니다.Java에서 컴퓨터 고 보드를 구현하는 간단한 방법

바둑 게임에서는 수평선과 수직선이 교차하는 위치에 "돌"(흰색 또는 검은 색)이 있습니다.

사용자가 다른 장소에 돌을 배치하지 못하도록 제한하는 몇 가지 간단한 방법은 무엇입니까?
어쩌면 간단한 해결책이 보이지 않을 수도 있습니다.

편집
나는 내 질문이 더 바꿔한다 생각 : 나는 수평 및 수직 라인의 교차점에 내 돌을 거짓말을 할 수 있도록 내가, 이동 보드의 배경 이미지 작업을 수행하는 방법을 알고 싶어요 . 그냥 평범한 Go 보드 이미지를 얻는 것에 대해 생각하고 있었고 실제로 돌을 렌더링 할 때 픽셀이 올바른 위치에 놓여 돌이 놓여있는 것을 발견했습니다. 그러나이 솔루션은 최고의 솔루션으로 보이지 않았습니다. 보드 이미지를 확대하거나 축소 할 때 돌 이미지의 크기를 걱정하고 비례에 대해 생각해야하기 때문입니다.

+0

@ skaffman : 숙제 문제라고 생각하십니까? 나는 실망했다. 어쩌면 게임은 Go이기 때문일 수 있습니다. – CPerkins

+0

Skaffman이 분명히 그의 코멘트를 삭제했지만 이것은 내 개인 프로젝트입니다. 나는 확률 론적 AI를 적용하고 배우는 동안 바둑 게임 엔진을 구현하려고합니다. – codingbear

+0

나는 그것을 듣고 기쁘다, codingbear. 스카프 만 (Skaffman)이 질문을 편집했고, 나는 그가 "숙제"라고 재검토했다고 생각했습니다. 숙제가 아니기 때문에 저는 그 태그를 제거 할 것입니다 : 그것은 사람들을 막아 버리는 경향이 있습니다. 귀하의 진전 상황을 지속적으로 알려 주시기 바랍니다. – CPerkins

답변

2

여기 열거 형을 사용하십시오 :

enum Stone {BLAC, WHITE, NONE} 

class Board { 
    static final int dimension = 19; 
    private Stone[][] board = new Stone[dimension][dimension]; 
    // ... 
} 

편집을 :

여기에 작은 데모입니다 (보드없이 이미지의 크기가 조정, 단지 좋은 오래된 그래픽!) :

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

public class GoBoardDemo { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setLayout(new BorderLayout()); 
     frame.add(new GoPanel(19), BorderLayout.CENTER); 
     frame.setSize(600, 625); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.setVisible(true); 
    } 
} 


@SuppressWarnings("serial") 
class GoPanel extends JPanel { 

    Square[][] board; 
    boolean whiteToMove; 

    GoPanel(int dimension) { 
     board = new Square[dimension][dimension]; 
     whiteToMove = true; 
     initBoard(dimension); 
    } 

    private void initBoard(int dimension) { 
     super.setLayout(new GridLayout(dimension, dimension)); 
     for(int row = 0; row < dimension; row++) { 
      for(int col = 0; col < dimension; col++) { 
       board[row][col] = new Square(row, col); 
       super.add(board[row][col]); 
      } 
     } 
     repaint(); 
    } 

    private class Square extends JPanel { 

     Stone stone; 
     final int row; 
     final int col; 

     Square(int r, int c) { 
      stone = Stone.NONE; 
      row = r; 
      col = c; 
      super.addMouseListener(new MouseAdapter(){ 
       @Override 
       public void mouseClicked(MouseEvent me) { 
        if(stone != Stone.NONE) return; 
        stone = whiteToMove ? Stone.WHITE : Stone.BLACK; 
        whiteToMove = !whiteToMove; 
        repaint(); 
       } 
      }); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      int w = super.getWidth(); 
      int h = super.getHeight(); 
      g.setColor(new Color(0xB78600)); 
      g.fillRect(0, 0, w, h); 
      g.setColor(Color.BLACK); 
      if(row == 0 || row == board.length-1 || col == 0 || col == board.length-1) { 
       if(col == 0) { 
        g.drawLine(w/2, h/2, w, h/2); 
        if(row == 0) g.drawLine(w/2, h/2, w/2, h); 
        else if(row == 18) g.drawLine(w/2, h/2, w/2, 0); 
        else g.drawLine(w/2, 0, w/2, h); 
       } 
       else if(col == 18) { 
        g.drawLine(0, h/2, w/2, h/2); 
        if(row == 0) g.drawLine(w/2, h/2, w/2, h); 
        else if(row == 18) g.drawLine(w/2, h/2, w/2, 0); 
        else g.drawLine(w/2, 0, w/2, h); 
       } 
       else if(row == 0) { 
        g.drawLine(0, h/2, w, h/2); 
        g.drawLine(w/2, h/2, w/2, h); 
       } 
       else { 
        g.drawLine(0, h/2, w, h/2); 
        g.drawLine(w/2, h/2, w/2, 0); 
       } 
      } else { 
       g.drawLine(0, h/2, w, h/2); 
       g.drawLine(w/2, 0, w/2, h); 
      } 
      stone.paint(g, w); 
     } 
    } 
} 

enum Stone { 

    BLACK(Color.BLACK), WHITE(Color.WHITE), NONE(null); 

    final Color color; 
    private final static Random rand = new Random(); 

    private Stone(Color c) { 
     color = c; 
    } 

    public void paint(Graphics g, int dimension) { 
     if(this == NONE) return; 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setColor(color); 
     int x = 5; 
     g2d.fillOval(rand.nextInt(x), rand.nextInt(x), dimension-x, dimension-x); 
    } 
} 

무작위적인 내용은 유기농 느낌의 구현입니다. CPerkins가 말했습니다. 음, 어쨌든 그것을하려고했습니다.

+0

굉장합니다. 정확히 내가 알고 싶었던 것. 나는 그래픽에 대해 더 많이 배우기 시작해야한다. 이것은 꽤 흥미 롭습니다. – codingbear

+0

반갑습니다. –

1

줄을 생각하지 마십시오. 교차로를 생각해보십시오. 교차점은 체스 보드의 사각형이 그리드를 형성하는 것과 같은 방식으로 그리드로 표시 될 수 있습니다.

Java에서 가장 간단한 표현은 정사각형 배열입니다. 같은 : Location 교차로를 나타내는 (있는 경우)가 배치 된 부분에 대한 참조를 보유하는 개체이다

Location[MAX_Y][MAX_X]; 

.

1
int[][] grid = new int[19][19]; 

그리드가 있습니다. 이 배열의 각 위치는 선 교차를 나타냅니다.

2

위치를 구현하는 방법에 대한 답변이 제공되었습니다. 하지만 사용자가 배치에서 사용자를 제한하는 방법은 다른 점입니다.

아마도 도면 영역을 만들 계획이며 마우스 클릭을 감지 할 것입니다. 돌 배치를 교차점으로 제한하는 방법은 그리기 프로그램이 "스냅"이라는 기능을 구현하는 것과 같습니다 ("그리드에 맞추기"에서처럼).

기본적으로 이는 각 측정 기준의 픽셀 범위에 해당하는 클릭을 줄의 한쪽으로 줄이는 것을 의미합니다. 두 치수 모두에서이 작업을 수행하면 이동 된 클릭이 한 지점에 놓입니다.

기본적으로 각 셀의 중간 점을 찾고 하나의 셀 중간 점과 다음 셀 중간 점 사이에있는 클릭은 해당 중간 점 사이의 선으로 계산됩니다.게임을 기쁘게 유기 느낌을 가질 수 있도록,


    // Since traditionally, boards are not square, you'd call this twice: once with the 
    // width in X for the X click, and once again for Y. 
    // Naturally, you'll want to accomodate e.g., 9x9 boards for short games. 
    int snapClick (int gridWidth, int clickPos, int numCells) { 
     int cellWidth = (int) (gridWidth/numCells); 
     int snappedClick = Math.round ((clickPos + (cellWidth/2))/cellWidth); 
     return snappedClick; 
    } 

이 덧붙여, 실제 게임에, 돌은 (는) 도심에 배치되지 않습니다

그래서 기본적으로,이 같은 것을 할 것이다. 그리드에서 돌의 위치뿐만 아니라 화면에 표시하기 위해 화면에서 약간 어긋나게 정렬하는 솔루션을 고려할 수도 있습니다.

+0

하, 게임의 유기적 인 느낌 *에 대해서는 전혀 생각하지 않았지만, 완벽하게 이해할 수 있습니다. 잘 알고 있습니다! –

+0

그는 내 모든 질문에 답하지 않았지만 정말 멋지다! – codingbear

0

기본 목표가 AI를 구현하는 것이라면 Go Text Protocol을 구현하고 많은 기존 GTP 프런트 엔드 중 하나를 사용하는 것이 좋습니다. GUI를 학습 경험으로 구축하려면 다음 단계로 진행하십시오. 상업용 go GUI를 작성한 사람으로서 나는 경고합니다. 보이는 것보다 훨씬 어렵습니다 (체스 앱은 비교하면 간단 할 것입니다).

관련 문제