绘制tic-tac-toe板

时间:2014-12-15 20:20:22

标签: java graphics

我正在制作终极Tic-Tac-Toe游戏。如果您不熟悉规则,那很好。但是电路板布局只是3x3的Tic-Tac-Toe电路板。我需要一个算法,因为缺少一个更好的术语,所以我可以在任何我想要的地方制作xy,它会正确地绘制它。

    int width = 67; // Note: I've determined this variable means a lot to this "algorithm" because changing it changed the lines dramatically.
    g.drawRect(0, 0, x, y); // Changing this made the boxes go to the center, so this works
    g.drawLine(width, 0, width, y);
    g.drawLine(width*2, 0, width*2, y);
    g.drawLine(0, width, x, width);
    g.drawLine(0, width*2, x, width*2);

类构造函数要求输入xy,因此这些是不同的。

具体来说,无论我做x和y坐标是什么,我都希望这个能够工作。

代码中的最后4行构成了4个交叉条(形状像一个非常大的#)。

制作1:这很好用。

制作2:水平( - )线有效,而不是垂直(|)。

制作3:第三个框甚至没有出现。

另请注意,以上3项测试仅为1排Tic-Tac-Toe板。

我也明白width不能是一个单一的值(就像现在一样),但改变它会使得这些线远离它们应该的位置,所以我不知道要改变它到。

3 个答案:

答案 0 :(得分:0)

庵。除了你要求我们为你做的工作之外......

我建议甚至不要使用Java Graphics来绘制x的形状并绘制o的形状(它会使你的程序变脏,但你知道......无论这是一个教程) 。相反,我会将一系列面板放在JTextAreas上。给他们一个巨大的字体,并使他们的'isFocusable()'布尔值为false。然后,我会为每个鼠标添加鼠标监听器,因此只要鼠标单击JTextArea,它就会运行一个方法。我会在这里为你写一个方法,它非常简单。它将采用一个参数,一个JTextArea。这将是单击的区域,可以很容易地找到,因为您将在mouseListener的mousePressed()方法中调用此方法。请记住,这将需要一个mouseListener用于所有9个JTextAreas。此方法还假设您已创建两个布尔值,一个用于第一个播放器,另一个用于第二个布尔值。如果它是Player1,则此方法将找出,然后将转向更改为Player2,反之亦然。 ****注意****确保在创建时将Player1的值设置为true,或者至少在调用此方法之前将其设置为true。

public void makingMove(JTextArea jta) {
    if (player1) {
        jta.setText("x");
        player1 = false;
        player2 = true;
    }
    if (player2) {
        jta.setText("o");
        player1 = true;
        player2 = false;
    }

}
嗯,这会有用吗?没有!如果你单击一个已经有字母的JTextArea怎么办?它会取代它!我们不能拥有!所以,现在我们需要改变我们的makingMove方法,所以我们知道我们不会违反任何规则:

public void makingMove(JTextArea jta) {
    if (jta.getText() == null) {
        if (player1) {
            jta.setText("x");
            player1 = false;
            player2 = true;
        }
        if (player2) {
            jta.setText("o");
            player1 = true;
            player2 = false;
        }
    }
    else {
        JOptionPane.showMessageDialog(null, "You can't move there, someone already has!");
    }
}

完成了吗?错误!现在我们需要创建一个方法来检查是否有人赢了! 我们将在makeMove()方法中的else语句之后调用它。像这样:

.....
    }
    else {
        JOptionPane.showMessageDialog(null, "You can't move there, someone already has!");
    }
checkWinnerX(1, 2, 3, 4, 5, 6, 7, 8, 9);
checkWinnerY(1, 2, 3, 4, 5, 6, 7, 8, 9);
}

checkWinnerX方法必须使用9个参数,与checkWinnerO方法相同。每个输入对象都是JTextArea,因此我们可以比较它们的输入。这个方法假定,你的JTextAreas被命名为1-9,就像它是一个电话的拨号盘一样。另外,我们有checkWinnerX和checkWinnerO方法调用方法来清除所有内容,并重置游戏,如果你愿意,你可以将其指定给一个按钮,但我肯定会推荐一个。 *****注意****** 我不会编写checkWinnerO方法,因为它与checkWinnerX相同,而是使用所有的o来代替。而且我相信你明白了。这是处理这个问题的极其低效的方法,但是很好。

public static void checkWinnerX(JTextArea 1, JTextArea 2, etc.. up to 9) {
    if (1.equals("x") && 2.equals("x") && 3.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();
    }
    if (4.equals("x") && 5.equals("x") && 6.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (7.equals("x") && 8.equals("x") && 9.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (1.equals("x") && 2.equals("x") && 3.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (1.equals("x") && 5.equals("x") && 9.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (7.equals("x") && 5.equals("x") && 3.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (1.equals("x") && 4.equals("x") && 7.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (2.equals("x") && 5.equals("x") && 8.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
    if (3.equals("x") && 6.equals("x") && 9.equals("x")) {
        JOptionPane.showMessageDialogue(null, "The winner is X!");
        clear();

    }
}

public static void clear() {
    1.setText(null);
    2.setText(null);
    3.setText(null);
    4.setText(null);
    5.setText(null);
    6.setText(null);
    7.setText(null);
    8.setText(null);
    9.setText(null);
}

现在,如果您已正确设置了mouseListener,并使用GridBagConstraints正确格式化您的游戏板。你几乎已经完成了它 我可以用千种不同的方法和对象来做这一千种方式,我选择这种方式是因为你指定了你想要一个算法'为了它。现在,您应该可以参考这个非常精简的制作此游戏的方法,并编写自己的代码。

希望这有帮助。

答案 1 :(得分:0)

如果我理解正确,你需要一个3 x 3网格的tic tac toe board。

这是一个快速Swing应用程序,绘制一个3 x 3网格的tic tac toe板。 9个面板上有9个tic tac toe board。

Tic Tac Toe board

这是代码。绘图代码位于DrawingPanel类中。

package com.ggl.testing;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TicTacToe implements Runnable {

    private JFrame frame;

    private List<DrawingPanel> drawingPanels;

    public TicTacToe() {
        this.drawingPanels = new ArrayList<>();
    }

    @Override
    public void run() {
        frame = new JFrame();
        frame.setTitle("Ultimate Tic Tac Toe");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                exitProcedure();
            }
        });

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(3, 3, 10, 10));
        for (int i = 0; i < 9; i++) {
            DrawingPanel drawingPanel = new DrawingPanel();
            mainPanel.add(drawingPanel);
            drawingPanels.add(drawingPanel);
        }


        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void exitProcedure() {
        frame.dispose();
        System.exit(0);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TicTacToe());
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = -3774580797998095321L;

        public DrawingPanel() {
            this.setPreferredSize(new Dimension(170, 170));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());

            Graphics2D g2d = (Graphics2D) g;

            g2d.setStroke(new BasicStroke(5.0F));
            Rectangle r = new Rectangle(0, 0, getWidth(), getHeight());

            int sectionWidth = r.width / 3;
            int sectionHeight = r.height / 3;

            g2d.setColor(Color.BLACK);
            g2d.drawLine(r.x, r.y + sectionHeight, 
                    r.x + r.width, r.y + sectionHeight);
            g2d.drawLine(r.x, r.y + sectionHeight + sectionHeight, 
                    r.x + r.width, r.y + sectionHeight + sectionHeight);
            g2d.drawLine(r.x + sectionWidth, r.y, r.x + sectionWidth, 
                    r.y + r.height);
            g2d.drawLine(r.x + sectionWidth + sectionWidth, r.y, 
                    r.x + sectionWidth + sectionWidth, r.y + r.height);
        }

    }
}

答案 2 :(得分:0)

请参阅Java平台文档了解Graphics class。特别是drawLine() method的文档,以及drawRect() method的文档(尽管您不必严格需要drawRect()来完成任务)。

根据您的描述,听起来您希望重用代码示例中的四个drawLine()语句来创建九个小网格中的每一个以及一个大网格。

假设您的调用代码如下所示:

int totalWidth = 200;

// draw big grid
drawGrid(g, 0, 0, totalWidth);

// draw small grids
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        drawGrid(g, totalWidth / 3 * i, totalWidth / 3 * j, totalWidth / 3);
    }
}

这就是我要做的事情:

private void drawGrid(Graphics g, int x, int y, int width) {
    // draw box around grid (not necessary)
    //g.drawRect(x, y, width, width);

    // draw vertical grid lines
    g.drawLine(width / 3 + x, y, width / 3 + x, y + width);
    g.drawLine(width / 3 * 2 + x, y, width / 3 * 2 + x, y + width);

    // draw horizontal grid lines
    g.drawLine(x, width / 3 + y, x + width, width / 3 + y);
    g.drawLine(x, width / 3 * 2 + y, x + width, width / 3 * 2 + y);
}

请注意,这并没有在小网格周围放置任何填充,因此它看起来像一个巨大的网格。我想你会想要添加一些填充以使其看起来正确。你可以从它循环的调用代码那里创建小网格。