返回列表 发帖

[原创代码] [Perl]Win32::Console版生命游戏

本帖最后由 523066680 于 2014-9-22 11:34 编辑

环境: Perl 5.16.3, Win32
循环设置了1000次,按ESC可提前退出。
思路写的不太漂亮,先简单实现吧
use Term::ReadKey;
use Win32::Console;
use Time::HiRes 'sleep';
use IO::Handle;
STDOUT->autoflush(1);
system("mode con lines=40 cols=80");
our $OUT=Win32::Console->new(STD_OUTPUT_HANDLE);
$OUT->Cursor(20, 20, 99, 0);  #hide cursor
my ($i, $j);
our ($rows, $cols) = (40, 40);
our ($mxrow, $mxcol) = ($rows-1, $cols-1);
# init
our @coord;
my (@h, @n);
my $y = 0;
foreach (<DATA>) {
    s/\r?\n$//;
    tr/\*\./10/;
    @{$h[$y++]} = ( split("", $_) );
}
foreach $i (0 .. $mxrow) {
    foreach $j (0 .. $mxcol) {
        $coord[$i][$j]{'x'} = $j*2;
        $coord[$i][$j]{'y'} = $i;
        $h[$i][$j] = 0 unless (defined $h[$i][$j]);
        $n[$i][$j] = 0;
    }
}
&Draw(\@n, \@h);
foreach (0..1000) {
    sleep 0.1;
    @n = ();
    &NextBuffer(\@h, \@n);
    &Draw(\@h, \@n);
    @h = (@n);
    &KeyFunc();
}
sub NextBuffer {
    my ($ra, $rb) = (shift, shift);
    my ($i, $j, $sum, $n);
    my ($L, $R, $U, $D, $vi, $vj);
    foreach $i (0 .. $mxrow) {
        $U = ($i-1) < 0 ? $mxrow : ($i-1);
        $D = ($i+1) > $mxrow ? 0 : ($i+1);
        foreach $j (0 .. $mxcol) {
            $sum = 0;
            $L = ($j-1) < 0 ? $mxcol : ($j-1);
            $R = ($j+1) > $mxcol ? 0 : ($j+1);
            $sum = $ra->[$U][$L] + $ra->[$U][$j] + $ra->[$U][$R] +
                   $ra->[$i][$L] +        0      + $ra->[$i][$R] +
                   $ra->[$D][$L] + $ra->[$D][$j] + $ra->[$D][$R];
            if ($sum == 3) {
                $rb->[$i][$j] = 1;
            } elsif ($sum == 2) {
                $rb->[$i][$j] = $ra->[$i][$j];
            } else {
                $rb->[$i][$j] = 0;
            }
        }
    }
}
sub Draw {
    my ($ra, $rb) = (shift, shift);
    foreach $i (0 .. $mxrow) {
        foreach $j (0 .. $mxcol) {
            if ($rb->[$i][$j] != $ra->[$i][$j]) {
                &Point(
                    $coord[$i][$j]{'x'},
                    $coord[$i][$j]{'y'},
                    $rb->[$i][$j],
                );
            }
        }
    }
}
sub Point {
    my ($mx, $my, $light) = (shift, shift, shift);
    my $color;
    if ($light == 1) {
        $color = $FG_WHITE|$BG_GRAY;
    } else {
        $color = $FG_WHITE|$BG_BLACK;
    }
    $OUT->Cursor($mx, $my);
    $OUT->FillAttr($color, 2, $mx, $my);
}
sub KeyFunc {
    my $key;
    $key = ReadKey(-1);
    return if (not defined $key);
    if ( ord($key) == 27 ) {
        exit;
    }
}
__DATA__
......................**...............
......................**...............
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.........*..........**...**............
.......*.*............***..............
......*.*............*...*.............
**...*..*.............*.*..............
**....*.*..............*...............
.......*.*......*.*....................
.........*......**.....................
.................*...*.................
.....................**......*.........
....................*.*......*.*.......
...............*..............*.*....**
..............*.*.............*..*...**
.............*...*............*.*......
..............***............*.*.......
............**...**..........*.........
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
.......................................
...............**......................
...............**......................COPY
[url=][/url]

我都没做过这个东东

TOP

