Runtime files update
[MacVim.git] / runtime / macros / life / life.vim
blob552a49301abd4adee1a03bdd39ea3100c3a56c61
1 " Macros to play Conway's Game of Life in vi
2 " Version 1.0m: edges wrap
3 " by Eli-the-Bearded Benjamin Elijah Griffin <vim@eli.users.panix.com>
4 " Sept 1996
5 " This file may be free distributed so long as these credits remain unchanged.
7 " Modified by Bram Moolenaar (Bram@vim.org), 1996 Sept 10
8 " - Made it quite a bit faster, but now needs search patterns in the text
9 " - Changed the order of mappings to top-down.
10 " - Made "g" run the whole thing, "C" run one generation.
11 " - Added support for any uppercase character instead of 'X'
13 " Rules:
14 "   If a germ has 0 or 1 live neighbors it dies of loneliness
15 "   If a germ has 2 or 3 live neighbors it survives
16 "   If a germ has 4 to 8 live neighbors it dies of starvation
17 "   If an empty box has 3 live neighbors a new germ is born
19 "   A new born germ is an "A".  Every generation it gets older: B, C, etc.
20 "   A germ dies of old age when it reaches "Z".
22 " Notice the rules do not mention edges. This version has the edges wrap
23 " around. I have an earlier version that offers the option of live edges or
24 " dead edges. Email me if you are interested. -Eli-
26 " Note: This is slow!  One generation may take up to ten minutes (depends on
27 " your computer and the vi version).
29 " Quite a lot of the messy stuff is to work around the vi error "Can't yank
30 " inside global/macro".  Still doesn't work for all versions of vi.
32 " To use these macros:
34 " vi            start vi/vim
36 " :so life.mac  Source this file
38 " g             'g'o!  runs everything until interrupted: "IR".
40 " I             Initialize everything. A board will be drawn at the end
41 "               of the current buffer. All line references in these macros
42 "               are relative to the end of the file and playing the game
43 "               can be done safely with any file as the current buffer.
45 "       Change the left field with spaces and uppercase letters to suit
46 "       your taste.
48 " C             'C'ompute one generation.
49 " +             idem, time running one generation.
50 " R             'R'un 'C'ompute until interrupted.
51 " i<nr><Esc>z   Make a number the only thing on the current line and use
52 "               'z' to time that many generations.
54 " Time to run 30 generations on my 233 AMD K6 (FreeBSD 3.0):
55 "   vim   5.4 xterm     51 sec
56 "   gvim  5.4 Athena    42 sec
57 "   gvim  5.4 Motif     42 sec
58 "   gvim  5.4 GTK       50 sec
59 "   nvi   1.79 xterm    58 sec
60 "   vi    3.7 xterm     2 min 30 sec
61 "   Elvis 2.1 xterm     7 min 50 sec
62 "   Elvis 2.1 X11       6 min 31 sec
64 " Time to run 30 generations on my 850 AMD Duron (FreeBSD 4.2):
65 "   vim   5.8   xterm    21 sec
66 "   vim   6.0   xterm    24 sec
67 "   vim   6.0   Motif    32 sec
68 "   nvi   1.79  xterm    29 sec
69 "   vi    3.7   xterm    32 sec
70 "   elvis 2.1.4 xterm    34 sec
72 " And now the macros, more or less in top-down order.
74 "  ----- macros that can be used by the human -----
76 " 'g'o: 'I'nitialize and then 'R'un 'C'ompute recursively (used by the human)
77 map g IR
80 " 'R'un 'C'ompute recursively (used by the human and 'g'o)
81 map R CV
82 " work around "tail recursion" problem in vi, "V" == "R".
83 map V R
86 " 'I'nitialize the board (used by the human and 'g'o)
87 map I G)0)0)0)0)1)0)0)2)0)0)0)0,ok,-11k,-,R,IIN
90 " 'C'ompute next generation (used by the human and others)
91 map C T>>>>>>>>B&
94 " Time running one generation (used by the human)
95 map + <1C<2
98 " Time running N generations, where N is the number on the current line.
99 " (used by the human)
100 map z ,^,&,*,&<1,*<2
102 "  ----- END of macros that can be used by the human -----
104 "  ----- Initialisation -----
106 map ,- :s/./-/g\r
107 map ,o oPut 'X's in the left box, then hit 'C' or 'R'\e
108 map ,R 03stop\e
110 " Write a new line (used by 'I'nitialize board)
111 map )0 o-                    --....................--....................-\e
112 map )1 o-        VIM         --....................--....................-\e
113 map )2 o-       LIVES        --....................--....................-\e
116 " Initialisation of the pattern/command to execute for working out a square.
117 " Pattern is: "#<germ><count>"
118 " where <germ>   is " " if the current germ is dead, "X" when living.
119 "       <count>  is the number of living neighbours (including current germ)
120 "                expressed in X's
122 map ,Il8 O#XXXXXXXXXX .`a22lr \e
123 map ,Id8 o# XXXXXXXX .`a22lr \e
124 map ,Il7 o#XXXXXXXXX .`a22lr \e
125 map ,Id7 o# XXXXXXX .`a22lr \e
126 map ,Il6 o#XXXXXXXX .`a22lr \e
127 map ,Id6 o# XXXXXX .`a22lr \e
128 map ,Il5 o#XXXXXXX .`a22lr \e
129 map ,Id5 o# XXXXX .`a22lr \e
130 map ,Il4 o#XXXXXX .`a22lr \e
131 map ,Id4 o# XXXX .`a22lr \e
132 map ,Il3 o#XXXXX .,a\e
133 map ,Id3 o# XXX .`a22lrA\e
134 map ,Il2 o#XXXX .,a\e
135 map ,Id2 o# XX .`a22lr \e
136 map ,Il1 o#XXX .`a22lr \e
137 map ,Id1 o# X .`a22lr \e
138 map ,Il0 o#XX .`a22lr \e
139 map ,Id0 o#  .`a22lr \e
141 " Patterns used to replace a germ with it's next generation
142 map ,Iaa o=AB =BC =CD =DE =EF =FG =GH =HI =IJ =JK =KL =LM =MN =NO =OP =PQ =QR\e
143 map ,Iab o=RS =ST =TU =UV =VW =WX =XY =YZ =Z \e
145 " Insert the searched patterns above the board
146 map ,IIN G?^top\r,Il8,Id8,Il7,Id7,Il6,Id6,Il5,Id5,Il4,Id4,Il3,Id3,Il2,Id2,Il1,Id1,Il0,Id0,Iaa,Iab
148 "  ----- END of Initialisation -----
150 "  ----- Work out one line -----
152 " Work out 'T'op line (used by show next)
153 map T G,c2k,!9k,@,#j>2k,$j
155 " Work out 'B'ottom line (used by show next)
156 map B ,%k>,$
158 " Work out a line (used by show next, work out top and bottom lines)
159 map > 0 LWWWWWWWWWWWWWWWWWW,rj
161 " Refresh board (used by show next)
162 map & :%s/^\(-[ A-Z]*-\)\(-[ A-Z]*-\)\(-[.]*-\)$/\2\3\3/\r
165 " Work around vi multiple yank/put in a single macro limitation
166 " (used by work out top and/or bottom line)
167 map ,$ dd
168 map ,% "cp
169 map ,! "byy
170 map ,@ "cyy
171 map ,# "bP
172 map ,c c$\e
174 "  ----- END of Work out one line -----
176 "  ----- Work out one square -----
178 " The next three work out a square: put all nine chars around the current
179 " character on the bottom line (the bottom line must be empty when starting).
181 " 'W'ork out a center square (used by work out line)
182 map W makh,3`ah,3`ajh,3(
185 " Work out a 'L'eft square (used by work out line)
186 map L makf-h,1`ak,2`af-h,1`a,2`ajf-h,1`aj,2(
189 " Work out a 'R'ight square (used by work out line)
190 map ,r makh,2`akF-l,1`ah,2`aF-l,1`ajh,2`ajF-l,1(
192 " 'M'ove a character to the end of the file (used by all work out square
193 " macros)
195 map ,1 y G$p
196 map ,2 2y G$p
197 map ,3 3y G$p
200 "  ----- END of Work out one square -----
202 "  ----- Work out one germ -----
204 " Generate an edit command that depends on the number of living in the last
205 " line, and then run the edit command. (used by work out square).
206 " Leaves the cursor on the next character to be processed.
208 map ( ,s,i,X0i?^#\e\x16\x16\r\e0,df.l,Y21h
210 " Delete 's'paces (deads);
211 " The number of remaining characters is the number of living neighbours.
212 map ,s :.g/ /s///g\x16\r
214 " Insert current character in the last line
215 map ,i `ay GP
217 " Replace any uppercase letter with 'X';
218 map ,X :.g/[A-Z]/s//X/g\x16\r
220 " Delete and execute the rest of the line
221 map ,d "qd$@q
223 " Yank and execute the rest of the line
224 map ,Y "qy$@q
226 " Yank the character under the cursor
227 map ,j y 
229 " Put the current cut buffer after the cursor
230 map ,m p
232 " Delete the character under the cursor
233 map ,n x
235 " Replace a character by it's next, A --> B,  B --> C, etc.
236 map ,a `a,jGi?=\e,ma\x16\x16\r\e0,dll,j`a21l,ml,nh
238 "  ----- END of Work out one germ -----
240 "  ----- timing macros  -----
242 " Get current date (used by time a generation)
243 map << :r!date\r
244 map <1 G?^top\rO\e<<
245 map <2 G?^top\rk<<
248 " Turn number on current line into edit command (used by time N generations)
249 map ,^ AiC\x16\x16\x16\e\e
252 " Delete current line and save current line (used by time N generations)
253 map ,& 0"gd$
256 " Run saved line (used by time N generations)
257 map ,* @g
259 "  ----- END of timing macros  -----
261 " End of the macros.