Java中的环绕游戏使用枚举类 - 如何找到胜利者

时间:2015-02-11 21:38:55

标签: java enums

我正在为一个班级项目创建一个“环绕游戏”。这个想法是,如果一个玩家被四面包围(如果适用)那么该玩家将失去并且围绕他们的玩家将获胜。这是胜利应该是什么样子的一个例子。我正在做我的有点不同,因为我使用图标来显示而不是数字,但它是相同的想法。在以下所有情况下,玩家1获胜。

enter image description here

所以我的问题出现在surroundGame类中,我不知道如果有胜利者怎么告诉它。我有一个带有单元格图标的枚举类,一个是播放器1,等等。

public enum Cell {
ONE, TWO, EMPTY;
}

另外,我有一个enum gameStatus类:

public enum GameStatus {
 PLAYER1_WON, PLAYER2_WON, TIE, IN_PROGRESS
} 

这是surroundGame类,问题出现在名为isWinner和isSurrounded的方法中。

package project2;

import java.awt.Point;
import java.util.*;


public class SurroundGame {
private Cell[][] board;
private GameStatus status;
private int size;
private Cell turn;
private Cell whoStarts;

some code edited out....

private GameStatus isWinner() {

    for (int r = 0; r < size; r++) {
        for (int c = 0; c < size; c++) {
            if (board[r][c] == Cell.EMPTY) {
                return GameStatus.IN_PROGRESS;
            }
        }
    }
    for (int r = 0; r < size; r++) {
        for (int c = 0; c < size; c++) {
            if (isSurrounded(Cell.ONE)) {
                return GameStatus.PLAYER1_WON;
            }
            if (isSurrounded(Cell.TWO)) {
                return GameStatus.PLAYER2_WON;
            }
        }
    }
        return GameStatus.TIE;
}

private boolean isSurrounded(Cell type) {
    for (int r = 0; r < size; r++) {
        for (int c = 0; c < size; c++) {
            if (board[r][c + 1] == type && board[r][c - 1] == type) {
                if (board[r + 1][c] == type && board[r - 1][c] == type) {
                    return true;
            }
            }
        }
    }

    return false;
}


public GameStatus getGameStatus() {
    return status;
}

}

问题在于我无法弄清楚如何判断一名球员何时获胜。当我测试GUI时,如果它以平局结束(没有人赢)正常工作,所有其他功能也是如此,所以我知道唯一的问题是玩家实际获胜的特定实例。我在isWinner方法中使用了helper方法isSurrounded,但我不能正确使用循环的逻辑,因为它不起作用。我尝试过使用两个辅助方法,一个用于查看单元格的列是否被包围,另一个用于查看单元格的行是否被包围,然后在isWinner中检查这两个方法以产生获胜者,但这也是不行。 另外,我想出了如何明确声明一个左上角的胜利,但这对于每次胜利的编码都要做很多工作,特别是因为游戏板的大小可以在3到10之间变化,我最终计划添加多个球员。但无论如何,这是我在isWinner方法中的表现方式

int row = 0;
    int col = 0;
    if (board[row][col] == Cell.ONE && board[row][col + 1] == Cell.TWO
            && board[row + 1][col] == Cell.TWO) {
        return GameStatus.PLAYER2_WON;
    }
    if (board[row][col] == Cell.TWO && board[row][col + 1] == Cell.ONE
            && board[row + 1][col] == Cell.ONE) {
        return GameStatus.PLAYER1_WON;
    }

我真的不想为每一种可能的场景做到这一点,而且我确信有一种更有效的方法来找到像我上面尝试的循环赢家。任何帮助将不胜感激!谢谢!

3 个答案:

答案 0 :(得分:0)

在isWinner()的第一个循环中,您正在检查空单元格的每个位置。由于您的获胜解决方案无疑仍然会打开单元格,因此在检查isSurrounded()之前它会返回IN_PROGRESS。您应首先检查是否有任何位置,然后检查游戏是否处于平局或仍在继续。

此外,您正在循环调用isSurround并在isSurround内循环。这是一个不必要的调用和循环,只需在每个单元格类型的循环外调用isSurround,并让该函数完成所有循环,就像设置它一样。

这应该效果更好

private GameStatus isWinner(){
    if(isSurrounded(Cell.ONE)){
        return GameStatus.PLAYER1_WON;
    }
    if(isSurrounded(Cell.TWO)){
        return GameStatus.PLAYER2_WON;
    }
    for (int r = 0; r < size; r++) {
        for (int c = 0; c < size; c++) {
            if (board[r][c] == Cell.EMPTY) {
                return GameStatus.IN_PROGRESS;
            }
        }
    return GameStatus.TIE;
}

答案 1 :(得分:0)

我相信如果你将坐标(row,col)封装在一个类中,你会让生活更轻松。然后,您可以实现listSurroundingCoordinates

等方法
class Coord {
    private final int row;
    private final int col;
    private final static int SIZE = 4;

    public List<Coord> listSurroundingCoordinates() {
        List<Coord> coords = new ArrayList<>();
        if (row > 0)
            coords.add(new Coords(row - 1, col));
        if (row < SIZE - 1)
            coords.add(new Coords(row + 1, col));
        if (col > 0)
            coords.add(new Coords(row, col - 1));
        if (col < SIZE - 1)
            coords.add(new Coords(row, col + 1));
        return coords;
    }

    // need equals and hashCode to be defined
}

然后你的电路板变成Map<Coord, Player> board - 你不再需要一个'空'值,因为它没有地图中的坐标所表示。

一旦你实现了检查胜利是一件相当简单的事情(我在这里使用过Java 8):

public boolean hasWon(CellValue player) {
    return board.keySet().stream()
        .filter(c -> !board.get(c).equals(player))
        .filter(c -> c.listSurroundingCoords().stream()
            .allMatch(s -> board.containsKey(s) && board.get(s).equals(player)))
        .findAny().isPresent();
}

如果您不使用Java 8或必须使用数组,请告诉我,我可以使用标准迭代发布等效内容并避免使用Map

答案 2 :(得分:0)

嘿,你也在Jags课上?

我刚完成项目并使用以下作为我的isSurrounded()方法。它肯定不像上面的其他人那么复杂,但是它为较低级别的课程提供了点:

private boolean isSurrounded(Cell type, Cell other) {
    for (int r = 0; r < size; r++) {
        for (int c = 0; c < size; c++) {
            if(board[r][c] == type){
                int count = 0;
                int win_count = 0;
                log(c + " " + r);
                if((r-1) >= 0 && (r - 1) < size){
                    win_count++;
                    if (board[r - 1][c] == other) {
                        count++;
                    }
                }

                if((r + 1) >= 0 && (r + 1) < size){
                    win_count++;
                    if (board[r + 1][c] == other) {
                        count++;
                    }
                }

                if((c + 1) >= 0 && (c + 1) < size){
                    win_count++;
                    if (board[r][c + 1] == other) {
                        count++;
                    }
                }

                if((c - 1) >= 0 && (c - 1) < size){
                    win_count++;
                    if (board[r][c - 1] == other) {
                        count++;
                    }
                }
                if(win_count == count){
                    return true;
                }
            }
        }
    }
    return false;
}