corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /*Taken from http://try.kotlinlang.org/#/Examples/Longer%20examples/Life/Life.kt*/
2 /**
3 * This is a straightforward implementation of The Game of Life
4 * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life
5 */
6 package life
7  
8 /*
9 * A field where cells live. Effectively immutable
10 */
11 class Field(
12 val width: Int,
13 val height: Int,
14 // This function tells the constructor which cells are alive
15 // if init(i, j) is true, the cell (i, j) is alive
16 init: (Int, Int) -> Boolean
17 ) {
18 private val live: Array<Array<Boolean>> = Array(height) { i -> Array(width) { j -> init(i, j) } }
19  
20 private fun liveCount(i: Int, j: Int)
21 = if (i in 0..height - 1 &&
22 j in 0..width - 1 &&
23 live[i][j]) 1 else 0
24  
25 // How many neighbors of (i, j) are alive?
26 fun liveNeighbors(i: Int, j: Int) =
27 liveCount(i - 1, j - 1) +
28 liveCount(i - 1, j) +
29 liveCount(i - 1, j + 1) +
30 liveCount(i, j - 1) +
31 liveCount(i, j + 1) +
32 liveCount(i + 1, j - 1) +
33 liveCount(i + 1, j) +
34 liveCount(i + 1, j + 1)
35  
36 // You can say field[i, j], and this function gets called
37 operator fun get(i: Int, j: Int) = live[i][j]
38 }
39  
40 /**
41 * This function takes the present state of the field
42 * and returns a new field representing the next moment of time
43 */
44 fun next(field: Field): Field {
45 return Field(field.width, field.height) { i, j ->
46 val n = field.liveNeighbors(i, j)
47 if (field[i, j])
48 // (i, j) is alive
49 n in 2..3 // It remains alive iff it has 2 or 3 neighbors
50 else
51 // (i, j) is dead
52 n == 3 // A new cell is born if there are 3 neighbors alive
53 }
54 }
55  
56 /** A few colony examples here */
57 fun main(args: Array<String>) {
58 // Simplistic demo
59 runGameOfLife("***", 3)
60 // "Star burst"
61 runGameOfLife("""
62 _______
63 ___*___
64 __***__
65 ___*___
66 _______
67 """, 10)
68 // Stable colony
69 runGameOfLife("""
70 _____
71 __*__
72 _*_*_
73 __*__
74 _____
75 """, 3)
76 // Stable from the step 2
77 runGameOfLife("""
78 __**__
79 __**__
80 __**__
81 """, 3)
82 // Oscillating colony
83 runGameOfLife("""
84 __**____
85 __**____
86 ____**__
87 ____**__
88 """, 6)
89 // A fancier oscillating colony
90 runGameOfLife("""
91 -------------------
92 -------***---***---
93 -------------------
94 -----*----*-*----*-
95 -----*----*-*----*-
96 -----*----*-*----*-
97 -------***---***---
98 -------------------
99 -------***---***---
100 -----*----*-*----*-
101 -----*----*-*----*-
102 -----*----*-*----*-
103 -------------------
104 -------***---***---
105 -------------------
106 """, 10)
107 }
108  
109 // UTILITIES
110  
111 fun runGameOfLife(fieldText: String, steps: Int) {
112 var field = makeField(fieldText)
113 for (step in 1..steps) {
114 println("Step: $step")
115 for (i in 0..field.height - 1) {
116 for (j in 0..field.width - 1) {
117 print(if (field[i, j]) "*" else " ")
118 }
119 println("")
120 }
121 field = next(field)
122 }
123 }
124  
125 fun makeField(s: String): Field {
126 val lines = s.replace(" ", "").split('\n').filter({ it.isNotEmpty() })
127 val longestLine = lines.toList().maxBy { it.length } ?: ""
128  
129 return Field(longestLine.length, lines.size) { i, j -> lines[i][j] == '*' }
130 }