0

我正在 Java 上创建一个黑白棋(黑白棋)游戏。下面包括我的功能,当瓷砖需要向左、向右、在下方或上方翻转时。出于某种原因,每当启动垂直翻转时,它总是可以正常工作。但是,当启动水平翻转时,有时它什么也不做(当它应该做某事时),或者翻转不应该翻转的空白图块。游戏板是一个 8 x 8 矩阵,使用名为 BlankPiece 的扩展 JButton。除了功能之外,我还会发布它。谁能建议一种更有效/更好的方式来运行这个游戏而没有错误?任何帮助是极大的赞赏!如果您需要澄清,请询问。

   public void checkFlipDown(BlankPiece temp)
    {
        for(int j = temp.getRow() - 1; j>=0; j--){
            // j equals the square right above the clicked one, and it keeps going up until it hits the top of the board
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement
        }
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getRow(); i >= j; i--)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[i][temp.getCol()].change(temp.pieceType());
                }
            }
        else
        {
            // if no other border pieces exist, go out of the loop
            break;
        }
        }
    }
    public void checkFlipUp(BlankPiece temp)
    {
        for(int j = temp.getRow() + 1; j<=7; j++){
            // j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getRow(); i <= j; i++)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[i][temp.getCol()].change(temp.pieceType());
                }
            }
        else
        {
            break;
        }
        }
    }
    public void checkFlipLeft(BlankPiece temp)
    {
        for(int j = temp.getCol() + 1; j<=7; j++){
            // j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getCol(); i <= j; i++)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[temp.getRow()][i].change(temp.pieceType());
                }
            }
        else
        {
            break;
        }
        }
    }
    public void checkFlipRight(BlankPiece temp)
    {
        for(int j = temp.getCol() - 1; j>=0; j--){
            // j equals the square to the right of the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getCol(); i >= j; i--)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[temp.getRow()][i].change(temp.pieceType());
                }
            }
        else if (gameboard[j][temp.getRow()].pieceType() == 0)
        {
            break;
        }
        }
    }

这就是我的四个功能(一个用于西、东、北和南)。空白片如下:

import java.awt.Color;

import javax.swing.*;


public class BlankPiece extends JButton
{
    private final ImageIcon bbutton = new ImageIcon("bbutton.png");
    private final ImageIcon gbutton = new ImageIcon("gbutton.jpg");
    private final ImageIcon pbutton = new ImageIcon("pbutton.png");
    private int x;
    private int y;

    BlankPiece(int x, int y)
    {
      this.setBackground(Color.BLACK);
      this.setIcon(bbutton);
      this.x = x;
      this.y = y;
    }
    public void setGreen()
    {
          this.setBackground(Color.BLACK);
          this.setIcon(gbutton);
    }
    public void setPurple()
    {
          this.setBackground(Color.BLACK);
          this.setIcon(pbutton);
    }
    public int getRow() {
        // TODO Auto-generated method stub
        return x;
    }
    public int getCol() {
        return y;
    }
    public void resetImage(int count)
    {
        if (count % 2 == 0)
        {
              this.setIcon(gbutton);
        }
        else
        {
            this.setIcon(pbutton);
        }
    }

    public boolean isSet()
    {

        String image = "" + this.getIcon();

        if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
        {
        }
        return false;
    }
    public int pieceType()
    {
        if(getIcon().equals(pbutton)) // purple
        {
            return -1;
        }
        else if(getIcon().equals(bbutton)) // blank
        {
            return 0;
        }
        else // green
        {
            return 1;
        }
    }
    public void change(int i) {
        if (i == -1)
        {
            setIcon(pbutton);
        }
        else if(i == 1)
        {
            setIcon(gbutton);
        }
        else
        {
            setIcon(bbutton);
        }

    }

}

问题不在于没有调用任何 checkflip(它们都使用相同的正确参数调用),而是 checkFlipRight 或 CheckFlipLeft 函数中的某些内容......

编辑:按要求提供完整的工作示例。

创建一个包含两个文件的文件夹

一个叫做 Reversi.java,另一个叫做 BlankPiece.java

REVERSI.JAVA:

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

