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)
对于那些不熟悉的人,可以在这里找到规则: 维基百科 - 康威的生命游戏
我添加了一些调试代码(使用 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,并且我从一个干净的板开始,而不是重新使用上一代(因为你明确设置了每个位置,所以这并不重要)。
归档时间: |
|
查看次数: |
284 次 |
最近记录: |