Hayatın En Kısa Oyunu


59

Conway'in Yaşam Oyunu , hücresel otomasyonun klasik bir örneğidir. Hücreler kare bir ızgara oluşturur ve her birinin iki durumu vardır: canlı veya ölü. Her seferinde, her bir hücre aynı anda kendi durumuna ve sekiz komşusununkilere göre güncellenir:

  • Tam olarak iki veya üç canlı komşu varsa, canlı bir hücre hayatta kalır
  • Tam olarak üç canlı komşusu varsa ölü bir hücre canlanır

Göreviniz, kabul etmeyi seçmeniz durumunda, en sevdiğiniz dilde en kısa oyun yaşamı uygulamasını kodlamak.

Kurallar:

  • Şebeke en az 20x20 olmalıdır
  • Izgara etrafından sarılmalıdır (ızgara bir Torus'un yüzeyi gibidir)
  • Uygulamanız kullanıcının kendi başlangıç ​​düzenini girmesine izin vermelidir
  • Ne olduğunu göremiyorsanız, GoL biraz anlamsızdır, bu nedenle çalışan otomatonun görsel çıktısı olmalı, her bir dönüşün sonucu görülebilecek kadar uzun süre gösteriliyor!

8
Stack Overflow'ta daha önce: Code Golf: Conway'in Yaşam Oyunu ve yorumlardaki APL uygulama linkine baktığınızdan emin olun.
dmckee

1
Ah, bunu görmedim. Ama bu biraz farklı değil (meydan okumayı bir araya getiren çalışmayı silmemi kurtarır mısınız?
Griffin

6
Problem değil. Stack Overflow ile ilgili birçok bulmaca burada da yapıldı, ancak insanlar size benzer zorluklarla bağlantı kurma konusunda takıntılı olduğumu söyleyecek.
dmckee

@Griffin: Hepsini ;önce }s kaldırabilirsiniz . Ayrıca vars zaman zaman elimine edilebilir (eğer kodunuzu kırmazsa). Ve tek satırlık için fors, ifs vs, ortadan kaldırabilir { }tamamen: for(...) for(...) dosomething().
pimvdb

@pimvdb, şerefe, henüz tam olarak golf oynamadım, vaktim olmadı. sadece boş bir meydan okuma yapmak yerine benim de gittiğimi göstermek istedim. Yakında maksimum hızda golf olacak.
Griffin,

Yanıtlar:


27

JavaScript ile HTML5 Tuval, 940 639 586 519 karakterler

<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>

Her zaman tuval ile bir şeyler yapmak istemişimdir, işte benim girişim (orijinal versiyon çevrimiçi ) Tıklayarak hücreleri değiştirebilirsiniz (çalışma modunda da mümkündür).

Şimdi yeni sürümünü buradan da deneyebilirsiniz .

Ne yazık ki, henüz çözemediğim bir sorun var. Çevrimiçi sürüm 11 karakterden daha uzun çünkü jsFiddle, tuvalin hemen önüne bir metin düğümü koyar (neden?) Ve bu nedenle tuval artık ilk çocuk değildir.

Düzenleme 1: Çok sayıda optimizasyon ve yeniden yapılandırma.

Düzenleme 2: Birkaç küçük değişiklik.

Düzenleme 3: Komut dosyası bloğunun tümüne ek olarak küçük değişiklikler yapıldı.


Güzel, ancak 1yavaş yavaş adım atmaktan ziyade benimki kadar hızlı olması için aralık gecikmesini değiştirin . Ayrıca çizim yapmak istiyorsanız (her kareye tıklamak yerine), farenin konumunu en yakın blok boyutuna getirebilir ve o noktadaki dikdörtgeni doldurabilirsiniz. Daha fazla karakter ama daha fazla puan.
Griffin

Sen yerini alabilir new Array('#FFF','#800')ile ['#FFF','#800'].
Lowjacker

Çizim hakkında söylese de, süper golf oynadım çizime izin vermiyor ve günah kadar çirkin. Haha. Sen içinde iki rengi ayarlayabilirsiniz siçin diziden tanve redonlar en kısa temsiller ile iki renk olduğundan - sana iki karakter kazandırır. Ayrıca, mümkünse, değişmeyen sürümünü jaralığın içine koyun . Eminim sıkılacak daha çok şey vardır.
Griffin

@Griffin ve Lowjacker: Çok teşekkür ederim. Ayrıca, çok daha fazlasını golf oynayabileceğinizden (ve zaten bazı fikirleriniz olduğundan) eminim. Maalesef bunu yapacak zamanı bulamadım. Daha iyi bir golf versiyonu yarın takip edecek - İnşallah ...
Howard,

2
Html ve body etiketlerini kaldırabilirsiniz. Aynı işleyecektir
arodebaugh

32

Python, 219 karakter

Maksimum golf oyununa gittim, soruyu tatmin etmek için yeterli arayüze sahip oldum.

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)

