我有一种方法,在"Torus“板上检查获胜条件,这是一个没有边界的董事会。这意味着如果你在左上角放置4个对角线石头,在右下角放置2个对角线石头,如果它们位于相同的对角线上,如果你忽略了边界,就会连接起来,这就会导致胜利。基本上这是一个连接6游戏。
size()返回板的大小,要么是18,要么是20。
currentPlayer是一个字符串,类似于"P1“或"P2”。
r和c是刚刚移动的行和列。
public boolean checkTorusWinner(int r, int c){
int count = 0;
boolean hasWinner = false;
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
/*
Checks Horizontally for a Win.
*/
for (int i = c; i < hSize; i++) {
if (board[r][i] == currentPlayer) {
count++;
} else {
count = 0;
}
if (i == size() - 1) {
hSize = size() - 2;
for (int j = 0; j < hSize; j++) {
if (board[r][j] == currentPlayer) {
count++;
} else {
count = 0;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
/*
Checks Vertically for a Win
*/
for (int i = r; i < vSize; i++) {
if (board[i][c] == currentPlayer) {
count++;
} else {
count = 0;
}
if (i == size() - 1) {
i = -1;
vSize = size() - 2;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
/*
Checks Diagonally from Top left to Bottom right
*/
if (c - r >= 0) {
int startingC;
startingC = c - r;
int size = size();
for (int i = r, j = c; j < size; i++, j++) {
if (board[i][j] == currentPlayer) {
count++;
} else {
count = 0;
}
if (j == size() - 1) {
j = startingC - 1;
i = -1;
size = size() - 2;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
} else {
int size = size();
int startingR;
startingR = r - c;
for (int i = r, j = c; i < size; i++, j++) {
if (board[i][j] == currentPlayer) {
count++;
} else {
count = 0;
}
if (i == size() - 1) {
j = -1;
i = startingR - 1;
size = size() - 2;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
}
/*
Checks Diagonally from bottom left to top right;
*/
if (r + c <= 17) {
int loop = 0;
int startingR;
startingR = r + c;
for (int i = r, j = c; i >= 0; i--, j++) {
if (board[i][j] == currentPlayer) {
count++;
} else {
count = 0;
}
if (i == 0 && loop == 0) {
i = startingR + 1;
j = -1;
loop++;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
} else if (r + c > 17) {
int loop = 0;
int startingC;
startingC = (r + c) - (size() - 1);
for (int i = r, j = c; i >= startingC; i--, j++) {
if (board[i][j] == currentPlayer) {
count++;
} else {
count = 0;
}
if (i == startingC && loop == 0) {
i = size();
j = startingC - 1;
loop++;
}
if (count == 6) {
boardType = "none";
hasWinner = true;
break;
}
}
}
return hasWinner;
}不幸的是,这种方法的长度不能满足我校的要求:它必须是最多80行。我不知道该如何缩短这段代码,这样它才能继续工作。
发布于 2018-03-05 08:01:59
谢谢你分享你的代码。
您的代码是一种处理问题的过程方法。
一般来说,过程方法没有什么问题,但是Java是一种面向对象( oriented )编程语言,如果您想成为一名优秀的Java程序员,那么您应该开始以面向对象的方式解决问题。
但是OOP并不意味着将代码“拆分”成随机类。
OOP的最终目标是减少代码重复、提高可读性和支持重用以及扩展代码。
执行OOP意味着您遵循某些原则(除其他外):
从OO的角度来看,您有当前的位置,您必须检查该位置是否是至少5个其他(不包括自身)相等元素行的一部分。
第一个含义是,您只需查看当前的位置邻居和没有必要扫描整个董事会。
最简单的方法是朝每个方向走,并计算属于当前玩家的连续邻居。然后,您添加存款指示,并检查和。
我使用一个技巧来安全地计算“环绕”数组中的索引:
(arrayLength + currentIndex + differece) % arrayLength 其中%是模数运算符。
以下是我将如何实现这一目标:
class FiledPosition{
final int r, c;
FiledPosition(int r, int c){
this.r=r;
this.c=c;
}
}
interface NeighborCalculator
FiledPosition getFor(FiledPosition current);
}
enum Direction {NORTH,NORTH_EAST,EAST,SOUTH_EAST,SOUTH,SOUTH_WEST,WEST,NORTH_WEST}上面的代码可能存在于不同的类中。下面的内容必须在您的解决方案类中
private final Direction[][] opposits = new Direction[][]{
{NORTH,SOUTH},
{NORTH_EAST,SOUTH_WEST},
{NORTH_WEST,SOUTH_EAST},
{EAST,WEST}
}
private final int WIN_COUNT_EXCLUDUNG_CURRENT = 5;
Map<Direction, NeighborCalculator> neigborSelector = new HashMap<>();
public boolean checkTorusWinner(int r, int c){
neigborSelector.put(NORTH, new NeighborCalculator(){ // pre java8 anonymous inner class
public FiledPosition getFor(FiledPosition currentPoint ){
return new Point((vSize+currentPoint.r-1)%vSize, currentPoint.c));
}
});
neigborSelector.put(NORTH_EAST,currentPoint -> new Point((vSize+currentPoint.r-1)%vSize, (hSize+currentPoint.c+1)%hSize)); // java8 lambda
neigborSelector.put(EAST,currentPoint -> new Point(currentPoint.r, (hSize+currentPoint.c+1)%hSize));
neigborSelector.put(SOUTH_EAST,currentPoint -> new Point((vSize+currentPoint.r+1)%vSize, (hSize+currentPoint.c+1)%hSize));
// similar for all directions, should be in the classes constructor.
Map<Direction, Counter> lineSectionCounts = new HashMap<>();
String currentPlayer = board[r][c];
int hSize = size();
int vSize = size();
// count consecutive same in each direction without current
for(Direction direction : Direction.values()){
int consecutiveSame = 0;
FiledPosition neigborPosition = neigborSelector.get(direction).getFor(new FiledPosition(r,c));
while(currentPlayer.equals(board[neigborPosition.r][neigborPosition.c])){
consecutiveSame++;
neigborPosition = neigborSelector.get(direction).getFor(neigborPosition);
}
lineSectionCounts.put(consecutiveSame); // auto boxed
}
// sum up opposit directions
for(Direction[] opposit : opposits){
if(WIN_COUNT_EXCLUDUNG_CURRENT < lineSectionCounts.get(oposit[0]) + lineSectionCounts.get(oposit[1])) // auto unbox
return true; // current Player won.
}
return false; // no winner yet
}这个完整的代码有57行(24行没有配置)。需要完整地配置neigborSelector映射(如果您使用jav8 lambdas),需要少4行。
这段代码使用了基本的Java概念,如类、接口和枚举,您应该已经听说过了。
https://codereview.stackexchange.com/questions/188729
复制相似问题