最短的人生游戏


59

康威的《人生游戏》是蜂窝自动化的经典例子。这些单元形成一个正方形网格,每个单元具有两个状态:存活或死亡。在每个回合中,每个小区都会根据其状态及其八个邻居的状态同时进行更新:

  • 如果一个活细胞恰好有两个或三个活的邻居,则它仍然活着
  • 如果一个死细胞正好有三个活着的邻居,它就会活着

您的任务(如果您选择接受)是用您喜欢的语言编写最短的《人生游戏》实现代码。

规则:

  • 网格必须至少为20x20
  • 网格必须环绕(所以网格就像圆环的表面一样)
  • 您的实现必须允许用户输入自己的启动模式
  • 如果您看不到正在发生的事情,GoL会毫无意义,因此必须有自动机运行的视觉输出,每转的结果显示的时间足够长!

8
以前在Stack Overflow:《代码高尔夫:Conway的人生游戏》中,请确保查看注释中的APL实现链接。
dmckee 2011年

1
啊,我没看到。但这有点不同,不是(让我删除将挑战放在一起的工作吗?
Griffin

6
这不是一个问题。已经在Stack Overflow上运行的许多难题也已在此完成,但是人们会告诉您,我对链接到类似的挑战很着迷。
dmckee,2011年

@格里芬:您可以删除s ;之前}的所有内容。也var可以有时将s消除(如果它不会破坏您的代码)。对于单行fors,ifs等,您可以{ }完全消除:for(...) for(...) dosomething()
pimvdb 2011年

@pimvdb,干杯,我还没有完全打高尔夫球,还没有时间。只是想表明我也有尝试的机会,而不是无所事事地挑战自己。很快就会打高尔夫球。
格里芬

Answers:


27

HTML5画布用JavaScript,940个 639 586 519字符

<html><body onload="k=40;g=10;b=[];setInterval(function(){c=[];for(y=k*k;y--;){n=0;for(f=9;f--;)n+=b[(~~(y/k)+k+f%3-1)%k*k+(y+k+~~(f/3)-1)%k];c[y]=n==3||n-b[y]==3;r.fillStyle=b[y]?'red':'tan';r.fillRect(y%k*g,~~(y/k)*g,g-1,g-1)}if(v.nextSibling.checked)b=c},1);v=document.body.firstChild;v.width=v.height=g*k;v.addEventListener('click',function(e){b[~~((e.pageY-v.offsetTop)/g)*k+~~((e.pageX-v.offsetLeft)/g)]^=1},0);r=v.getContext('2d');for(y=k*k;y--;)b[y]=0"><canvas></canvas><input type="checkbox"/>Run</body></html>

我一直想用画布做些事情,所以这是我的尝试(在线原始版本)。您可以通过单击来切换单元格(在运行模式下也可以)。

您现在也可以在这里尝试新版本。

不幸的是,有一个我无法解决的问题。在线版本的长度增加了11个字符,因为jsFiddle将一个文本节点放在画布的前面(为什么?),因此画布不再是第一个孩子。

编辑1:大量的优化和重组。

编辑2:几个较小的更改。

编辑3:内联完整的脚本块以及较小的更改。


很好,但是将间隔延迟更改1为与我的速度一样快,而不是缓慢的步进。同样,如果要实现绘图(而不是单击每个正方形),则可以将鼠标位置舍入到最接近的块大小并在该点填充矩形。更多的角色,但更多的积分。
格里芬

您可以替换new Array('#FFF','#800')['#FFF','#800']
Lowjacker 2011年

尽管说了绘画,但我的超级高尔夫不允许绘画,并且作为罪恶是丑陋的。哈哈。您可以将s数组中的两种颜色设置为tan和,red因为它们是具有最短表示形式的两种颜色-为您节省了两个字符。另外,如果可能,请将的文字版本j放入间隔中。我敢肯定,还有更多的选择。
格里芬

@格里芬和Lowjacker:非常感谢。我也很确定您可以打更多的高尔夫球(并且已经有了一些想法)。不幸的是,我没有时间这样做。明天将发布更好的高尔夫球版本-我希望...
霍华德

2
您可以删除html和body标签。它的功能相同
arodebaugh

32

Python,219个字符

我力求最大程度地打高尔夫球,并提供足够的界面来满足这个问题。

import time
P=input()
N=range(20)
while 1:
 for i in N:print''.join(' *'[i*20+j in P]for j in N)
 time.sleep(.1);Q=[(p+d)%400 for d in(-21,-20,-19,-1,1,19,20,21)for p in P];P=set(p for p in Q if 2-(p in P)<Q.count(p)<4)

您可以这样运行它:

echo "[8,29,47,48,49]" | ./life.py

列表中的数字表示起始单元格的坐标。第一行是0-19,第二行是20-39,依此类推。

在一个有21行的终端中运行它,看起来非常时髦。


1
这完全应该赢了。我猜“输入容易度”的权重很高。
2012年

@primo我什至会建议mma应该有一个单独的比赛。
luser droog 2013年

2
那么《 Py的生活》呢?
Christopher Wirt'3

您总是可以再保存一个字符... 2-(p in P)== 2-({p}<P)。但是随后您必须将输入更改为{8,29,47,48,49}:)
JBernardo

21

TI-BASIC,96字节(非竞争条目为87字节)

适用于TI-84系列图形计算器(!)。这是相当大的挑战,因为那里是写一个缓冲的图形程序(绝对没有内置)没有简单的方法,并在图形屏幕只有四个相关的图形命令:Pxl-On()Pxl-Off()Pxl-Change(),和pxl-Test()

使用屏幕上每个可访问的像素,并正确包装。每个单元格为一个像素,该程序在屏幕右侧向水平方向逐行更新。因为计算器只有15MHz z80处理器,而BASIC是一种慢速解释语言,所以代码大约每五分钟只能得到一帧。

用户输入很容易:在运行程序之前,请使用钢笔工具在图形屏幕上绘制形状。

改编自我在计算器论坛Omnimaga举行的代码高尔夫竞赛中的比赛

