Game Kehidupan Terpendek

59

Permainan Kehidupan Conway adalah contoh klasik otomatisasi seluler. Sel-sel membentuk kotak persegi dan masing-masing memiliki dua keadaan: hidup atau mati. Pada setiap belokan, setiap sel secara bersamaan memperbarui sesuai dengan kondisinya dan dari delapan tetangganya:

  • Sel hidup tetap hidup jika memiliki dua atau tiga tetangga hidup
  • Sel mati menjadi hidup jika memiliki tiga tetangga yang hidup

Misi Anda, jika Anda memilih untuk menerimanya, adalah untuk mengkode implementasi Game of Life terpendek dalam bahasa favorit Anda.

Aturan:

  • Kisi-kisi harus setidaknya 20x20
  • Kisi harus membungkus (sehingga kisi-kisi itu seperti permukaan Torus)
  • Implementasi Anda harus memungkinkan pengguna untuk memasukkan pola awal mereka sendiri
  • GoL sedikit tidak ada gunanya jika Anda tidak dapat melihat apa yang terjadi, jadi harus ada output visual dari otomat berjalan, dengan hasil setiap belokan yang ditampilkan cukup lama untuk dilihat!
Grifon
sumber
8
Sebelumnya di Stack Overflow: Code Golf: Conway's Game of Life , dan pastikan untuk melihat tautan implementasi APL dalam komentar.
dmckee
1
Ah, saya tidak melihatnya. Tapi ini sedikit berbeda bukan (selamatkan saya menghapus pekerjaan yang menyatukan tantangan?
Griffin
6
Ini bukan masalah. Banyak teka-teki yang sudah berjalan di Stack Overflow telah dilakukan di sini juga, tetapi orang-orang akan memberi tahu Anda bahwa saya terobsesi dengan menghubungkan ke tantangan serupa.
dmckee
@ Griffin: Anda dapat menghapus semua yang ;sebelumnya }s. varS juga dapat dihilangkan kadang-kadang (jika tidak merusak kode Anda). Dan untuk satu baris fors, ifs dll, Anda dapat menghilangkan { }sepenuhnya: for(...) for(...) dosomething().
pimvdb
@ pimvdb, tepuk tangan, saya belum bermain golf sepenuhnya, belum punya waktu. Saya hanya ingin menunjukkan bahwa saya juga ikut, daripada dengan iseng mengatur tantangan. Akan golf ke max segera.
Griffin

Jawaban:

27

Kanvas HTML5 dengan JavaScript, 940 639 586 519 karakter

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

Saya selalu ingin melakukan sesuatu dengan kanvas, jadi inilah usaha saya (versi asli online ). Anda dapat beralih sel dengan mengklik (juga dimungkinkan dalam mode berjalan).

Anda sekarang juga dapat mencoba versi baru di sini .

Sayangnya ada masalah yang belum bisa saya atasi. Versi online lebih panjang 11 karakter karena jsFiddle menempatkan simpul teks tepat sebelum kanvas (mengapa?) Dan dengan demikian kanvas tidak lagi menjadi anak pertama.

Sunting 1: Banyak optimisasi dan restrukturisasi.

Sunting 2: Beberapa perubahan kecil.

Sunting 3: Menyusun blok skrip lengkap ditambah perubahan kecil.

Howard
sumber
Bagus, tapi ubah jeda interval untuk 1membuatnya secepat milikku daripada langkah lambat itu. Juga jika Anda ingin menerapkan gambar (daripada mengklik pada setiap kotak) Anda dapat membulatkan posisi mouse ke blocksize terdekat dan mengisi kotak pada saat itu. Lebih banyak karakter tetapi lebih banyak poin.
Griffin
Anda bisa menggantinya new Array('#FFF','#800')dengan ['#FFF','#800'].
Lowjacker
Meskipun mengatakan itu tentang menggambar, golf super saya tidak memungkinkan menggambar dan jelek seperti dosa. Ha ha. Anda dapat mengatur dua warna Anda dalam sarray tandan redkarena keduanya adalah warna dengan representasi terpendek - menghemat dua karakter. Juga, jika mungkin, masukkan versi literal jke dalam interval. Saya yakin ada banyak lagi yang harus dimatikan.
Griffin
@ Griffin dan Lowjacker: terima kasih banyak. Saya juga cukup yakin bahwa Anda dapat bermain golf lebih banyak (dan sudah memiliki beberapa ide). Sayangnya saya tidak menemukan waktu untuk melakukannya. Versi golf yang lebih baik akan mengikuti besok - Saya harap ...
Howard
2
Anda dapat menghapus tag html dan tubuh. Ini akan berfungsi sama
arodebaugh
32

