Nevu - ein Neuanfang

Anwendungen, Tools, Userlibs und anderes nützliches.
Norbie
Beiträge: 134
Registriert: 29.08.2004 12:45
Wohnort: Chemnitz
Kontaktdaten:

Nevu - ein Neuanfang

Beitrag von Norbie »

Hallo, einige erinnern sich vieleicht noch an Nevu, wenn nicht, hier ist ein altes Forumsthema dazu, dass mitlerweile sehr alt ist: http://www.purebasic.fr/german/viewtopic.php?t=6832

Ich habe das Programm neugeschreiben, vereinfacht und gut Kommentiert, so dass es besser von euch verstanden und vielleicht sogar erweitert werden kann:

Code: Alles auswählen

;Nevu V1

;Gebrauchsanweisung:
;Am anfang mutation auf 100 stellen und futter auf 30 lassen
;im menü auf running drücken
;wenn es mehr als 100 Zellen gibt im menü auf visualisieren drücken, und nach belieben zusehen
;mutation am besten wieder auf einen wert unter 10 und über 0 stellen
;Vosicht:wenn die visualisierung an ist, läuft die Simulation viel langsammer 
; Homepage: www.nevu.de 
;MfG Marcel Richter

;{ complexität des codes für die Turingmaschine der Einzeller
#abc=2 ;anzahl der zeichen im alphabet der turingmaschine. mindestens 2, max 127 da in byte gespeichert
#zustandcount=5000  ;wieviele zustände kennt die turingmaschine (man könnte sagen wieiele zeielen hat der code der ki maximal)
#bandsize=10000 ;wieviele speicherzellen hat das turingband? muss größer als eingabe und ausgabeteil sein.
#maxsteps=100000 ;wieviele arbeitsschritte kan die turingmaschine einer zelle maximal machen?
;wichtig, da manche turingcodes die entstehen sonst endlos laufen, und das programm abstürtzen lässt
;}
;{ config
#weltx=200 ;breite der simulierten welt
#welty=200 ; höhe der simulierten welt
#naehrwert=40 ; wieviel energie bekommt eine zelle gutgeschrieben, wenn es etwas zufressen findet?
#futterminimum=1500 ;wieviel essen\energie muss eine zelle angesammelt haben, bevor sie sich teilt 
#maxalter=5000 ; wie alt kann eine zelle maximal werden?
;}
;{ Codelesbarkeit
#futter=1
#leer=0
#turing_terminationszustand=-1 ; wenn die zuringmaschine diesen zustand ereicht, beendet sie sich und ist fertig
;}
;{ Bandzeiger
#hoch_bewegen=0                    ;hier sind namen für bestimmte elemente des turingbandes gegeben, je nach funktion
#runter_bewegen=#hoch_bewegen+1    ; die ersten bestimen zb wohin sich eine zelle bewegt
#rechts_bewegen=#runter_bewegen+1
#links_bewegen=#rechts_bewegen+1

#blickhoch=#links_bewegen+1         ; und diese zeiger, zeigen auf die stellen im turingband auf die geschrieben wird
#blickrunter=#blickhoch+1           ; was um die zelle vorgeht
#blickrechts=#blickrunter+1
#blicklinks=#blickrechts+1
;}
InitSprite()