本帖最后由 523066680 于 2014-9-21 12:07 编辑
我都没做过这个东东
neorobin 发表于 2014-9-21 11:38


    规则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。

    有些生命游戏的模式超赞  发个wiki链接
Conway's Game of Life

[url=][/url]

TOP

接触这个游戏倒是很早很早的了, 上次 BAT 的竞赛当时我也没见着, 后来只瞅了下, 以后也许BAT弄一下吧

TOP

本帖最后由 523066680 于 2014-9-21 12:56 编辑

回复 4# neorobin


      确定不使用 C + 图形库 吗 ……
有时间搞个3D+半透明效果方块组成的细胞自动机,应该很有趣。
[url=][/url]

TOP

回复 5# 523066680


    YOUTUBE 上看到好多人做过了

TOP

回复 6# neorobin


    果然是走在前线的,表示也是业余玩个兴趣。
[url=][/url]

TOP

在这里 那个gif里的运动是谁算出来的真牛啊 很想输入看看
!scripting!

TOP

本帖最后由 neorobin 于 2014-9-28 15:52 编辑

Conway's Game of Life 是生命游戏中的一类, 规则可以简单描述成 23/3 或者 B3/S23, 即邻居是2或3个时继续存活, 空单元的邻居正好3个时, 可以在此处新生

专题网站  http://www.conwaylife.com/
上有 3000+ 个模式供下载
http://www.conwaylife.com/patterns/all.zip

看几个大的 (比较大的 GIF , 不知怎能在论坛显示?)


河豚火车


反射器


又该耕地了


饲养员


ALPHA 星入侵, 来势凶悍啊


不用出动这多战舰, 给我四驾战车, GO, 占领整个宇宙吧


这些大型生物对效率要求是很高的, 用汇编或者高级语言实现比较好

我还是发个简单的 BAT 版的吧, 学了下 CRLF 的 set allvar=   速度确实快了好象有一倍哦
set "M=20"
if "%1"=="" (
    for %%a in ( FontSize:00080008 FontFamily:00000030 WindowSize:00%M%00%M%
              ScreenColors:0000000f CodePage:000001b5 ScreenBufferSize:00%M%00%M%
    ) do for /f "tokens=1,2 delims=:" %%b in ("%%a") do (
        >nul reg add HKCU\Console\LIFEGAME /v %%b /t reg_dword /d 0x%%c /f
    )
    start "LIFEGAME" /max "%ComSpec%" /c "%~s0" 1&goto:eof
) else (
    >nul reg delete HKCU\Console\LIFEGAME /f
)
@echo off & setlocal enableDelayedExpansion
for /f "delims==" %%a in ('set') do if "%%a" neq "M" set "%%a="
set /a "M=0x%M%, L=M-2, im=M*M, _P=M+1, _Q=L*M+1"
for /l %%a in (1 1 !im!) do (
    if !random! lss 0x3fff (set "W= !W!") else set "W=#!W!"
if %%a lss !M! set "ET= !ET!"
)
for /l %%a in () do (
    set "U="
    for /l %%i in (!_P! !M! !_Q!) do (
        set /a "a=%%i-1+L"& for /f "tokens=1-3" %%a in ("!a! %%i !L!") do set "U=!U!!W:~%%a,1!!W:~%%b,%%c!!W:~%%b,1!"
    )
    for %%a in (!M!) do set "U=!U:~-%%a!!U!!U:~0,%%a!"
    set "W="
    for /l %%i in (!_P! !M! !_Q!) do (
        set /a "_b=%%i-2, _a=_b-m, _c=_b+m, _i=%%i-1"
        for /l %%a in (1 1 !L!) do (
            set /a "_b+=1, _a+=1, _c+=1, _i+=1"
            for /f "tokens=1-4" %%a in ("!_a! !_b! !_c! !_i!") do (
                set "_t=!U:~%%a,3!!U:~%%b,3!!U:~%%c,3!"
                set "_t=!_t: =!     !U:~%%d,1!#   " & set "W=!W!!_t:~9,1!"
            )
        )
        set "W=!W!  "
    )
    set "W=!ET!  !W!!ET!"
cls & echo !W:~0,-%_P%!
)COPY
1

评分人数

TOP

本帖最后由 523066680 于 2014-9-28 11:43 编辑

回复 9# neorobin