Python, 219 karakter

Saya menggunakan golf maksimum, dengan antarmuka yang cukup untuk memenuhi pertanyaan.

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)

Anda menjalankannya seperti ini:

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

Angka-angka dalam daftar mewakili koordinat sel awal. Baris pertama adalah 0-19, baris kedua adalah 20-39, dll.

Jalankan di terminal dengan 21 baris dan terlihat cukup manis.

Keith Randall
sumber
1
Ini benar-benar seharusnya menang. Saya kira 'kemudahan input' terbobot cukup tinggi.
primo
@ primo Saya bahkan melangkah lebih jauh dengan menyarankan mma harus memiliki kompetisi terpisah.
luser droog
2
Jadi, apakah Kehidupan Py ini?
Christopher Wirt
Anda selalu dapat menyimpan satu karakter lagi ... 2-(p in P)== 2-({p}<P). Tetapi kemudian Anda harus mengubah input Anda menjadi {8,29,47,48,49}:)
JBernardo
21

TI-BASIC, 96 byte (87 untuk entri yang tidak bersaing)

Untuk kalkulator grafik TI-84 series Anda (!). Ini cukup tantangan, karena tidak ada cara mudah untuk menulis rutin grafis buffered (pasti tidak ada yang dibangun di), dan layar grafik hanya memiliki empat perintah grafis yang relevan: Pxl-On(), Pxl-Off(), Pxl-Change(), dan pxl-Test().

Menggunakan setiap piksel yang dapat diakses di layar, dan membungkus dengan benar. Setiap sel adalah satu piksel, dan program memperbarui baris demi baris secara horizontal ke kanan melintasi layar. Karena kalkulator hanya memiliki prosesor z80 15MHz dan BASIC adalah bahasa yang ditafsirkan lambat, kode hanya mendapat satu frame setiap lima menit.

Input pengguna mudah: sebelum menjalankan program, gunakan alat Pena untuk menggambar bentuk Anda di layar grafik.

Diadaptasi dari entri saya ke kontes golf kode di forum kalkulator 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

Versi Omnimaga (87 byte)

Kode ini memiliki fitur tambahan: mendeteksi jika sedang dijalankan untuk pertama kalinya, dan jika mengacak status layar. Dalam menjalankan selanjutnya secara otomatis melanjutkan simulasi jika berhenti setelah bingkai selesai. Namun, itu bukan entri yang bersaing karena tidak membungkus layar; sel-sel di perbatasan luar akan selalu dianggap mati jika layar grafik dibersihkan sebelumnya.

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

