标题: [原创代码] [Perl]Win32::Console版生命游戏 [打印本页]
作者: 523066680 时间: 2014-9-21 11:20 标题: [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__
- ......................**...............
- ......................**...............
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .........*..........**...**............
- .......*.*............***..............
- ......*.*............*...*.............
- **...*..*.............*.*..............
- **....*.*..............*...............
- .......*.*......*.*....................
- .........*......**.....................
- .................*...*.................
- .....................**......*.........
- ....................*.*......*.*.......
- ...............*..............*.*....**
- ..............*.*.............*..*...**
- .............*...*............*.*......
- ..............***............*.*.......
- ............**...**..........*.........
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- ...............**......................
- ...............**......................
复制代码
作者: neorobin 时间: 2014-9-21 11:38
我都没做过这个东东
作者: 523066680 时间: 2014-9-21 12:06
本帖最后由 523066680 于 2014-9-21 12:07 编辑
我都没做过这个东东
neorobin 发表于 2014-9-21 11:38
规则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。
有些生命游戏的模式超赞 发个wiki链接
Conway's Game of Life
作者: neorobin 时间: 2014-9-21 12:27
接触这个游戏倒是很早很早的了, 上次 BAT 的竞赛当时我也没见着, 后来只瞅了下, 以后也许BAT弄一下吧
作者: 523066680 时间: 2014-9-21 12:47
本帖最后由 523066680 于 2014-9-21 12:56 编辑
回复 4# neorobin
确定不使用 C + 图形库 吗 ……
有时间搞个3D+半透明效果方块组成的细胞自动机,应该很有趣。
作者: neorobin 时间: 2014-9-21 13:05
回复 5# 523066680
YOUTUBE 上看到好多人做过了
作者: 523066680 时间: 2014-9-21 16:12
回复 6# neorobin
果然是走在前线的,表示也是业余玩个兴趣。
作者: 普大喜奔 时间: 2014-9-27 23:55
在这里 那个gif里的运动是谁算出来的真牛啊 很想输入看看
作者: neorobin 时间: 2014-9-28 10:52
本帖最后由 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%!
- )
复制代码
作者: 523066680 时间: 2014-9-28 11:27
本帖最后由 523066680 于 2014-9-28 11:43 编辑
回复 9# neorobin
上传到公共图床然后论坛贴图咯,可能加载会比wikipedia的快一些
作者: 普大喜奔 时间: 2014-9-28 12:59
回复 9# neorobin
cmd命令怎么删掉_106.lif结尾的文件名 del .*_106.lif不行啊 你给的链接里面好多文件 我要删掉不能用的
作者: 普大喜奔 时间: 2014-9-28 13:40
回复 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
- )
- pause
复制代码
有没有比这个简便的命令写法
作者: 523066680 时间: 2014-9-28 14:57
回复 neorobin
cmd命令怎么删掉_106.lif结尾的文件名 del .*_106.lif不行啊 你给的链接里面好多文件 我要 ...
普大喜奔 发表于 2014-9-28 12:59
把.*改成 *
你可以改成 dir *_106.lif 看看结果对不对,然后改成del
作者: 普大喜奔 时间: 2014-9-28 18:10
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')
复制代码
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 %1
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |