我正在为一个班级项目创建一个“环绕游戏”。这个想法是,如果一个玩家被四面包围(如果适用)那么该玩家将失去并且围绕他们的玩家将获胜。这是胜利应该是什么样子的一个例子。我正在做我的有点不同,因为我使用图标来显示而不是数字,但它是相同的想法。在以下所有情况下,玩家1获胜。
所以我的问题出现在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;
}
我真的不想为每一种可能的场景做到这一点,而且我确信有一种更有效的方法来找到像我上面尝试的循环赢家。任何帮助将不胜感激!谢谢!
答案 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;
}