Versi ini mungkin adalah kode golf paling golf yang pernah saya tulis, dan berisi beberapa optimisasi membingungkan yang benar-benar buruk:

  • Saya menggunakan status jam sebagai bendera. Pada awal program, jam tanggal / waktu diaktifkan, dan saya menggunakan nilai flag isClockOn global untuk menentukan apakah itu adalah iterasi pertama. Setelah bingkai pertama diambil, saya mematikan jam. Menghemat satu byte di atas metode terpendek lainnya dan sekitar empat di atas metode yang jelas.

  • Saya menyimpan status tiga kolom di sebelah kolom yang diperbarui dalam larik 63-elemen dari nomor basis-7. Tempat 49 memegang kolom ke kanan, tempat 7 memegang kolom tengah, dan tempat unit memegang kolom kiri - 1 untuk sel hidup dan 0 untuk sel mati. Lalu saya mengambil sisa mod 6 dari jumlah tiga angka di sekitar sel yang dimodifikasi untuk menemukan jumlah total sel tetangga yang hidup (itu seperti pembagian dengan 9 trik — pada basis 7, sisanya mod 6 sama dengan jumlah dari digit). Menghemat sekitar 10 byte dengan sendirinya dan memberikan kesempatan untuk menggunakan dua optimasi berikutnya. Diagram contoh (misalkan ada peluncur yang berpusat pada kolom tertentu di 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
    ...
    

    Sel pusat akan tetap mati, karena dikelilingi oleh tepat lima sel hidup.

  • Setelah setiap baris selesai, angka-angka dalam array diperbarui dengan membagi angka-angka yang ada dengan 7, membuang bagian desimal, dan menambahkan 49 kali nilai sel dalam kolom baru. Menyimpan ketiga kolom setiap kali melalui akan jauh lebih lambat dan kurang elegan, mengambil setidaknya 20 byte lebih banyak, dan menggunakan tiga daftar daripada satu, karena nilai sel di setiap baris harus disimpan sebelum sel diperbarui. Sejauh ini, ini adalah cara terkecil untuk menyimpan posisi sel.

  • Cuplikan int(3fPart(3cosh(memberi 1ketika input sama dengan 3/6, 2ketika sama dengan 4/6, dan 0ketika sama dengan 0, 1/6, 2/6, atau 5/6. Menghemat sekitar 6 byte.

lirtosiast
sumber
19

Mathematica - 333

Fitur:

  • Antarmuka interaktif: klik sel untuk membuat pola Anda

  • Grid yang bagus

  • Tombol: RUN, PAUSE, CLEAR

Kode di bawah.

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

masukkan deskripsi gambar di sini

Jika Anda ingin merasakan bagaimana ini berjalan, contoh kedua di blog ini hanyalah versi yang lebih rumit (analisis Fourier langsung, antarmuka yang lebih baik) dari kode di atas. Contoh harus dijalankan langsung di browser Anda setelah unduhan plugin gratis.

Vitaliy Kaurov
sumber
2
+1, bagus untuk bersenang-senang. Ya itu masalahnya dengan situs ini, ada banyak pertanyaan lama yang cenderung dilewatkan orang.
Griffin
@ Griffin terima kasih telah memperhatikannya;)
Vitaliy Kaurov
15

C 1063 karakter

Sebagai tantangan, saya melakukan ini di C menggunakan API Windows yang tidak ramah untuk IO waktu nyata. Jika capslock aktif, simulasi akan berjalan. Ini akan tetap diam jika capslock mati. Gambar pola dengan mouse; klik kiri menghidupkan kembali sel dan klik kanan membunuh sel.

#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 yang dikompilasi dapat ditemukan di sini

Sunting: Saya sudah mengomentari sumbernya. Ini tersedia di sini

Kaslai
sumber
Saya ingin melihat versi komentar ini!
luser droog
1
Tentu, jika saya dapat mengingat apa yang saya pikirkan ... = p
Kaslai
1
@luserdroog Ini dia pastebin.com/BrX6wgUj
Kaslai
Ini luar biasa.
rayryeng
12

J (39 karakter)

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

Berdasarkan versi APL ini (algoritma yang sama, konvolusi toroidal).

Contoh penggunaan:

   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
kaoD
sumber
10

Mathematica, 123 karakter

Implementasi yang sangat mendasar yang tidak menggunakan fungsi CellularAutomaton bawaan Mathematica.

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

Ruby 1.9 + SDL (380 325 314)

EDIT : 314 karakter, dan memperbaiki bug dengan sel ekstra yang muncul hidup pada iterasi pertama. Menaikkan ukuran kisi menjadi 56 karena rutin warna hanya terlihat pada 8 bit terendah.

EDIT : Golf hingga 325 karakter. Lebar / tinggi kisi sekarang 28 karena 28 * 9 adalah yang terbesar yang dapat Anda miliki saat masih menggunakan nilai sebagai warna latar belakang. Ia juga memproses hanya satu kejadian SDL per iterasi sekarang, yang menyingkirkan loop dalam sepenuhnya. Kurasa cukup ketat!

Simulasi mulai dijeda, dengan semua sel mati. Anda dapat menekan tombol apa saja untuk beralih jeda / berhenti, dan klik sel mana saja untuk beralih antara hidup dan mati. Menjalankan iterasi setiap sepersepuluh detik.

Bungkusnya agak miring.

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}

Terlihat seperti ini:

Cuplikan layar aplikasi dalam aksi

Tantangan yang menyenangkan! Saya menyambut setiap perbaikan yang dapat dilihat siapa pun.

Paul Prestidge
sumber
Usaha yang bagus tapi saya bisa melihat langsung bahwa Anda salah. Anda tidak dapat memiliki pola seperti itu di GoL. Bacalah peraturan lainnya: en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
Griffin
@ Griffin Saya pikir tangkapan layar diambil setelah jeda dan beralih beberapa sel secara manual - saya akan memeriksa aturan lagi. Terima kasih!
Paul Prestidge
7
@ Griffin tidak bisakah pola seed berada dalam konfigurasi yang memungkinkan?
ardnew
7

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

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

Tidak Disatukan:

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

Bagian yang lebih besar dari kode di sini adalah hal-hal Swing GUI. Permainan itu sendiri adalah dalam actionPerformedmetode yang dipicu oleh Timer, dan fungsi pembantu nyang menghitung tetangga.

Pemakaian:

Kompilasi dengan scalac filenamedan jalankan dengan scala L.
Mengklik kuadrat membaliknya dari hidup ke mati, dan opsi menu memulai dan menghentikan permainan. Jika Anda ingin mengubah ukuran kisi, ubah tiga nilai pertama dalam baris: masing var(w,h,c,d,r)=(20,20,20,0,false)-masing adalah lebar, tinggi dan ukuran sel (dalam piksel).

Gareth
sumber
Saya menemukan 2 peningkatan golf: import java.awt.event._dan contents+=m("Go",true)+=m("Stop",false)}}, mengarah ke 1093 karakter.
pengguna tidak diketahui
@ pengguna tidak diketahui Terima kasih. Saya menemukan beberapa peningkatan sendiri - hingga 1063 sekarang.
Gareth
Sialan kau sibuk. Teruskan! Saya akan menguji jawaban ketika beberapa orang lagi mempostingnya.
Griffin
7

