Thuật toán xây dựng mê cung

5 767 7
Thuật toán xây dựng mê cung

Đang tải... (xem toàn văn)

Thông tin tài liệu

VIETBOOK Thuật toán xây dựng mê cung Trong thần thoại Hi Lạp, có quỷ Minôto dữ, hang sâu Đờng vào hang mê cung, có can đảm vào diệt quỷ không dễ lần đợc vào hang quỷ mà bị lạc, không tìm đợc lối Ngời anh hùng Têzê liều vào hang quỷ Để giúp anh, nàng Arian đa cho Têzê cuộn nàng cầm đầu mối Khi vào mê lộ Têzê kéo dần cuộn chỉ, đến lúc quay cần lại để lần theo mà khỏi mê cung Chuyện thần thoại nh vậy, mê cung hấp dẫn nhiều nhà kiến trúc, hoạ sĩ, thi sĩ hàng chục kỉ qua Các nhà toán học ý đến mê cung mang nhiều ý nghĩa sâu sắc liên quan đến nhiều ngành toán học đại Ngay sống thờng ngày, thờng gặp mê cung toán đố vui "Tìm đờng mê cung" Trong báo xin giới thiệu với bạn thuật toán xây dựng mê cung kích thớc tuỳ ý Ta xem tất đờng mê cung tập hợp ô đợc nối với Ban đầu tất ô không đợc nối xung quanh tất ô có tờng Lấy tờng kiểm tra xem ô bên tờng có đợc nối đờng hay không Nếu nh vậy, thử tờng khác Nếu không phá tờng kết hợp hai tập hợp đờng với Hình: Một mê cung kích thớc 20x20 Ta dùng mảng hai chiều để lu lại mê cung xây dựng đợc Mỗi thành phần mảng chứa giá trị 1, or 2, biểu thị ô có tờng dọc, biểu thị ô có tờng ngang Ta sử dụng hai cấu trúc sau để thể tập hợp đờng tập hợp tờng PMazeCell = ^MazeCell; MazeCell = record (* Trỏ tới đầu danh sách tất ô tới đợc từ ô Dễ dàng nhận biết để so sánh *) mset:PMazeCell; (* Trỏ tới ô tập hợp ô nối với *) next:PMazeCell; end; PMazeWall=^MazeWall; MazeWall = record (* Có tờng hay không, tờng ngang hay dọc *) wall:byte; (* Toạ độ tờng *) x,y:integer; end; Thuật toán xây dựng mê cung: Khởi tạo: Gọi walls cells hai biến trỏ đến mảng tờng ô Dễ thấy số ô width*height, số tờng tối đa (width-1)*height+(height-1)*width (không kể tờng nằm cạnh mê cung) Ta gọi hàm GetMem để cấp phát nhớ cho hai trỏ Xây tất tờng lúc hai ô đến Với tất ô, khởi tạo trờng mset trỏ tới nó, trờng next đặt nil (tập hợp đờng gồm ô) Đổi chỗ ngẫu nhiên mảng tờng: Ban đầu mảng tờng đợc xếp theo thứ tự: tờng dọc, sau đến tờng ngang theo thứ tự tăng dần toạ độ x y Ta lần lợt chọn cặp tờng đổi chỗ chúng cho để đợc mảng tờng ngẫu nhiên Xoá tờng để nhập ô vào với nhau: Bây ta có danh sách ngẫu nhiên tờng Ta duyệt lại danh sách tờng Với tờng, ta chọn ô có toạ độ toạ độ tờng Xem xét ô phía bên tờng liệu hai ô có đợc nối với đờng hay không Điều kiểm tra lệnh if nh sau: if ca^.mset = cb^.mset then Nếu chúng cha đợc nối ta phá tờng (đặt trờng wall = ) nối chúng lại thủ tục Trang VIETBOOK ConnectSets: procedure ConnectSets(mset,add:PMazeCell); begin (* Chuyển đến cuối danh sách *) while mset^.nextnil mset:=mset^.next; (* Trỏ đến đầu danh sách *) add:=add^.mset; (* Gắn vào ô *) mset^.next:=add; (* Thay đổi tính đồng ô *) while add nil begin add^.mset:=mset^.mset; add:=add^.next; end; end; Ghi kết quả: Công việc lại ghi kết mảng output Trớc hết ta đặt tất tờng cạnh mê cung Và sau chép tờng từ mảng tờng vào mảng output Trên thuật toán để tạo mê cung, mong nhận đợc góp ý bạn Nguyễn Minh Thắng 11A Tin Đại Học Khoa Học Tự Nhiên, Hà Nội uses crt,graph; type PMazeCell = ^MazeCell; MazeCell = record mset,next:PMazeCell; end; PMazeWall=^MazeWall; MazeWall = record wall:byte; x,y:integer; end; const Vert=1; Horiz=2; var maze:array[0 100,0 100] of byte; gd,gm,w,h:integer; procedure ConnectSets(mset,add:PMazeCell); begin while mset^.nextnil mset:=mset^.next; add:=add^.mset; mset^.next:=add; while add nil begin add^.mset:=mset^.mset; add:=add^.next; end; end; procedure GenerateMaze(width,height:integer); Trang VIETBOOK var cells:PMazeCell; walls:PMazeWall; ncells,nwalls:integer; i,x,y:integer; ca,cb:PMazeCell; w,temp:PMazeWall; wt:MazeWall; function CellAt(x,y:integer):pointer; begin CellAt:=pointer(longint(cells)+(x+y*width)*sizeof(MazeCell)); end; begin randomize; ncells:=width*height; GetMem(cells,sizeof(MazeCell)*ncells); nwalls:=(width-1)*height+(height-1)*width; GetMem(walls,sizeof(MazeWall)*nwalls); ca:=cells; for i:=1 to ncells begin ca^.mset:=ca; ca^.next:=nil; ca:=pointer(longint(ca)+sizeof(MazeCell)); end; w:=walls; for x:=1 to width-1 for y:=0 to height-1 begin w^.wall:=Vert; w^.x:=x; w^.y:=y; w:=pointer(longint(w)+sizeof(mazewall)); end; for y:=1 to height-1 for x:=0 to width-1 begin w^.wall:=Horiz; w^.x:=x; w^.y:=y; w:=pointer(longint(w)+sizeof(MazeWall)); end; for i:=nwalls-1 downto begin w:=pointer(longint(walls)+random(i)*sizeof(MazeWall)); wt:=w^; temp:=pointer(longint(walls)+i*sizeof(MazeWall)); w^:=temp^; temp^:=wt; end; w:=walls; for i:=0 to nwalls-1 begin Trang VIETBOOK ca:=CellAt(w^.x,w^.y); if w^.wall=Horiz then cb:=CellAt(w^.x,w^.y-1) else cb:=CellAt(w^.x-1,w^.y); if ca^.mset cb^.mset then begin ConnectSets(ca,cb); w^.wall:=0; end; w:=pointer(longint(w)+sizeof(mazewall)) end; FillChar(maze,SizeOf(maze),0); for x:=0 to width-1 begin maze[x,0]:=Horiz; maze[x,height]:=Horiz; end; for y:=0 to height-1 begin maze[0,y]:=Vert; maze[width,y]:=Vert; end; w:=walls; for i:=0 to nwalls-1 begin maze[w^.x,w^.y]:=maze[w^.x,w^.y] or w^.wall; w:=pointer(longint(w)+sizeof(mazewall)) end; FreeMem(cells,sizeof(MazeCell)*ncells); FreeMem(walls,sizeof(MazeWall)*nwalls); end; procedure TestMaze; var i,j:integer; ch:char; begin clrscr; Writeln('Hay nhap vao kich thuoc me cung'); Write('Rong ( ... việc lại ghi kết mảng output Trớc hết ta đặt tất tờng cạnh mê cung Và sau chép tờng từ mảng tờng vào mảng output Trên thuật toán để tạo mê cung, mong nhận đợc góp ý bạn Nguyễn Minh Thắng 11A Tin... procedure TestMaze; var i,j:integer; ch:char; begin clrscr; Writeln('Hay nhap vao kich thuoc me cung' ); Write('Rong (

Ngày đăng: 08/12/2015, 01:26

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan