原件存檔 Original files吳哲宇 Che-Yu Wu

國三下(2010 年 1 月到 4 月)Grade 9, second term (January to April 2010)

演化:把 ff 改成 fun 的字串生物Evolution: string-command creatures that turn ff into fun

畫面上是一群會追食物的小圓。每個生物帶著一串指令,基因的樣子像 ADD s,ADH f。程式對每個新生的生物做同一件事:把字串 "ff" 丟進它的指令串,依序執行,得到的字如果在 goodword 清單裡,就在 ff--result.txt 記一筆「ff-->fun」,接著記下這個生物的基因。goodword 清單有 15 個字(frog 寫了兩次):fun、cell、hello、nice、fly、frog、yeah、yoy、flash、frank、facebook、majer、favorite、cat。

4 月版的 ClsEater 會執行六種指令:ADD 在尾巴接一個字,ADH 在頭上加一個字,LFT 把整串倒過來,LRD 與 RRD 留下左邊或右邊幾個字,DEL 刪掉第幾個字。另外三種指令 ERA(刪一段)、SUB(取一段)、SPA(插底線)來自 2009 年 11 月的文字編輯習題,放在習題程式 B 的資料夾裡,食物物件的基因變異時還會長出它們。

生物吃到食物,就用亂數在 ADD、ADH、LRD、RRD、LFT、DEL 裡挑一個,接到自己的指令串後面,吃到優等食物一次學兩條。繁殖時每條指令有一半的機率被複製給後代。成功過的生物例外:它和它往下 9 代的後代,複製時都完整保留指令串。

On screen a crowd of small circles chases food. Each creature carries a list of commands, its gene looking like ADD s,ADH f. The program does the same thing for every newborn: it feeds the string "ff" through the creature's commands in order, and if the result is on the goodword list it writes "ff-->fun" (or the word it got) to ff--result.txt, followed by the creature's gene. The goodword list has 15 entries (frog appears twice): fun, cell, hello, nice, fly, frog, yeah, yoy, flash, frank, facebook, majer, favorite, cat.

The April ClsEater runs six commands: ADD appends a character, ADH puts one at the front, LFT reverses the string, LRD and RRD keep the left or right n characters, and DEL deletes the n-th character. Three more, ERA (erase a stretch), SUB (take a stretch) and SPA (insert an underscore), come from a text-editing exercise of November 2009 that sits in the folder of exercise program B, and the food objects' genes grow them when they mutate.

A creature that eats food picks one of ADD, ADH, LRD, RRD, LFT and DEL at random and appends it to its own list; superior food teaches two. When a creature reproduces, each command has a one in two chance of being copied to the offspring, The exception is a creature that has succeeded: it and its next 9 generations of descendants copy the whole list.

    Public Function WordTran(ByVal Texta, ByVal Command) As String
        Try
            CommandText = Split(Command)(0)
            Select Case CommandText
                Case "ADD"
                    Texta += Split(Command)(1)
                Case "ADH"
                    Texta = Split(Command)(1) + Texta
                Case "LFT"
                    Texta = LeftToRight(Texta)
                Case "LRD"
                    Texta = Microsoft.VisualBasic.Left(Texta, CInt(Split(Command)(1)))
                Case "RRD"
                    Texta = Microsoft.VisualBasic.Right(Texta, CInt(Split(Command)(1)))
                Case "DEL"
                    Texta = Microsoft.VisualBasic.Left(Texta, CInt(Split(Command)(1)) - 1) & Microsoft.VisualBasic.Mid(Texta, CInt(Split(Command)(1)) + 1)
                Case Else
                    If BigCommands.Item(CommandText) IsNot Nothing Then
                        For Each Commanda As String In BigCommands.Item(CommandText)
                            WordTran(Texta, Commanda)
                        Next
                    End If
            End Select
            Return Texta
        Catch ex As Exception
            Return Texta
        End Try
        Return Texta
    End Function
ClsEater.vb 的 WordTran:每個指令對字串做什麼。指令數字超出範圍時 VB 丟出錯誤,Catch 把字串原樣傳回。WordTran in ClsEater.vb: what each command does to the string. When a number is out of range VB throws an error and the Catch returns the string unchanged.
                        objEater.Live += 25
                        Select Case ran.Next(0, 6)
                            Case 0
                                objEater.Commands.Add("ADD " & Chr(97 + ran.Next(0, 26)))
                            Case 1
                                objEater.Commands.Add("ADH " & Chr(97 + ran.Next(0, 26)))
                            Case 2
                                objEater.Commands.Add("LRD " & ran.Next(0, 14))
                            Case 3
                                objEater.Commands.Add("RRD " & ran.Next(0, 14))
                            Case 4
                                objEater.Commands.Add("LFT")
                            Case 5
                                objEater.Commands.Add("DEL " & ran.Next(0, 14))
                        End Select
Form1.vb:生物吃到普通食物,隨機學一條指令。Form1.vb: a creature that eats ordinary food learns one random command.
            If objEater.TryWord = False Then
                testword = objEater.result("ff")
                Print("Try " + testword)
                objEater.ResultText = testword
                If goodword.Contains(testword) Then
                    BestObjEater = objEater
                    '(這裡省略 10 行被註解掉的舊寫法)
                    Label4.Text = "成功!!!!!!~" + oktime.ToString
                    oktime += 1
                    My.Computer.FileSystem.WriteAllText("C:\Users\Majer\Desktop\演化\演化\ff--result.txt", "ff-->" + testword + vbNewLine, True)
                    My.Computer.FileSystem.WriteAllText("C:\Users\Majer\Desktop\演化\演化\ff--result.txt", "|" + BestObjEater.DNA + "|" + vbNewLine, True)
                    objEater.TruelyNum = 10
                End If
                objEater.TryWord = True