Pure Bash, 244 byte

Bekerja pada alam semesta 36x24 yang dibungkus dengan toroid:

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"

Karena ini adalah skrip shell, metode input ini kongruen dengan perintah shell lainnya - yaitu dari stdin:

$ ./conway.sh << EOF

   O 
    O 
  OOO 

EOF


  O O                                                       
   OO                                                       
   O                                                        

















    O                                                       
  O O                                                       
   OO                                                       

... dll

Kami dapat mengarahkan input dari sumber teks apa pun, disalurkan melalui trfilter untuk mendapatkan generasi awal yang menarik, misalnya

man tr | tr [:alnum:] O | ./conway.sh
Trauma Digital
sumber
6

JavaScript, 130

Tidak sepenuhnya menanggapi tantangan, tetapi sebagai catatan, inilah mesin Game of Life dalam 130 byte yang dibuat oleh Subzey dan saya pada tahun 2013.

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}
xem
sumber
Ini sepertinya memiliki beberapa masalah dengan baris pertama. Misalnya pengaturan @@\n@@(2 x 2 persegi di sudut kiri atas) atau .@\n.@\n.@. (1 oleh 3 kolom)
Annan
5

C # - 675 karakter

Saya selalu ingin menulis versi dari program ini. Tidak pernah tahu hanya butuh waktu setengah jam untuk versi yang cepat dan kotor. (Golf tentu saja membutuhkan waktu lebih lama.)

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

Pemakaian

  • Masukkan pola awal dengan mengklik sel untuk menghidupkannya (hidup).
  • Mulai game dengan menekan tombol keyboard apa saja.
  • Gim ini berjalan selama 99 generasi setiap kali sebuah tombol ditekan (saya bisa membuatnya menjadi 9 untuk menyelamatkan arang, tapi itu tampak terlalu timpang).