Böyle koşuyorsun:

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

Listedeki sayılar, başlangıç ​​hücrelerinin koordinatlarını temsil eder. İlk satır 0-19, ikinci satır 20-39 vb.

21 satır ile bir terminalde çalıştırın ve oldukça şık görünüyor.


1
Bu tamamen kazanmalıydı. Sanırım 'girdi kolaylığı' oldukça yüksek.
primo

@primo mma'nın ayrı bir rekabete sahip olması gerektiğini önerecek kadar ileri gitmiştim.
kullanıcı

2
Öyleyse Py'nin hayatı bu mu?
Christopher Wirt

Her zaman bir tane daha char kaydedebilirsiniz ... 2-(p in P)== 2-({p}<P). Fakat girişinizi {8,29,47,48,49}:) olarak değiştirmelisiniz :)
JBernardo

21

TI-BASIC, 96 bayt (rakip olmayan girişler için 87)

TI-84 serisi grafik hesap makineniz için (!). Bu orada bir tamponlu grafik rutin (yerleşik kesinlikle hiçbir şey) yazmak için kolay bir yolu olduğunu ve grafik ekran sadece dört alakalı grafik komutları çünkü, oldukça zor oldu: Pxl-On(), Pxl-Off(), Pxl-Change(), ve pxl-Test().

Ekrandaki erişilebilir her pikseli kullanır ve doğru şekilde sarılır. Her hücre bir pikseldir ve program ekran boyunca sağa doğru yatay olarak satır satır güncellenir. Hesap makineleri yalnızca 15MHz z80 işlemciye sahip olduğundan ve BASIC yavaş yorumlanmış bir dil olduğundan, kod her beş dakikada bir yalnızca bir kare alır.

Kullanıcı girişi kolaydır: Programı çalıştırmadan önce, şekilinizi grafik ekranda çizmek için Kalem aracını kullanın.

Bir benim girişten Uyarlanmış hesap forumda Omnimaga kod golf yarışması .

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 sürümü (87 bayt)

Bu kod ek bir özelliğe sahiptir: ilk defa çalıştırılıp çalıştırılmadığını ve ekran durumunu rasgele ayarlarsa algılar. Sonraki işlemlerde, bir çerçeve bittikten sonra durduğunda otomatik olarak simülasyonu sürdürür. Ancak, ekranı kapsımadığından rakip bir giriş değildir; Grafik ekran önceden temizlenmişse, dış sınırdaki hücreler her zaman ölü sayılır.

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

