优雅的计算位置中每种类型有多少件的方法

钦迈·班纳吉(Chinmay Banerjee)

我有一个具有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语句添加案例吗?但是我不知道如何使它更优雅。

罗勒·布尔克

tl; dr

为每个片段的颜色和角色定义枚举。

使用错误的名称Enum#ordinal获取其定义内每个枚举对象的位置的索引号。使用该数字作为数组的索引。

for ( Piece piece : pieces )          // `Piece` is class with two member fields: a `Color` enum object and a `Role` enum object.
{
    pieceCount                        // Your two-dimensional array. 
        [ piece.color().ordinal() ]   // Get the `Piece` object’s `Color` enum object’s definition position.
        [ piece.role().ordinal() ]    // Get the `Piece` object’s `Role` enum object’s definition position.
        ++                            // Using those two index numbers as index into your arrays, increment the count.
    ;
}

细节

使用枚举使此任务更加简单。枚举提供了该方法ordinal,是一个不正确的名称,因为它实际上返回定义枚举对象的顺序的从零开始的索引(而不是从一开始的序数)。我们可以使用该枚举索引号作为数组的索引。

让我们Piece用一对嵌套枚举Color定义您的记录Role

一个记录是在Java中16的新功能,一个简短的方式来写一个类,其主要目的是透明的和不可改变的数据通信。编译器隐式创建构造函数,getter,equalshashCodetoString该解决方案不是必需的,但非常适合您的Piece班级。

package work.basil.example.chess;

public record Piece(Color color , Role role)
{
    public enum Color
    { WHITE, BLACK }

    public enum Role
    { KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN }
}

因此Piece.Color.WHITE.ordinal()返回0,而BLACK返回1。

我们需要一些样本数据。

List < Piece > pieces = List.of(
        new Piece( Piece.Color.BLACK , Piece.Role.QUEEN ) ,
        new Piece( Piece.Color.BLACK , Piece.Role.KNIGHT ) ,
        new Piece( Piece.Color.WHITE , Piece.Role.PAWN )
);

我们可以通过询问每个枚举的长度,以软编码的方式定义您的数组。

int[][] pieceCount = new int[ Piece.Color.values().length ][ Piece.Role.values().length ]; // [2][6]

接下来,我们将棋子循环播放。我们要求每一个Piece对象Color,并Role通过调用名不副实枚举成员领域对象的索引位置ordinal()的方法。

for ( Piece piece : pieces )
{
    pieceCount[ piece.color().ordinal() ][ piece.role().ordinal() ]++;
}

这是整个示例应用程序类。

package work.basil.example.chess;

import java.util.Arrays;
import java.util.List;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        List < Piece > pieces = List.of(
                new Piece( Piece.Color.BLACK , Piece.Role.QUEEN ) ,
                new Piece( Piece.Color.BLACK , Piece.Role.KNIGHT ) ,
                new Piece( Piece.Color.WHITE , Piece.Role.PAWN )
        );
        int[][] pieceCount = new int[ Piece.Color.values().length ][ Piece.Role.values().length ]; // [2][6]
        for ( Piece piece : pieces )
        {
            pieceCount[ piece.color().ordinal() ][ piece.role().ordinal() ]++;
        }

        System.out.println( "pieces = " + pieces );
        for ( int i = 0 ; i < pieceCount.length ; i++ )
        {
            System.out.println( Arrays.toString( pieceCount[ i ] ) );
        }
    }
}

运行时。

pieces = [Piece[color=BLACK, role=QUEEN], Piece[color=BLACK, role=KNIGHT], Piece[color=WHITE, role=PAWN]]
[0, 0, 0, 0, 0, 1]
[0, 1, 0, 0, 1, 0]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

计算 Spark 中每种类型的最佳方法

来自分类Dev

如何转换数组中的每种类型?

来自分类Dev

mysql join:获取每种类型计数的零件

来自分类Dev

计算每种类型的对象数量 - Instanceof 或 getClassName

来自分类Dev

如何在/ proc / filesystems中获取有关每种类型的文件系统的信息

来自分类Dev

在C#DBML中获取具有最新/更大日期的每种类型的记录

来自分类Dev

MySQL查询以获取每种类型的有限行

来自分类Dev

每种类型都有对应的文字吗?

来自分类Dev

MySQL查询以获取每种类型的有限行

来自分类Dev

实体框架中每种类型的流利表映射

来自分类Dev

从表中为每种类型计数值

来自分类Dev

在Neo4j中获取每种类型的节点属性和每种类型的关系属性

来自分类Dev

为每种类型编译时间typeid

来自分类Dev

通用接口与每种类型的接口

来自分类Dev

在每种类型中对下载的应用程序数量进行排名,并仅过滤每种类型中排名前2的应用程序

来自分类Dev

删除每种类型实体框架的前十名以外的所有内容

来自分类Dev

附带对象的工厂,其中每种类型的对象都有一个公共参数

来自分类Dev

每种类型的导入模块都有一个错误

来自分类Dev

如何获取e剂中每种类型的最小值和最大值

来自分类Dev

mysql按日期范围显示行和分组中的每种类型

来自分类Dev

从查找表中获取每种类型和每个日期的最大ID

来自分类Dev

多重连接查询仅选择每种类型中的一种

来自分类Dev

为模板参数中的每种类型声明并实现重载的虚函数

来自分类Dev

将“是”标志应用于每种类型的帐户的所有日期的所有第一个实例

来自分类Dev

未捕获的错误:不能实例化多个Backbone.RelationalModel,每种类型具有相同的ID

来自分类Dev

C ++是否有一个容器,最多可以存储每种类型的一个对象?

来自分类Dev

如何建立一对一的关系,每种关系只有七种类型之一-实体框架

来自分类Dev

关键字段的自定义命名在EF中的TPT(每种类型的表)策略中不起作用

来自分类Dev

一种优雅的方法来计算一个文件中的模式在另一个文件中出现了多少次

Related 相关文章

  1. 1

    计算 Spark 中每种类型的最佳方法

  2. 2

    如何转换数组中的每种类型?

  3. 3

    mysql join:获取每种类型计数的零件

  4. 4

    计算每种类型的对象数量 - Instanceof 或 getClassName

  5. 5

    如何在/ proc / filesystems中获取有关每种类型的文件系统的信息

  6. 6

    在C#DBML中获取具有最新/更大日期的每种类型的记录

  7. 7

    MySQL查询以获取每种类型的有限行

  8. 8

    每种类型都有对应的文字吗?

  9. 9

    MySQL查询以获取每种类型的有限行

  10. 10

    实体框架中每种类型的流利表映射

  11. 11

    从表中为每种类型计数值

  12. 12

    在Neo4j中获取每种类型的节点属性和每种类型的关系属性

  13. 13

    为每种类型编译时间typeid

  14. 14

    通用接口与每种类型的接口

  15. 15

    在每种类型中对下载的应用程序数量进行排名,并仅过滤每种类型中排名前2的应用程序

  16. 16

    删除每种类型实体框架的前十名以外的所有内容

  17. 17

    附带对象的工厂,其中每种类型的对象都有一个公共参数

  18. 18

    每种类型的导入模块都有一个错误

  19. 19

    如何获取e剂中每种类型的最小值和最大值

  20. 20

    mysql按日期范围显示行和分组中的每种类型

  21. 21

    从查找表中获取每种类型和每个日期的最大ID

  22. 22

    多重连接查询仅选择每种类型中的一种

  23. 23

    为模板参数中的每种类型声明并实现重载的虚函数

  24. 24

    将“是”标志应用于每种类型的帐户的所有日期的所有第一个实例

  25. 25

    未捕获的错误:不能实例化多个Backbone.RelationalModel,每种类型具有相同的ID

  26. 26

    C ++是否有一个容器,最多可以存储每种类型的一个对象?

  27. 27

    如何建立一对一的关系,每种关系只有七种类型之一-实体框架

  28. 28

    关键字段的自定义命名在EF中的TPT(每种类型的表)策略中不起作用

  29. 29

    一种优雅的方法来计算一个文件中的模式在另一个文件中出现了多少次

热门标签

归档