Moyen simple d'implémenter computer - go board en Java


Je veux faire un simple plateau de Go pour concevoir un Ordinateur Go jeu.

Dans un jeu de go, vous allongez une "pierre" (blanche ou noire) sur une position où les lignes horizontales et verticales se croisent.

Quels sont les moyens simples d'empêcher les utilisateurs de placer leurs pierres à d'autres endroits?
Peut-être que je ne vois tout simplement pas de solution simple.

MODIFIER
Je suppose que je devrais mieux reformuler ma question: Je veux savoir comment faire l'image d'arrière-plan de Go board, donc que je puisse poser mes pierres à l'intersection des lignes horizontales et verticales. Je pensais à obtenir une image Go board juste régulière, et quand je rends réellement des pierres, je trouve la bonne position des pixels pour mentir des pierres. Cependant, cette solution ne semblait pas être la meilleure solution, car je dois m'inquiéter de la taille des images en pierre et penser à la proportionnalité lorsque j'agrandit ou rétrécit la fenêtre du tableau.

Author: CPerkins, 2009-10-16

5 answers

J'utiliserais des énumérations ici:

enum Stone {BLAC, WHITE, NONE}

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

Modifier :

Voici une petite démo (pas de redimensionnement de la carte et pas d'images, juste de bons vieux graphiques!):

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);
    }
}

Les choses aléatoires là-dedans sont une implémentation dont CPerkins parlait. Eh bien, j'ai essayé de le faire de toute façon.

 2
Author: Bart Kiers, 2009-10-17 19:25:52

Comment mettre en œuvre les positions a été répondu. Mais ce que vous avez demandé, c'est comment limiter les utilisateurs dans leur placement, ce qui est une chose différente.

Vraisemblablement, vous prévoyez de créer une zone de dessin et vous détecterez les clics de souris. La façon dont vous limiteriez le placement de la pierre aux intersections ressemble à ce que font les programmes de dessin pour implémenter une fonctionnalité appelée "snap" (comme dans "snap to grid").

Fondamentalement, cela signifie simplement réduire les clics qui tombent sur une plage de pixels dans chacun dimension en être sur l'une des lignes. Faire cela dans les deux dimensions met le clic déplacé à un point.

Essentiellement, ce que vous faites est de trouver le milieu de chaque cellule, et tout clic qui se situe entre le milieu d'une cellule et le suivant sera compté comme étant sur la ligne entre ces milieux.

Donc, fondamentalement, ce serait quelque chose comme ceci:


    // 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;
    }

Incidemment, dans les jeux réels, les pierres ne sont pas parfaitement placées, donc les jeux ont une sensation organique agréable. Vous pourrait envisager une solution dans laquelle vous stockez pas seulement de la position des pierres dans la grille, mais aussi dans certains légèrement moins de parfaitement l'alignement sur l'écran pour l'affichage.

 2
Author: CPerkins, 2009-10-16 23:13:37

Ne pense pas aux lignes. Pensez aux intersections. Les intersections peuvent être représentées comme une grille de la même manière que les carrés sur un échiquier forment une grille.

En Java, la représentation la plus simple serait un tableau carré. Quelque chose comme:

Location[MAX_Y][MAX_X];

Location est un objet représentant l'intersection et contenant une référence à la pièce qui y est placée (le cas échéant).

 1
Author: Brian Agnew, 2009-10-16 09:23:35
int[][] grid = new int[19][19];

Voilà votre grille. Chaque emplacement de ce tableau représente une intersection de ligne.

 1
Author: Bombe, 2009-10-16 09:24:06

Si votre objectif principal est d'implémenter l'IA, je suggère d'implémenter le Go Text Protocol et d'utiliser l'un des nombreux frontaux GTP existants. Si vous voulez construire l'interface graphique comme une expérience d'apprentissage, allez-y (sans jeu de mots). En tant que quelqu'un qui a écrit une interface graphique go commerciale, je vous préviens, c'est beaucoup plus difficile qu'il n'y paraît (Une application d'échecs serait simple en comparaison).

 0
Author: mikerobi, 2010-03-16 02:14:11