创建并填充Raku对象数组?

hsm*_*ers 5 raku

我选择在Perl 6中重新设计我的先前代码的一部分,在这种情况下,是棋盘。前两节课进展顺利(或者至少工作了,我知道的很少,我无法说出它们的正确性) ,但我坚持使用第三个。这是代码:

#!/home/hsmyers/rakudo741/bin/perl6
# board.p6 - Beginnings of a PGN toolset. And place to start learning
#            Perl 6/Raku.
use v6d;

#!___________________________________________________________

constant $size = 4;

class Piece {
    my Str @namesOfPieces[$size] = <
        white-rook white-knight white-bishop white-queen
    >;
    my Str @abrevsOfPieces[$size] = <
        R N B Q K B N R
    >;
    my Str @symbolsOfPieces[$size] = <
        &#9814; &#9816; &#9815; &#9813; &#9812; &#9815; &#9816; &#9814;
    >;
    my Str @codeptsOfPieces[$size] = (
        "\x2656", "\x2658", "\x2657", "\x2655",
    );
    has Str $.name;
    has Str $.abrev;
    has Str $.symbol;
    has Uni $.codept;

    submethod BUILD( :$i ) {
        $!name   = @namesOfPieces[$i];
        $!abrev  = @abrevsOfPieces[$i];
        $!symbol = @symbolsOfPieces[$i];
        $!codept = @codeptsOfPieces[$i].NFC;
    }
}

class Square {
    my Int @colors[$size] = <
        1 0 1 0 1 0 1 0
    >;
    my Str @names[$size] = <
        a1 b1 c1 d1 e1 f1 g1 h1
    >;
    has Int   $.color;
    has Int   $.index;
    has Str   $.name;
    has Piece $.piece;

    submethod BUILD( :$i ) {
        $!color = @colors[$i];
        $!index = $i;
        $!name  = @names[$i];
        $!piece = Piece.new(:i($i));
    }
}

class Board is Array {
}

my $p = Piece.new(:i(0));
$p.say;
my $s = Square.new(:i(0));
$s.say;

#!___________________________________________________________

my @b := Board.new(
    Square.new(:i(0)),
    Square.new(:i(1)),
    Square.new(:i(2))
);
say @b;
say @b.WHAT;
Run Code Online (Sandbox Code Playgroud)

在cli上运行时,结果为:

Piece.new(name => "white-rook", abrev => "R", symbol => "?", codept => Uni.new(0x2656).NFC)
Square.new(color => IntStr.new(1, "1"), index => 0, name => "a1", piece => Piece.new(name => "white- 
rook", abrev => "R", symbol => "?", codept => Uni.new(0x2656).NFC))
[Square.new(color => IntStr.new(1, "1"), index => 0, name => "a1", piece => Piece.new(name => 
"white-rook", abrev => "R", symbol => "?", codept => Uni.new(0x2656).NFC)) Square.new(color => 
IntStr.new(0, "0"), index => 1, name => "b1", piece => Piece.new(name => "white-knight", abrev => 
"N", symbol => "?", codept => Uni.new(0x2658).NFC)) Square.new(color => IntStr.new(1, "1"), index => 
2, name => "c1", piece => Piece.new(name => "white-bishop", abrev => "B", symbol => "?", codept => 
Uni.new(0x2657).NFC))]
(Board)
Run Code Online (Sandbox Code Playgroud)

到目前为止,Board类(实际上是空的)仅是我的尝试而已。令人惊讶的是(至少对我而言),它提供了一定程度的可操作性。它具有不同的“新”和“构建”,均未提供有效的解决方案。考虑到实际计数为64而不是4,因此当前方法行不通。

我目前的想法是,我需要构建一个由64个正方形组成的数组,这将依次创建必要的部分。我试图增加自我,却无济于事。有什么建议吗?

Jon*_*ton 8

Array这里继承可能不是最好的设计选择;它揭示并致力于的底层表示形式,Board随着代码的发展,它将带来重构挑战。相反,我建议a Board具有一个ArraySquare初始化的Square对象。

假设董事会本来应该是$size平方的,那么您可以执行以下操作:

class Board {
    has @.squares[$size ** 2];

    method TWEAK() {
        @!squares = map { Square.new(i => $_ % $size) }, ^($size ** 2);
    }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,取0到但不包括$size平方的范围,然后将每个值映射到一个Square实例。(我们对索引取模,以避免索引超出其他类别之一的范围。)

2D数组可能更可取:

class Board {
    has @.squares[$size;$size];

    method TWEAK() {
        @!squares = (map -> $i { Square.new(:$i) }, ^$size) xx $size;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们map又一次,但是这一次,因为我们只是做一维,所以我们放弃了模。使用命名$i参数意味着我们可以使用:$i便利,这是便利的简称:i($i)(在您发布的代码中也有机会这样做)。然后,我们使该表达式产生一行,并使用xx它运行$size一次以获取每一列的数据。

最终,它可能不会像这样简单。也许Square应该使用两个构造函数参数(一个数字和一个字母)来形成其名称。这可能是最好的做mapmap。此外,Piece实例的初始化可能也想发生Board。自上次下象棋已经过去了25年,但我敢肯定,在比赛开始时并不是每个方块都有一块。