2
0

Life2.Mod 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. MODULE Life2;
  2. IMPORT G := Graph, Random;
  3. CONST maxW = 180; maxH = 100;
  4. cellSize = 5;
  5. initial = 0.2;
  6. TYPE
  7. Field = ARRAY maxH, maxW OF INTEGER;
  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. colors: ARRAY 9 OF G.Color; (* Color constants: black, red etc. *)
  14. saved: ARRAY 3 OF INTEGER; (* Saved neighbour colors *)
  15. nofcolors: INTEGER; (* Number of saved neighbour colors *)
  16. PROCEDURE Save(y, x: INTEGER);
  17. BEGIN
  18. IF nofcolors < LEN(saved) THEN
  19. saved[nofcolors] := m2[y, x];
  20. INC(nofcolors)
  21. END
  22. END Save;
  23. PROCEDURE GetColor(): INTEGER;
  24. VAR c: INTEGER;
  25. BEGIN
  26. IF saved[0] = saved[1] THEN c := saved[0]
  27. ELSIF saved[0] = saved[2] THEN c := saved[0]
  28. ELSIF saved[1] = saved[2] THEN c := saved[1]
  29. ELSE c := saved[Random.Int(3)]
  30. END;
  31. RETURN c
  32. END GetColor;
  33. PROCEDURE Neighbours(x, y: INTEGER): INTEGER;
  34. VAR n: INTEGER;
  35. BEGIN
  36. n := 0;
  37. nofcolors := 0;
  38. IF y # 0 THEN
  39. IF m2[y - 1, x] # 0 THEN INC(n); Save(y - 1, x) END;
  40. IF (x # 0) & (m2[y - 1, x - 1] # 0) THEN INC(n); Save(y - 1, x - 1) END;
  41. IF (x # W - 1) & (m2[y - 1, x + 1] # 0) THEN INC(n); Save(y - 1, x + 1) END
  42. END;
  43. IF (x # 0) & (m2[y, x - 1] # 0) THEN INC(n); Save(y, x - 1) END;
  44. IF (x # W - 1) & (m2[y, x + 1] # 0) THEN INC(n); Save(y, x + 1) END;
  45. IF y # H - 1 THEN
  46. IF m2[y + 1, x] # 0 THEN INC(n); Save(y + 1, x) END;
  47. IF (x # 0) & (m2[y + 1, x - 1] # 0) THEN INC(n); Save(y + 1, x - 1) END;
  48. IF (x # W - 1) & (m2[y + 1, x + 1] # 0) THEN INC(n); Save(y + 1, x + 1) END
  49. END;
  50. RETURN n
  51. END Neighbours;
  52. PROCEDURE Live;
  53. VAR x, y, n, c: INTEGER;
  54. BEGIN
  55. m2 := m;
  56. FOR y := 0 TO H - 1 DO
  57. FOR x := 0 TO W - 1 DO
  58. n := Neighbours(x, y);
  59. IF n = 3 THEN
  60. m[y, x] := GetColor()
  61. ELSIF n # 2 THEN
  62. m[y, x] := 0
  63. END
  64. END
  65. END
  66. END Live;
  67. PROCEDURE DrawCell(x, y: INTEGER);
  68. VAR xx, yy: INTEGER; c: G.Color;
  69. BEGIN
  70. xx := x0 + x * cellSize;
  71. yy := y0 + y * cellSize;
  72. c := colors[m[y, x]];
  73. G.FillRect(xx, yy, xx + cellSize - 1, yy + cellSize - 1, c)
  74. END DrawCell;
  75. PROCEDURE Draw;
  76. VAR x, y: INTEGER;
  77. BEGIN
  78. FOR y := 0 TO H - 1 DO
  79. FOR x := 0 TO W - 1 DO
  80. DrawCell(x, y)
  81. END
  82. END;
  83. G.Flip;
  84. G.Delay(20)
  85. END Draw;
  86. PROCEDURE Run;
  87. BEGIN
  88. REPEAT
  89. Draw;
  90. Live
  91. UNTIL G.KeyPressed()
  92. END Run;
  93. PROCEDURE Init;
  94. VAR x, y: INTEGER;
  95. BEGIN
  96. G.Settings(640, 400, {});
  97. G.Init();
  98. G.GetScreenSize(SW, SH);
  99. W := SW DIV cellSize;
  100. H := SH DIV cellSize;
  101. IF W >= maxW THEN W := maxW - 1 END;
  102. IF H >= maxH THEN H := maxH - 1 END;
  103. G.MakeCol(colors[0], 10, 10, 10);
  104. G.MakeCol(colors[1], 240, 0, 0);
  105. G.MakeCol(colors[2], 230, 230, 230);
  106. G.MakeCol(colors[3], 0, 100, 255);
  107. G.MakeCol(colors[4], 0, 230, 0);
  108. G.MakeCol(colors[5], 255, 255, 0);
  109. G.MakeCol(colors[6], 230, 0, 230);
  110. G.MakeCol(colors[7], 150, 80, 0);
  111. G.MakeCol(colors[8], 255, 150, 0);
  112. FOR y := 0 TO H - 1 DO
  113. FOR x := 0 TO W - 1 DO
  114. IF Random.Uniform() < initial THEN
  115. m[y, x] := Random.Int(8) + 1
  116. ELSE
  117. m[y, x] := 0
  118. END
  119. END
  120. END;
  121. x0 := (SW - cellSize * W) DIV 2;
  122. y0 := (SH - cellSize * H) DIV 2
  123. END Init;
  124. BEGIN
  125. Init;
  126. Run;
  127. G.Close
  128. END Life2.