Kompromi bermain golf

  • Anda hanya dapat mengaktifkan sel dengan mouse, tidak mati, jadi jika Anda membuat kesalahan Anda harus me-restart program.
  • Tidak ada garis kisi, tapi itu tidak terlalu mengganggu pemutaran.
  • Kecepatan pembaruan sebanding dengan kecepatan CPU, jadi pada komputer yang sangat cepat mungkin hanya akan kabur.
  • Sel-sel hidup berwarna merah karena "hitam" menggunakan 2 karakter lebih banyak.
  • Kecilnya sel dan fakta bahwa mereka tidak menggunakan semua bentuk ruang juga merupakan kompromi yang menyelamatkan karakter.
Igby Largeman
sumber
5

GW-BASIC, 1086 1035 byte (di-token)

Dalam bentuk token, ini adalah 1035 byte. (Formulir ASCII, tentu saja, sedikit lebih lama.) Anda mendapatkan formulir yang dilemahkan dengan menggunakan SAVE"lifeperintah tanpa menambahkan ",adalam juru bahasa.

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

Ini adalah versi maksimum golf, tetapi tetap fitur: saat memulai, Anda mendapatkan editor, di mana Anda dapat bergerak dengan tombol kursor; ruang mengaktifkan / menonaktifkan bakteri di bidang saat ini, cmembersihkan layar, Kembali memulai mode permainan.

Berikut ini versi yang kurang membingungkan, yang juga menetapkan papan permainan awal dengan dua struktur (benda yang berputar-putar dan peluncur):

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

Saya menulis ini dalam 15 menit sambil bosan dan menunggu seorang teman, yang sedang bermain golf dengan "muridnya" untuk Conway's Game of Life pada saat yang sama.

Fungsinya seperti ini: Segera menggunakan buffer layar mode teks 80x25 (ubah inisial yang DEF SEGdigunakan &hB000jika Anda menggunakan kartu grafis Hercules; pengaturan ini berfungsi dengan Qemu dan (lebih lambat) dosbox). Tanda bintang *adalah bakteri.

Ini berfungsi dua-jalan: pertama, tempat kelahiran ditandai dengan +dan kematian menandai sasarannya .. Di pass kedua, +dan .diganti dengan *dan , masing-masing.

The TIMERhal yang membuatnya menunggu setengah detik setelah setiap putaran, dalam kasus tuan rumah Qemu Anda sangat cepat ☺

Saya tidak berharap untuk harga menang-terpendek di sini tapi untuk yang keren, terutama mengingat pengaturan papan awal. Saya juga punya versi di mana mesin game diganti dengan kode assembly, jika Anda tertarik ...

mirabilos
sumber
Mengingat Anda menambah 1 label pada versi yang bukan golf, apakah mungkin untuk melakukan hal yang sama pada versi golf? (yaitu, 1, 2, 3, dll) Atau apakah nomor baris tidak menghitung?
Zacharý
nomor baris, ketika ditandai, dihitung sebagai kata (16 bit), jika saya tidak sepenuhnya salah
mirabilos
Baiklah kalau begitu, kurasa aku pasti memikirkan dialek BASIC lainnya.
Zacharý
@ Zacharý Klik “Format program tokenised GW-BASIC” lalu “Format program” di sini untuk melihat bahwa, memang, nomor baris selalu dua byte, dan untuk detail lebih mendalam tentang format token.
mirabilos
5

Mathematica, 115 byte

Berikut ini adalah solusi mudah untuk ini:

ListAnimate[ArrayPlot/@CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},
{2,2,2}}},{1,1}},{RandomInteger[1,{9,9}],0},90]]
JeremyKun
sumber
1
Mathematica baik-baik saja, tetapi sebagai aturan menyatakan program harus memungkinkan pengguna untuk memasukkan pola mereka sendiri. Aturan ini disengaja karena beberapa bahasa memungkinkan implementasi pendek seperti ini tetapi tanpa interaksi pengguna. Tentu Anda bisa meletakkan array sendiri di sana, tetapi itu tidak akan menang.
Griffin
"Input" di Mathematica sebagian besar melalui antarmuka notebook, jadi saya tidak berpikir "interaksi pengguna" benar-benar mungkin. Anda cukup mengganti argumen RandomInteger ke fungsi CellularAutomaton dengan apa pun yang Anda inginkan, dan mengevaluasi kembali kodenya.
JeremyKun
3
Interaksi pengguna dimungkinkan. Metode paling sederhana yang dapat saya pikirkan saat ini adalah berbagai tombol. Ayo lakukan.
Griffin
4