上传到公共图床然后论坛贴图咯,可能加载会比wikipedia的快一些
[url=][/url]

TOP

回复 9# neorobin
cmd命令怎么删掉_106.lif结尾的文件名 del .*_106.lif不行啊 你给的链接里面好多文件 我要删掉不能用的
!scripting!

TOP

回复 9# neorobin
@echo off
setlocal enabledelayedexpansion
for /r %%a in (*.lif) do (
set var=%%a
set var=!var:~-8!
if !var!==_106.lif del %%a
)
pauseCOPY
有没有比这个简便的命令写法
!scripting!

TOP

回复  neorobin
cmd命令怎么删掉_106.lif结尾的文件名 del .*_106.lif不行啊 你给的链接里面好多文件 我要 ...
普大喜奔 发表于 2014-9-28 12:59


把.*改成 *

    你可以改成  dir *_106.lif 看看结果对不对,然后改成del
1

评分人数

[url=][/url]

TOP

Conway's Game of Life 是生命游戏中的一类, 规则可以简单描述成 23/3 或者 B3/S23, 即邻居是2或3个时继续存 ...
neorobin 发表于 2014-9-28 10:52

大神发的这个链接好多好看的矩阵,我把代码改了下,用把.lif文件拖到importGrid.cmd上就可以看矩阵的效果了
也可以直接运行cell.py,用随机矩阵玩
cell.py
import sys
import os
import random
import time
cols=100
rows=80
dict={' ':0,'*':1}
cells=[[' ' for x in range(cols)] for y in range(rows)]
grid=[[' ' for x in range(cols)] for y in range(rows)]
if len(sys.argv)>1:
    f=sys.argv[1]
    try:
        txt=open(f,'r')
    except:
        print('file not found')
        os.system('pause >nul')
        exit()
    y=1
    for line in txt.readlines():
        if y==rows-1:
            print('err:too much lines')
            break
        if line[0]=='#':continue
        for x in range(cols-2):
            try:
                if line[x]=='*':cells[y][x+1]='*'
            except:
                y+=1
                break
else:
    print('cmdline:cell.py *.lif')
    while True:
        level=input('larger number,less cells ( >0 ):')
        try:
            if int(level)>0:
                for y in range(1,rows-1):
                    for x in range(1,cols-1):
                        r=random.randint(0,int(level))
                        if r==0:cells[y][x]='*'
                break
        except:pass
for y in cells:print(' '.join(y))
print("press key to begin...")
os.system('pause >nul')
i=0
while True:
    for y in range(1,rows-1):
        for x in range(1,cols-1):
            num=dict[cells[y-1][x-1]]+\
                dict[cells[y-1][x+1]]+\
dict[cells[y-1][x]]+\
dict[cells[y+1][x-1]]+\
dict[cells[y+1][x+1]]+\
dict[cells[y+1][x]]+\
dict[cells[y][x-1]]+\
dict[cells[y][x+1]]
            if num==3:grid[y][x]='*'
            elif num==2:grid[y][x]=cells[y][x]
            else:grid[y][x]=' '
    for y in range(1,rows-1):
        for x in range(1,cols-1):
            cells[y][x]=grid[y][x]
    time.sleep(0.01)
    os.system('cls')
    i+=1
    print('time: '+str(i))
    num=0
    for y in range(1,rows-1):
        for x in range(1,cols-1):
            num+=dict[cells[y][x]]
    if num==0:
        print('cells all dead,press key to exit...')
        break
    else:
        for y in cells:print(' '.join(y))
os.system('pause >nul')COPY
importGrid.cmd:
@echo off & setlocal enabledelayedexpansion & color 0a & title PYTHON CELL
if "%2"=="" (
for %%a in (FontSize:00080005  WindowSize:005c00c8  ScreenColors:0000000f  CodePage:000003a8  ScreenBufferSize::005c00c8) do for /f "tokens=1,2 delims=:" %%b in ("%%a") do (
>nul reg add HKCU\Console\PYTHON_CELL /v %%b /t reg_dword /d 0x%%c /f)
start "PYTHON_CELL" /max "%ComSpec%" /c "%~s0" %1 1&goto:eof
) else (
>nul reg delete HKCU\Console\PYTHON_CELL /f
)
python %~dp0cell.py %1COPY
!scripting!

TOP

返回列表