Life.Mod 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. MODULE Life;
  2. IMPORT G := Graph, Random;
  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. sw, sh: INTEGER; (* Screen size in pixels *)
  10. W, H: INTEGER; (* Actual 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: G.Color;
  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: INTEGER;
  49. c: G.Color;
  50. BEGIN
  51. xx := x0 + x * cellSize;
  52. yy := y0 + y * cellSize;
  53. IF m[y, x] THEN c := red ELSE c := black END;
  54. G.FillRect(xx, yy, xx + cellSize - 1, yy + cellSize - 1, c)
  55. END DrawCell;
  56. PROCEDURE Draw;
  57. VAR x, y: INTEGER;
  58. BEGIN
  59. FOR y := 0 TO H - 1 DO
  60. FOR x := 0 TO W - 1 DO
  61. DrawCell(x, y)
  62. END
  63. END;
  64. G.Flip
  65. END Draw;
  66. PROCEDURE Run;
  67. BEGIN
  68. REPEAT
  69. Draw;
  70. Live
  71. UNTIL G.KeyPressed()
  72. END Run;
  73. PROCEDURE Init;
  74. VAR x, y: INTEGER;
  75. BEGIN
  76. G.Settings(640, 480, {});
  77. G.Init;
  78. G.GetScreenSize(sw, sh);
  79. W := sw DIV cellSize;
  80. H := sh DIV cellSize;
  81. IF W >= maxW THEN W := maxW - 1 END;
  82. IF H >= maxH THEN H := maxH - 1 END;
  83. G.MakeCol(red, 240, 0, 0);
  84. G.MakeCol(black, 10, 10, 10);
  85. G.MakeCol(white, 230, 230, 230);
  86. FOR y := 0 TO H - 1 DO
  87. FOR x := 0 TO W - 1 DO
  88. m[y, x] := Random.Uniform() < initial
  89. END
  90. END;
  91. x0 := (sw - cellSize * W) DIV 2;
  92. y0 := (sh - cellSize * H) DIV 2
  93. END Init;
  94. BEGIN
  95. Init;
  96. Run;
  97. G.Close
  98. END Life.