Java (OpenJDK 8) - 400 388 367 byte

Edit Kedua dan (mungkin) Final: Berhasil bermain golf tambahan 21 byte setelah menemukan tambang emas (imo) ini - pasti merekomendasikan orang baru untuk membaca ini (terutama jika Anda akan mencoba beberapa tantangan ini menggunakan Java).

Kode yang dihasilkan (mungkin akan berakhir bermain golf lebih banyak lagi jika saya mencari tahu bagaimana cara memperpendek loop bersarang untuk loop ...):

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

Cobalah online!

(Posting asli dimulai di sini.)

Saya benar-benar berpikir sejenak bahwa saya akan dapat setidaknya menantang jawaban Python terbaik dengan pengetahuan saya tentang Java lol (yang bisa dibilang terbatas) ... Itu adalah tantangan yang saya nikmati tetapi tetap ikut (walaupun bergabung dengan partai mungkin hanya sebuah sedikit terlambat ...)

Tidak banyak yang benar-benar - penjelasan dasar sebagai berikut (ungolfed):

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

(informasi lebih lanjut tentang pernyataan lambda di Java 8 di sini )

Ya, ada masalah dengan pendekatan saya.

Karena sebagian besar dari Anda mungkin memperhatikan, kode golf saya seperti saat ini berdiri akan berulang selamanya. Untuk mencegah hal ini, penghitung dapat diperkenalkan di bagian atas dan digunakan dalam loop sementara untuk hanya menampilkan n(dalam kasus ini, 5) iterasi sebagai berikut (perhatikan bvariabel baru ditambahkan):

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

Selain itu, beberapa poin perlu disebutkan. Program ini tidak memeriksa apakah inputnya benar dan karena itu akan gagal dengan (kemungkinan besar) suatu ArrayOutOfBoundsException; dengan demikian, pastikan untuk memeriksa bahwa input tersebut valid dengan sepenuhnya mengisi bagian dari array (skewered array akan membuang pengecualian yang disebutkan di atas). Juga, papan seperti saat ini terlihat 'cair' - yaitu, tidak ada pemisahan antara satu generasi dan berikutnya. Jika Anda ingin menambahkannya untuk memeriksa ulang apakah generasi yang dihasilkan memang valid, tambahan System.out.println();perlu ditambahkan sebelum for(int[]t:u)Arrays.fill(t,0);(lihat ini Coba online! Untuk kejelasan). Dan yang terakhir, namun tidak kalah pentingnya, mengingat ini adalah golf kode pertama saya, umpan balik sangat dihargai :)

Kode lama dari jawaban 388 byte sebelumnya:

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

Dan dari jawaban 400 byte awal:

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);}
NotBaal
sumber
Posting pertama yang luar biasa, selamat datang di PPCG!
Zacharý
Terima kasih, saya pasti akan melakukan lebih banyak dari ini - mereka menyenangkan :)
NotBaal
Bergabunglah dengan kami, kami memiliki Dennis. Juga, ini bukan program lengkap atau fungsi, yang perlu, IIRC.
Zacharý
Oh benar lupa bagian 'program': P Mengedit itu sedikit.
NotBaal
Ini bisa menjadi fungsi juga.
Zacharý
4

Stensil , 6 byte

Bukan bahasa favorit saya, tetapi adalah singkat ...

4 byte kode ditambah bendera nlist dan Torus.

3me

Cobalah online!

Adalah ...
3 3
 anggota dari
m the m oore-lingkungan-hitung dengan diri atau
e tegalan e -neighbourhood-hitungan tanpa diri
...?

Adm
sumber
3

Scala - 799 karakter

Jalankan sebagai skrip. Klik mouse pada kotak untuk mengaktifkan atau menonaktifkannya dan tombol apa pun memulai atau menghentikan pembuatan.

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)
DonMac
sumber
3

