康威的生活 | 电源外壳

Chr*_*her 5 powershell conways-game-of-life

我一直致力于在 Powershell 中创建一个基本的 Conway's Game of Life 模拟器,以更加熟悉该语言。但是我当前的代码错误地计算了相邻单元格的数量,因此游戏无法运行。我相信我的包装是正确的,据我所知,但我的邻居数量似乎“上升”了。

这是代码:

function next-gen{
    param([System.Array]$origM)

    $tmpM = $origM

    For($x=0; $x -lt $tmpM.GetUpperBound(0); $x++ ){
        For($y=0; $y -lt $tmpM.GetUpperBound(1); $y++){
            $neighborCount = getNeighbors $tmpM $x $y
            if($neighborCount -lt 2 -OR $neighborCount -gt 3){
                $tmpM[$x,$y] = 0
            }
            elseif($neighborCount -eq 3){
                $tmpM[$x, $y] = 1
            }
        } 
    }
    $Global:origM = $tmpM
}

function getNeighbors{
    param(
        [System.Array]$g,
        [Int]$x,
        [Int]$y
    )
    $newX=0
    $newY=0
    $count=0

    for($newX = -1; $newX -le 1; $newX++){
        for($newY = -1; $newY -le 1; $newY++){
            if($g[$(wrap $x $newX),$(wrap $y $newY)]){
                $count++
            }
        }
    }
    return $count
}

function wrap{
    param(
        [Int]$z,
        [Int]$zEdge
    )

    $z+=$zEdge
    If($z -lt 0){
        $z += $size
    }
    ElseIf($z -ge $size){
        $z -= $:size
    }
    return $z
}

function printBoard{
    0..$m.GetUpperBound(0) | 
    % { $dim1=$_; (0..$m.GetUpperBound(1) | % { $m[$dim1, $_] }) -join ' ' }
    write-host ""
}
#board is always a square, size represents both x and y
$size = 5

$m = New-Object 'int[,]' ($size, $size)
$m[2,1] = 1
$m[2,2] = 1
$m[2,3] = 1

clear
printBoard

For($x=0; $x -lt 1; $x++){
    next-gen $m
    printBoard
    write-host ""
}
Run Code Online (Sandbox Code Playgroud)

使用上面演示中的电路板设置,结果应该是一个闪光灯:

Gen0

0 0 0 0 0
0 0 0 0 0
0 1 1 1 0
0 0 0 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

第一代

0 0 0 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

对于那些不熟悉的人,可以在这里找到规则: 维基百科 - 康威的生命游戏

Mik*_*ard 2

我添加了一些调试代码(使用 write-verbose),并找到了错误所在。

首先,您正在检查$tmpm数组中的邻居(正在更新)而不是当前一代)。$global:OrigM其次,当您的意思是$Global:M在下一代函数末尾时进行设置,但实际上必须是$script:M,因为该变量存在于脚本作用域中,而不是全局作用域中。

此外,getNeighbors还错误地将目标位置本身视为邻居,而不仅仅是周围的 8 个位置。

function next-gen{
    param([System.Array]$origM)
    $size=1+$origM.GetUpperBound(0) 
    $tmpM = New-Object 'int[,]' ($size, $size)

    For($x=0; $x -lt $size; $x++ ){
        For($y=0; $y -lt $size; $y++){
            $neighborCount = getNeighbors $origm $x $y
            if($neighborCount -lt 2 -OR $neighborCount -gt 3){
                $tmpM[$x,$y] = 0
                write-verbose "Clearing $x,$y"
            }
            elseif($neighborCount -eq 3 -or $OrigM[$x,$y] -eq 1){
                $tmpM[$x, $y] = 1
                write-verbose "Setting $x,$y"
            }
        } 
    }
     $script:M = $tmpM
}

function getNeighbors{
    param(
        [System.Array]$g,
        [Int]$x,
        [Int]$y
    )
    $newX=0
    $newY=0
    $count=0

    for($newX = -1; $newX -le 1; $newX++){
        for($newY = -1; $newY -le 1; $newY++){
            if($newX -ne 0 -or $newY -ne 0){
                $neighborx=wrap $x $newx
                $neighborY=wrap $y $newY
                write-verbose "x=$x y=$y Nx=$neighborx Ny=$neighborY"
                if($g[$neighborx,$neighborY] -eq 1){
                    write-verbose "Neighbor at $neighborx, $neighborY is Set!"
                    $count++
                }
            }
        }
    }
    write-verbose "x=$x y=$y Neighbor count = $count"
    return $count
}

function wrap{
    param(
        [Int]$z,
        [Int]$zEdge
    )

    $z+=$zEdge
    If($z -lt 0){
        $z += $size
    }
    ElseIf($z -ge $size){
        $z -= $size
    }
    return $z
}

function printBoard{
    0..$m.GetUpperBound(0) | 
    % { $dim1=$_; (0..$m.GetUpperBound(1) | % { $m[$dim1, $_] }) -join ' ' }
    write-host ""
}
#board is always a square, size represents both x and y
$size = 5

$m = New-Object 'int[,]' ($size, $size)
$m[2,1] = 1
$m[2,2] = 1
$m[2,3] = 1

clear
printBoard

For($x=0; $x -lt 1; $x++){
    next-gen $m
    printBoard
    write-host ""
}
Run Code Online (Sandbox Code Playgroud)

PS 你在下一代循环中的边界检查关闭了 1,并且我从一个干净的板开始,而不是重新使用上一代(因为你明确设置了每个位置,所以这并不重要)。