public class Reversi extends JPanel {
    BlankPiece [][] gameboard = new BlankPiece[8][8];
    JPanel toparea = new JPanel();
    JPanel gamearea = new JPanel();
    JPanel greenarea = new JPanel();
    JPanel purplearea = new JPanel();
    JPanel logo = new JPanel();
    JLabel logoarea = new JLabel();
    JLabel greenlogo = new JLabel();
    JLabel purplelogo = new JLabel();
    ImageIcon blackicon = new ImageIcon("bbutton.png");
    ImageIcon icon = new ImageIcon("reversilogo.png");
    ImageIcon dgreen = new ImageIcon("DarkGreen.png");
    ImageIcon lgreen = new ImageIcon("LightGreen.png");
    ImageIcon dpurple = new ImageIcon("DarkPurple.png");
    ImageIcon lpurple = new ImageIcon("LightPurple.png");
    int count = 0;
    int jplus = 0;
    public Reversi()
    {  
        gamearea.setLayout(new GridLayout(8,8));
        for (int row = 0; row < gameboard.length; row++)
        {
            for(int col = 0; col < gameboard.length; col++)
            {
                gameboard[row][col] = new BlankPiece(row, col);
                gamearea.add(gameboard[row][col]);
                gameboard[row][col].addActionListener(new ButtonListener());

            }
        }
        logoarea.setPreferredSize(new Dimension(304,73));
        toparea.setLayout(new BorderLayout());
        this.setLayout(new BorderLayout());
        toparea.setBackground(new Color(97,203,242));
        gamearea.setBackground(new Color(83,35,215));
        logo.setBackground(new Color(97,203,242));
        logoarea.setIcon(icon);
        greenlogo.setIcon(dgreen);
        purplelogo.setIcon(lpurple);
        toparea.add(greenlogo, BorderLayout.WEST);
        toparea.add(purplelogo, BorderLayout.EAST);
        toparea.add(logo, BorderLayout.CENTER);
        logo.add(logoarea);
        this.add(toparea, BorderLayout.NORTH);
        this.add(gamearea, BorderLayout.CENTER);
        gameboard[3][3].setGreen();
        gameboard[3][4].setPurple();
        gameboard[4][3].setPurple();
        gameboard[4][4].setGreen();
    }
    private class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            BlankPiece temp = (BlankPiece)e.getSource();  // #1
            int row = temp.getRow();  // #2
            System.out.println(row);
            int col = temp.getCol();
            System.out.println(col);

            temp.isSet();

            // col and row are the column and row of blankpiece that was clicked
            String image = "" + temp.getIcon();
            if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
            {
                JOptionPane.showMessageDialog(null, "This spot is already occupied by " +
                        "a piece. Please pick an empty tile.");
            }
            else 
            {
                temp.resetImage(count++);
                System.out.println("About to check");
                checkFlipDown(gameboard[row][col]);
                checkFlipUp(gameboard[row][col]);
                checkFlipLeft(gameboard[row][col]);
                checkFlipRight(gameboard[row][col]);
            }
            if (count % 2 == 0)
            {
                greenlogo.setIcon(dgreen);
                purplelogo.setIcon(lpurple);
            }
            else
            {
                greenlogo.setIcon(lgreen);
                purplelogo.setIcon(dpurple);
            }
        } 
    } 
    public void checkFlipDown(BlankPiece temp)
    {
        for(int j = temp.getRow() - 1; j>=0; j--){
            // j equals the square right above the clicked one, and it keeps going up until it hits the top of the board
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement
        }
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getRow(); i >= j; i--)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[i][temp.getCol()].change(temp.pieceType());
                }
            }
        else
        {
            // if no other border pieces exist, go out of the loop
            break;
        }
        }
    }
    public void checkFlipUp(BlankPiece temp)
    {
        for(int j = temp.getRow() + 1; j<=7; j++){
            // j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getRow(); i <= j; i++)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[i][temp.getCol()].change(temp.pieceType());
                }
            }
        else
        {
            break;
        }
        }
    }
    public void checkFlipLeft(BlankPiece temp)
    {
        for(int j = temp.getCol() + 1; j<=7; j++){
            // j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getCol(); i <= j; i++)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[temp.getRow()][i].change(temp.pieceType());
                }
            }
        else
        {
            break;
        }
        }
    }
    public void checkFlipRight(BlankPiece temp)
    {
        for(int j = temp.getCol() - 1; j>=0; j--){
            // j equals the square to the right of the clicked one, and it keeps going down until it hits the bottom of the board
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
            //if the spot right above the clicked one is not black AND it is the other player's color,
            continue;
            // keep going with the block statement            2,4 jj = 3,4,5,6,7
        }
        if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
        // if the spot right above is not black AND it is the same player's color,
            for(int i = temp.getCol(); i >= j; i--)
                // i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
                {
                // change the colors of all colors in the clicked color's column and rows in between the other border piece
                    gameboard[temp.getRow()][i].change(temp.pieceType());
                }
            }
        else if (gameboard[j][temp.getRow()].pieceType() == 0)
        {
            break;
        }
        }
    }

}

空白片.JAVA

import java.awt.Color;

import javax.swing.*;


public class BlankPiece extends JButton
{
    private final ImageIcon bbutton = new ImageIcon("bbutton.png");
    private final ImageIcon gbutton = new ImageIcon("gbutton.jpg");
    private final ImageIcon pbutton = new ImageIcon("pbutton.png");
    private int x;
    private int y;

    BlankPiece(int x, int y)
    {
      this.setBackground(Color.BLACK);
      this.setIcon(bbutton);
      this.x = x;
      this.y = y;
    }
    public void setGreen()
    {
          this.setBackground(Color.BLACK);
          this.setIcon(gbutton);
    }
    public void setPurple()
    {
          this.setBackground(Color.BLACK);
          this.setIcon(pbutton);
    }
    public int getRow() {
        // TODO Auto-generated method stub
        return x;
    }
    public int getCol() {
        return y;
    }
    public void resetImage(int count)
    {
        if (count % 2 == 0)
        {
              this.setIcon(gbutton);
        }
        else
        {
            this.setIcon(pbutton);
        }
    }

