java - 一种优雅的方式来计算每个位置中每种类型的数量
问题描述
我有一个抽象类,它有 1 个属性,如下所示:
PieceColor {
WHITE, BLACK
}
abstract class Piece {
PieceColor color
abstract char getAbbr();
}
此类棋子已由 Bishop Knight Rook King Queen 和 Pawn 类扩展。这些类中的每一个都有一个名为 getAbbr() 的方法,它返回 Piece 的缩写 KQBNRP。
现在我有一个Map<Piece, Tile> piecePlacements
代表特定时间当前在棋盘上的所有棋子。
我需要计算有多少种类型的棋子,比如白车、黑皇后等。但是这样做的正常方法太长了,而且很难看。我就是这样做的...
//0: White pieces, 1: Black pieces; 0-5: KQRBNP
int[][] pieceCount = new int[2][6];
for(Piece piece : piecePlacements.keySet()) {
switch (piece.getAbbr()) {
case 'K' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][0]++;
} else {
pieceCount[1][0]++;
}
break;
case 'Q' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][1]++;
} else {
pieceCount[1][1]++;
}
break;
case 'R' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][2]++;
} else {
pieceCount[1][2]++;
}
break;
case 'B' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][3]++;
} else {
pieceCount[1][3]++;
}
break;
case 'N' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][4]++;
} else {
pieceCount[1][4]++;
}
break;
case 'P' :
if (piece.color == PieceColor.WHITE) {
pieceCount[0][5]++;
} else {
pieceCount[1][5]++;
}
break;
}
}
必须有一种更优雅的方法,它需要更少的代码行。我的意思是如果有超过 6 种类型的碎片和 2 种颜色会怎样。我不能像这样继续在 switch 语句中添加案例吗?但我不知道如何使它更优雅。
解决方案
执行此操作的正常方法是使用枚举enum
器(在 Java中调用)。枚举器允许您定义一组值,它们会自动完成所有其余的工作,例如在后台为每个值分配一个唯一的 ID。这是一个简单的例子:
public enum PieceType {
KING,
QUEEN,
ROOK,
BISHOP,
KNIGHT,
PAWN;
}
然后你可以在Piece
课堂上使用它。我还将添加适当的封装,这是您应该遵循的。
public class Piece {
private final PieceType type;
private final boolean isBlack;
public Piece(PieceType type, boolean isBlack) {
this.type = type;
this.isBlack = isBlack;
}
public PieceType getType() {
return type;
}
public boolean isBlack() {
return isBlack;
}
}
现在我们已经完成了所有设置,编写 for 循环变得微不足道:
for (Piece piece : piecePlacements) {
pieceCount[piece.isBlack() ? 1 : 0][piece.getType().ordinal()]++;
}
对于第一个维度的索引,我们使用三元运算符。这允许我们编写条件表达式而无需写出整个 if 语句。在这种情况下,如果piece.isBlack()
为真,则插入 的索引1
,否则插入 的索引0
。
对于第二维的索引,我们使用ordinal()
方法。这是所有枚举器都隐含的特殊方法。它返回给定枚举器值的唯一 ID,而且好的部分是,您不必担心它是如何得出该 ID 的。它会自动完成这一切。
推荐阅读
- django - Django - 使用 POST 请求仅上传模型中的图片
- java - 如何在JAVA中计算soap消息体的大小
- postgresql - postgresql jsonb通过内部属性查询
- python - 有没有办法通过 UDP 发送大文件
- c# - Autofac:解决 ApiControllers 的依赖关系
- azure - 在 Azure 应用程序洞察中激活节点登录
- symfony - 在 Symfony 上设置 Redis 缓存前缀键
- python-3.x - 接受一个包含多个单词的字符串并将每个单词的首字母大写的程序(Python 3.x)
- oop - 覆盖 ABAP 类中的属性?
- javascript - 嵌套在 for 循环外的 return 语句出现问题