Life2Print.Mod 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. MODULE Life2Print;
  2. (*This program saves screenshots of the Game of Life in PNG files.*)
  3. IMPORT G := Graph, Int, Str := Strings, Random;
  4. CONST maxW = 60*8; maxH = 33*8;
  5. cellSize = 2;
  6. initial = 0.2;
  7. TYPE
  8. Field = ARRAY maxH, maxW OF INTEGER;
  9. VAR
  10. S: G.Bitmap;
  11. W, H: INTEGER; (* Real width and height of field in cells *)
  12. m, m2: Field; (* m2 is a temporary copy of m *)
  13. x0, y0: INTEGER; (* Field offset on screen in pixels *)
  14. colors: ARRAY 9 OF INTEGER; (* Color constants: black, red etc. *)
  15. saved: ARRAY 3 OF INTEGER; (* Saved neighbour colors *)
  16. nofcolors: INTEGER; (* Number of saved neighbour colors *)
  17. fileno: INTEGER;
  18. PROCEDURE Print;
  19. VAR s: ARRAY 256 OF CHAR;
  20. BEGIN s := 'shot';
  21. Int.Append(fileno, s);
  22. Str.Append('.png', s);
  23. IF G.SavePng(S, s) THEN END;
  24. INC(fileno)
  25. END Print;
  26. PROCEDURE Save(y, x: INTEGER);
  27. BEGIN
  28. IF nofcolors < LEN(saved) THEN
  29. saved[nofcolors] := m2[y, x];
  30. INC(nofcolors)
  31. END
  32. END Save;
  33. PROCEDURE GetColor(): INTEGER;
  34. VAR c: INTEGER;
  35. BEGIN
  36. IF saved[0] = saved[1] THEN c := saved[0]
  37. ELSIF saved[0] = saved[2] THEN c := saved[0]
  38. ELSIF saved[1] = saved[2] THEN c := saved[1]
  39. ELSE c := saved[Random.Int(3)]
  40. END;
  41. RETURN c
  42. END GetColor;
  43. PROCEDURE Neighbours(x, y: INTEGER): INTEGER;
  44. VAR n: INTEGER;
  45. BEGIN
  46. n := 0;
  47. nofcolors := 0;
  48. IF y # 0 THEN
  49. IF m2[y - 1, x] # 0 THEN INC(n); Save(y - 1, x) END;
  50. IF (x # 0) & (m2[y - 1, x - 1] # 0) THEN INC(n); Save(y - 1, x - 1) END;
  51. IF (x # W - 1) & (m2[y - 1, x + 1] # 0) THEN INC(n); Save(y - 1, x + 1) END
  52. END;
  53. IF (x # 0) & (m2[y, x - 1] # 0) THEN INC(n); Save(y, x - 1) END;
  54. IF (x # W - 1) & (m2[y, x + 1] # 0) THEN INC(n); Save(y, x + 1) END;
  55. IF y # H - 1 THEN
  56. IF m2[y + 1, x] # 0 THEN INC(n); Save(y + 1, x) END;
  57. IF (x # 0) & (m2[y + 1, x - 1] # 0) THEN INC(n); Save(y + 1, x - 1) END;
  58. IF (x # W - 1) & (m2[y + 1, x + 1] # 0) THEN INC(n); Save(y + 1, x + 1) END
  59. END;
  60. RETURN n
  61. END Neighbours;
  62. PROCEDURE Live;
  63. VAR x, y, n, c: INTEGER;
  64. BEGIN
  65. m2 := m;
  66. FOR y := 0 TO H - 1 DO
  67. FOR x := 0 TO W - 1 DO
  68. n := Neighbours(x, y);
  69. IF n = 3 THEN
  70. m[y, x] := GetColor()
  71. ELSIF n # 2 THEN
  72. m[y, x] := 0
  73. END
  74. END
  75. END
  76. END Live;
  77. PROCEDURE DrawCell(x, y: INTEGER);
  78. VAR xx, yy, c: INTEGER;
  79. BEGIN
  80. xx := x0 + x * cellSize;
  81. yy := y0 + y * cellSize;
  82. c := colors[m[y, x]];
  83. G.RectFill(S, xx, yy, xx + cellSize - 1, yy + cellSize - 1, c)
  84. END DrawCell;
  85. PROCEDURE Draw;
  86. VAR x, y: INTEGER;
  87. BEGIN
  88. FOR y := 0 TO H - 1 DO
  89. FOR x := 0 TO W - 1 DO
  90. DrawCell(x, y)
  91. END
  92. END;
  93. G.Flip
  94. END Draw;
  95. PROCEDURE Run;
  96. BEGIN
  97. REPEAT
  98. Draw;
  99. Live;
  100. Print
  101. UNTIL G.KeyPressed()
  102. END Run;
  103. PROCEDURE Init;
  104. VAR x, y: INTEGER;
  105. BEGIN
  106. G.Settings(800, 300, {G.sharpPixels, G.spread(*, G.fullscreen*)});
  107. S := G.Init();
  108. W := S.w DIV cellSize;
  109. H := S.h DIV cellSize;
  110. IF W >= maxW THEN W := maxW - 1 END;
  111. IF H >= maxH THEN H := maxH - 1 END;
  112. colors[0] := G.MakeCol(10, 10, 10);
  113. colors[1] := G.MakeCol(240, 0, 0);
  114. colors[2] := G.MakeCol(230, 230, 230);
  115. colors[3] := G.MakeCol(0, 100, 255);
  116. colors[4] := G.MakeCol(0, 230, 0);
  117. colors[5] := G.MakeCol(255, 255, 0);
  118. colors[6] := G.MakeCol(230, 0, 230);
  119. colors[7] := G.MakeCol(150, 80, 0);
  120. colors[8] := G.MakeCol(255, 150, 0);
  121. fileno := 1;
  122. FOR y := 0 TO H - 1 DO
  123. FOR x := 0 TO W - 1 DO
  124. IF Random.Uniform() < initial THEN
  125. m[y, x] := Random.Int(8) + 1
  126. ELSE
  127. m[y, x] := 0
  128. END
  129. END
  130. END;
  131. x0 := (S.w - cellSize * W) DIV 2;
  132. y0 := (S.h - cellSize * H) DIV 2
  133. END Init;
  134. BEGIN
  135. Init;
  136. Run;
  137. G.Close
  138. END Life2Print.