    public boolean isSet()
    {

        String image = "" + this.getIcon();

        if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
        {
        }
        return false;
    }
    public int pieceType()
    {
        if(getIcon().equals(pbutton)) // purple
        {
            return -1;
        }
        else if(getIcon().equals(bbutton)) // blank
        {
            return 0;
        }
        else // green
        {
            return 1;
        }
    }
    public void change(int i) {
        if (i == -1)
        {
            setIcon(pbutton);
        }
        else if(i == 1)
        {
            setIcon(gbutton);
        }
        else
        {
            setIcon(bbutton);
        }

    }

}
4

1 回答 1

1

不幸的是,我无法运行您的代码,因为它使用了图像,没有它们就不可能知道哪个部分在工作。但是,我有一个不同方法的建议,我认为它可以帮助您解决问题(请注意所描述的想法,而不一定要注意代码)。

问题描述:(据我了解)当玩家将一个颜色的棋子放在棋盘上时(游戏中有两种颜色,每个玩家一个),系统需要沿各个方向遍历所有的块(有8个其中),直到遇到以下情况之一:

  • 一块相同颜色的块:在这种情况下,所有中间颜色相反的块都被翻转为玩家的颜色(即它们被“捕获”)
  • 一块空白/块:在这种情况下,不会发生颜色翻转
  • 板的边缘:再次没有发生翻转。

上面的描述意味着问题可以进一步划分为我们需要首先解决的更小的问题。

要解决的问题:

  • 我们如何识别“方向”
  • 考虑到每次下一个块,我们如何沿着一个方向遍历
  • 我们如何识别应该被捕获的片段
  • 我们如何识别板的边缘

您的方法试图一起解决上述所有问题。这使它变得复杂。此外,对于不同的方向重复相同的工作,这并不需要如此。根据以上描述,特定方向不需要特殊操作。如果我们解决一个方向的问题,那么它应该解决所有的问题。

建议的方法:您可以在下面找到要使用的算法(伪代码)来查找要捕获的所有片段。请注意片段本身如何尝试解决问题并将工作传播到下一个片段,直到找到所有捕获的片段。这样你就不会自己解决问题。您只需正确地向您的对象描述它。我已将注释内联以解释每个类应该是什么。我希望它对你来说清楚和有用。

// Convenient class to hold together a row and a column pair
public class Index { ... }

// Checks if an index falls out of board edges
public static boolean isValid(Index index) {...}

// Holds the array of pieces. Has method to get a piece by index
public class Board { ... } 

public enum ColorType { BLANK, WHITE, BLACK; } // the types of a Piece    

// The possible directions to traverse
public enum Direction {
    UP_LEFT, UP, UP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT;

    // given an index it returns the next index along the same direction
    public Index next(Index index) {
        switch (this) {
        case UP_LEFT:
            return new Index(index.row() - 1, index.column() - 1);
        case BOTTOM:
            return new Index(index.row() + 1, index.column());
        ... // similar for the rest of cases
        }
    }
}

public class Piece {

    private Board board;
    private ColorType color = ColorType.BLANK;
    private Index index;

    ....

    // Should be called privately when the piece is put on the board and from BLANK becomes WHITE or BLACK
    private void checkCaptures() {
        Direction[] directions = Direction.values();

        for (Direction direction : directions) {
            // get next piece's index along the direction
            Index nextIndex = direction.next(this.index);

            if ( isValid(nextIndex) ) { // if the index is not valid (i.e. edge of the board) ignore it

                // get next piece in the same direction
                Piece piece = board.getPiece(nextIndex);

                // find all pieces that should be captured in this direction 
                List<Piece> candidatesToCapture = new ArrayList<Piece>();
                piece.findCaptureCandidates(candidatesToCapture, this.color, direction);

                for (Piece candidate : candidatesToCapture) {
                    // flip the color (WHITE to BLACK and vice-versa)
                    candidate.capture(); 
                }
            } 
        }
    }

    private void findCaptureCandidates(List<Piece> captured, ColorType firstColor, Direction d) {

        Index next = d.next(this.index);

        if (this.color == firstColor) {
            // This piece has the same color with the first one.
            // No need to search further for this direction. All pieces collected in the list
            // between the first one and this one, have opposite color and should be captured.

        } else if (this.color == ColorType.BLANK) {
            // found a blank piece. Stop the search and clear any captured pieces found so far
            captured.clear();
        } else {
            // this piece has the opposite color of the first
            if ( isValid(next) ) {
                // this is not the last piece in this direction. 
                // Since it has a flipped color it is a candidate for capturing
                captured.add(this);

                // ask the next piece recursively to also check itself
                Piece piece = board.getPiece(next);
                piece.findCaptureCandidates(captured, firstColor, d);
            } else {
                // next index is not valid i.e. we have reached board edge. 
                // Stop the search and clear any captured pieces found so far
                captured.clear();
            }
        } 
    }
}
于 2013-08-02T13:13:09.637 回答