Life.Mod 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. MODULE Life;
  2. IMPORT G := Graph;
  3. CONST maxW = 60*4; maxH = 33*4;
  4. cellSize = 4;
  5. initial = 0.44;
  6. TYPE
  7. Field = ARRAY maxH, maxW OF BOOLEAN;
  8. VAR
  9. S: G.Bitmap;
  10. W, H: INTEGER; (* Real width and height of field in cells *)
  11. m, m2: Field; (* m2 is a temporary copy of m *)
  12. x0, y0: INTEGER; (* Field offset on screen in pixels *)
  13. red, black, white: INTEGER; (* Color constants: black, red etc. *)
  14. PROCEDURE Neighbours(x, y: INTEGER): INTEGER;
  15. VAR n: INTEGER;
  16. BEGIN
  17. n := 0;
  18. IF y # 0 THEN
  19. IF m2[y - 1, x] THEN INC(n) END;
  20. IF (x # 0) & m2[y - 1, x - 1] THEN INC(n) END;
  21. IF (x # W - 1) & m2[y - 1, x + 1] THEN INC(n) END;
  22. END;
  23. IF (x # 0) & m2[y, x - 1] THEN INC(n) END;
  24. IF (x # W - 1) & m2[y, x + 1] THEN INC(n) END;
  25. IF y # H - 1 THEN
  26. IF m2[y + 1, x] THEN INC(n) END;
  27. IF (x # 0) & m2[y + 1, x - 1] THEN INC(n) END;
  28. IF (x # W - 1) & m2[y + 1, x + 1] THEN INC(n) END;
  29. END;
  30. RETURN n
  31. END Neighbours;
  32. PROCEDURE Live;
  33. VAR x, y, n: INTEGER;
  34. BEGIN
  35. m2 := m;
  36. FOR y := 0 TO H - 1 DO
  37. FOR x := 0 TO W - 1 DO
  38. n := Neighbours(x, y);
  39. IF n = 3 THEN
  40. m[y, x] := TRUE
  41. ELSIF n # 2 THEN
  42. m[y, x] := FALSE
  43. END
  44. END
  45. END
  46. END Live;
  47. PROCEDURE DrawCell(x, y: INTEGER);
  48. VAR xx, yy, c: INTEGER;
  49. BEGIN
  50. xx := x0 + x * cellSize;
  51. yy := y0 + y * cellSize;
  52. IF m[y, x] THEN c := red ELSE c := black END;
  53. G.RectFill(S, xx, yy, xx + cellSize - 1, yy + cellSize - 1, c)
  54. END DrawCell;
  55. PROCEDURE Draw;
  56. VAR x, y: INTEGER;
  57. BEGIN
  58. FOR y := 0 TO H - 1 DO
  59. FOR x := 0 TO W - 1 DO
  60. DrawCell(x, y)
  61. END
  62. END;
  63. G.Flip
  64. END Draw;
  65. PROCEDURE Run;
  66. BEGIN
  67. REPEAT
  68. Draw;
  69. Live
  70. UNTIL G.KeyPressed()
  71. END Run;
  72. PROCEDURE Init;
  73. VAR x, y: INTEGER;
  74. BEGIN
  75. G.Settings(640, 480, {G.sharpPixels, G.spread, G.fullscreen});
  76. S := G.Init();
  77. W := S.w DIV cellSize;
  78. H := S.h DIV cellSize;
  79. IF W >= maxW THEN W := maxW - 1 END;
  80. IF H >= maxH THEN H := maxH - 1 END;
  81. red := G.MakeCol(240, 0, 0);
  82. black := G.MakeCol(10, 10, 10);
  83. white := G.MakeCol(230, 230, 230);
  84. FOR y := 0 TO H - 1 DO
  85. FOR x := 0 TO W - 1 DO
  86. m[y, x] := G.Uniform() < initial
  87. END
  88. END;
  89. x0 := (S.w - cellSize * W) DIV 2;
  90. y0 := (S.h - cellSize * H) DIV 2
  91. END Init;
  92. BEGIN
  93. Init;
  94. Run;
  95. G.Close
  96. END Life.