Bu sürüm muhtemelen şimdiye kadar yazmış olduğum en golf kodlu kod ve gerçekten kötü engelleyici optimizasyonlar içeriyor:

  • Saat durumunu bir bayrak olarak kullanıyorum. Programın başında tarih / saat saati etkin ve ilk yinelemenin olup olmadığını belirlemek için global isClockOn bayrağının değerini kullanıyorum. İlk kare çizildikten sonra saati kapatırım. En kısa diğer yönteme bir bayt, en açık yöntemden ise dörde kadar tasarruf sağlar.

  • Bir üç elemanın durumlarını, bir 7 elemanlı taban-7 sayıları dizisinde güncellenen yanına depolarım. 49'un yeri sütunu sağa, 7'si orta sütunu ve birimler yeri sol sütunu tutar - canlı bir hücre için 1 ve ölü bir hücre için 0. Daha sonra, toplam canlı komşu hücrelerin sayısını bulmak için değiştirilen hücrenin etrafındaki üç sayının toplamının 6 modunu alıyorum (bu, 9 numara ile bölünebilirlik gibidir - üs 7'de, geri kalan mod 6, toplamın toplamına eşittir.) rakamlar). Kendi başına yaklaşık 10 bayt tasarruf sağlar ve sonraki iki optimizasyonu kullanma fırsatı sunar. Örnek şema (diyelim ki Y = 45'deki belirli bir sütunda ortalanmış bir planör var:

    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
    ...
    

    Merkez hücre ölü kalacaktır, çünkü tam olarak beş canlı hücre ile çevrilidir.

  • Her satır tamamlandıktan sonra, dizideki sayılar, varolan sayıları 7'ye bölerek, ondalık bölümü atılarak ve yeni sütundaki hücrelerin değerlerinin 49 katını ekleyerek güncelleştirilir. Her üç sütunun da her seferinde saklanması çok daha yavaş ve daha az zarif olur, en az 20 bayt alır ve bir satır yerine üç liste kullanır, çünkü her satırdaki hücrelerin değerleri hücrelerin güncellenmeden önce depolanması gerekir. Bu, hücre pozisyonlarını depolamak için en küçük yoldur.

  • Pasajı int(3fPart(3cosh(verir 1girişi, 3/6 eşit olduğunda 2o 4/6 eşit olduğunda, ve 00, 1/6, 2/6 veya 5/6 eşit olduğunda. Yaklaşık 6 bayt kaydeder.


19

Mathematica - 333

Özellikleri:

  • Etkileşimli arayüz: kalıplarınızı oluşturmak için hücreleri tıklayın

  • Güzel ızgara

  • Düğmeler: ÇALIŞTIR, DURAKLAT, TEMİZLE

Kod aşağıda.

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"}}]

görüntü tanımını buraya girin

Bu nasıl çalıştırdığını bir fikir elde etmek istiyorsanız, içinde 2 örnek bu blog yukarıdaki yalnızca bir kod daha ayrıntılı sürümü (canlı Fourier analizi, daha iyi bir arayüz) 'dir. Örnek, ücretsiz eklenti indirildikten sonra doğrudan tarayıcınızda çalışmalıdır.


2
+1, gitmek için güzel bir tane. Evet, bu sitedeki sorun işte, kaçırmaya meyilli tonlarca eski soru var.
Griffin

@Griffin fark ettiğiniz için teşekkür eder;)
Vitaliy Kaurov

15

C 1063 karakter

Bir meydan okuma olarak, ben C-in golf dostu Windows API kullanarak gerçek zamanlı IO yaptım. Büyük harf açıksa, simülasyon çalışacaktır. Capslock kapalıysa sabit kalacaktır. Fare ile desen çizin; sol tıklama hücreleri yeniden canlandırır ve sağ tıklama hücreleri öldürür.

#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);}}}

Derlenmiş EXE burada bulunabilir

Düzenleme: Kaynağı yorumladım. İşte kullanılabilir


Bunun yorumlanmış bir versiyonunu görmek isterim!
kullanıcı

1
Tabi, ne düşündüğümü hatırlayabilirsem ... = p
Kaslai

1
@luserdroog İşte pastebin.com/BrX6wgUj
Kaslai

Bu sadece harika.
rayryeng - Monica

12

J (39 karakter)

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

Göre bu APL versiyonu (aynı algoritma, toroid biçimli kıvrım).

Örnek kullanım:

   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 karakter

Mathematica'nın yerleşik CellularAutomaton işlevini kullanmayan çok temel bir uygulama.

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

8

Yakut 1.9 + SDL (380 325 314)

EDIT : 314 karakter ve ilk yinelemede canlı görünen fazladan hücrelerde bir hata düzeltildi. Renk rutini yalnızca en düşük 8 bitte göründüğü için ızgara boyutunu 56'ya çıkardı.

EDIT : 325 karaktere kadar golf oynadı. Izgara genişliği / yüksekliği şimdi 28'dir, çünkü değeri arka plan rengi olarak kullanırken elde edebileceğiniz en büyük miktar 28 * 9'dur. Ayrıca, yineleme başına yalnızca bir SDL olayını işler, bu da iç döngüyü tamamen ortadan kaldırır. Oldukça sıkı sanırım!

Simülasyon durduruldu, tüm hücreler öldü. Duraklatmak / duraklatmak için herhangi bir tuşa basabilir ve canlı ile ölü arasında geçiş yapmak için herhangi bir hücreye tıklayabilirsiniz. Her saniyenin onda birine bir yineleme yapar.

Kaydırma biraz riskli.

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}

Buna benzer:

Uygulamadaki uygulamanın ekran görüntüsü

Eğlenceli meydan okuma! Herkesin görebileceği herhangi bir iyileştirme kabul ediyorum.


İyi deneme ama yanıldığını hemen anlıyorum. GoL’da böyle bir kalıp olamaz. Kuralları bir kez daha okuyun: en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
Griffin

@Griffin Bazı ekranların manuel olarak duraklatılıp değiştirildikten sonra ekran görüntüsünün alındığını düşünüyorum - Yine de kuralları tekrar kontrol edeceğim. Teşekkürler!
Paul Prestidge

7
@Griffin tohum deseni herhangi bir yapılandırmada olamaz mı?
saat

7

Scala, 1181 1158 1128 1063 1018 1003 999 992 987 karakterler

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}}