;{ konstanten
Enumeration
  #hauptfenster
  #hauptfenster_gadget_text_weltzeit
  #hauptfenster_gadget_text_Zellenanzahl
  #hauptfenster_gadget_text_rundenprosek
  #hauptfenster_menu
  #hauptfenster_menu_visualisierung
  #hauptfenster_menu_running
  #hauptfenster_menu_reset
  #hauptfenster_menu_laden
  #hauptfenster_menu_speichern
  #hauptfenster_menu_web
  #hauptfenster_gadget_trackbar_futter
  #hauptfenster_gadget_text_futter
  #hauptfenster_gadget_trackbar_mutationen
  #hauptfenster_gadget_text_mutationen
  #timer_hauptfenster_statistik
  
  #visualisierungsfenster
EndEnumeration
;}
;{ Statistiksysem
Structure STATISTIK
  weltzeit.l      ;wie viele runden wurden berechnet?
  alteweltzeit.l ;um die runden pro sekunde zu berechnen
EndStructure
Global statistik.STATISTIK
;}
;{ Zellenspeichersystem
Structure BODY
  schreiben.b      ;speichert, was auf das band geschreiben werden soll - vorsicht Byte geht nur bis 128
  richtung.b       ; In welche richtung soll der schreib\lesekopf verschoben werden?
  zielzustand.l    ; in welchen zustand soll die turingmaschine anschließend wechseln?
EndStructure
Structure ZUSTAND
  eingabezeichen.BODY[#abc] ;jeder zustand muss auf jedes eingelesene zeichen reagieren können
EndStructure
Structure ZELLE
  zustand.ZUSTAND[#zustandcount] ;jede zelle hat viele zustände gespeichert in der die turingmaschine sein kann
  x.l ;x und y position der zellen in der welt
  y.l
  band.b[#bandsize] ; das turingband
  magen.l           ;die energiereserven der zelle
  alter.l           ;wie alt ist die zelle?
EndStructure
Global NewList Zellen.ZELLE()
;}
;{ Statusspeicher
Structure STATUS
  visualisierung.l  ;ist true wenn die welt gezeichnet werden soll
  running.l         ;ist true wenn die simulation läuft
EndStructure
Global status.STATUS
;}
;{ Weltstruc
Structure WELTSTRUC
  inhalt.l    ;inhalt eines feldes der welt(leer oder futter)
EndStructure
Global Dim welt.WELTSTRUC(#weltx,#welty)
;}
;{ Umweltstruc
Structure UMWELTSTRUC
  mutationen.l        ;speichert wie sehr kinder mutiert werden
  essenzusatz.l       ;Wieviel futter wird verteilt
EndStructure
Global umwelt.UMWELTSTRUC
;}


Procedure update_gui_umweltkontrollen()
  ;aktualisiert die gui
  SetGadgetState(#hauptfenster_gadget_trackbar_futter,umwelt\essenzusatz)
  SetGadgetText(#hauptfenster_gadget_text_futter,Str(umwelt\essenzusatz))
  SetGadgetState(#hauptfenster_gadget_trackbar_mutationen,umwelt\mutationen)
  SetGadgetText(#hauptfenster_gadget_text_mutationen,Str(umwelt\mutationen))
EndProcedure


Procedure openhauptfenster()
  OpenWindow(#hauptfenster,60,60,200,200,#PB_Window_MinimizeGadget ,"Nevu - Steuerfenster")
    CreateGadgetList(WindowID(#hauptfenster))
      TextGadget(#PB_Any,15,10,100,15,"Weltzeit:")
      TextGadget(#hauptfenster_gadget_text_weltzeit,130,10,70,15,"0")
      TextGadget(#PB_Any,15,30,100,15,"Zellenanzahl:")
      TextGadget(#hauptfenster_gadget_text_zellenanzahl,130,30,70,15,"0")
      TextGadget(#PB_Any,15,50,100,15,"Runden pro Sek:")
      TextGadget(#hauptfenster_gadget_text_rundenprosek,130,50,70,15,"0")
      
      TextGadget(#PB_Any,5,90,150,12,"Essenzusatz:")
      TrackBarGadget(#hauptfenster_gadget_trackbar_futter, 0, 103, 150, 20, 0, 100)
      TextGadget(#hauptfenster_gadget_text_futter,150,103,30,12,"0")
        
      TextGadget(#PB_Any,5,120,150,12,"Mutation:")
      TrackBarGadget(#hauptfenster_gadget_trackbar_mutationen, 0, 138, 150, 20, 0, 100)
      TextGadget(#hauptfenster_gadget_text_mutationen,150,138,30,15,"0")  
   CreateMenu(#hauptfenster_menu,WindowID(#hauptfenster))
     MenuTitle("Steuerung")
     MenuItem(#hauptfenster_menu_visualisierung, "Visualisieren")
     MenuItem(#hauptfenster_menu_running, "running")
     MenuItem(#hauptfenster_menu_reset, "reset")
     MenuItem(#hauptfenster_menu_laden, "laden")
     MenuItem(#hauptfenster_menu_speichern, "speichern")
     MenuItem(#hauptfenster_menu_web, "Visit http://www.nevu.de") 
 
     SetTimer_(WindowID(#hauptfenster),#timer_hauptfenster_statistik,1000,0)
     update_gui_umweltkontrollen()
EndProcedure

Procedure start_visualisierung()
  OpenWindow(#visualisierungsfenster,100,100,#weltx, #welty, #PB_Window_SystemMenu,"Visualisierung",WindowID(#hauptfenster))
  OpenWindowedScreen(WindowID(#visualisierungsfenster),0,0,#weltx, #welty, 0, 0, 0)
  status\visualisierung=#True  
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_visualisierung, 1)
EndProcedure
Procedure stop_visualisierung()
  status\visualisierung=#False
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_visualisierung, 0)
  CloseScreen()
  CloseWindow(#visualisierungsfenster)
EndProcedure
Procedure visualisiere_welt()
  ClearScreen($000000)
  StartDrawing(ScreenOutput())
  For x=0 To #weltx-1
    For y=0 To #welty-1
      If welt(x,y)\inhalt=#futter
        Plot(x,y,$00ff00)
      EndIf
;       If welt(x,y)\inhalt=#mauer
;         Plot(x,y,$0000ff)
;       EndIf
    Next
  Next
    ForEach zellen()
      Box(zellen()\x, zellen()\y,2,2, $ffffff)
    Next
  StopDrawing()
  FlipBuffers()
EndProcedure

Procedure start_running()
  status\running=#True
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_running, 1)
EndProcedure
Procedure stop_running()
  status\running=#False
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_running, 0)
EndProcedure

Procedure place_food()
  ;verteilt je nach einstellung futter in der welt
  For i=1 To umwelt\essenzusatz
    x=Random(#weltx-1)
    y=Random(#welty-1)
    If welt(x, y)\inhalt=0
      welt(x, y)\inhalt=1
    EndIf
  Next
EndProcedure

;Diese zwei funktionen sorgen dafür das zellen die links aus der welt fallen, rechts wieder landen
Procedure real_x(x)
  ProcedureReturn (x%#weltx+(#False Or x<0)*#weltx)
EndProcedure
Procedure real_y(y)
    ProcedureReturn (y%#welty+(#False Or y<0)*#welty)
EndProcedure

Procedure run_turing()

  ;erst im web nachlesen was eine turingmaschine ist!
  zustandsnummer=0 ;speichert den zustand in dem die turingmaschine ist
  bandzeiger=0     ;auf welche stelle auf dem band zeigt der schreib\lesekopf?
  Steps=0          ; wieviele arbeitsschritte hat die turingmamaschine schon gemacht?
  
  Repeat
    If bandzeiger<0 ;das band ist zu einem kreis verbogen, ein wirklich unendlich langes band geht ja nicht^^
      bandzeiger+#bandsize
    ElseIf bandzeiger>=#bandsize
      bandzeiger-#bandsize
    EndIf
    
    gelesenes_zeichen=zellen()\band[bandzeiger] ;schreib\lesekopf liest das zeichen ein
    zellen()\band[bandzeiger]=zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\schreiben ;dem zustand und eingelesenem zeichen entsprechend wird ein zeichen geschrieben
    bandzeiger+zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\richtung ;verschiebt den schreib\lesekopf 
    zustandsnummer=zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\zielzustand ;versetzt die turingmaschine in den neuen zustand
    Steps+1
  Until zustandsnummer=#turing_terminationszustand Or Steps>#maxsteps ;#turing_terminationszustand entspricht dem end von PB 
  If Steps>#maxsteps
    ProcedureReturn #False ;das programm lief zu lange, der turingcode wird als fehlerhaft eingestuft
  Else
    ProcedureReturn #True
  EndIf
EndProcedure

Procedure reset()
  ClearList(zellen()) ;alle zellen löschen
  ;For k=1 To 100
    AddElement(Zellen())
    zellen()\band[#hoch_bewegen]=1 ;auf das band an der stelle wo bestimmt wird ob sich die zelle hoch bewegt, wird eine 1
    ;geschrieben
    zellen()\magen=1000 ;der zelle etwas zu essen mitgeben
    For i=1 To 1000000  ;den genetichen code etwas durcheinander wirbeln
      zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\schreiben=Random(#abc-1)
      zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\richtung=-1+Random(2)
      zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=Random(#zustandcount-1)
      zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=#turing_terminationszustand
    Next
    zellen()\zustand[0]\eingabezeichen[1]\schreiben=1 ;die zelle findet eine eins auf dem turingband und schreibt wieder eine
    zellen()\zustand[0]\eingabezeichen[1]\zielzustand=#turing_terminationszustand ; und beendet sich sofort( eine minimal-ki)
    zellen()\x=Random(#weltx-1)  ;irgendwo freisetzen
    zellen()\y=Random(#welty-1)
  statistik\weltzeit=0
EndProcedure

Procedure calculate_zellen()
  ForEach zellen()
    zellen()\alter+1
    If zellen()\alter>#maxalter ;zu alte zellen töten muhaha
      DeleteElement(zellen())
      Continue
    EndIf
    
    zellen()\band[#blickhoch]=welt(real_y(zellen()\y-1), real_x(zellen()\x))\inhalt   ;hier wird der umwelt der zelle entsprechen
    zellen()\band[#blickrunter]=welt(real_y(zellen()\y+1), real_x(zellen()\x))\inhalt ;etwas aufs band geschrieben, die augen und ohren
    zellen()\band[#blicklinks]=welt(real_y(zellen()\y), real_x(zellen()\x-1))\inhalt
    zellen()\band[#blickrechts]=welt(real_y(zellen()\y), real_x(zellen()\x+1))\inhalt
    
    If run_turing()=#False    ;hier wird das turingprogramm ausgeführt
      DeleteElement(zellen()) ;und wen es fehler gab, die zelle getötet
      Continue
    EndIf
    
  ;{ Fressen
    If welt(zellen()\x, zellen()\y)\inhalt=#futter
      zellen()\magen+#naehrwert
      welt(zellen()\x, zellen()\y)\inhalt=#leer
    EndIf
    zellen()\magen-1
    If zellen()\magen<=0      ;tja, die zelle ist zu dumm um essen zu finden->tot..nur die besten überleben
      DeleteElement(zellen())
      Continue
    EndIf 
  ;}
  ;{ Bewegen
    ;je nachdem was auf dem turingband steht, nachdem die turingmaschine lief, bewegt sich die zelle ein stück
    If zellen()\alter>45    ; die erste zeit beweg sich die zelle nach der geburt nicht
      If zellen()\band[#hoch_bewegen]
        zellen()\y-1
        zellen()\magen-1
      EndIf
      If zellen()\band[#runter_bewegen]
        zellen()\y+1
        zellen()\magen-1
      EndIf
      If zellen()\band[#rechts_bewegen]
        zellen()\x+1
        zellen()\magen-1
      EndIf
      If zellen()\band[#links_bewegen]
        zellen()\x-1
        zellen()\magen-1
      EndIf
      zellen()\x=real_x(zellen()\x); wenn eine zelle über den rand fiel wird sie heir wieder zurecht gerückt
      zellen()\y=real_x(zellen()\y)
    EndIf
  ;}
  ;{ vermehrung
    If zellen()\magen >= #futterminimum
      zellen()\magen=zellen()\magen/2
      mutterzellenspeicheradresse=@zellen()
      zellen()\alter=0 ;beide zellen sind wieder jung
      AddElement(zellen())
      CopyMemory(mutterzellenspeicheradresse, @zellen(), SizeOf(ZELLE)) ;und hier entsteht ein neues leben ;)
      For i=1 To umwelt\mutationen ; das hier gleich noch etwas verändert wird
        zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\schreiben=Random(#abc-1)
        zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\richtung=-1+Random(2)
        zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=Random(#zustandcount-1)
        If Random(50)=1 
          zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=#turing_terminationszustand
        EndIf
      Next
    EndIf
  ;}
  Next
EndProcedure

Procedure main()
  ;unser prozess soll schön im hintergrund laufen und kein anderes programm stören
  SetPriorityClass_(GetCurrentProcess_(), #IDLE_PRIORITY_CLASS)
  openhauptfenster()
  Repeat
    Select WindowEvent()
      Case #PB_Event_CloseWindow
        Select EventWindow()
          Case #hauptfenster
            ;AK
            ;If MessageRequester("Wirklich beenden?","Sicher, dass sie das Programm beenden wollen?",#PB_MessageRequester_YesNo)=6
              End
            ;EndIf
          Case #visualisierungsfenster
            stop_visualisierung()
          Default
            CloseWindow(EventWindow())  
        EndSelect
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #hauptfenster_gadget_trackbar_futter
            umwelt\essenzusatz=GetGadgetState(#hauptfenster_gadget_trackbar_futter) 
            update_gui_umweltkontrollen()
          Case #hauptfenster_gadget_trackbar_mutationen
            umwelt\mutationen=GetGadgetState(#hauptfenster_gadget_trackbar_mutationen) 
            update_gui_umweltkontrollen()
        EndSelect
      Case #PB_Event_Menu
        Select EventMenu()
          Case #hauptfenster_menu_web
            ;nicht entfernen
          SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
            ShellExecute_(0,"open","http:\\www.nevu.de","","",#SW_SHOWNORMAL)
          SetPriorityClass_(GetCurrentProcess_(), #IDLE_PRIORITY_CLASS)
          Case #hauptfenster_menu_visualisierung
            If status\visualisierung
              stop_visualisierung()
            Else
              start_visualisierung()
            EndIf
          Case #hauptfenster_menu_running
            If status\running
              stop_running()
            Else
              start_running()
            EndIf 
          Case #hauptfenster_menu_reset
            reset()
          Case #hauptfenster_menu_speichern
            CreateFile(1,"save.save")
            ForEach zellen() ;alle zellen in ein file speichern
              If WriteData(1,@zellen(),SizeOf(ZELLE))<>SizeOf(ZELLE)
                MessageRequester("Fehler","Fehler beim speichern. Nicht genügend festplattenplatz?")
              EndIf
            Next
            CloseFile(1)
          Case #hauptfenster_menu_laden
            ClearList(zellen())
            If OpenFile(1,"save.save")
              Repeat ;alle zellen aus einer datei laden
                AddElement(zellen())
                ReadData(1, @zellen(), SizeOf(ZELLE))
              Until Eof(1)
            Else
              MessageRequester("Fehler","Konnte Savefile nicht öffnen")
            EndIf
            CloseFile(1)
        EndSelect
      Case #WM_TIMER 
        Select EventwParam() 
          Case #timer_hauptfenster_statistik
            SetGadgetText(#hauptfenster_gadget_text_zellenanzahl,Str(CountList(zellen())))
            SetGadgetText(#hauptfenster_gadget_text_rundenprosek,Str(statistik\weltzeit-statistik\alteweltzeit))
            SetGadgetText(#hauptfenster_gadget_text_weltzeit,Str(statistik\weltzeit))
            statistik\alteweltzeit=statistik\weltzeit
        EndSelect         
      Case 0
        If status\visualisierung
          visualisiere_welt()
        EndIf
        If status\running
          statistik\weltzeit+1
          calculate_zellen()
          place_food()
        Else
          Delay(10)
        EndIf 
    EndSelect        
  ForEver
EndProcedure

umwelt\essenzusatz=30 
umwelt\mutationen=1
reset()
main()
Verbesserungen vielleicht gleich hier posten.
http://www.nevu.de/ Künstliche Intelligenz, die letzte Herausforderung!
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

cool. heute haben wir in der schule über evolution, mutation und selektion geredet und ich musste dadran denken, was wohl aus nevu geworden ist, und jetz das hier :allright:
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Beitrag von DrShrek »

@Norbie,
Hier noch ein paar Ideen um Dein 'Nevu' interresanter zu machen:

1a)
Geschlechter
-> Vorteil: Mutationen regelmässig bzw häufiger.

1b)
Bei einfacher Zellteilung:
Nur Kopien...Mutation eher zufählig und nicht sehr häufig.

2)
Baue verschiedene Typen ein:
Und zwar nach den 'Schere, Stein, Papier' -Prinzip.

3)
Futterstellen sollten unterschiedlich ergiebig sein

4)
Bau mehr´Eigenschaften für die 'Wesen' ein: z.B.: Selbstheilung


5)
Futter (Pflanzen) sollten auch älter werden ...und letzlich absterben.

6)
Futtertypen (Giftig/ungiftig) (Dann brauchst du keine Mauer!)




Und hier dein Orginalcode an PB 4.0/4.01 angepasst:

Code: Alles auswählen

;Nevu V1  (PB4.0/PB4.01)

;Gebrauchsanweisung: 
;Am anfang mutation auf 100 stellen und futter auf 30 lassen 
;im menü auf running drücken 
;wenn es mehr als 100 Zellen gibt im menü auf visualisieren drücken, und nach belieben zusehen 
;mutation am besten wieder auf einen wert unter 10 und über 0 stellen 
;Vosicht:wenn die visualisierung an ist, läuft die Simulation viel langsammer 
; Homepage: www.nevu.de 
;MfG Marcel Richter 

;{ complexität des codes für die Turingmaschine der Einzeller 
#abc=2 ;anzahl der zeichen im alphabet der turingmaschine. mindestens 2, max 127 da in byte gespeichert 
#zustandcount=5000  ;wieviele zustände kennt die turingmaschine (man könnte sagen wieiele zeielen hat der code der ki maximal) 
#bandsize=10000 ;wieviele speicherzellen hat das turingband? muss größer als eingabe und ausgabeteil sein. 
#maxsteps=100000 ;wieviele arbeitsschritte kan die turingmaschine einer zelle maximal machen? 
;wichtig, da manche turingcodes die entstehen sonst endlos laufen, und das programm abstürtzen lässt 
;} 
;{ config 
#weltx=200 ;breite der simulierten welt 
#welty=200 ; höhe der simulierten welt 
#naehrwert=40 ; wieviel energie bekommt eine zelle gutgeschrieben, wenn es etwas zufressen findet? 
#futterminimum=1500 ;wieviel essen\energie muss eine zelle angesammelt haben, bevor sie sich teilt 
#maxalter=5000 ; wie alt kann eine zelle maximal werden? 
;} 
;{ Codelesbarkeit 
#futter=1 
#leer=0 
#turing_terminationszustand=-1 ; wenn die zuringmaschine diesen zustand ereicht, beendet sie sich und ist fertig 
;} 
;{ Bandzeiger 
#hoch_bewegen=0                    ;hier sind namen für bestimmte elemente des turingbandes gegeben, je nach funktion 
#runter_bewegen=#hoch_bewegen+1    ; die ersten bestimen zb wohin sich eine zelle bewegt 
#rechts_bewegen=#runter_bewegen+1 
#links_bewegen=#rechts_bewegen+1 

#blickhoch=#links_bewegen+1         ; und diese zeiger, zeigen auf die stellen im turingband auf die geschrieben wird 
#blickrunter=#blickhoch+1           ; was um die zelle vorgeht 
#blickrechts=#blickrunter+1 
#blicklinks=#blickrechts+1 
;} 
InitSprite() 

;{ konstanten 
Enumeration 
  #hauptfenster 
  #hauptfenster_gadget_text_weltzeit 
  #hauptfenster_gadget_text_Zellenanzahl 
  #hauptfenster_gadget_text_rundenprosek 
  #hauptfenster_menu 
  #hauptfenster_menu_visualisierung 
  #hauptfenster_menu_running 
  #hauptfenster_menu_reset 
  #hauptfenster_menu_laden 
  #hauptfenster_menu_speichern 
  #hauptfenster_menu_web 
  #hauptfenster_gadget_trackbar_futter 
  #hauptfenster_gadget_text_futter 
  #hauptfenster_gadget_trackbar_mutationen 
  #hauptfenster_gadget_text_mutationen 
  #timer_hauptfenster_statistik 
  
  #visualisierungsfenster 
EndEnumeration 
;} 
;{ Statistiksysem 
Structure STATISTIK 
  weltzeit.l      ;wie viele runden wurden berechnet? 
  alteweltzeit.l ;um die runden pro sekunde zu berechnen 
EndStructure 
Global statistik.STATISTIK 
;} 
;{ Zellenspeichersystem 
Structure BODY 
  schreiben.b      ;speichert, was auf das band geschreiben werden soll - vorsicht Byte geht nur bis 128 
  richtung.b       ; In welche richtung soll der schreib\lesekopf verschoben werden? 
  zielzustand.l    ; in welchen zustand soll die turingmaschine anschließend wechseln? 
EndStructure 
Structure ZUSTAND 
  eingabezeichen.BODY[#abc] ;jeder zustand muss auf jedes eingelesene zeichen reagieren können 
EndStructure 
Structure ZELLE 
  zustand.ZUSTAND[#zustandcount] ;jede zelle hat viele zustände gespeichert in der die turingmaschine sein kann 
  x.l ;x und y position der zellen in der welt 
  y.l 
  band.b[#bandsize] ; das turingband 
  magen.l           ;die energiereserven der zelle 
  alter.l           ;wie alt ist die zelle? 
EndStructure 
Global NewList Zellen.ZELLE() 
;} 
;{ Statusspeicher 
Structure STATUS 
  visualisierung.l  ;ist true wenn die welt gezeichnet werden soll 
  running.l         ;ist true wenn die simulation läuft 
EndStructure 
Global Status.STATUS 
;} 
;{ Weltstruc 
Structure WELTSTRUC 
  inhalt.l    ;inhalt eines feldes der welt(leer oder futter) 
EndStructure 
Global Dim welt.WELTSTRUC(#weltx,#welty) 
;} 
;{ Umweltstruc 
Structure UMWELTSTRUC 
  mutationen.l        ;speichert wie sehr kinder mutiert werden 
  essenzusatz.l       ;Wieviel futter wird verteilt 
EndStructure 
Global umwelt.UMWELTSTRUC 
;} 


Procedure update_gui_umweltkontrollen() 
  ;aktualisiert die gui 
  SetGadgetState(#hauptfenster_gadget_trackbar_futter,umwelt\essenzusatz) 
  SetGadgetText(#hauptfenster_gadget_text_futter,Str(umwelt\essenzusatz)) 
  SetGadgetState(#hauptfenster_gadget_trackbar_mutationen,umwelt\mutationen) 
  SetGadgetText(#hauptfenster_gadget_text_mutationen,Str(umwelt\mutationen)) 
EndProcedure 


Procedure openhauptfenster() 
  OpenWindow(#hauptfenster,60,60,200,200,"Nevu - Steuerfenster",#PB_Window_MinimizeGadget) 
  CreateGadgetList(WindowID(#hauptfenster)) 
  TextGadget(#PB_Any,15,10,100,15,"Weltzeit:") 
  TextGadget(#hauptfenster_gadget_text_weltzeit,130,10,70,15,"0") 
  TextGadget(#PB_Any,15,30,100,15,"Zellenanzahl:") 
  TextGadget(#hauptfenster_gadget_text_Zellenanzahl,130,30,70,15,"0") 
  TextGadget(#PB_Any,15,50,100,15,"Runden pro Sek:") 
  TextGadget(#hauptfenster_gadget_text_rundenprosek,130,50,70,15,"0") 
  
  TextGadget(#PB_Any,5,90,150,12,"Essenzusatz:") 
  TrackBarGadget(#hauptfenster_gadget_trackbar_futter, 0, 103, 150, 20, 0, 100) 
  TextGadget(#hauptfenster_gadget_text_futter,150,103,30,12,"0") 
  
  TextGadget(#PB_Any,5,120,150,12,"Mutation:") 
  TrackBarGadget(#hauptfenster_gadget_trackbar_mutationen, 0, 138, 150, 20, 0, 100) 
  TextGadget(#hauptfenster_gadget_text_mutationen,150,138,30,15,"0")  
  CreateMenu(#hauptfenster_menu,WindowID(#hauptfenster)) 
  MenuTitle("Steuerung") 
  MenuItem(#hauptfenster_menu_visualisierung, "Visualisieren") 
  MenuItem(#hauptfenster_menu_running, "running") 
  MenuItem(#hauptfenster_menu_reset, "reset") 
  MenuItem(#hauptfenster_menu_laden, "laden") 
  MenuItem(#hauptfenster_menu_speichern, "speichern") 
  MenuItem(#hauptfenster_menu_web, "Visit http://www.nevu.de") 
  
  SetTimer_(WindowID(#hauptfenster),#timer_hauptfenster_statistik,1000,0) 
  update_gui_umweltkontrollen() 
EndProcedure 

Procedure start_visualisierung() 
  OpenWindow(#visualisierungsfenster,100,100,#weltx, #welty,"visualisierung",#PB_Window_SystemMenu,WindowID(#hauptfenster)) 
  OpenWindowedScreen(WindowID(#visualisierungsfenster),0,0,#weltx, #welty, 0, 0, 0) 
  Status\visualisierung=#True  
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_visualisierung, 1) 
EndProcedure 
Procedure stop_visualisierung() 
  Status\visualisierung=#False 
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_visualisierung, 0) 
  CloseScreen() 
  CloseWindow(#visualisierungsfenster) 
EndProcedure 
Procedure visualisiere_welt() 
  ClearScreen($000000) 
  StartDrawing(ScreenOutput()) 
  For x=0 To #weltx-1 
    For y=0 To #welty-1 
      If welt(x,y)\inhalt=#futter 
        Plot(x,y,$00FF00) 
      EndIf 
      ;       If welt(x,y)\inhalt=#mauer 
      ;         Plot(x,y,$0000ff) 
      ;       EndIf 
    Next 
  Next 
  ForEach Zellen() 
    Box(Zellen()\x, Zellen()\y,2,2, $FFFFFF) 
  Next 
  StopDrawing() 
  FlipBuffers() 
EndProcedure 

Procedure start_running() 
  Status\running=#True 
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_running, 1) 
EndProcedure 
Procedure stop_running() 
  Status\running=#False 
  SetMenuItemState(#hauptfenster_menu, #hauptfenster_menu_running, 0) 
EndProcedure 

Procedure place_food() 
  ;verteilt je nach einstellung futter in der welt 
  For i=1 To umwelt\essenzusatz 
    x=Random(#weltx-1) 
    y=Random(#welty-1) 
    If welt(x, y)\inhalt=0 
      welt(x, y)\inhalt=1 
    EndIf 
  Next 
EndProcedure 

;Diese zwei funktionen sorgen dafür das zellen die links aus der welt fallen, rechts wieder landen 
Procedure real_x(x) 
  ProcedureReturn (x%#weltx+(#False Or x<0)*#weltx) 
EndProcedure 
Procedure real_y(y) 
  ProcedureReturn (y%#welty+(#False Or y<0)*#welty) 
EndProcedure 

Procedure run_turing() 
  
  ;erst im web nachlesen was eine turingmaschine ist! 
  zustandsnummer=0 ;speichert den zustand in dem die turingmaschine ist 
  bandzeiger=0     ;auf welche stelle auf dem band zeigt der schreib\lesekopf? 
  Steps=0          ; wieviele arbeitsschritte hat die turingmamaschine schon gemacht? 
  
  Repeat 
    If bandzeiger<0 ;das band ist zu einem kreis verbogen, ein wirklich unendlich langes band geht ja nicht^^ 
      bandzeiger+#bandsize 
    ElseIf bandzeiger>=#bandsize 
      bandzeiger-#bandsize 
    EndIf 
    
    gelesenes_zeichen=Zellen()\band[bandzeiger] ;schreib\lesekopf liest das zeichen ein 
    Zellen()\band[bandzeiger]=Zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\schreiben ;dem zustand und eingelesenem zeichen entsprechend wird ein zeichen geschrieben 
    bandzeiger+Zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\richtung ;verschiebt den schreib\lesekopf 
    zustandsnummer=Zellen()\zustand[zustandsnummer]\eingabezeichen[gelesenes_zeichen]\zielzustand ;versetzt die turingmaschine in den neuen zustand 
    Steps+1 
  Until zustandsnummer=#turing_terminationszustand Or Steps>#maxsteps ;#turing_terminationszustand entspricht dem end von PB 
  If Steps>#maxsteps 
    ProcedureReturn #False ;das programm lief zu lange, der turingcode wird als fehlerhaft eingestuft 
  Else 
    ProcedureReturn #True 
  EndIf 
EndProcedure 

Procedure reset() 
  ClearList(Zellen()) ;alle zellen löschen 
  ;For k=1 To 100 
  AddElement(Zellen()) 
  Zellen()\band[#hoch_bewegen]=1 ;auf das band an der stelle wo bestimmt wird ob sich die zelle hoch bewegt, wird eine 1 
  ;geschrieben 
  Zellen()\magen=1000 ;der zelle etwas zu essen mitgeben 
  For i=1 To 1000000  ;den genetichen code etwas durcheinander wirbeln 
    Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\schreiben=Random(#abc-1) 
    Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\richtung=-1+Random(2) 
    Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=Random(#zustandcount-1) 
    Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=#turing_terminationszustand 
  Next 
  Zellen()\zustand[0]\eingabezeichen[1]\schreiben=1 ;die zelle findet eine eins auf dem turingband und schreibt wieder eine 
  Zellen()\zustand[0]\eingabezeichen[1]\zielzustand=#turing_terminationszustand ; und beendet sich sofort( eine minimal-ki) 
  Zellen()\x=Random(#weltx-1)  ;irgendwo freisetzen 
  Zellen()\y=Random(#welty-1) 
  statistik\weltzeit=0 
EndProcedure 

Procedure calculate_zellen() 
  ForEach Zellen() 
    Zellen()\alter+1 
    If Zellen()\alter>#maxalter ;zu alte zellen töten muhaha 
      DeleteElement(Zellen()) 
      Continue 
    EndIf 
    
    Zellen()\band[#blickhoch]=welt(real_y(Zellen()\y-1), real_x(Zellen()\x))\inhalt   ;hier wird der umwelt der zelle entsprechen 
    Zellen()\band[#blickrunter]=welt(real_y(Zellen()\y+1), real_x(Zellen()\x))\inhalt ;etwas aufs band geschrieben, die augen und ohren 
    Zellen()\band[#blicklinks]=welt(real_y(Zellen()\y), real_x(Zellen()\x-1))\inhalt 
    Zellen()\band[#blickrechts]=welt(real_y(Zellen()\y), real_x(Zellen()\x+1))\inhalt 
    
    If run_turing()=#False    ;hier wird das turingprogramm ausgeführt 
      DeleteElement(Zellen()) ;und wen es fehler gab, die zelle getötet 
      Continue 
    EndIf 
    
    ;{ Fressen 
    If welt(Zellen()\x, Zellen()\y)\inhalt=#futter 
      Zellen()\magen+#naehrwert 
      welt(Zellen()\x, Zellen()\y)\inhalt=#leer 
    EndIf 
    Zellen()\magen-1 
    If Zellen()\magen<=0      ;tja, die zelle ist zu dumm um essen zu finden->tot..nur die besten überleben 
      DeleteElement(Zellen()) 
      Continue 
    EndIf 
    ;} 
    ;{ Bewegen 
    ;je nachdem was auf dem turingband steht, nachdem die turingmaschine lief, bewegt sich die zelle ein stück 
    If Zellen()\alter>45    ; die erste zeit beweg sich die zelle nach der geburt nicht 
      If Zellen()\band[#hoch_bewegen] 
        Zellen()\y-1 
        Zellen()\magen-1 
      EndIf 
      If Zellen()\band[#runter_bewegen] 
        Zellen()\y+1 
        Zellen()\magen-1 
      EndIf 
      If Zellen()\band[#rechts_bewegen] 
        Zellen()\x+1 
        Zellen()\magen-1 
      EndIf 
      If Zellen()\band[#links_bewegen] 
        Zellen()\x-1 
        Zellen()\magen-1 
      EndIf 
      Zellen()\x=real_x(Zellen()\x); wenn eine zelle über den rand fiel wird sie heir wieder zurecht gerückt 
      Zellen()\y=real_x(Zellen()\y) 
    EndIf 
    ;} 
    ;{ vermehrung 
    If Zellen()\magen >= #futterminimum 
      Zellen()\magen=Zellen()\magen/2 
      mutterzellenspeicheradresse=@Zellen() 
      Zellen()\alter=0 ;beide zellen sind wieder jung 
      AddElement(Zellen()) 
      CopyMemory(mutterzellenspeicheradresse, @Zellen(), SizeOf(ZELLE)) ;und hier entsteht ein neues leben ;) 
      For i=1 To umwelt\mutationen ; das hier gleich noch etwas verändert wird 
        Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\schreiben=Random(#abc-1) 
        Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\richtung=-1+Random(2) 
        Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=Random(#zustandcount-1) 
        If Random(50)=1 
          Zellen()\zustand[Random(#zustandcount-1)]\eingabezeichen[Random(#abc-1)]\zielzustand=#turing_terminationszustand 
        EndIf 
      Next 
    EndIf 
    ;} 
  Next 
EndProcedure 

Procedure main() 
  ;unser prozess soll schön im hintergrund laufen und kein anderes programm stören 
  SetPriorityClass_(GetCurrentProcess_(), #IDLE_PRIORITY_CLASS) 
  openhauptfenster() 
  Repeat 
    Select WindowEvent() 
      Case #PB_Event_CloseWindow 
        Select EventWindow() 
          Case #hauptfenster 
            ;AK 
            ;If MessageRequester("Wirklich beenden?","Sicher, dass sie das Programm beenden wollen?",#PB_MessageRequester_YesNo)=6 
            End 
            ;EndIf 
          Case #visualisierungsfenster 
            stop_visualisierung() 
          Default 
            CloseWindow(EventWindow())  
        EndSelect 
      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case #hauptfenster_gadget_trackbar_futter 
            umwelt\essenzusatz=GetGadgetState(#hauptfenster_gadget_trackbar_futter) 
            update_gui_umweltkontrollen() 
          Case #hauptfenster_gadget_trackbar_mutationen 
            umwelt\mutationen=GetGadgetState(#hauptfenster_gadget_trackbar_mutationen) 
            update_gui_umweltkontrollen() 
        EndSelect 
      Case #PB_Event_Menu 
        Select EventMenu() 
          Case #hauptfenster_menu_web 
            ;nicht entfernen 
            SetPriorityClass_(GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS) 
            ShellExecute_(0,"open","http:\\www.nevu.de","","",#SW_SHOWNORMAL) 
            SetPriorityClass_(GetCurrentProcess_(), #IDLE_PRIORITY_CLASS) 
          Case #hauptfenster_menu_visualisierung 
            If Status\visualisierung 
              stop_visualisierung() 
            Else 
              start_visualisierung() 
            EndIf 
          Case #hauptfenster_menu_running 
            If Status\running 
              stop_running() 
            Else 
              start_running() 
            EndIf 
          Case #hauptfenster_menu_reset 
            reset() 
          Case #hauptfenster_menu_speichern 
            CreateFile(1,"save.save") 
            ForEach Zellen() ;alle zellen in ein file speichern 
              If WriteData(1,@Zellen(),SizeOf(ZELLE))<>SizeOf(ZELLE) 
                MessageRequester("Fehler","Fehler beim speichern. Nicht genügend festplattenplatz?") 
              EndIf 
            Next 
            CloseFile(1) 
          Case #hauptfenster_menu_laden 
            ClearList(Zellen()) 
            If OpenFile(1,"save.save") 
              Repeat ;alle zellen aus einer datei laden 
                AddElement(Zellen()) 
                ReadData(1, @Zellen(), SizeOf(ZELLE)) 
              Until Eof(1) 
            Else 
              MessageRequester("Fehler","Konnte Savefile nicht öffnen") 
            EndIf 
            CloseFile(1) 
        EndSelect 
      Case #WM_TIMER 
        Select EventwParam() 
          Case #timer_hauptfenster_statistik 
            SetGadgetText(#hauptfenster_gadget_text_Zellenanzahl,Str(CountList(Zellen()))) 
            SetGadgetText(#hauptfenster_gadget_text_rundenprosek,Str(statistik\weltzeit-statistik\alteweltzeit)) 
            SetGadgetText(#hauptfenster_gadget_text_weltzeit,Str(statistik\weltzeit)) 
            statistik\alteweltzeit=statistik\weltzeit 
        EndSelect          
      Case 0 
        If Status\visualisierung 
          visualisiere_welt() 
        EndIf 
        If Status\running 
          statistik\weltzeit+1 
          calculate_zellen() 
          place_food() 
        Else 
          Delay(10) 
        EndIf 
    EndSelect        
  ForEver 
EndProcedure 

umwelt\essenzusatz=30 
umwelt\mutationen=1 
reset() 
main() 
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Benutzeravatar
Machete @PB
Beiträge: 81
Registriert: 12.09.2006 03:12

Beitrag von Machete @PB »

Schade das es das nicht für 3.3 gibt :( , hört sich ziemlich cool an :allright:
Benutze Topos-PB-Version 3.3
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@Norbie

cool... ich war erst gegen ende des anderen threads drauf gestoßen.
schön, dass es eine überarbeitete version gibt, werd ich mir die tage ausgiebig ansehen.

btw:
schreib doch bitte deine PB-Version in deine signatur,
auch im Kopf des Listings ist eine Versionsangabe gut aufgehoben. ;)


@Machete
> Schade das es das nicht für 3.3 gibt
so schwierig sollte es nicht sein, das umzuschreiben.
auf den ersten blick sehe ich da nichts extrem spezifisches.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Also, besonders "klug" ist das nicht, was die da machen. Ich sehe da wenig Lernerfolg. Wird da noch was draus?
Optimismus ist ein Mangel an Information.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

"Also, besonders "klug" ist das nicht, was die da machen. Ich sehe da wenig Lernerfolg. Wird da noch was draus?"
...sagte Zeus zu Chronos, als er die Erde betrachtete... :lol:
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Beitrag von DarkSoul »

das da läuft auf 3,3 nicht, da hab ich mir die compilierte version gezogen.
wow! ein universum... ein digitales gewächshaus mit echten lebewesen!! :allright: :allright: :allright:

Lösch das nie! und wenn - lass dich nich vom tierschutzbund erwischen von wegen pixelamöbenmord! :mrgreen:
Bild
Antworten