我正在Java上创建一个reverside(othello)游戏。以下是我的功能,适用于瓷砖需要向左、向右、向下或向上翻转所选部分的情况。出于某种原因,每当启动垂直翻转时,它总是能正常工作。但是,当启动水平翻转时,有时它什么也不做(当它应该做某事时),或者翻转不应该翻转的空白瓷砖。游戏板是一个8乘8的矩阵,使用一个名为BlankPiece的扩展JButton。我将在发布功能之外发布它。有人能提出一个更有效/更好的方法来运行这个游戏而没有bug吗?非常感谢您的帮助!如果你需要澄清,只需询问。
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
reversity.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);
}
}
}
不幸的是,我无法运行您的代码,因为它使用图像,如果没有图像,就无法判断哪个部分正在工作。然而,我有一个不同的方法建议,我认为这将帮助您解决问题(请注意所描述的想法,而不一定是代码)。
问题描述:(据我所知)当玩家在棋盘上放一块一种颜色的东西时(游戏中有两种颜色,每个玩家一种),系统需要沿着所有方向遍历所有区块(共有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();
}
}
}
}