Ungolfed:

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
    }
}

Buradaki kodun daha büyük kısmı Swing GUI olayıdır. Oyunun kendisi, actionPerformedtarafından tetiklenen yöntemde Timerve nkomşuları sayan yardımcı fonksiyonda .

Kullanımı:

Derleyin scalac filenameve sonra çalıştırın scala L.
Bir kareye tıklamak canlıdan ölüme çevirir ve menü seçeneği oyunu başlatır ve durdurur. Izgara boyutunu değiştirmek istiyorsanız, satırdaki ilk üç değeri değiştirin: var(w,h,c,d,r)=(20,20,20,0,false)sırasıyla genişlik, yükseklik ve hücre boyutu (piksel cinsinden).


2 golf iyileştirmesi buldum: import java.awt.event._ve contents+=m("Go",true)+=m("Stop",false)}}1093 karaktere ulaştı.
kullanıcı bilinmeyen

@ user unknown teşekkürler. Kendim için birkaç gelişme buldum - şimdi 1063'e kadar.
Gareth,

Kahretsin, meşguldün. Aynen böyle devam! Birkaç kişi daha gönderdiğinde cevapları test edeceğim.
Griffin,

7

Saf Bash, 244 bayt

Toroidal olarak sarılmış 36x24 evrende çalışır:

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"

Bu bir kabuk betiği olduğundan, giriş yöntemi diğer kabuk komutlarıyla uyumludur - yani stdin:

$ ./conway.sh << EOF

   O 
    O 
  OOO 

EOF


  O O                                                       
   OO                                                       
   O                                                        

















    O                                                       
  O O                                                       
   OO                                                       

... vb

Girdiyi, trilginç başlangıç ​​nesiller elde etmek için filtreden geçirilen herhangi bir metin kaynağından yönlendirebiliriz.

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

6

JavaScript, 130

Mücadeleye tamamen cevap vermiyor, ama kayıt için, işte 2013 yılında Subzey ve ben tarafından yapılan 130 baytlık bir Game of Life motoru.

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}

Bunun ilk satırda bazı problemleri var gibi görünüyor. Örneğin, ayar @@\n@@(sol üst köşede 2 x 2 kare) veya .@\n.@\n.@. (1 tarafından 3 sütun)
Annan

5

675 karakter

Her zaman bu programın bir versiyonunu yazmak istemişimdir. Hızlı ve kirli bir sürüm için sadece tembel yarım saat süreceğini bilmiyordum. (Golf oynamak elbette çok daha uzun sürüyor.)

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();}};}}

kullanım

  • Açmak için hücreleri tıklayarak canlı bir desen girin (canlı).
  • Herhangi bir klavye tuşuna basarak oyuna başlayın.
  • Bir tuşa her basıldığında oyun 99 nesiller boyunca oynanır (bir karakter kazanmayı 9 yapabilirdim ama bu çok topal görünüyordu).

