Java Reversi游戏翻转瓷砖

时间:2013-08-01 19:53:39

标签: java reversi

我正在创建一个关于Java的reversi(othello)游戏。下面是我的功能,当瓷砖需要翻转到所选部分的左侧,右侧,下方或上方时。出于某种原因,无论何时启动垂直翻转,它始终都能正常工作。但是,当启动水平翻转时,有时它什么都不做(什么时候应该做什么),或翻转不应该翻转的空白区块。游戏板是一个8乘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;
        }
        }
    }

所以这些是我的四个功能(一个用于西,东,北和南)。 BlankPiece如下:

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

}

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

    }

}

1 个答案:

答案 0 :(得分: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();
            }
        } 
    }
}