PROCEDURE SplitPuzzle( outName: TEXT; startNum: CARDINAL; VAR M: PZImage.T; level: CARDINAL; )= CONST SmallImage = 10; (* Ignore pieces with this perimeter or less *) VAR n: CARDINAL := 0; cont: CARDINAL := startNum; newImage : REF PZImage.T; rimg: REF Pixels; BEGIN WITH NY = NUMBER(M), NX = NUMBER(M[0]) DO rimg := NEW(REF Pixels, (NX+NY) DIV 2); PROCEDURE FindNeighbourhood(x, y: CARDINAL) = (* Given a pixel with coordinates "(x,y)" inside some piece of the puzzle "M", finds all pixels that are connected to it (in the 4-neighbor topology). Those pixels are copied into the array "img" starting at index "n", and then set to zero. A pixel is assumed to be inside if its value is greater than "level". *) BEGIN IF n >= NUMBER(rimg^) THEN WITH nimg = NEW(REF Pixels, 2*n) DO SUBARRAY(nimg^,0,n) := SUBARRAY(rimg^,0,n); rimg := nimg; END; END; WITH point = rimg^[n] DO point.pos := IntPoint{x, y}; point.level := M[y,x]; END; n := n+1; M[y,x] := 0; IF y > 0 THEN IF (M[y-1,x] > level) THEN FindNeighbourhood(x, y-1) END END; IF x > 0 THEN IF (M[y,x-1] > level) THEN FindNeighbourhood(x-1, y) END; END; IF y < NY-1 THEN IF (M[y+1,x] > level) THEN FindNeighbourhood(x, y+1) END END; IF x < NX-1 THEN IF (M[y,x+1] > level) THEN FindNeighbourhood(x+1, y) END END; END FindNeighbourhood; BEGIN FOR y:=0 TO NY-1 DO FOR x:=0 TO NX-1 DO IF (M[y,x] > level) THEN n := 0; FindNeighbourhood(x, y); IF n > SmallImage THEN newImage := CreateImage(M, SUBARRAY(rimg^, 0, n)); SavePatchMatrix(outName, cont, newImage^); cont := cont+1; END END END END END END END SplitPuzzle;