Golf anlaşmaları

  • Hücreleri yalnızca fareyle açıp kapatabilirsiniz, bu nedenle bir hata yaparsanız programı yeniden başlatmanız gerekir.
  • Izgara çizgileri yoktur, ancak bu oynanabilirliğe çok fazla zarar vermez.
  • Güncelleme hızı CPU hızı ile orantılıdır, bu yüzden çok hızlı bilgisayarlarda muhtemelen bir bulanıklık olacaktır.
  • Canlı hücreler kırmızıdır çünkü "siyah" 2 karakter daha kullanır.
  • Hücrelerin küçüklüğü ve tüm form alanını kullanmadıkları gerçeği de karakter kazandıran ödünlerdir.

5

GW-BASIC, 1086 1035 bayt (belirtilmiş)

Tokenleştirilmiş formda, bu 1035 bayttır. (ASCII formu, elbette, biraz daha uzundur.) Tercümana eklenmeden SAVE"lifekomutu kullanarak tokenlenmiş formu alırsınız ",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

Bu maksimum golf versiyonudur, ancak yine de özellikli: Başladıktan sonra imleç tuşları ile hareket edebileceğiniz bir editör elde edersiniz; boşluk mevcut alandaki bakterileri açar / kapatır c, ekranı temizler, Dönüş oyun moduna başlar.

Burada ayrıca iki yapılı (dairesel dönen bir plan ve bir planör) oluşan ilk oyun tahtasını ayarlayan daha az karışık bir versiyonu izler:

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

Bunu 15 dakika içinde sıkılmış ve Conway'in Yaşam Oyunu için çırağıyla aynı anda kodlayan bir arkadaşımı beklerken yazdım.

Bu gibi çalışır: Hemen 80x25 boyutlarındaki metin modu ekranı tampon kullanır (baş harfini değiştirmek DEF SEGkullanmak &hB000bir Hercules grafik kartı iseniz; bu ayarlar QEMU ile çalışmak ve (yavaş) dosbox). Yıldız işareti *bir bakteridir.

İki geçişli çalışır: ilk önce doğum yerleri ile işaretlenir +ve ölüm hedefleriyle işaretlenir .. İkinci geçişte, +ve .ile ikame edilir *ve sırası ile,.

Asıl TIMERmesele, Qemu sunucunuzun çok hızlı olması durumunda her turdan sonra yarım saniye beklemektir.

Burada en düşük kazancı olan fiyatı beklemiyorum, özellikle de ilk pano kurulumu düşünüldüğünde, soğuk bir fiyat. Ayrıca ilginizi çekiyorsa, oyun motorunun montaj kodu ile değiştirildiği bir versiyonum da var.


Etiketlerini golf oynamayan sürümde 1 arttırdığınızı göz önünde bulundurarak, aynı şeyi golf halindeki sürümde yapmak mümkün müdür? (yani 1, 2, 3, vb) Ya satır numaraları sayılmaz mı?
Zacharý

satır numaraları, belirtildiğinde, tamamen yanılmıyorsam kelime (16 bit) olarak sayılır
mirabilos,

Tamam o zaman sanırım başka bir TEMEL lehçesi daha sonra düşünüyorum.
Zacharý,

@ Zacharý “GW-BASIC kodlanmış program formatı” nı ve ardından “Program formatı” nı tıklayın , burada satır numaralarının sürekli olarak iki bayt olduğunu ve sembol formatıyla ilgili daha ayrıntılı bilgi için burayı tıklayın .
mirabilos

5

Mathematica, 115 bayt

İşte bu kolay bir kopyasını:

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

1
Mathematica iyidir, ancak kuralların belirttiği gibi, program kullanıcının kendi kalıplarını girmesine izin vermelidir. Bu kural kasıtlıdır, çünkü birkaç dil bu gibi kısa uygulamalara izin verir, ancak kullanıcı etkileşimi olmadan. Tabii ki kendi dizinizi oraya koyabilirsiniz, ama kazanamayacak.
Griffin

