Toon posts:

Excel vba - Game of Life help

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goedenavond,

Ik ben momenteel bezig met het leren van Excel Vba dmv het boek "Gestructureerd programmeren in Excel VBA" en nu is een opdracht in het boek om Conway's The game of life te creëren in Excel VBA.

Ik heb meerdere subroutines gecreëerd, een voor het willekeurig invullen van 1`en, een om de boel te resetten en een subroutine die zogenaamd controleert of een cell doodgaat of in leven blijft.

Ik krijg krijg alleen niet het resultaat dat ik wil en ik hoop dat iemand mij kan helpen.

Screenshot van het routine dat checkt of een cel doodgaat of in leven blijft:
Afbeeldingslocatie: https://i.imgur.com/XAEsy0Q.jpg

[ Voor 3% gewijzigd door Verwijderd op 21-02-2017 22:26 ]

Beste antwoord (via Verwijderd op 05-03-2017 23:45)


  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Lustucru schreef op woensdag 22 februari 2017 @ 00:05:
[...] Is elke generatie gelijk over het hele bord? Nu heb je een generatie per cel... Je zult waarschijnlijk eerst het hele bord moeten berekenen voordat je de nieuwe toestand in het bord schrijft.
Witte schreef op woensdag 22 februari 2017 @ 12:20:
Er zit nog een fout in: tijdens een generatie laat je al cellen sterven of tot leven komen
Hoezo 'nog'? ;)
Ik heb een tijdje geleden precies dit geprogrammeerd in Excel, ik heb dat opgelost door 2 collecties aan te maken:

* voor de geboorten
* voor de sterfgevallen
Mwah, ik zou één collectie opbouwen met daarin de nieuwe status. Kan ook de if then constructie simpeler:

code:
1
2
3
4
5
6
7
8
Select nBuren
case 3
      newState(x,y)=1
case 2
      newState(x,y)=currentState(x,y)
case else
      newState(x,y)=0
end select
Aan de randen gaat het ook mis bij jou. Je controleert bijvoorbeeld kolom 2 met buren in kolom 1, maar kolom 1 komt zelf nooit aan de beurt.
dat zou best wel eens correct kunnen zijn als 'rij1, kolom1, rij 42, kolom 42 intentionally left blank' :)

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland

Alle reacties


Acties:
  • +1 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Welkom op GoT.

Ik zie op het eerste gezicht een fout en een problematisch ding:
- je vermindert het aantal buren met één, ongeacht of de cel zelf leeft of niet. Dat is niet correct.
- is elke generatie gelijk over het hele bord? Nu heb je een generatie per cel... Je zult waarschijnlijk eerst het hele bord moeten berekenen voordat je de nieuwe toestand in het bord schrijft.


Ik krijg krijg alleen niet het resultaat dat ik wil
Het helpt als je beschrijft wat niet lukt ipv alleen dat het niet is wat je wilt.
Screenshot van het routine
Liever geen screenshots van code. Zet de code tussen [code=vb][/code] tags

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • +1 Henk 'm!

  • Witte
  • Registratie: Februari 2000
  • Laatst online: 29-07 11:23
Er zit nog een fout in: tijdens een generatie laat je al cellen sterven of tot leven komen: dit beïnvloedt cellen die er na 'aan de beurt' zijn. Dit is onjuist: alle cellen sterven of komen tegelijk tot leven in een volgende generatie.

Ik heb een tijdje geleden precies dit geprogrammeerd in Excel, ik heb dat opgelost door 2 collecties aan te maken:

* voor de geboorten
* voor de sterfgevallen

Tijdens het evalueren bouw je je collecties op, na het evalueren pas je de collectie toe op de populatie. Dan kan je naar de volgende cycle.

[ Voor 39% gewijzigd door Witte op 22-02-2017 12:25 ]

Houdoe


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor de replies! _/-\o_

Mijn excuses voor het niet gebruiken van de tags en het niet duidelijk omschrijven wat "niet lukt".
De eerste keer dat ik actief ben op een forum en ik liep gister helemaal vast met mijn geklungel :X .

Nu ik jullie suggesties lees, denk ik van "maar natuurlijk..", maar goed even kijken of het me lukt om het toe te passen zodra ik thuis ben.

Acties:
  • 0 Henk 'm!

  • Witte
  • Registratie: Februari 2000
  • Laatst online: 29-07 11:23
Aan de randen gaat het ook mis bij jou. Je controleert bijvoorbeeld kolom 2 met buren in kolom 1, maar kolom 1 komt zelf nooit aan de beurt.

Wat je kan doen: neem je for-loopjes wél van 1 tot max i.p.v. 2 tot max -1, en beschouw 0 als max en max+1 als 1. (voor zowel rijen als kolommen)
Daarmee creeer je een soort oneindig veld.

[ Voor 5% gewijzigd door Witte op 22-02-2017 13:32 ]

Houdoe


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Lustucru
  • Registratie: Januari 2004
  • Niet online

Lustucru

26 03 2016

Lustucru schreef op woensdag 22 februari 2017 @ 00:05:
[...] Is elke generatie gelijk over het hele bord? Nu heb je een generatie per cel... Je zult waarschijnlijk eerst het hele bord moeten berekenen voordat je de nieuwe toestand in het bord schrijft.
Witte schreef op woensdag 22 februari 2017 @ 12:20:
Er zit nog een fout in: tijdens een generatie laat je al cellen sterven of tot leven komen
Hoezo 'nog'? ;)
Ik heb een tijdje geleden precies dit geprogrammeerd in Excel, ik heb dat opgelost door 2 collecties aan te maken:

* voor de geboorten
* voor de sterfgevallen
Mwah, ik zou één collectie opbouwen met daarin de nieuwe status. Kan ook de if then constructie simpeler:

code:
1
2
3
4
5
6
7
8
Select nBuren
case 3
      newState(x,y)=1
case 2
      newState(x,y)=currentState(x,y)
case else
      newState(x,y)=0
end select
Aan de randen gaat het ook mis bij jou. Je controleert bijvoorbeeld kolom 2 met buren in kolom 1, maar kolom 1 komt zelf nooit aan de beurt.
dat zou best wel eens correct kunnen zijn als 'rij1, kolom1, rij 42, kolom 42 intentionally left blank' :)

De oever waar we niet zijn noemen wij de overkant / Die wordt dan deze kant zodra we daar zijn aangeland


Acties:
  • 0 Henk 'm!

  • Witte
  • Registratie: Februari 2000
  • Laatst online: 29-07 11:23
in mijn collectie-systeem sla ik uiteraard alleen de cellen op die gaan veranderen. lijkt efficienter dan om het hele speelveld te dupliceren

Houdoe


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Sorry voor de late reactie,

Ik ben in ieder geval verder met mijn "projectje".
Multidimensional arrays kende ik nog niet toen ik hier om hulp vroeg -- dus ik zat eerst met de vraag hoe ik een collectie kon maken die bijhield wat de nieuwe status van de cellen zou worden.

off-topic: ik heb geen achtergrond in programmeren en dit is puur uit interesse, maar online staat er zoveel geschreven dat je door de bomen het bos niet kan zien.
Dus ik ben blij dat er fora zoals deze zijn waarbij mensen je een beetje in de goede richting kunnen duwen. /offtopic
Lustucru schreef op woensdag 22 februari 2017 @ 15:47:

[...]
dat zou best wel eens correct kunnen zijn als 'rij1, kolom1, rij 42, kolom 42 intentionally left blank' :)
Ja de range is van B2:AO41 ,dus ik denk niet dat het een probleem is (?).

In ieder geval:
De code is onnodig ingewikkeld.
Ik ben nog aan het kijken hoe het netter/efficiënter kan,maar ik was blij dat ik een stap vooruit had gemaakt.

Het probleem wat ik nu heb, is dat als ik het vergelijk met een andere simulator (https://bitstorm.org/gameoflife) ,het een iets ander resultaat geeft -- wat waarschijnlijk te maken heeft met de range die ik opgegeven heb.

Bijv bij "glider".
Bij de andere simulator bewegen de gekleurde vakjes uit de range, maar bij mij vormt het een blokje zodra het bij de rand komt, waardoor er verder geen beweging meer komt.
Dus nog even kijken hoe ik dat opgelost ga krijgen.

Suggesties zijn welkom! O-)

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 

Sub Startspel()
Application.ScreenUpdating = False
Dim kol As Integer, rij As Integer, buren As Integer
Dim x As Integer, y As Integer, nieuwegen() As Variant
ReDim nieuwegen(2 To 41, 2 To 41)

For rij = 2 To 41
    For kol = 2 To 41
    buren = 0
        For x = -1 To 1
            For y = -1 To 1
                If Cells(rij, kol).Offset(x, y) = 1 Then
                buren = buren + 1
                End If
            Next
        Next
     
        If Cells(rij, kol) = 1 Then
        buren = buren - 1
        End If
    
        If buren = 3 Then
            nieuwegen(rij, kol) = 1
        ElseIf buren = 2 And Cells(rij, kol) = 1 Then
            nieuwegen(rij, kol) = 1
        Else
            nieuwegen(rij, kol) = ""
        End If
    Next
Next

    For rij = 2 To 41
            For kol = 2 To 41
            If Cells(rij, kol) <> nieuwegen(rij, kol) Then
            Cells(rij, kol) = nieuwegen(rij, kol)
            End If
            Next
    Next
Application.ScreenUpdating = True
End Sub

[ Voor 2% gewijzigd door Verwijderd op 06-03-2017 00:00 . Reden: nettere opmaak van tekst ]

Pagina: 1