J, 45

Saya pikir saya akan mencobanya. Ini belum golf dengan baik, tapi saya akan mencoba lagi segera.

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

Contoh:

   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
salinan
sumber
3

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

Saya percaya ini memenuhi semua persyaratan.

Tidak Disatukan:

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

Saya belum menginstal Matlab sekarang untuk mengujinya, saya baru saja memasukkan kode yang saya tulis beberapa tahun yang lalu.
Tidak Disatukan:

%% 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 adalah hardcoded tetapi bisa apa saja
  • membungkus
  • untuk input pengguna, seseorang dapat mengubah papan inital baik dengan hardcoding matriks lain atau menggunakan variabel editor. Tidak cantik, tapi berhasil
  • 20 karakter dapat disimpan jika output grafis dilewati, papan masih akan dicetak sebagai teks di setiap iterasi. Sel satu piksel yang berubah setiap milidetik juga tidak terlalu berguna
DenDenDo
sumber
bekerja di R2014a, baru diuji
masterX244
3

Perl, 218 216 211 202 byte

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

(Tidak ada baris baru di akhir kode ini.)

Membaca pola awal dari input standar, sebagai file teks di mana sel-sel hidup direpresentasikan sebagai 1, sel-sel mati direpresentasikan sebagai spasi, garis dipisahkan oleh baris baru. Input tidak boleh memiliki karakter selain ini. Garis bisa panjang variabel, dan akan diisi atau dipotong dengan lebar 79 persis. Input contoh adalah glider gun:

                                  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

Saat program menjalankan Game of Life, setiap negara dibuang ke output standar dalam format yang mirip dengan input, kemudian menunda 0,1 detik. Penundaan dapat disesuaikan dengan mengubah argumen keempat dari panggilan pilih.

Papan permainan memiliki kode keras untuk ukuran 79x23. Itu dibungkus dengan torus: jika Anda meninggalkan papan di bagian bawah, Anda berakhir di bagian atas; jika Anda pergi di sisi kanan, Anda berakhir di sisi kiri tetapi bergeser satu baris ke bawah.

Ini versi alternatif yang tidak membaca input apa pun dan mulai dari papan acak:

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

Kode ini berasal dari permainan program perl hidup yang saya buat bertahun-tahun yang lalu . Saya telah banyak mengubahnya untuk membuat papan toroidal dan kode golf.

Ini mungkin bukan metode terpendek untuk mengimplementasikan Game of Life di perl, tapi itu salah satu yang kurang dipahami.

Papan disimpan $bsebagai string '1'dan ' ', satu untuk setiap sel, hanya semuanya diulang setidaknya tiga kali. Panggilan membongkar ketiga mengekstrak 17 nilai untuk setiap sel: ada satu untuk sel itu sendiri dan dua untuk masing-masing dari delapan sel tetangga, dalam urutan acak, dan setiap nilai adalah '1'atau string kosong. Sel harus hidup dalam iterasi berikutnya jika jika jumlah '1'nilai di antara 17 nilai ini adalah 5, 6, atau 7. Panggilan paket ketiga menggabungkan nilai-nilai 17 ini ke bidang lebar 18 karakter kiri disejajarkan dan diisi dengan byte byte di sebelah kanan . Panggilan membongkar kedua mengambil bidang 18 lebar, mengirim karakter pada posisi 7, membongkar ruang dari posisi 17 jika itu'1', atau membongkar karakter dari posisi 4 sebaliknya. Hasil ini adalah persis nilai yang seharusnya dimiliki sel pada generasi berikutnya.

b_jonas
sumber
2

Python, 589 byte

Tombol mouse: kiri - pasang sel, kanan - hapus sel, mulai - tengah / berhenti.