Mathematica'daki "giriş" çoğunlukla dizüstü bilgisayar arayüzü üzerinden yapılır, bu yüzden "kullanıcı etkileşimi" nin gerçekten mümkün olduğunu sanmıyorum. Sadece RandomInteger argümanını CellularAutomaton işlevinde istediğin şeyle değiştir ve kodu yeniden değerlendir.
JeremyKun

3
Kullanıcı etkileşimi mümkündür. Şu an aklıma gelen en basit yöntem bir dizi buton. Git bir adam ver.
Griffin

4

Java (OpenJDK 8) - 400 388 367 bayt

İkincisi ve (muhtemelen) Son Düzenleme: Bu (imo) altın madenlerini bulduktan sonra fazladan 21 byte golf oynamayı başardı - kesinlikle bunları okumak için yeni insanlara önerin (özellikle de Java kullanarak bu zorlukların bazılarını deneyecekseniz).

Sonuç kodu (döngüler için iç içe geçmiş çiftlerin nasıl kısaltılacağını öğrenirsem muhtemelen golf oynamaya daha fazla son vereceğim):

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);}}

Çevrimiçi deneyin!

(Orijinal gönderi burada başlar.)

Aslında bir an için en azından Python cevabına (tartışmalı olarak sınırlı) Java lol bilgisiyle meydan okuyabileceğimi düşündüm ... Yine de katılmaktan çok zevk aldım (partiye katılmamıza rağmen) Birazcık geç...)

Gerçekten fazla bir şey yok - aşağıdaki temel açıklama (asılsız):