Form1.vb:對新生的生物試 "ff",成功就寫進 ff--result.txt。Form1.vb: try "ff" on a newborn and write a success to ff--result.txt.

ff--result.txt 留下 32 筆成功紀錄:fun 13 筆、yoy 12 筆、fly 4 筆、cat 2 筆、frog 1 筆。最短的 fly 只有 16 條指令,最長的 yoy 有 4,574 條。短的那一筆裡有 LRD 0 這種把字串清空、再用 ADD 和 ADH 重新拼起來的做法。cell、hello、nice、yeah、flash、frank、facebook、majer、favorite 在這份檔案裡沒有成功紀錄。

SaveText 資料夾有 37 個實驗資料夾,其中 36 個有 Diary.txt,逐行記下每個新生物試出的字(Try fffs)和族群的增減(Copy OK Live 2、Died OK Live 5)。起始生物的基因是 ADD s,ADH f,所以這 36 份 Diary 開頭第一個 Try 都是 fffs。

ff--result.txt holds 32 success records: fun 13, yoy 12, fly 4, cat 2, frog 1. The shortest, a fly, takes 16 commands and the longest, a yoy, 4,574. The short one uses LRD 0 to empty the string and then rebuilds it with ADD and ADH. cell, hello, nice, yeah, flash, frank, facebook, majer and favorite have no success record in this file.

The SaveText folder holds 37 experiment folders, 36 of them with a Diary.txt that logs, line by line, the word each newborn produced (Try fffs) and the population going up and down (Copy OK Live 2, Died OK Live 5). The starting creature's gene is ADD s,ADH f, so the first Try in each of those 36 Diaries is fffs.

ff-->fly
|Speed 36;
 Shape AA;
 Live 3522;
 CopyTime 31;
 Width 24;
 Hash 18288157;
 R 90;
 G 61;
 B 34;
 WordsTrans-
 ADD l,ADH t,ADH n,LFT,LRD 13,DEL 13,RRD 7,LRD 2,LRD 5,ADH t,
 LFT,LRD 0,LRD 0,ADD l,ADD y,ADH f|
ff--result.txt 第 47、48 行:一筆 fly 的紀錄(為了排版,基因在逗號處換行)。Lines 47 and 48 of ff--result.txt: one record for fly (the gene is wrapped at commas for layout).
Time-->0
Try fffs
Copy OK Live 2
Try fffs
Copy OK Live 3
Try fffs
Copy OK Live 4
Try fffs
Tor OK Live 5
Try ssffff
Try fffs
Died OK Live 5
Copy OK Live 6
Try ffs
Try fffs
Tor OK Live 8
Try dfffss
Try fffs
Tor OK Live 10
Try
Died OK Live 9
Try dfffss
Died OK Live 9
Died OK Live 8
Copy OK Live 9
Try cfff
SaveText/No_0/Diary.txt 開頭 26 行。The first 26 lines of SaveText/No_0/Diary.txt.

下面是重播器。選一筆 ff--result.txt 裡的紀錄,可以一步一步看 "ff" 怎麼變成目標字,也可以切換中英文。我照 ClsEater.vb 的寫法重新實作了這些指令,再把檔案裡的成功紀錄逐筆跑過,30 筆都得到記錄上的字。選單最後面另有兩筆記錄,照記錄的基因串跑不出目標字,原因見重播器下方的說明。

Below is the replayer. Pick a record from ff--result.txt and watch "ff" turn into the target word one command at a time, in Chinese or English. I re-implemented the commands as ClsEater.vb writes them and ran the recorded successes through it: 30 of them give the recorded word. Two more records, at the end of the menu, do not reach their target when their gene is run as recorded; the note under the replayer says why.

指令串重播器。預設是 fly 那筆,16 步。The command-string replayer, opened on the fly record, 16 steps.

在新分頁開整站 Open the whole site ↗

第 1 行的 fun 用到 SUB,4 月版的 ClsEater 不認得這個指令,我改用習題程式 B 的寫法跑它,得到 fun。習題的 pb.in 有 7 條指令,照同一套寫法跑出來的 7 列,和 pb.out 逐列相同。

第 27 行(fly)和第 29 行(fun)跑不出來。記錄的是生物出生時的基因,生物在第一個畫面可能已經吃了食物、學了新指令才被檢查,新指令沒有寫回記錄。第 29 行是起始生物,基因只有 ADD s,ADH f,只能得到 fffs。這是推測,沒有直接證據。

The fun on line 1 uses SUB, which the April ClsEater does not know, so I ran it the way exercise program B writes it and got fun. The exercise's pb.in holds 7 commands, and the 7 lines produced by the same code match pb.out line for line.

Lines 27 (fly) and 29 (fun) do not reproduce. What is logged is the gene a creature was born with, and in its first frame a creature may already have eaten food and learned new commands before it is checked; those commands are not written back. Line 29 is the starting creature, whose gene is only ADD s,ADH f and gives fffs. This is a guess with no direct evidence.