dari impor Tkinter *
impor salinan
z = rentang
F = 50
T = Tk ()
S = 9
f = [F * [0] untuk saya in'7 '* F]
c = Kanvas (T, lebar = S * F, tinggi = S * F)
c.pack ()
def p (x, y, a): f [y] [x] = f [y] [x] atau c.create_oval (x * S, y * S, x * S + S, y * S + S) jika a lain c.delete (f [y] [x])
r = 1
def 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 ('<Tombol 2>', R)
def L ():
 T.after (99, L)
 jika r: kembali
 g = copy.deepcopy (f)
 untuk y in z (F):
	untuk x in z (F):
	 n = 8
	 untuk j in z (-1,2):
		untuk saya dalam z (-1,2):
		 jika i atau j: n- = bukan g [(y + j)% F] [(x + i)% F]
	 jika 1 <n <4:
		jika n == 3 dan bukan g [y] [x]: p (x, y, 1)
	 lain: p (x, y, 0)
L ()
T.mainloop ()

Dan di sini adalah versi di mana Anda dapat menarik mouse untuk menggambar. Grafik sedikit lebih menyenangkan.

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()
Oleh Prypin
sumber
Ini tidak mengikuti aturan main kehidupan dengan benar.
Steven Rumbalski
1
@StevenRumbalski: Oh benarkah?
Oleh Prypin
2
Benarkah. Anda memiliki kesalahan lekukan di versi kedua Anda. Bagian yang dimulai dengan if 1<n<4:harus indentasi pada tingkat yang sama denganfor j in z(-1,2):
Steven Rumbalski
2

Python 2, 456 byte

Meskipun saya tahu ini adalah posting lama, saya tidak dapat menahan diri untuk mencobanya. Papan awal dapat berukuran berapa saja asalkan Anda menggambar batas di sekitarnya dan memiliki ruang tambahan di baris terakhir.

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 (perhatikan ruang ekstra di baris terakhir)

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

Cara Menjalankan

python Golf.py < input.txt
Raffi
sumber
time.sleep(0.1)==None=> not time.sleep(.1), (f=='@'and(x==3 or x==2)) atau (f == '' dan x == 3) =>x==3or f=='@'and x==2
CalculatorFeline
^, Anda lupa satu, 1 if=> 1if.
Zacharý
2

Pengolahan 270.261 249 byte

Grid adalah 100 * 100 piksel layar, input datang dalam bentuk gambar 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();}

Tidak disatukan

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

tangkapan layar

PrincePolka
sumber
2

Lua + LÖVE / Love2D , 653 byte

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

atau ditempatkan:

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

Klik pada bidang untuk menambahkan sel hidup. Klik di luar bidang untuk menjalankannya.

Cobalah online!

masukkan deskripsi gambar di sini

Sheepolution
sumber
1

Nota bene 529 515

Dimulai dengan contoh dari Rosetta Code . Diminta dengan argumen nama file ( gs -- gol.ps pulsar), file yang berisi 20 * 20 angka biner (dipisahkan oleh spasi). Infinite loop: papan gambar, tunggu masuk, hitung generasi berikutnya.

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

Spasi, dengan beberapa tumpukan komentar (hanya yang saya butuhkan).

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

file data pulsar:

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
luser droog
sumber
1

JavaScript 676

Maaf Griffin, saya hanya tidak bisa melihat kode Anda dan tidak menulis ulang sedikit ... harus mencukur dua karakter tetapi itu sangat berharga!

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}

Tetapi seperti yang mereka katakan, lebih mudah untuk meminta pengampunan daripada izin ...;)

WallyWest
sumber
1

Oktaf (153)

sama seperti Matlab oleh DenDenDo di Game Terpendek Kehidupan , tetapi harus mengubah imshow ke imagesc:

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
Martin Novy
sumber
1

Python 2: 334 Bytes

Hanya terlambat 6 tahun.

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"

Anda dapat menjalankannya seperti:

python gol.py
0000000
0001000
0000100
0011100
0000000
0000000
0000000

Di mana 0s dan 1s mewakili sel-sel mati dan hidup, baris baru tambahan pada akhir memulai eksekusi.

Kisi-kisi harus persegi.

Lebih mudah dijalankan daripada python terpendek, mendukung ukuran grid apa pun, dan terlihat cantik saat dijalankan.

Ini juga 100 byte lebih, jadi begitulah.

Backerupper
sumber
0

PHP, 201 byte (tidak diuji)

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;

Jalankan dengan -nr.

kerusakan

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