/*
 * 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

( burada Java 8'deki lambda ifadeleri hakkında daha fazla bilgi )

Evet, yaklaşımımın bir manası var.

Muhtemelen çoğunuzun farkına vardığı gibi, şu anki haliyle golf kodum sonsuza kadar sürecek. Bunu önlemek için, en üste bir sayaç eklenebilir ve süre döngüsünde yalnızca n(bu durumda, 5) yineleme aşağıdaki gibi görüntülenir ( beklenen yeni değişkeni dikkate alın):

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);}}

Ek olarak, bahsetmeye değer birkaç nokta. Bu program girişin doğru olup olmadığını kontrol etmez ve bu nedenle (muhtemelen) bir ArrayOutOfBoundsException; Bu durumda, bir dizinin bir bölümünü tamamen doldurarak girişin geçerli olduğundan emin olun (eğriltilmiş diziler yukarıda belirtilen istisnayı atar). Ayrıca, tahta şu anda 'akışkan' göründüğü için - yani, bir nesil ile diğeri arasında hiçbir ayrım yoktur. Bunu, üretilen kuşakların gerçekten geçerli olup olmadığını kontrol etmek için eklemek isterseniz, System.out.println();hemen önce ilave bir ilave yapılması gerekiyor for(int[]t:u)Arrays.fill(t,0);( açıklığa kavuşturmak için bunu çevrimiçi deneyin! ). Ve son olarak, ama en azından, bu benim ilk kod golf olduğum göz önüne alındığında, herhangi bir geri bildirim büyük beğeni topluyor :)

Önceki 388 baytlık cevabın eski kodu:

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);}}

Ve ilk 400 byte cevabından:

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);}

Şaşırtıcı ilk gönderi, PPCG'ye hoş geldiniz!
Zacharý

Teşekkürler, kesinlikle daha fazlasını yapacağım - eğlenceliler :)
NotBaal

Bize katıl, Dennis’iz. Ayrıca, bu tam bir program veya olması gereken bir fonksiyon değildir, IIRC.
Zacharý

Doğru, 'program' bölümünü unuttum: P Biraz içinde düzenleme.
NotBaal,

Bu sadece bir fonksiyon olabilir.
Zacharý,

4

Şablon , 6 bayt

Benim favori dil, ancak bir kısa ...

4 kod baytı artı nlist ve Torus bayrakları.

3me

Çevrimiçi deneyin!

... mı
3 3
 üyesi m öz veya oore-mahalle-sayımı  Moor e öz olmadan -neighbourhood-sayımı ...?
m
e


3

Scala - 799 karakter

Bir komut dosyası olarak çalıştır. Bir kareye bir fare tıklaması, onu açıp kapatır ve herhangi bir tuş üretimi başlatır veya durdurur.

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

J'ye denerim dedim. Henüz pek iyi golf oynamamış, ancak yakında tekrar deneyeceğim.

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

Örnek:

   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

İşleme 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);}

Bunun tüm gereklilikleri karşıladığına inanıyorum.

Ungolfed:

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

Şu anda test etmek için Matlab yüklü değil, birkaç yıl önce yazdığım kodu yazdım.
Ungolfed:

%% 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 kodlanmış ancak herhangi bir şey olabilir
  • saran
  • kullanıcı girişi için giriş kartını ya başka bir matrisi kodlayarak ya da değişken editörü kullanarak değiştirebilirsiniz. Güzel değil ama işe yarıyor
  • Grafik çıktısı atlanırsa 20 karakter kaydedilebilir, tahta her tekrarda metin olarak basılır. Her milisaniyeyi değiştiren bir piksel hücreler zaten çok kullanışlı değil

R2014a'da çalışıyor, yeni test edildi
masterX244

3

Perl, 218 216 211 202 bayt

$,=$/;$~=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}

(Bu kodun sonunda yeni satır yok.)

Canlı hücrelerin temsil edildiği bir metin dosyası 1, boşluk olarak temsil edilen ölü hücreler, satırlar bir yeni satırla ayrıldığından standart girdiden başlangıç ​​şablonunu okur . Girdide bunlardan başka karakterler bulunmamalıdır. Çizgiler değişken uzunluk olabilir ve tam olarak 79 genişliğe kadar yastıklı veya kesilmiş olacaktır. Örnek giriş bir planör tabancasıdır:

                                  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

Program Game of Life'ı çalıştırırken, her durum girişe benzer bir biçimde standart çıktıya atılır, ardından 0,1 saniye geciktirilir. Gecikme, seçilen aramanın dördüncü argümanı değiştirilerek özelleştirilebilir.

Oyun tahtası 79x23 büyüklüğünde kodlanmış. Bir torusla sarılır: tahtayı altta bırakırsanız, üste çıkarsınız; sağ tarafta bırakırsanız, sol tarafta olursunuz ancak bir sıra aşağı kaydırırsınız.

İşte herhangi bir girişi okumayan ve rastgele bir tahtadan başlayan alternatif bir sürüm:

$,=$/;$/=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}

Bu kod, yıllar önce yazdığım karışık bir yaşam oyun perl programından türetilmiştir . Yönetim kurulunda kodu yıpratmak ve değiştirmek için çok şey değiştirdim.

Bu muhtemelen Perl'de Yaşam Oyununu uygulamak için en kısa yöntem değildir, ancak daha az anlaşılır olanlardan biridir.

Tahta $bbir dizi halinde saklanır '1've ' 'her hücre için bir tane olmak üzere, her şey en az üç kez tekrarlanır. Üçüncü paket açma çağrısı, her hücre için 17 değer alır: isteğe bağlı bir sırayla hücrenin kendisi için bir tane ve sekiz komşu hücrenin her biri için iki tane vardır ve her değer '1'veya boş bir dizedir. Hücre, '1'bu 17 değer arasındaki değerlerin sayısı 5, 6 veya 7 olduğunda , bir sonraki yinelemede canlı olmalıdır . Üçüncü paket çağrısı, bu 17 değerleri, hizalanmış ve sağda nul baytlarla dolgulu olarak bırakılan 18 karakterlik bir alana birleştirir. . İkinci paket açma çağrısı 18 genişliğinde bir alanı alır, 7 numaralı pozisyondaki karaktere gönderir, eğer boşsa, 17 numaralı pozisyondaki boşluğu açar.'1', aksi takdirde karakteri 4 numaralı pozisyondan çıkarır. Bu sonuç tam olarak hücrenin yeni nesilde sahip olması gereken değerdir.


2

Python, 589 bayt

Fare düğmeleri: sola - bir hücre koy, sağa - bir hücreyi kaldır, orta başlat / durdur.

Tkinter ithalatından *
ithalat kopyası
z = aralığı
F = 50
T = Tk ()
G = 9
f = [F * [0] '7' i * F için
c = Kanvas (T, genişlik = S * K, yükseklik = S * F)
c.pack ()
def p (x, y, a): f [y] [x] = f [y] [x] veya c.create_oval (x * S, y * S, x * S + S, y * S + S) başka bir c.delete (f [y] [x]) ise
r = 1
def R (e): global r; r = 1-r
exec ("c.bind ('<Button-% i>', lambda e: p (örneğin / s, ey / S,% i));" *% 2 (1,1,3,0))
c.bind ( '<Düğme-2>', R)
def L ():
 T.after (99, L)
 eğer r: dönüş
 g = copy.deepcopy (f)
 z (F) 'de y için:
	x in z (F) için:
	 n = 8
	 j için z (-1,2):
		i z için (-1,2):
		 eğer i veya j: n- = değil g [(y + j)% F] [(x + i)% F]
	 eğer 1 <n <4 ise:
		eğer n == 3 ve g [y] [x] değilse: p (x, y, 1)
	 Başka: p (x, y, 0)
(L)
T.mainloop ()

Ve işte fareyi çizmek için sürükleyebileceğiniz bir versiyon. Grafikler biraz daha hoş.

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()

Bu, hayat oyun kurallarını doğru şekilde takip etmiyor.
Steven Rumbalski,

1
@StevenRumbalski: Gerçekten mi?
Oleh Prypin

2
Gerçekten mi. İkinci versiyonunuzda bir girinti hatası var. if 1<n<4:for j in z(-1,2):
İle

2

Python 2,456 bayt

Bunun eski bir yazı olduğunu bildiğim halde, kendime bir şans vermekten kendimi alamadım. İlk pano, etrafına kenarlık çizdiğiniz ve son satırda fazladan boşluk bıraktığınız sürece herhangi bir boyutta olabilir.

Golf.py

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 (son satırdaki fazladan boşluğu not edin)

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

Nasıl koşulur

python Golf.py < input.txt

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

^, Birini unuttun, 1 if=> 1if.
Zacharý

2

İşleme 270261 249 bayt

Izgara, 100 * 100 piksel ekrandır, giriş, png resmi biçiminde gelir

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();}

Ungolfed

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();
}

ekran görüntüsü


2

Lua + LÖVE / Love2D , 653 bayt

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

veya aralıklı:

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

Canlı hücreleri eklemek için alana tıklayın. Çalıştırmak için alanın dışına tıklayın.

Çevrimiçi deneyin!

görüntü tanımını buraya girin


1

dipnot 529 515

Rosetta Kodundan bir örnek ile başladı . Bir dosya adı argümanı ( gs -- gol.ps pulsar) ile çağır , 20 * 20 ikili sayı içeren dosya (boşlukla ayrılmış). Sonsuz döngü: tahta çizmek, girmek için bekleyin, gelecek nesli hesaplayın.

[/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

Birkaç yığın yorumu ile aralıklı (sadece ihtiyacım olanları).

[
/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

pulsar veri dosyası:

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

Üzgünüm Griffin, koduna bakamadım ve tekrar yazamadım ... iki karakteri tıraş etmek zorunda kaldım ama buna değdi!

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}

Ama dedikleri gibi affetmek istemek izin almaktan daha kolaydır ...;)


1

Oktav (153)

DenDenDo'nun En Kısa Yaşam Oyunu'ndaki Matlab ile aynı olmasına rağmen, imshow'u imagesc olarak değiştirmek zorunda kaldı:

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
imagesc(b)
drawnow
b=p(b,s(b))
end

1

Python 2: 334 Bayt

Sadece 6 yıl gecikti.

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"

Gibi çalıştırabilirsiniz:

python gol.py
0000000
0001000
0000100
0011100
0000000
0000000
0000000

0'ların ve 1'lerin ölü ve canlı hücreleri temsil ettiği yerlerde, sonunda ilave bir yeni satır yürütmeye başlar.

Izgaralar kare olmalıdır.

Koşması en kısa python olandan daha kolaydır, herhangi bir boyuttaki ızgaraları destekler ve koşarken güzel görünür.

Aynı zamanda 100 byte daha fazla, bu yüzden var.


0

PHP, 201 bayt (test edilmedi)

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;

İle koş -nr.

Yıkmak

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.