Bài toán trò chơi đời sống game life
Trò chơi đời sốngTrần Thông Quế và Trần Văn LộCác kiểu dữ liệu trừu tượng có nhiều ứng dụng trong thực tế đó là Bảng (TABLE). Một trong các ứng dụng của bảng là Trò chơi đời sống (GAME LIFE). Đó là bài toán được nhà toán học Anh J.H Conway nêu ra vào năm 1970. Trước hết ta hãy làm quen với các khái niệm cơ bản của bài toán GAME LIFE. Về mặt toán học, ta coi đời sống của một quần thể sống diễn ra trên một bảng vuông (lưới ô vuông) không giới hạn. Mỗi ô vuông có thể tồn tại cơ thể sống hoặc không. Ô vuông có một cơ thể sống gọi là tế bào sống, ngược lại gọi là tế bào chết. Các tế bào thay đổi từ thế hệ này sang thế hệ sau tuỳ thuộc vào các tế bào sống ở lân cận. Mỗi tế bào có tám tế bào lân cận tiếp giáp với tế bào đã cho theo các cạnh và góc. Các tế bào thay đổi theo những quy luật sau: - Nếu số tế bào sống lân cận với tế bào cho trước mà không nhiều hơn 1 thì đến thế hệ sau nó sẽ chết (chết vì cô độc). - Nếu số tế bào sống lân cận với tế bào cho trước mà là 2 hoặc 3 thì tới thế hệ sau tế bào cho trước ấy vẫn sống. - Nếu số tế bào sống lân cận với tế bào cho trước mà nhiều từ 4 trở lên thì đến thế hệ sau nó sẽ chết (chết vì quá đông). - Nếu có đúng 3 tế bào sống lân cận với một tế bào chết thì ở thế hệ sau nó sẽ trở thành tế bào sống. Trong trường hợp còn lại, một tế bào chết thì vẫn còn chết ở thế hệ sau. - Trong mỗi thế hệ, sự sinh ra và chết đi diễn ra đồng thời và không ảnh hưởng tới nhau. Dưới đây là các ví dụ minh hoạ (ký tự x biểu thị tế bào sống): Để lập trình mô tả GAME LIFE ta có thể cài đặt các thế hệ của một cộng đồng nhờ một mảng hai chiều khá lớn (dùng PASCAL FREE). Ta quy ước 1 biểu diễn tế bào sống, 0 biểu diễn tế bào chết. Để xác định được sự thay đổi của các tế bào từ thế hệ này sang thế hệ khác, ta chỉ cần đếm số tế bào sống lân cận với tế bào đang xét và áp dụng các luật từ 1 đến 4 nêu trên. Trong chương trình dưới đây, chúng tôi biểu diễn tế bào sống bằng những ô tô màu đỏ, còn các tế bào chết là các ô trống (có màu nền). Chương trình này cũng tạo hai phương thức nhập liệu: một là nhập liệu từ bàn phím, hai là máy tính tự phát sinh ngẫu nhiên các quần thể các tế bào. Program Tro_Choi_Doi_Song; Uses crt,graph; Type table=array[0 49,0 48] of boolean; Var t,newt:table;c:char; {========================} Procedure Initgr; Var gd,gm:integer; Begin gd:=detect; initgraph(gd,gm,'C:BpBgí); if graphresult<>grok then begin write('Loi Do Hoa ! Go Enter Ket Thuc'); readln; halt(1) end End; {========================} Procedure Input_Table; Var i,j,n:integer; Begin textbackground(blue);clrscr; textcolor(white); for i:=0 to 49 do for j:=0 to 48 do t[i,j]:=false; writeln(' Ban Tu Nhap Du Lieu Hay De May Tinh Tu Tao(1/0)?'); Write(' (1 la tu nhap, 0 la may tinh tu tao du lieu):'); readln(i); if i=1 then begin n:=1; writeln(' Nhap Toa Do Cac Te Bao Song Cua Cong Dong (hang cot),'); writeln(' Dieu Kien : 1<=hang<=47, 1<=cot<=48), Ket Thuc Go : 0 0'); repeat repeat write(' Toa Do Te Bao Song Thu ',n,' : '); readln(i,j) until (0<=i) and (49>i) and (0<=j) and (48>j); if (i>0) and (j>0) then begin t[i,j]:=true;inc(n) end; until (i=0) and (j=0); end else begin n:=100+random(500); for i:=1 to n do t[1+random(48),1+random(47)]:=true end; End; {========================} Function Number(i,j:integer):integer; Var n,k:integer; Begin n:=0; for k:=i-1 to i+1 do begin if t[k,j-1] then inc(n); if t[k,j+1] then inc(n) end; if t[i-1,j] then inc(n); if t[i+1,j] then inc(n); Number:=n End; {========================} Procedure New_Table; Var i,j:integer; Begin for i:=1 to 48 do for j:=1 to 47 do case number(i,j) of 0,1:newt[i,j]:=false; 2 :newt[i,j]:=t[i,j]; 3 :newt[i,j]:=true else newt[i,j]:=false; end; for i:=1 to 48 do for j:=1 to 47 do t[i,j]:=newt[i,j]; End; {========================} Procedure Draw_T; var i:integer; Begin setcolor(lightgray); Setbkcolor(blue); rectangle(0,0,480,470); for i:=1 to 47 do line(i*10,1,i*10,469); for i:=1 to 46 do line(1,i*10,479,i*10); settextstyle(0,0,2); setcolor(red); outtextxy(485,30,'Life Gamé); settextstyle(0,0,1); setcolor(white); outtextxy(485,90,'Hit Anykey to Go on'); outtextxy(495,150,'Enter to Restart'); outtextxy(510,210,'Esc to Stop'); End; {========================} Procedure Draw_cell(i,j:integer); Begin if t[i,j] then begin setfillstyle(1,red); bar((i-1)*10+1,(j-1)*10+1,i*10-1,j*10-1); end else begin setfillstyle(1,blue); bar((i-1)*10+1,(j-1)*10+1,i*10-1,j*10-1); end; End; {========================} Procedure Draw_Table; Var i,j:integer; Begin for i:=1 to 48 do for j:=1 to 47 do Draw_Cell(i,j); End; {========================} Procedure Life_Table; Begin while keypressed do c:=readkey; repeat Draw_Table; New_Table; c:=readkey; until (c=#27) or (c=#13); End; {========================} BEGIN Randomize; Initgr; Repeat Restorecrtmode; Input_Table; Setgraphmode(getgraphmode); Draw_T; Life_Table; Until c=#27; Closegraph; END. . Bảng (TABLE). Một trong các ứng dụng của bảng là Trò chơi đời sống (GAME LIFE) . Đó là bài toán được nhà toán học Anh J.H Conway nêu ra vào năm 1970. Trước. hãy làm quen với các khái niệm cơ bản của bài toán GAME LIFE. Về mặt toán học, ta coi đời sống của một quần thể sống diễn ra trên một bảng vuông (lưới ô