0
While 1
For(X,0,94
Ans/7+49seq(pxl-Test(remainder(Y,63),remainder(X+1,95)),Y,62,123
For(Y,0,62
If 1=pxl-Test(Y,X)+int(3fPart(3cosh(fPart(6ֿ¹iPart(sum(Ans,Y+1,Y+3
Pxl-Change(Y,X
End
End
End

Omnimaga版本(87字节)

该代码还有一个附加功能:它检测它是否是第一次运行,以及是否使屏幕状态随机化。在后续运行中,如果在一帧结束后停止运行,它将自动继续模拟。但是,它不是竞争性条目,因为它不会包裹屏幕。如果事先清除图形屏幕,则外部边框上的单元格将始终被视为已失效。

0
While 1
For(X,0,93
Ans/7+49seq(pxl-Test(Y,X+1),Y,0,62
For(Y,1,61
If 2rand>isClockOn=pxl-Test(Y,X)+int(3fPart(3cosh(fPart(6ֿ¹iPart(sum(Ans,Y,Y+2
Pxl-Change(Y,X
End
End
ClockOff
End

这个版本可能是我编写过的最复杂的代码,并且包含一些真正令人讨厌的混淆性优化:

  • 我将时钟状态用作标志。在程序开始时,启用了日期/时间时钟,我使用全局isClockOn标志的值来确定它是否是第一次迭代。绘制第一帧后,我关闭时钟。在最短的其他方法上节省一个字节,在最明显的方法上节省大约四个字节。

  • 我将要更新的三列的状态存储在以7为底的63元素数组中。49的位置将列保留在右侧,7的位置将列保留在中间,单元的位置将左列保留-活细胞为-1,死细胞为0。然后,我将被修改的单元格周围的三个数字之和的余数mod 6求出存活的邻居单元格的总数(就像被9除数的技巧一样-在基数7中,余数mod 6等于数字)。自己节省大约10个字节,并有机会使用接下来的两个优化。示例图(假设在Y = 45处的某个列上有一个滑翔机居中:

    Row # | Cell State       | Stored number | Mod 6 = cell count
    ...
    44      Live, Live, Live   49+7+1 = 57     3
    45      Dead, Dead, Live   49+0+0 = 49     1
    46      Dead, Live, Dead   0+7+0  = 7      1
    ...
    

    中心单元将保持死状态,因为它正好被五个活动单元包围。

  • 每行完成后,通过将现有数字除以7,舍弃小数部分,然后将新列中单元格的值加49倍,来更新数组中的数字。每次存储所有三列都将慢得多,并且不够美观,至少要多占用20个字节,并使用三个列表而不是一个列表,因为必须在更新单元之前存储每一行​​中单元的值。到目前为止,这是存储单元位置的最小方法。

  • 该代码段int(3fPart(3cosh(给出1当输入等于3/6,2当它等于4/6,并且0当它等于0,1/6,2/6,5/6或。节省约6个字节。


19

Mathematica-333

特征:

  • 互动界面:单击单元格即可制作图案

  • 不错的网格

  • 按钮:运行,暂停,清除

代码如下。

Manipulate[x=Switch[run,1,x,2,CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},{2,2,2}}},
{1,1}},x],3,Table[0,{k,40},{j,40}]];EventHandler[Dynamic[tds=Reverse[Transpose[x]];
ArrayPlot[tds,Mesh->True]],{"MouseClicked":>(pos=Ceiling[MousePosition["Graphics"]];
x=ReplacePart[x,pos->1-x[[Sequence@@pos]]];)}],{{run,3,""},{1->"||",2->">",3->"X"}}]

在此处输入图片说明

如果您想了解它的运行方式,此博客中的第二个示例只是上面代码的更详细的版本(实时傅里叶分析,更好的界面)。免费下载插件后,示例应立即在您的浏览器中运行。


2
+1,是个不错的选择。是的,这就是该网站的问题,有很多旧问题容易被人们遗漏。
格里芬

@Griffin感谢您的注意;)
Vitaliy Kaurov 2013年

15

C 1063个字符

作为一个挑战,我使用了高尔夫不友好的Windows API进行实时IO的C语言编写。如果启用了大写锁定,则模拟将运行。如果关闭大写锁定,它将保持静止。用鼠标绘制图案;左键单击可以使细胞恢复活力,右键单击可以杀死细胞。

#include <windows.h>
#include<process.h>
#define K ][(x+80)%20+(y+80)%20*20]
#define H R.Event.MouseEvent.dwMousePosition
#define J R.Event.MouseEvent.dwButtonState
HANDLE Q,W;char*E[3],O;Y(x,y){return E[0 K;}U(x,y,l,v){E[l K=v;}I(){E[2]=E[1];E[1]=*E;*E=E[2];memset(E[1],0,400);}A(i,j,k,l,P){while(1){Sleep(16);for(i=0;i<20;++i)for(j=0;j<20;++j){COORD a={i,j};SetConsoleCursorPosition(Q,a);putchar(E[0][i+j*20]==1?'0':' ');}if(O){for(i=0;i<20;++i)for(j=0;j<20;++j){for(k=i-1,P=0;k<i+2;++k)for(l=j-1;l<j+2;++l){P+=Y(k,l);}U(i,j,1,P==3?1:Y(i,j)==1&&P==4?1:0);}I();}}}main(T,x,y,F,D){for(x=0;x<21;++x)puts("#####################");E[0]=malloc(800);E[1]=E[0]+400;I();I();W=GetStdHandle(-10);Q=GetStdHandle(-11);SetConsoleMode(W,24);INPUT_RECORD R;F=D=O=0;COORD size={80,25};SetConsoleScreenBufferSize(Q,size);_beginthread(A,99,0);while(1){ReadConsoleInput(W,&R,1,&T);switch(R.EventType){case 1:O=R.Event.KeyEvent.dwControlKeyState&128;break;case 2:switch(R.Event.MouseEvent.dwEventFlags){case 1:x=H.X;y=H.Y;case 0:F=J&1;D=J&2;}if(F)U(x,y,0,1);if(D)U(x,y,0,0);}}}

可以在这里找到已编译的EXE

编辑:我已经评论了源。在这里可用


我希望看到此评论的版本!
luser droog 2012年

1
当然,如果我能记住我在想什么... = p
Kaslai 2012年

1
@luserdroog这是pastebin.com/BrX6wgUj
Kaslai 2012年

太棒了
rayryeng '16

12

J(39个字符)

l=:[:+/(3 4=/[:+/(,/,"0/~i:1)|.])*.1,:]

基于此APL版本(相同的算法,环形卷积)。

用法示例:

   r =: (i.3 3) e. 1 2 3 5 8
   r
0 1 1          NB. A glider!
1 0 1
0 0 1

   R =: _1 _2 |. 5 7 {. r
   R
0 0 0 0 0 0 0  NB. Test board
0 0 0 1 1 0 0
0 0 1 0 1 0 0
0 0 0 0 1 0 0
0 0 0 0 0 0 0

   l R
0 0 0 0 0 0 0  NB. Single step
0 0 0 1 1 0 0
0 0 0 0 1 1 0
0 0 0 1 0 0 0
0 0 0 0 0 0 0

10

Mathematica,123个字符

一个非常基本的实现,不使用Mathematica的内置CellularAutomaton函数。

ListAnimate@NestList[ImageFilter[If[3<=Total@Flatten@#<=3+#[[2]][[2]],1,0]&,#,1]&,Image[Round/@RandomReal[1,{200,200}]],99]

8

Ruby 1.9 + SDL(380 325 314)

编辑:314个字符,并修复了一个错误,该错误具有在第一次迭代中仍然存在的额外单元格。将网格大小增加到56,因为颜色例程仅查看最低的8位。

编辑:打高尔夫球到325个字符。网格宽度/高度现在为28,因为28 * 9是您可以使用的最大尺寸,同时仍将其用作背景色。现在,每次迭代也只处理一个SDL事件,从而完全消除了内部循环。我觉得挺紧的!

模拟开始暂停,所有单元均消失。您可以按任意键切换暂停/取消暂停,然后单击任意单元格以在活动状态和无效状态之间进行切换。每十分之一秒运行一次迭代。

包装有点古怪。

require'sdl'
SDL.init W=56
R=0..T=W*W
b=[]
s=SDL::Screen.open S=W*9,S,0,0
loop{r="#{e=SDL::Event.poll}"
r['yU']?$_^=1:r[?Q]?exit: r['nU']?b[e.y/9*W+e.x/9]^=1:0
b=R.map{|i|v=[~W,-W,-55,-1,1,55,W,57].select{|f|b[(i+f)%T]}.size;v==3||v==2&&b[i]}if$_
R.map{|i|s.fillRect i%W*9,i/W*9,9,9,[b[i]?0:S]*3}
s.flip
sleep 0.1}

看起来像这样:

实际应用的屏幕截图

有趣的挑战!我欢迎任何人看到的任何改进。


很好的尝试,但我可以立即看到您错了。GoL中不能有这样的模式。再次阅读规则:en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
Griffin

@Griffin我认为屏幕截图是在手动暂停和切换某些单元格后拍摄的-不过,我会再次检查规则。谢谢!
Paul Prestidge

7
@Griffin不能将种子模式设置为任何可能的配置?
ardnew

7

Scala,1181 1158 1128 1063 1018 1003 999 992 987个字符

import swing._
import event._
object L extends SimpleSwingApplication{import java.awt.event._
import javax.swing._
var(w,h,c,d,r)=(20,20,20,0,false)
var x=Array.fill(w,h)(0)
def n(y:Int,z:Int)=for(b<-z-1 to z+1;a<-y-1 to y+1 if(!(a==y&&b==z)))d+=x((a+w)%w)((b+h)%h)
def top=new MainFrame with ActionListener{preferredSize=new Dimension(500,500)
menuBar=new MenuBar{contents+=new Menu("C"){contents+={new MenuItem("Go/Stop"){listenTo(this)
reactions+={case ButtonClicked(c)=>r= !r}}}}}
contents=new Component{listenTo(mouse.clicks)
reactions+={case e:MouseClicked=>var p=e.point
x(p.x/c)(p.y/c)^=1
repaint}
override def paint(g:Graphics2D){for(j<-0 to h-1;i<-0 to w-1){var r=new Rectangle(i*c,j*c,c,c)
x(i)(j)match{case 0=>g draw r
case 1=>g fill r}}}}
def actionPerformed(e:ActionEvent){if(r){var t=x.map(_.clone)
for(j<-0 to h-1;i<-0 to w-1){d=0
n(i,j)
x(i)(j)match{case 0=>if(d==3)t(i)(j)=1
case 1=>if(d<2||d>3)t(i)(j)=0}}
x=t.map(_.clone)
repaint}}
val t=new Timer(200,this)
t.start}}

取消高尔夫:

import swing._
import event._

object Life extends SimpleSwingApplication
{
    import java.awt.event._
    import javax.swing._
    var(w,h,c,d,run)=(20,20,20,0,false)
    var x=Array.fill(w,h)(0)
    def n(y:Int,z:Int)=for(b<-z-1 to z+1;a<-y-1 to y+1 if(!(a==y&&b==z)))d+=x((a+w)%w)((b+h)%h)
    def top=new MainFrame with ActionListener
    {
        title="Life"
        preferredSize=new Dimension(500,500)
        menuBar=new MenuBar
        {
            contents+=new Menu("Control")
            {
                contents+={new MenuItem("Start/Stop")
                {
                    listenTo(this)
                    reactions+=
                    {
                        case ButtonClicked(c)=>run= !run
                    }
                }}
            }
        }
        contents=new Component
        {
            listenTo(mouse.clicks)
            reactions+=
            {
                case e:MouseClicked=>
                    var p=e.point
                    if(p.x<w*c)
                    {
                        x(p.x/c)(p.y/c)^=1
                        repaint
                    }
            }
            override def paint(g:Graphics2D)
            {
                for(j<-0 to h-1;i<-0 to w-1)
                {
                    var r=new Rectangle(i*c,j*c,c,c)
                    x(i)(j) match
                    {
                        case 0=>g draw r
                        case 1=>g fill r
                    }
                }
            }
        }
        def actionPerformed(e:ActionEvent)
        {
            if(run)
            {
                var t=x.map(_.clone)
                for(j<-0 to h-1;i<-0 to w-1)
                {
                    d=0
                    n(i,j)
                    x(i)(j) match
                    {
                        case 0=>if(d==3)t(i)(j)=1
                        case 1=>if(d<2||d>3)t(i)(j)=0
                    }
                }
                x=t.map(_.clone)
                repaint
            }
        }
        val timer=new Timer(200,this)
        timer.start
    }
}

此处代码的大部分是Swing GUI内容。游戏本身是actionPerformed由触发的方法Timer,以及辅助n邻居的助手功能。

用法:

使用进行编译scalac filename,然后使用进行运行scala L
单击一个正方形可以将它从活动状态切换为活动状态,并且菜单选项启动和停止游戏。如果要更改网格的大小,请更改行中的前三个值:var(w,h,c,d,r)=(20,20,20,0,false)它们分别是宽度,高度和像元大小(以像素为单位)。


我发现了2个高尔夫改进:import java.awt.event._contents+=m("Go",true)+=m("Stop",false)}},得出1093个字符。
用户未知,

@user未知谢谢。我自己发现了一些改进-现在降至1063。
加雷斯

该死的你一直很忙。保持!当更多人发布答案时,我将对其进行测试。
格里芬

7

纯Bash,244个字节

适用于环形包装的36x24 Universe:

mapfile a
for e in {0..863};{
for i in {0..8};{
[ "${a[(e/36+i/3-1)%24]:(e+i%3-1)%36:1}" == O ]&&((n++))
}
d=\ 
c=${a[e/36]:e%36:1}
[ "$c" == O ]&&((--n==2))&&d=O
((n-3))||d=O
b[e/36]+=$d
n=
}
printf -vo %s\\n "${b[@]}"
echo "$o"
exec $0<<<"$o"

由于这是一个shell脚本,因此输入方法与其他shell命令是一致的-即来自stdin:

$ ./conway.sh << EOF

   O 
    O 
  OOO 

EOF


  O O                                                       
   OO                                                       
   O                                                        

















    O                                                       
  O O                                                       
   OO                                                       

...等等

我们可以重定向来自任何文本源的输入,通过tr过滤器进行管道传递以获得有趣的初始代,例如

man tr | tr [:alnum:] O | ./conway.sh

6

JavaScript,130

并非完全能应对挑战,但为了记录,这是Subzey和I在2013年制作的130字节字节的“生命游戏”引擎。

http://xem.github.io/miniGameOfLife/

/* Fill an array with 0's and 1's, and call g(array, width, height) to iterate */
g=function(f,c,g,d,e,b,h){g=[];e=[c+1,c,c-1,1];for(b=c*c;b--;g[b]=3==d||f[b]&&2==d,d=0)for(h in e)d+=f[b+e[h]]+f[b-e[h]];return g}

第一行似乎有一些问题。例如设置@@\n@@(左上角2乘2平方)或.@\n.@\n.@。(1分3列)
安南

5

C#-675个字符

我一直想写这个程序的一个版本。从来不知道快速而肮脏的版本只需要花费半小时。(当然,打高尔夫球需要更长的时间。)

using System.Windows.Forms;class G:Form{static void Main(){new G(25).ShowDialog();}
public G(int z){var g=new Panel[z,z];var n=new int [z,z];int x,y,t;for(int i=0;i<z;
i++)for(int j=0;j<z;j++){var p=new Panel{Width=9,Height=9,Left=i*9,Top=j*9,BackColor
=System.Drawing.Color.Tan};p.Click+=(s,a)=>p.Visible=!p.Visible;Controls.Add(g[i,j]=
p);}KeyUp+=(s,_)=>{for(int i=0;i<99;i++){for(x=0;x<z;x++)for(y=0;y<z;y++){t=0;for(int 
c=-1;c<2;c++)for(int d=-1;d<2;d++)if(c!=0||d!=0){int a=x+c,b=y+d;a=a<0?24:a>24?0:a;b=
b<0?24:b>24?0:b;t+=g[a,b].Visible?0:1;}if(t==3||t>1&&!g[x,y].Visible)n[x,y]=1;if(t<2
||t>3)n[x,y]=0;}for(x=0;x<z;x++)for(y=0;y<z;y++)g[x,y].Visible=n[x,y]<1;Update();}};}}

用法

  • 通过单击单元格以将其打开(活动)来输入起始模式。
  • 通过按任意键盘键开始游戏。
  • 每次按下一个键,该游戏就会运行99代(我本可以保存9个字符才能设置为9代,但这似乎太la脚了)。

打高尔夫球的妥协

  • 您只能使用鼠标打开单元格,而不能关闭它,因此,如果您犯了错误,则必须重新启动程序。
  • 没有网格线,但这不会太大地损害可玩性。
  • 更新速度与CPU速度成正比,因此在速度非常快的计算机上,它可能只是模糊的。
  • 活细胞是红色的,因为“黑色”使用另外2个字符。
  • 单元格的小巧以及它们不会用完所有表单空间的事实也是节省字符的折衷方案。

5

GW-BASIC,1086 1035字节(标记)

以标记形式,这是1035个字节。(当然,ASCII格式会更长一些。)您可以通过使用SAVE"life命令获得标记化格式,而无需",a在解释器中追加。

10 DEFINT A-Z:DEF SEG=&HB800:KEY OFF:COLOR 7,0:CLS:DEF FNP(X,Y)=PEEK((((Y+25)MOD 25)*80+((X+80)MOD 80))*2)
20 X=0:Y=0
30 LOCATE Y+1,X+1,1
40 S$=INKEY$:IF S$=""GOTO 40
50 IF S$=CHR$(13)GOTO 150
60 IF S$=" "GOTO 130
70 IF S$=CHR$(0)+CHR$(&H48)THEN Y=(Y-1+25)MOD 25:GOTO 30
80 IF S$=CHR$(0)+CHR$(&H50)THEN Y=(Y+1)MOD 25:GOTO 30
90 IF S$=CHR$(0)+CHR$(&H4B)THEN X=(X-1+80)MOD 80:GOTO 30
100 IF S$=CHR$(0)+CHR$(&H4D)THEN X=(X+1)MOD 80:GOTO 30
110 IF S$="c"THEN CLS:GOTO 20
120 GOTO 40
130 Z=PEEK((Y*80+X)*2):IF Z=42 THEN Z=32ELSE Z=42
140 POKE(Y*80+X)*2,Z:GOTO 40
150 LOCATE 1,1,0:ON KEY(1)GOSUB 320:KEY(1) ON
160 V!=TIMER+.5:FOR Y=0 TO 24:FOR X=0 TO 79:N=0
170 Z=FNP(X-1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
180 Z=FNP(X,Y-1):IF Z=42 OR Z=46 THEN N=N+1
190 Z=FNP(X+1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
200 Z=FNP(X-1,Y):IF Z=42 OR Z=46 THEN N=N+1
210 Z=FNP(X+1,Y):IF Z=42 OR Z=46 THEN N=N+1
220 Z=FNP(X-1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
230 Z=FNP(X,Y+1):IF Z=42 OR Z=46 THEN N=N+1
240 Z=FNP(X+1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
250 Z=PEEK((Y*80+X)*2):IF Z=32 THEN IF N=3 THEN Z=43
260 IF Z=42 THEN IF N<2 OR N>3 THEN Z=46
270 POKE(Y*80+X)*2,Z:NEXT:NEXT:FOR Y=0 TO 24:FOR X=0 TO 79:Z=PEEK((Y*80+X)*2):IF Z=46 THEN Z=32
280 IF Z=43 THEN Z=42
290 POKE(Y*80+X)*2,Z:NEXT:NEXT
300 IF TIMER<V!GOTO 300
310 IF INKEY$=""GOTO 160
320 SYSTEM

这是版本最多的版本,但仍然很实用:启动时会得到一个编辑器,在其中可以使用光标键移动;空格键可在当前场上打开/关闭细菌,c清除屏幕,然后返回开始游戏模式。

以下是一个不太混淆的版本,该版本还设置了具有两种结构的初始游戏板(圆形旋转的物体和滑翔机):

1000 REM Conway's Game of Life
1001 REM -
1002 REM Copyright (c) 2012 Thorsten "mirabilos" Glaser
1003 REM All rights reserved. Published under The MirOS Licence.
1004 REM -
1005 DEFINT A-Z:DEF SEG=&hB800
1006 KEY OFF:COLOR 7,0:CLS
1007 DEF FNP(X,Y)=PEEK((((Y+25) MOD 25)*80+((X+80) MOD 80))*2)
1010 PRINT "Initial setting mode, press SPACE to toggle, RETURN to continue"
1020 PRINT "Press C to clear the board, R to reset. OK? Press a key then."
1030 WHILE INKEY$="":WEND
1050 CLS
1065 DATA 3,3,4,3,5,3,6,3,7,3,8,3,3,4,4,4,5,4,6,4,7,4,8,4
1066 DATA 10,3,10,4,10,5,10,6,10,7,10,8,11,3,11,4,11,5,11,6,11,7,11,8
1067 DATA 11,10,10,10,9,10,8,10,7,10,6,10,11,11,10,11,9,11,8,11,7,11,6,11
1068 DATA 4,11,4,10,4,9,4,8,4,7,4,6,3,11,3,10,3,9,3,8,3,7,3,6
1069 DATA 21,0,22,1,22,2,21,2,20,2,-1,-1
1070 RESTORE 1065
1080 READ X,Y
1090 IF X=-1 GOTO 1120
1100 POKE (Y*80+X)*2,42
1110 GOTO 1080
1120 X=0:Y=0
1125 LOCATE Y+1,X+1,1
1130 S$=INKEY$
1140 IF S$="" GOTO 1130
1150 IF S$=CHR$(13) GOTO 1804
1160 IF S$=" " GOTO 1240
1170 IF S$=CHR$(0)+CHR$(&h48) THEN Y=(Y-1+25) MOD 25:GOTO 1125
1180 IF S$=CHR$(0)+CHR$(&h50) THEN Y=(Y+1) MOD 25:GOTO 1125
1190 IF S$=CHR$(0)+CHR$(&h4B) THEN X=(X-1+80) MOD 80:GOTO 1125
1200 IF S$=CHR$(0)+CHR$(&h4D) THEN X=(X+1) MOD 80:GOTO 1125
1210 IF S$="c" THEN CLS:GOTO 1120
1220 IF S$="r" GOTO 1050
1225 IF S$=CHR$(27) THEN END
1230 GOTO 1130
1240 Z=PEEK((Y*80+X)*2)
1250 IF Z=42 THEN Z=32 ELSE Z=42
1260 POKE (Y*80+X)*2,Z
1270 GOTO 1130
1804 LOCATE 1,1,0
1900 ON KEY(1) GOSUB 2300
1910 KEY(1) ON
2000 V!=TIMER+.5
2010 FOR Y=0 TO 24
2020  FOR X=0 TO 79
2030   N=0
2040   Z=FNP(X-1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2050   Z=FNP(X  ,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2060   Z=FNP(X+1,Y-1):IF Z=42 OR Z=46 THEN N=N+1
2070   Z=FNP(X-1,Y  ):IF Z=42 OR Z=46 THEN N=N+1
2080   Z=FNP(X+1,Y  ):IF Z=42 OR Z=46 THEN N=N+1
2090   Z=FNP(X-1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2100   Z=FNP(X  ,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2110   Z=FNP(X+1,Y+1):IF Z=42 OR Z=46 THEN N=N+1
2120   Z=PEEK((Y*80+X)*2)
2130   IF Z=32 THEN IF N=3 THEN Z=43
2140   IF Z=42 THEN IF N<2 OR N>3 THEN Z=46
2150   POKE (Y*80+X)*2,Z
2160  NEXT X
2170 NEXT Y
2200 FOR Y=0 TO 24
2210  FOR X=0 TO 79
2220   Z=PEEK((Y*80+X)*2)
2230   IF Z=46 THEN Z=32
2240   IF Z=43 THEN Z=42
2250   POKE (Y*80+X)*2,Z
2260  NEXT X
2270 NEXT Y
2280 IF TIMER<V! GOTO 2280
2290 IF INKEY$="" GOTO 2000
2300 SYSTEM

我花了15分钟写这本书,当时他无聊地等待一个朋友,他和他的“徒弟”同时为康威的《人生游戏》打高尔夫球。

它的功能如下:它立即使用80x25文本模式屏幕缓冲区(如果DEF SEG使用的&hB000是Hercules图形卡,请更改要使用的首字母缩写;这些设置适用于Qemu和(较慢的)dosbox)。星号*是细菌。

它可以通过两遍:首先,用标记出生地,用标记+死亡.。在第二遍中,+.分别替换为*

TIMER事情是让等待每一轮后半秒,如果你的Qemu主机是非常快的☺

我不希望这里有一个最短的双赢价格,而是一个很酷的价格,尤其是考虑到初始的电路板设置。如果您有兴趣,我还提供了一个版本,其中的游戏引擎已被汇编代码替换。


考虑到您在非高尔夫版本上将标签增加1,是否可以在高尔夫版本上进行相同的标记?(即123,等),或者做行号不算数?
扎卡里

行号,当标记时,算作单词(16位),如果我没有完全误解的话
mirabilos

那好吧,猜想我当时一定在想其他BASIC方言。
扎卡里

@Zacharý单击“ GW-BASIC标记化的程序格式”,然后单击“程序格式”,实际上,行号一直是两个字节,并进一步详细介绍了令牌格式。
mirabilos

5

Mathematica,115个字节

这是一个简单的解决方案:

ListAnimate[ArrayPlot/@CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},
{2,2,2}}},{1,1}},{RandomInteger[1,{9,9}],0},90]]

1
Mathematica很好,但是按照规则规定,程序必须允许用户输入自己的模式。该规则是有意的,因为一些语言允许类似这样的简短实现,但没有用户交互。当然,您可以在其中放置自己的阵列,但不会成功。
格里芬

Mathematica中的“输入”主要是通过笔记本界面,因此我认为“用户交互”实际上是不可能的。您只需用所需的任何内容替换CellularAutomaton函数的RandomInteger参数,然后重新评估代码。
JeremyKun 2011年

3
可以进行用户交互。我现在想到的最简单的方法是按钮数组。给它一个去吧。
格里芬

4

的Java(OpenJDK的8) - 400个388 367字节

第二,(可能)最终编辑:托管高尔夫球找到这些(IMO)后,一个额外的21个字节的黄金矿山 -绝对推荐新人们阅读这些(特别是如果你要尝试一些使用Java这些挑战)。

产生的代码(如果我发现如何缩短循环的双嵌套的话,可能会使打高尔夫球更多。):

u->{int w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

在线尝试!

(原始帖子从这里开始。)

我实际上想了一会儿,我至少可以用我对Java大声笑的知识(可能有限)挑战最好的Python答案...尽管如此,我还是乐于参与其中(尽管参加了这个聚会可能只是一个有点晚...)

其实并没有太多内容-基本说明如下(已解包):

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    Stack<Point>r=new Stack<Point>(); // same with the only array list needed (note how I only use two data structures);
    for(;;) // notice how this is still an infinite loop but using a for loop;
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]>1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]>0)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]+(y>h-2?"\n":""));  // that extra part of the print statement adds a newline if we reached the end of the current 'line';
            }
        }
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

(有关Java 8中的lambda语句的更多信息,请点击此处

是的,我的方法有个陷阱。

正如大多数人可能注意到的那样,我目前使用的高尔夫球代码将永远循环。为了防止这种情况,可以在顶部引入一个计数器,并在while循环中使用该计数器,以仅显示n(在这种情况下为5)迭代,如下所示(注意已b添加新变量):

u->{int b=0,w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;++b<6;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

此外,还有几点值得一提。该程序不会检查输入是否正确,因此会(很可能)失败ArrayOutOfBoundsException;这样,请确保通过完全填充数组的一部分来检查输入是否有效(串起的数组将引发上述异常)。而且,当前的板看起来很“流畅”-也就是说,新一代与下一代之间没有分隔。如果您想添加此代码以再次检查生成的世代确实有效,则System.out.println();需要在之前添加一个额外的代码for(int[]t:u)Arrays.fill(t,0);(请参阅此在线尝试!)。最后但并非最不重要的一点是,鉴于这是我的第一个代码高尔夫球,任何反馈都将不胜感激:)

以前的388字节答案中的旧代码:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

从最初的400字节答案开始:

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

惊人的第一篇文章,欢迎来到PPCG!
扎卡里

谢谢,我肯定会做更多的这些-他们很有趣:)
NotBaal

加入我们,我们有丹尼斯。而且,它不是完整的程序,也不是功能,它必须是IIRC。
扎卡里

哦,对了,忘记了“程序”部分:P稍等片刻。
NotBaal

它也可以只是一个功能。
扎卡里

4

模具,6字节

不是我最喜欢的语言,但它短...

4个代码字节,再加上nlist和Torus标志。

3me

在线尝试!

是...
3 3
 中的一员
m 的自或oore,附近数
e 沼地Ë -neighbourhood数没有自我
......?


3

Scala-799个字符

作为脚本运行。鼠标单击一个正方形即可将其打开或关闭,并且任何键都将开始或停止生成。

import java.awt.Color._
import swing._
import event._
import actors.Actor._
new SimpleSwingApplication{var(y,r,b)=(200,false,Array.fill(20,20)(false))
lazy val u=new Panel{actor{loop{if(r){b=Array.tabulate(20,20){(i,j)=>def^(i:Int)= -19*(i min 0)+(i max 0)%20
var(c,n,r)=(0,b(i)(j),-1 to 1)
for(x<-r;y<-r;if x!=0||y!=0){if(b(^(i+x))(^(j+y)))c+=1}
if(n&&(c<2||c>3))false else if(!n&&c==3)true else n}};repaint;Thread.sleep(y)}}
focusable=true
preferredSize=new Dimension(y,y)
listenTo(mouse.clicks,keys)
reactions+={case e:MouseClicked=>val(i,j)=(e.point.x/10,e.point.y/10);b(i)(j)= !b(i)(j)case _:KeyTyped=>r= !r}
override def paintComponent(g:Graphics2D){g.clearRect(0,0,y,y);g.setColor(red)
for(x<-0 to 19;y<-0 to 19 if b(x)(y))g.fillRect(x*10,y*10,9,9)}}
def top=new Frame{contents=u}}.main(null)

3

J,45岁

我以为我会尝试一下。打起来还不是特别好,但是我会尽快再尝试一次。

(]+.&(3&=)+)+/((4&{.,(_4&{.))(>,{,~<i:1))&|.

例:

   f =: 5 5 $ 0 1 0 0 0   0 0 1 0 0   1 1 1 0 0   0 0 0 0 0    0 0 0 0 0
   f
0 1 0 0 0
0 0 1 0 0
1 1 1 0 0
0 0 0 0 0
0 0 0 0 0
   f (]+.&(3&=)+)+/((4&{.,(_4&{.))(>,{,~<i:1))&|. f
0 0 0 0 0
1 0 1 0 0
0 1 1 0 0
0 1 0 0 0
0 0 0 0 0

3

处理 536 532

int h=22,t=24,i,j;int[][]w=new int[t][t],b=new int[t][t];int[]q={1,0,-1};void draw(){if(t<9){clear();for(i=2;i<h;i++){for(j=2;j<h;j++)w[i][j]=b[i][j];w[i][1]=w[i][21];w[i][h]=w[i][2];w[1][i]=w[21][i];w[h][i]=w[2][i];}for(i=1;i<23;i++)for(j=1;j<23;j++){t=-w[i][j];for(int s:q)for(int d:q)t+=w[i+s][j+d];b[i][j]=w[i][j]>0&(t<2|t>3)?0:t==3?1:b[i][j];}a();}}void keyPressed(){t=0;}void mousePressed(){int i=mouseX/5+2,j=mouseY/5+2;w[i][j]=b[i][j]=1;a();}void a(){for(i=0;i<h-2;i++)for(j=0;j<h-2;j++)if(w[i+2][j+2]==1)rect(i*5,j*5,5,5);}

我相信这可以满足所有要求。

取消高尔夫:

int h=22,t=24,i,j;
int[][]w=new int[t][t],b=new int[t][t];
int[]q={1,0,-1};
void draw(){
  if(t<9){
  clear();
  for(i=2;i<h;i++){
    for(j=2;j<h;j++)
      w[i][j]=b[i][j];  
    w[i][1]=w[i][21];
    w[i][h]=w[i][2];
    w[1][i]=w[21][i];
    w[h][i]=w[2][i];
  }
  for(i=1;i<23;i++)
    for(j=1;j<23;j++){
      t=-w[i][j];
      for(int s:q)
        for(int d:q)
          t+=w[i+s][j+d];        
      b[i][j]=w[i][j]>0&(t<2|t>3)?0:t==3?1:b[i][j];  
  }
  a();
}
}
void keyPressed(){
  t=0;
}
void mousePressed(){
  int i=mouseX/5+2,j=mouseY/5+2;
  w[i][j]=b[i][j]=1;
  a();
}
void a(){
  for(i=0;i<h-2;i++)
    for(j=0;j<h-2;j++)
      if(w[i+2][j+2]==1)
        rect(i*5,j*5,5,5);
  }  

3

Matlab(152)

b=uint8(rand(20)<0.2)
s=@(m)imfilter(m,[1 1 1;1 0 1;1 1 1],'circular')
p=@(m,n)uint8((n==3)|(m&(n==2)))
while 1
imshow(b)
drawnow
b=p(b,s(b))
end

我现在还没有安装Matlab来测试它,我只是研究了几年前编写的代码。
取消高尔夫:

%% initialize
Bsize = 20;
nsteps = 100;
board = uint8(rand(Bsize)<0.2); % fill 20% of the board
boardsum = @(im) imfilter(im,[1 1 1; 1 0 1; 1 1 1], 'circular');
step = @(im, sumim) uint8((sumim==3) | (im & (sumim==2)) );

%% run
for i = 1:nsteps
    imshow(kron(board,uint8(ones(4))), [])
    drawnow
    ss(p,i) = sum(board(:));
    board = step(board, boardsum(board));
end
  • Boardsize是硬编码的,但可以是任何东西
  • 环绕
  • 对于用户输入,可以通过对另一个矩阵进行硬编码或使用变量编辑器来更改初始板。不漂亮,但是可以用
  • 如果跳过图形输出,则可以节省20个字符,该板在每次迭代时仍将以文本形式打印。每毫秒变化的一像素单元反正不是很有用

在R2014a中工作,刚刚经过测试
masterX244,2014年

3

Perl中,218个 216 211 202字节

$,=$/;$~=AX3AAAx76;$b=pack('(A79)23',<>)x6;{print unpack'(a79)23a0',$b;select$v,$v,$v,0.1;$b=pack'(A)*',unpack'((x7a/(x13)X4Ax!18)1817@0)4',pack'((a*)17xx!18)*',unpack"x1737(AA$~Ax$~AA$~@)2222",$b;redo}

(此代码末尾没有换行符。)

从标准输入中读取起始模式,作为文本文件,其中活动单元格表示为1,死单元格表示为空格,行之间用换行符分隔。输入中不得包含其他字符。线可以是可变长度的,并且将被填充或截断为正好79宽。输入示例是滑翔机枪:

                                  1
                                1 1
                      11      11            11
                     1   1    11            11
          11        1     1   11
          11        1   1 11    1 1
                    1     1       1
                     1   1
                      11









                                         11
                                         1
                                          111
                                            1

当程序运行“人生游戏”时,每个状态都以类似于输入的格式转储到标准输出,然后延迟0.1秒。可以通过更改选择调用的第四个参数来自定义延迟。

游戏板采用硬编码,尺寸为79x23。它被包裹在圆环中:如果将板子放在底部,则最终会在顶部。如果您离开右侧,则最终会到达左侧,但向下移动一排。

这是一个替代版本,它不读取任何输入,而是从随机板开始:

$,=$/;$/=AX3AAAx76;$b=pack("(A)*",map{rand 3<1}0..1816)x6;{print unpack'(a79)23a0',$b;select$v,$v,$v,0.1;$b=pack'(A)*',unpack'((x7a/(x13)X4Ax!18)1817@0)4',pack'((a*)17xx!18)*',unpack"x1737(AA$/Ax$/AA$/@)2222",$b;redo}

这段代码源自我几年前编写的混淆的life perl游戏。我做了很多修改,使板子成为环形并打高尔夫球。

这可能不是在perl中实现“生活游戏”的最短方法,但它是一种较难理解的方法。

该板被存储在$b作为一个字符串'1'以及' ',一个用于每个小区,只有整个事情重复至少三次。第三次解压缩调用为每个单元格提取17个值:该单元格本身有一个值,八个相邻单元格中的每个单元格按任意顺序有两个,每个值都是'1'或一个空字符串。如果'1'这17个值中的值数目是5、6或7,则该单元格应在下一次迭代中存在。第三个pack调用将这17个值连接到一个18个字符宽的字段,该字段左对齐并在右边填充nul字节。第二个解压缩调用占用了18个宽域,在位置7处的角色上分派,如果是'1',否则将字符从位置4解压缩。此结果恰好是单元格在下一代中应具有的值。


2

Python,589字节

鼠标按钮:向左-放置一个单元格,向右-移除一个单元格,中间-开始/停止。

从Tkinter进口*
导入副本
z =范围
F = 50
T = Tk()
S = 9
f = [F * [0] for i in'7'* F]
c =画布(T,宽度= S * F,高度= S * F)
c.pack()
def p(x,y,a):f [y] [x] = f [y] [x]或c.create_oval(x * S,y * S,x * S + S,y * S + S)如果是其他c.delete(f [y] [x])
r = 1
定义R(e):global r; r = 1-r
exec(“ c.bind('<Button-%i>',lambda e:p(ex / S,ey / S,%i));” * 2%(1,1,3,0))
c.bind('<Button-2>',R)
def L():
 T.后(99,L)
 如果r:return
 g = copy.deepcopy(f)
 对于z(F)中的y:
	对于z(F)中的x:
	 n = 8
	 对于z(-1,2)中的j:
		对于z(-1,2)中的i:
		 如果i或j:n- =否g [(y + j)%F] [(x + i)%F]
	 如果1 <n <4:
		如果n == 3而不是g [y] [x]:p(x,y,1)
	 其他:p(x,y,0)
L()
T.mainloop()

这是您可以拖动鼠标进行绘制的版本。图形更加令人愉快。

from Tkinter import*
import copy
z=range
F=50
T=Tk()
S=9
f=[F*[0]for i in'7'*F]
c=Canvas(T,bg='white',width=S*F,height=S*F)
c.pack()
def p(x,y,a):f[y][x]=f[y][x]or c.create_rectangle(x*S,y*S,x*S+S,y*S+S,fill='gray')if a else c.delete(f[y][x])
r=1
def R(e):global r;r=1-r
exec("c.bind('<Button-%i>',lambda e:p(e.x/S,e.y/S,%i));c.bind('<B%i-Motion>',lambda e:p(e.x/S,e.y/S,%i));"*2%(1,1,1,1,3,0,3,0))
c.bind('<Button-2>',R)
def L():
 T.after(99,L)
 if r:return
 g=copy.deepcopy(f)
 for y in z(F):
  for x in z(F):
   n=8
   for j in z(-1,2):
    for i in z(-1,2):
     if i or j:n-=not g[(y+j)%F][(x+i)%F]
   if 1<n<4:
    if n==3and not g[y][x]:p(x,y,1)
   else:p(x,y,0)
L()
T.mainloop()

这没有正确遵循生活游戏规则。
2011年

1
@StevenRumbalski:真的吗?
Oleh Prypin 2011年

2
真。您的第二个版本中有缩进错误。开头部分if 1<n<4:应与for j in z(-1,2):
Steven Rumbalski

2

Python 2,456字节

虽然我知道这是一篇老文章,但我无法自拔。初始板可以是任何尺寸,只要您在其周围画一个边框并在最后一行留出多余的空间即可。

高尔夫

import time,itertools as w,sys;t,q=map(lambda x:list(x[:-1]),sys.stdin.readlines()),list(w.product(range(-1,2),range(-1,2)));del q[4];n=map(lambda x:x[:],t[:])
while time.sleep(0.1)==None:
 for j in range(1,len(t)-1):
  for i in range(1,len(t[j])-1):x=sum(map(lambda s:1 if t[j+s[0]][i+s[1]]in'@'else 0,q));f=t[j][i];n[j][i]='@'if(f=='@'and(x==3 or x==2))or(f==' 'and x==3)else' '
 t=map(lambda x:x[:],n[:]);print'\n'.join(list(map(lambda x:''.join(x),t)))

Input.txt(请注意最后一行的额外空间)

+----------------------------------------+
|                    @                   |
|                     @                  |
|                   @@@                  |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
|                                        |
+----------------------------------------+ 

怎么跑

python Golf.py < input.txt

time.sleep(0.1)==None=> not time.sleep(.1)(f=='@'and(x==3 or x==2))or(f ==''和x == 3)=>x==3or f=='@'and x==2
CalculatorFeline

^,您忘记了一个,1 if=> 1if
扎卡里

2

处理中 270,261 249字节

网格是屏幕的100 * 100像素,输入以png图片的形式出现

void setup(){image(loadImage("g.png"),0,0);}void draw(){loadPixels();int n,i=0,j,l=10000;int[]a=new int[l],p=pixels;for(;i<l;a[i]=n==5?-1<<24:n==6?p[i]:-1,i++)for(j=n=0;j<9;j++)n+=j!=4?p[(i+l-1+j%3+100*(j/3-1))%l]&1:0;arrayCopy(a,p);updatePixels();}

不打高尔夫球

void setup() {
  image(loadImage("g.png"), 0, 0);
}
void draw() {
  loadPixels();
  int c=100, i=0, n, l=c*c, b=color(0);
  int[]a=new int[l], p=pixels;
  for (; i<l; i++) {
    n=p[(i+l-101)%l]&1;
    n+=p[(i+l-100)%l]&1;
    n+=p[(i+l-99)%l]&1;
    n+=p[(i+l-1)%l]&1;
    n+=p[(i+1)%l]&1;
    n+=p[(i+99)%l]&1;
    n+=p[(i+100)%l]&1;
    n+=p[(i+101)%l]&1;
    a[i]=n==5?b:p[i]==b&&n==6?b:-1;
  }
  arrayCopy(a, pixels, l);
  updatePixels();
}

屏幕截图


2

Lua + LÖVE/ Love2D,653字节

l=love f=math.floor t={}s=25 w=20 S=1 for i=1,w do t[i]={}for j=1,w do t[i][j]=0 end end e=0 F=function(f)loadstring("for i=1,#t do for j=1,#t[i]do "..f.." end end")()end function l.update(d)if S>0 then return end e=e+d if e>.2 then e=0 F("c=0 for a=-1,1 do for b=-1,1 do if not(a==0 and b==0)then c=c+(t[((i+a-1)%w)+1][((j+b-1)%w)+1]>0 and 1 or 0)end end end g=t[i][j]t[i][j]=(c==3 or(c==2 and g==1))and(g==1 and 5 or-1)or(g==1 and 4 or 0)")F("t[i][j]=t[i][j]%2")end end function l.draw()F("l.graphics.rectangle(t[i][j]==1 and'fill'or'line',i*s,j*s,s,s)")end function l.mousepressed(x,y)S=0 o,p=f(x/s),f(y/s)if t[o]and t[o][p]then t[o][p]=1 S=1 end end

或隔开:

l=love
f=math.floor
t={}s=25
w=20
S=1
for i=1,w do
    t[i]={}
    for j=1,w do
        t[i][j]=0
    end
end
e=0
F=function(f)
    loadstring("for i=1,#t do for j=1,#t[i] do  "..f.." end end")()
end
function l.update(d)
    if S>0 then
        return
    end
    e=e+d
    if e>.2 then
        e=0
        F([[
        c=0
        for a=-1,1 do
            for b=-1,1 do
                if not(a==0 and b==0)then
                    c=c+(t[((i+a-1)%w)+1][((j+b-1)%w)+1]>0 and 1 or 0)
                end
            end
        end
        g=t[i][j]
        t[i][j]=(c==3 or(c==2 and g==1))and(g==1 and 5 or-1) or (g==1 and 4 or 0)]])
        F("t[i][j]=t[i][j]%2")
    end
end
function l.draw()
    F("l.graphics.rectangle(t[i][j]==1 and'fill'or'line',i*s,j*s,s,s)") end
function l.mousepressed(x,y)
    S=0
    o,p=f(x/s),f(y/s)
    if t[o]and t[o][p] then
        t[o][p]=1
        S=1
    end
end

单击该字段以添加活细胞。在字段外单击以运行它。

在线尝试!

在此处输入图片说明


1

后记 529 515

Rosetta Code的示例开始。使用文件名参数(gs -- gol.ps pulsar)调用,该文件包含20 * 20二进制数字(以空格分隔)。无限循环:画板,等待输入,计算下一代。

[/f ARGUMENTS 0 get(r)file/n 20>>begin[/m
n 1 sub/b[n{[n{f token pop}repeat]}repeat]/c 400
n div/F{dup 0 lt{n add}if dup n ge{n sub}if}>>begin{0
1 m{dup 0 1 m{2 copy b exch get exch get 1 xor setgray
c mul exch c mul c c rectfill dup}for pop pop}for
showpage/b[0 1 m{/x exch def[0 1 m{/y exch def 0
y 1 sub 1 y 1 add{F dup x 1 sub 1 x
1 add{F b exch get exch get 3 2 roll add exch
dup}for pop pop}for b x get y get sub b x get y get
0 eq{3 eq{1}{0}ifelse}{dup 2 eq exch 3 eq
or{1}{0}ifelse}ifelse}for]}for]def}loop

用一些堆栈注释隔开(只是我需要的注释)。

[
/f ARGUMENTS 0 get(r)file
/n 20
/sz 400
%/r{rand 2147483647 div}
>>begin
[
/m n 1 sub
/b[
%n{[n{r .15 le{1}{0}ifelse}repeat]}repeat
 n{[n{f token pop}repeat]}repeat
]
/c sz n div
/F{dup 0 lt{n add}if dup n ge{n sub}if}
>>begin
{
    0 1 m{dup % y y
    0 1 m{ % y y x
        2 copy b exch get exch get 1 xor setgray
        c mul exch c mul c c rectfill
        dup 
    }for pop pop}for
    pstack
    showpage
    /b[0 1 m{/x exch def
      [0 1 m{/y exch def
          0   
          y 1 sub 1 y 1 add{F dup %s y y
          x 1 sub 1 x 1 add{F %s y y x
              b exch get exch get %s y bxy
              3 2 roll add exch %s+bxy y
              dup %s y y
          }for pop pop}for
          b x get y get sub
          b x get y get
          0 eq{3 eq{1}{0}ifelse}{dup 2 eq exch 3 eq or{1}{0}ifelse}ifelse
      }for]
      }for]def
}loop

脉冲星数据文件:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

1

JavaScript 676

对不起,格里芬,我只是看不到您的代码,也没有稍稍改写...不得不削掉两个字符,但这太值得了!

b=[];r=c=s=20;U=document;onload=function(){for(z=E=0;z<c;++z)for(b.push(t=[]),j=0;j<r;j++)with(U.body.appendChild(U.createElement("button")))t.push(0),id=z+"_"+j,style.position="absolute",style.left=s*j+"px",style.top=s*z+"px",onclick=a}; ondblclick=function(){A=E=E?clearInterval(A):setInterval(function(){Q=[];for(z=0;z<c;++z){R=[];for(j=0;j<r;)W=(c+z-1)%c,X=(c+z+1)%c,Y=(r+j-1)%r,Z=(r+j+1)%r,n=b[W][Y]+b[z][Y]+b[X][Y]+b[W][j]+b[X][j]+b[W][Z]+b[z][Z]+b[X][Z],R.push(b[z][j++]?4>n&&1<n:3==n);Q.push(R)}b=Q.slice();d()})};function a(e){E?0:P=e.target.id.split("_");b[P[0]][P[1]]^=1;d()}function d(){for(z=0;z<c;++z)for(j=0;j<r;)U.getElementById(z+"_"+j).innerHTML=b[z][j++]-0}

但是正如他们所说,请求宽恕比允许许可容易。



1

Python 2:334个字节

仅晚了6年。

import time
s='';s=map(list,iter(raw_input,s));k=len(s);l=(-1,0,1);n=int;z=range
while 1:
 r=[[0]*k for i in z(k)]
 for i in z(k*k):
  a,b=i//k,i%k
  m,g=sum([n(s[(a+c)%k][(b+d)%k])for c in l for d in l if c|d]),n(s[a][b])
  r[a][b]=n((m==2)&g or m==3)
  print'*'if r[a][b]else' ',
  if b-k+1==0:print
 s=r;time.sleep(.2);print"\033c"

您可以像这样运行它:

python gol.py
0000000
0001000
0000100
0011100
0000000
0000000
0000000

0和1分别代表死单元和活动单元,末尾的额外换行符开始执行。

网格必须为正方形。

它比最短的python运行起来更容易,支持任何大小的网格,并且在运行时看起来很漂亮。

它也多了100个字节,所以就可以了。


0

PHP,201字节(未测试)

for($s=file(f);print"\n";$s=$t)foreach($s as$y=>$r)for($x=-print"
";"
"<$c=$s[$y][++$x];print$t[$y][$x]=" X"[$n<4&$n>2-$a])for($n=-$a=$c>A,$i=$x-!!$x-1;$i++<=$x;)for($k=$y-2;$k++<=$y;)$n+=$s[$k][$i]>A;

用运行-nr

分解

for($s=file(f);                         # import input from file "f"
    print"\n";                              # infinite loop: 1. print newline
    $s=$t)                                  # 3. copy target to source, next iteration
    foreach($s as$y=>$r)                    # 2. loop through lines
        for($x=-print"\n";"\n"<$c=$s[$y][++$x]; # print newline, loop $x/$c through line characters (before line break)
            print                                   # 5. print new cell
                $t[$y][$x]=" X"[$n>2-$a&$n<4])      # 4. new cell is alive if neighbour count<4 and >2 (>1 if alive)
            for($n=-                                # 2. init neighbour count: exclude self
                $a=$c>A,                            # 1. $a=cell is alife
                $i=$x-!!$x-1;$i++<=$x;)             # 3. loop $i from one left to one right of current position
                for($k=$y-2;$k++<=$y;)                  # loop $k from one above to one below current position
                    $n+=$s[$k][$i]>A;                       # increase neighbor count if neighbour is alife
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.