Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[c#] Probleem met programmeren John Conway's Game of Life

Pagina: 1
Acties:

  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Hoi,

Om een programmeer taal te leren is het een goede oefening om dingen na te maken. Dit ben ik dus gaan doen met John Conway's Game of Life. Dit leek mij simpel te doen.

John Conway's Game of Life is een stel regels waarmee een soort leven nagebootst word. Er zijn 4 regels:

code:
1
2
3
4
1. Is een punt levend en omring door 2 of 3 levende buren dan blijft hij leven.
2. Is een levend punt omringd door meer dan 3 buren dan sterft hij door overbevolking.
3. Is een levend punt omringd door minder dan 2 buren dan sterf hij door eenzaamheid.
4. Is een door punt omringd door precies 3 buren dan word hij levend.


Dit leek mij simpel te doen, maar het stuk code dat de buren van een punt moet tellen maakt fouten: Waar een dood punt bv 4 buren heeft telt hij er soms 6 bv.

Mijn code:

C#:
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
43
44
45
46
47
48
        public int countneighbours(int x, int y)
        {
            //Number of Neighbors
            int n = 0;

            //Row above
            if (y >= 1)
            {
                if (x >= 1)
                {
                    if (raster[x-1,y-1]) {n++;}
                    if (raster[x,y-1]) {n++;}
                }

                if (x < raster_width)
                {
                    if (raster[x+1,y-1]) {n++;}
                }   
            }
            //Same row
            if (x >= 1)
            {
                if (raster[x - 1, y]) { n++; }
            }

            if (x < raster_width)
            {
                if (raster[x + 1, y]) { n++; }
            }
               

            //Row below
            if (y < raster_height)
            {
                if (x >= 1)
                {
                    if (raster[x - 1, y + 1]) { n++; }
                    if (raster[x, y + 1]) { n++; }
                }

                if (x < raster_width)
                {
                    if (raster[x + 1, y + 1]) { n++; }
                }  
                   
            }
            return n;
        }


Ik heb dit stuik code al 3 keer opnieuw geschreven en ik kan geen fout meer ontdekken.

Kan iemand mij hier bij helpen? Alvast bedankt!

edit:

Hier een plaatje met in iedere cel het aantal getelde buren, misschien zien jullie een patroon?:

http://img530.imageshack....48/gameoflifeerrorrn9.jpg

[ Voor 3% gewijzigd door Synch op 01-05-2008 12:23 ]


  • Invisible_man
  • Registratie: Juni 2006
  • Nu online
Wat je zou kunnen doen in het kader van object georienteerd programeren is elke cel zijn eigen instantie van een cel-klasse geven. In die klasse verwijs je met 4 (boven, onder, links, rechts) of 8 verwijzingen (als je ook diagonaal werkt) naar de buren. Heeft hij aan 1 kant geen buren omdat hij tegen de rand van het speelveld zit, laat je die waarden "null". Als je meer van deze techniek wil weten, zoek eens op de term recursiviteit.

Wil je het nog mooier maken, laat je elke cel in een eigen thread lopen.

Wat je nu met deze twee technieken gedaan hebt is telkens de nieuwe waarde van de cellen laten bepalen door de cellen (de objecten dus) zelf ipv door een algemeen stukje code ergens in je main classe. Oftewel: object georienteerd.

Edit: maar om even op jouw code terug te komen, in de "row above" kijk je eerst of je niet in de bovenste rij zit (anders zou je geen bovenburen hebben) en dan ga je kijken of je niet in de meest linker kolom zit. Zit je dat (x=0), neem je echter niet de cel direct boven [x,y] cel mee, de [0,y-1] cel dus.

"Same row" lijkt mij zo wel goed te gaan.

"Row below": Hier neem je weer [0,y+1] niet mee als x=0.

[ Voor 21% gewijzigd door Invisible_man op 01-05-2008 12:39 ]


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 12:15

Haan

dotnetter

Je checkt steeds twee dingen: "x >= 1" (dat is trouwens veel duidelijker te schrijven als "x > 0 )
en "x< breedte/hoogte", maar die kunnen natuurlijk allebei true zijn en dus allebei uitgevoerd worden, volgens mij ga je daar de fout in.

@hierboven: volgens mij is dat nog wat te ingewikkeld als je pas net bezig bent ;)

[ Voor 16% gewijzigd door Haan op 01-05-2008 12:33 ]

Kater? Eerst water, de rest komt later


Verwijderd

volgens mij is het 3 als je op de rand zit en anders 4.

int neigbours = x == 0 // bovenste rand
|| y == 0 // linker rand
|| y == length-1 // rechter rand
|| x == length - 1 // onderste rand
? 3 : 4;

  • Invisible_man
  • Registratie: Juni 2006
  • Nu online
Haan schreef op donderdag 01 mei 2008 @ 12:31:
Je checkt steeds twee dingen: "x >= 1" (dat is trouwens veel duidelijker te schrijven als "x > 0 )
en "x< breedte/hoogte", maar die kunnen natuurlijk allebei true zijn en dus allebei uitgevoerd worden, volgens mij ga je daar de fout in.

@hierboven: volgens mij is dat nog wat te ingewikkeld als je pas net bezig bent ;)
Om direct in deze opdracht te verwerken mischien wel, maar iig het recursief programeren is iets wat wel vrij snel al aan te leren is (en het is ook meer kijkend naar hoe ik deze opdracht zou uitvoeren om eerlijk te zijn :)).

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
ozakigames schreef op donderdag 01 mei 2008 @ 12:09:
Dit leek mij simpel te doen, maar het stuk code dat de buren van een punt moet tellen maakt fouten: Waar een dood punt bv 4 buren heeft telt hij er soms 6 bv.
Gokje: je hebt maar 1 instantie van je raster, en je loopt sequentieel door al je cellen heen om ze dood of levend te maken?
Stel dat je regel voor regel door je raster loopt, en voor elke regel van links naar rechts, dan zal je countneighbours(x, y) voor een cel de bijgewerkte versie van de drie cellen boven je en de cel links van je bekijken, maar de oude versie van de andere cellen. En dat levert een verkeerd aantal op.

Je zult dus altijd met twee versies van je raster moeten werken: 1 waar je de huidige situatie vanuit leest, en een tweede waarin je de nieuwe situatie in wegschrijft. Zo zul je dit probleem niet krijgen
[/quote]

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Invisible_man schreef op donderdag 01 mei 2008 @ 12:27:
Wat je zou kunnen doen in het kader van object georienteerd programeren is elke cel zijn eigen instantie van een cel-klasse geven. In die klasse verwijs je met 4 (boven, onder, links, rechts) of 8 verwijzingen (als je ook diagonaal werkt) naar de buren. Heeft hij aan 1 kant geen buren omdat hij tegen de rand van het speelveld zit, laat je die waarden "null". Als je meer van deze techniek wil weten, zoek eens op de term recursiviteit.

Wil je het nog mooier maken, laat je elke cel in een eigen thread lopen.
Dit lijkt mij hopeloos ingewikkeld en niet-performant. Recursiviteit heeft hier weinig toegevoegde waarde, komop mensen het gaat om een simpele twee dimensionale array.

@ts: Ik zou het probleem iets robuuster aanpakken. Wat je nu eigenlijk doet is alle uitzonderingen (de randen) eruit te filteren en daarvoor speciele conditie regels te creeren. Dit is onoverzichtelijke en is foutgevoelig. Je kan ook voor een simpelere oplossing gaan die alle cellen op een identieke behandelt, dus alle 8 vierkantjes eromheen bekijkt. Maar voor waardes van x en y die buiten het grid liggen gewoon 0 teruggeven.

[ Voor 23% gewijzigd door Orphix op 01-05-2008 12:43 ]


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Haan schreef op donderdag 01 mei 2008 @ 12:31:
Je checkt steeds twee dingen: "x >= 1" (dat is trouwens veel duidelijker te schrijven als "x > 0 )
en "x< breedte/hoogte", maar die kunnen natuurlijk allebei true zijn en dus allebei uitgevoerd worden, volgens mij ga je daar de fout in.

@hierboven: volgens mij is dat nog wat te ingewikkeld als je pas net bezig bent ;)
Hmm, volgens mij moeten die ook allebei uitgevoerd worden.

Eerst check ik of x >= 1 om vervolgens linksboven te checken (en onnodig ook gelijk boven, daar is de check niet voor nodig).
Als ik dan rechtsboven wil checken moet ik weten of rechtsboven niet buiten het veld is (dus x < raster_width).

Je moet namelijk (mits je niet aan de rand van het veld zit) alle 8 checks uitvoeren (ook diagonaal dus).
Wat je zou kunnen doen in het kader van object georienteerd programeren is elke cel zijn eigen instantie van een cel-klasse geven. In die klasse verwijs je met 4 (boven, onder, links, rechts) of 8 verwijzingen (als je ook diagonaal werkt) naar de buren. Heeft hij aan 1 kant geen buren omdat hij tegen de rand van het speelveld zit, laat je die waarden "null". Als je meer van deze techniek wil weten, zoek eens op de term recursiviteit.

Wil je het nog mooier maken, laat je elke cel in een eigen thread lopen.

Wat je nu met deze twee technieken gedaan hebt is telkens de nieuwe waarde van de cellen laten bepalen door de cellen (de objecten dus) zelf ipv door een algemeen stukje code ergens in je main classe. Oftewel: object georienteerd.

Edit: maar om even op jouw code terug te komen, in de "row above" kijk je eerst of je niet in de bovenste rij zit (anders zou je geen bovenburen hebben) en dan ga je kijken of je niet in de meest linker kolom zit. Zit je dat (x=0), neem je echter niet de cel direct boven [x,y] cel mee, de [0,y-1] cel dus.
Erm, threading etc lijkt mij een beetje overbodig. En met klassen werken lijkt me voor zo iets simpel ook niet nodig. Met je punt over mijn code heb je gelijk. In de hoeken gaat het fout, maar dat is volgens mij makkelijk op te lossen. Het neemt niet weg dat er in een punt midden in het veld ook fouten worden gemaakt. Toch bedankt!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Invisible_man schreef op donderdag 01 mei 2008 @ 12:27:
Wil je het nog mooier maken, laat je elke cel in een eigen thread lopen.
:D
Wordt lachen in een 15x15 grid ofzo :X

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
MrBucket schreef op donderdag 01 mei 2008 @ 12:38:
[...]

Gokje: je hebt maar 1 instantie van je raster, en je loopt sequentieel door al je cellen heen om ze dood of levend te maken?
Stel dat je regel voor regel door je raster loopt, en voor elke regel van links naar rechts, dan zal je countneighbours(x, y) voor een cel de bijgewerkte versie van de drie cellen boven je en de cel links van je bekijken, maar de oude versie van de andere cellen. En dat levert een verkeerd aantal op.

Je zult dus altijd met twee versies van je raster moeten werken: 1 waar je de huidige situatie vanuit leest, en een tweede waarin je de nieuwe situatie in wegschrijft. Zo zul je dit probleem niet krijgen
[/quote]
Nope, heb ik aan gedacht, ik schrijf alles weg naar raster_next en als ik klaar ben doen ik raster = raster_next. Toch bedankt.

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
ozakigames schreef op donderdag 01 mei 2008 @ 12:44:
[...]


Nope, heb ik aan gedacht, ik schrijf alles weg naar raster_next en als ik klaar ben doen ik raster = raster_next. Toch bedankt.
Hmm... jammer :P

  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

Ik heb Conway's Game of Life al eens gemaakt in C#, mijn implementatie kan je hier downloaden. :)

Sole survivor of the Chicxulub asteroid impact.


Verwijderd

Verwijderd in "[c#] Probleem met programmeren John Conw..."
int neighbours =
IsNeigbour(x-1,y-1) +
IsNeigbour(x-1,y) +
IsNeigbour(x-1,y+1) +
IsNeigbour(x,y-1) +
IsNeigbour(x,y+1) +
IsNeigbour(x+1,y-1);
IsNeigbour(x+1,y) +
IsNeigbour(x+1,y+1);

public int IsNeigbour(int x, int y)
{
if( x < 0 || y < 0 || y > raster.lenght - 1 || x > raster.length - 1)
return false;
else
return raster[x,y];
}

[ Voor 32% gewijzigd door Verwijderd op 01-05-2008 12:52 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 14:57

Gerco

Professional Newbie

RobIII schreef op donderdag 01 mei 2008 @ 12:44:
Wordt lachen in een 15x15 grid ofzo :X
Plus dat het incorrect resultaten gaat geven. Sommige cellen zullen dan uit de pas gaan lopen met de rest terwijl het toepassen van de rules 1 operatie zou moeten zijn.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Gerco schreef op donderdag 01 mei 2008 @ 12:49:
[...]

Plus dat het incorrect resultaten gaat geven. Sommige cellen zullen dan uit de pas gaan lopen met de rest terwijl het toepassen van de rules 1 operatie zou moeten zijn.
Daar is wel wat op te fispernullen maar dan heb je weer zo weinig aan je threads :P

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Verwijderd schreef op donderdag 01 mei 2008 @ 12:46:
Verwijderd in "[c#] Probleem met programmeren John Conw..."
int neighbours =
IsNeigbour(x-1,y-1) +
IsNeigbour(x-1,y) +
IsNeigbour(x-1,y+1) +
IsNeigbour(x,y-1) +
IsNeigbour(x,y+1) +
IsNeigbour(x+1,y-1);
IsNeigbour(x+1,y) +
IsNeigbour(x+1,y+1);

public int IsNeigbour(int x, int y)
{
if( x < 0 || y < 0 || y > raster.lenght - 1 || x > raster.length - 1)
return false;
else
return raster[x,y];
}
Jezus, ik had hem ook al aangepast naar 8 richtingen maar hij doet het nogsteeds niet, sorry. Ik denk dat ik maar eens alle belangrijke delen van mij code ga sturen.

Is +- 150 regels te veel?

  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
C#:
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 public void raster_update()
        {
            int x = 0;
            int y = 0;

            for (x = 0; x <= raster_width; x++)
            {

                for (y = 0; y <= raster_height; y++)
                {
                    //int surrounded = countneighbours(x, y);
                    int surrounded =
                        IsNeigbour(x - 1, y) +
                        IsNeigbour(x + 1, y) +
                        IsNeigbour(x, y - 1) +
                        IsNeigbour(x, y + 1) +

                        IsNeigbour(x - 1, y - 1) +
                        IsNeigbour(x + 1, y - 1) +
                        IsNeigbour(x - 1, y + 1) +
                        IsNeigbour(x + 1, y + 1);


                    if (raster[x, y] == true)
                    {

                        if (surrounded >= 2 && surrounded <= 3)
                        {
                            raster_next[x, y] = true;
                        }

                        if (surrounded > 3)
                        {
                            raster_next[x, y] = false;
                        }

                        if (surrounded < 2)
                        {
                            raster_next[x, y] = false;
                        }
                    }
                    else if (raster[x,y] == false)
                    {
                        if (surrounded == 3)
                        {
                            raster_next[x, y] = true;
                        }
                    }
                    Raster_neighbours[x, y] = surrounded;

                }

            }

            raster = raster_next;

        }


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public int IsNeigbour(int x, int y)
        {
            if (x < 0 || y < 0 || y > raster_height - 1 || x > raster_width - 1)
                return 0;
            else
            {
                if (raster[x, y] == true)
                {
                    return 1;
                }
                else
                { return 0; }
            }
        }


Sorry dat het zo moet maar ik word gek hier van.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
ozakigames schreef op donderdag 01 mei 2008 @ 12:55:
[...]


Jezus, ik had hem ook al aangepast naar 8 richtingen maar hij doet het nogsteeds niet, sorry. Ik denk dat ik maar eens alle belangrijke delen van mij code ga sturen.

Is +- 150 regels te veel?
Euh; here's an idea: debug je code eens? Stap er (stap voor stap) doorheen? Doet 't wat je ervan verwacht? Het is toch geen rocket science waar je nu mee bezig bent?

Debuggen: Hoe doe ik dat?

[ Voor 78% gewijzigd door RobIII op 01-05-2008 13:03 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Heb ik ook al geprobeerd. Volgens mij gaat het fout bij de linker checks. Het probleem is dat hij soms wel en soms niet goed telt.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
ozakigames schreef op donderdag 01 mei 2008 @ 13:06:
Het probleem is dat hij soms wel en soms niet goed telt.
De kunst van debuggen is juist om te kijken waarom er dan 'soms' wel en 'soms' niet goed geteld wordt.
ozakigames schreef op donderdag 01 mei 2008 @ 13:06:
Volgens mij gaat het fout bij de linker checks.
En volgens je debugger?

[ Voor 31% gewijzigd door RobIII op 01-05-2008 13:08 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Wat dacht je ervan als je het eens iets anders aanpakt:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public bool IsInBounds(int x, int y)
{
   return (x >= 0 && x < _width && y >= 0 && y < height);
}

public int GetNeighbourCount(int x, int y)
{
  int result = 0;
  for(int dy = -1; dy <= 1; dy++)
  {
     for(int dx = -1; dx <= 1; dx++)
     {
         if(dy == 0 && dx == 0)
            continue;
         if(IsInBounds(x + dx, y + dy) && _raster[y + dy, x + dx] == true)
            result++;
     }
  }

  return result;
}

[ Voor 0% gewijzigd door MrBucket op 01-05-2008 13:14 . Reden: Sorry, typvautje ]


  • AtleX
  • Registratie: Maart 2003
  • Niet online

AtleX

Tyrannosaurus Lex 🦖

In mijn implementatie controleer ik als volgt het aantal levende buren:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private int checkLivingNeighbours(int x, int y)
        {            
            int livingNeighbours = 0;

            for (int dx = -1; dx < 2; dx++)
            {
                for (int dy = -1; dy < 2; dy++)
                {
                    if (!((x + dx) == x && (y + dy) == y))
                    {
                        if (this.checkCell(x + dx, y + dy))
                            livingNeighbours++;
                    }
                }
            }
            return livingNeighbours;            
        }


En checkCell():
C#:
1
2
3
4
5
6
7
private bool checkCell(int x, int y)
        {
          if ((x < 0) || (x >= this.width)) return false;
          if ((y < 0) || (y >= this.height)) return false;

          return this.currentGeneration[x, y].getAlive();
        }

[ Voor 16% gewijzigd door AtleX op 01-05-2008 13:18 ]

Sole survivor of the Chicxulub asteroid impact.


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
x = 4
y = 6

Oke, ik heb al 1 fout met de check ontdekt.

Hij checkt punt 4,6 Hij checkt boven en dus of punt 4,5 is true.
Hij gaat door de check heen en add 1 bij neighbours.

Nu breekt mijn spreekwoordelijke klomp want als ik in het raster kijk zie ik bij 4,5 true staat (duhh), maar op het getekende veld is dat hokje wit.

Tot hier kan ik debuggen maar nu??

  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
AtleX schreef op donderdag 01 mei 2008 @ 13:17:
In mijn implementatie controleer ik als volgt het aantal levende buren:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private int checkLivingNeighbours(int x, int y)
        {            
            int livingNeighbours = 0;

            for (int dx = -1; dx < 2; dx++)
            {
                for (int dy = -1; dy < 2; dy++)
                {
                    if (!((x + dx) == x && (y + dy) == y))
                    {
                        if (this.checkCell(x + dx, y + dy))
                            livingNeighbours++;
                    }
                }
            }
            return livingNeighbours;            
        }


En checkCell():
C#:
1
2
3
4
5
6
7
private bool checkCell(int x, int y)
        {
          if ((x < 0) || (x >= this.width)) return false;
          if ((y < 0) || (y >= this.height)) return false;

          return this.currentGeneration[x, y].getAlive();
        }
Sorry maar dat is toch precies hetzelfde als wat ik doe (mooi programma trouwens)?

*snip* We zijn geen persoonlijke debug-service... Hier de code, let niet om de rommel en de fancy upload website.

[ Voor 8% gewijzigd door RobIII op 01-05-2008 13:31 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
ozakigames schreef op donderdag 01 mei 2008 @ 13:21:

Nu breekt mijn spreekwoordelijke klomp want als ik in het raster kijk zie ik bij 4,5 true staat (duhh), maar op het getekende veld is dat hokje wit.

Tot hier kan ik debuggen maar nu??
Dan heb je dus een inconsistentie in wat je tekent en in wat de daadwerkelijke data is; dan zoek je nu verder naar het probleem. What else? We gaan hier in PRG wel uit van een klein beetje eigen inzet en dit 'hou mijn handje eens vast' gedoe wordt dan ook niet erg op prijs gesteld.

Wil je voortaan trouwens de edit knop ( Afbeeldingslocatie: http://tweakimg.net/g/forum/templates/tweakers/images/icons/edit.gif ) gebruiken in plaats van 2 (of meer) posts achter elkaar te plaatsen? Zie ook topickick binnen 24 uur

[ Voor 32% gewijzigd door RobIII op 01-05-2008 13:34 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Oke, sorry voor de dubbelpost en de link (en sorry voor deze post maar door jouw edit kan ik heb niet meer editten). Ik ben al 2 dagen met dit onderdeel van de code bezig en ik ben zwaar gefrustreerd.

Ik gebruik xna voor dit project en ik ga daarom eerst eens uitzoeken wat er nu in welke volgorde gebeurd (ik neem aan dat hij eerst update en dan draw doet).

Mijn draw code is verder gewoon goed.

edit:
Variable-Step Game Loops
A variable-step game calls its Update and Draw methods in a continuous loop without regard to the TargetElapsedTime. Setting Game.IsFixedTimeStep to false causes a Game to use a variable-step game loop.
Dit heb ik gevonden in de help van xna 2.0 en daarna heb ik IsFixedTimeStep = false; er bij gezet. Helaas geen resultaat. Als het goed is doet hij nu draw en update om de beurt. Er zou nu maximaal 1 step verschil tussen de debug tekst en de draw moeten zitten.

Dit neemt niet weg dat bij de draw ik de raster en raster_neighbours draw. Ze zouden dus gewoon moeten aansluiten. Hierdoor kom ik tot de conclusie dat de fout in de countneighbours code zit.

[ Voor 47% gewijzigd door Synch op 01-05-2008 13:44 ]


Verwijderd

Invisible_man schreef op donderdag 01 mei 2008 @ 12:27:
Wil je het nog mooier maken, laat je elke cel in een eigen thread lopen.
M'n eerste implementatie van Life was op een 80x25 grid op een 3.25 MHz Z80. Als je iedere cel een eigen thread geeft, denk ik dat mijn Sinclair ZX81 oplossing een flinke quad core er nog steeds uitfietst... ;)

  • Fiander
  • Registratie: Februari 2001
  • Laatst online: 28-05 12:35
code:
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
            //Row above 
            if (y >= 1) 
            { 
                if (x >= 1) 
                { 
                    if (raster[x-1,y-1]) {n++;} 
                    if (raster[x,y-1]) {n++;} 
                } 

                if (x < raster_width) 
                { 
                    if (raster[x+1,y-1]) {n++;} 
                }    
            } 
            //Same row 
            if (x >= 1) 
            { 
                if (raster[x - 1, y]) { n++; } 
            } 

            if (x < raster_width) 
            { 
                if (raster[x + 1, y]) { n++; } 
            } 
                

            //Row below 
            if (y < raster_height) 
            { 
                if (x >= 1) 
                { 
                    if (raster[x - 1, y + 1]) { n++; } 
                    if (raster[x, y + 1]) { n++; } 
                } 

                if (x < raster_width) 
                { 
                    if (raster[x + 1, y + 1]) { n++; } 
                }   
                    
            }


zou je mij kunnen vertellen waarom in row above en in row below,
je controleert of x>=1 en vervolgens dat dubbel pakt ???

het lijkt mij dat je dit bedoelt ?
code:
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
43
            //Row above 
            if (y >= 1) 
            { 
                if (x >= 1) 
                { 
                    if (raster[x-1,y-1]) {n++;}                     
                } 

               if (raster[x,y-1]) {n++;} 

                if (x < raster_width) 
                { 
                    if (raster[x+1,y-1]) {n++;} 
                }    
            } 
            //Same row 
            if (x >= 1) 
            { 
                if (raster[x - 1, y]) { n++; } 
            } 

            if (x < raster_width) 
            { 
                if (raster[x + 1, y]) { n++; } 
            } 
                

            //Row below 
            if (y < raster_height) 
            { 
                if (x >= 1) 
                { 
                    if (raster[x - 1, y + 1]) { n++; }                   
                } 

                if (raster[x, y + 1]) { n++; } 

                if (x < raster_width) 
                { 
                    if (raster[x + 1, y + 1]) { n++; } 
                }   
                    
            }

Deze sig is een manueel virus!! Als je dit leest heb je het. Mail dit bericht naar iedereen die je kent, en verwijder alle bestanden van je computer.


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
ozakigames schreef op donderdag 01 mei 2008 @ 13:37:

Dit heb ik gevonden in de help van xna 2.0 en daarna heb ik IsFixedTimeStep = false; er bij gezet. Helaas geen resultaat. Als het goed is doet hij nu draw en update om de beurt. Er zou nu maximaal 1 step verschil tussen de debug tekst en de draw moeten zitten.

Dit neemt niet weg dat bij de draw ik de raster en raster_neighbours draw. Ze zouden dus gewoon moeten aansluiten. Hierdoor kom ik tot de conclusie dat de fout in de countneighbours code zit.
Het maakt voor je programma niet uit of je iFixedTimeStep gebruikt, dat betekend slechts dat elke 16MS je update method gedraait wordt (60x per seconde)

Wat je zeker moet weten is dat je je DRAW en UPDATE methods goed gescheiden houd en dat je Update gewoon een goed grid oplevert wat je DrawMethod dan in 1x kan lezen en tekst + vakjes bij kan zetten.

Post anders is het stukje uit je draw method die ervoor zorgt dat de vakjes met juiste waarden op het scherm komen.

~ Mijn prog blog!


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

ozakigames schreef op donderdag 01 mei 2008 @ 13:21:
Nu breekt mijn spreekwoordelijke klomp want als ik in het raster kijk zie ik bij 4,5 true staat (duhh), maar op het getekende veld is dat hokje wit.
ozakigames schreef op donderdag 01 mei 2008 @ 13:37:
Ik gebruik xna voor dit project en ik ga daarom eerst eens uitzoeken wat er nu in welke volgorde gebeurd (ik neem aan dat hij eerst update en dan draw doet).

Mijn draw code is verder gewoon goed.
Beide quotes spreken elkaar tegen, en het door mij dikgedrukte deel van de laatste quote is de oorzaak daarvan. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
-NMe- schreef op donderdag 01 mei 2008 @ 19:13:
[...]


[...]

Beide quotes spreken elkaar tegen, en het door mij dikgedrukte deel van de laatste quote is de oorzaak daarvan. ;)
Klopt, en in XNA gaat het half overlappend, Shawn Hargreaves (een MS techie) heeft het zo weergegeven op zijn blog:

Afbeeldingslocatie: http://blogs.msdn.com/blogfiles/shawnhar/WindowsLiveWriter/Anelfinabox_F9EB/async.png
(in het ideale geval, is dit hoe XNA werkt. zie voor echt diepe technische uitleg de blog items van af "An Elf in a Box" op http://blogs.msdn.com/shawnhar/

Maar imho zou dit geen problemen moeten geven, misschien slechts bij het debuggen, maar ik neem aan dat je niet 60x per seconden die berekeningen laat doen, anders is de game of life wel erg snel over. Probeer het stapgewijs te laten gebeuren bijvoorbeeld door een druk op de spatie.
(Zorg er dan wel voor dat je keyboardState en prevKeyboardState constructie hebt, anders is heel even de spatie indrukken nog steeds equivalent aan 1000jr, je doet dus eerst zoiets:
C#:
1
2
3
4
5
6
7
//in Update
keyBoardState = Keyboard.GetState()
if (keyBoardState.isKeyDown(Keys.Enter) && prevKeyBoardState.isKeyDown(Keys.Enter) == false)
{
  //Logica voor 1 stap verder
}
prevKeyBoardState = keyBoardState;

~ Mijn prog blog!


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
roy-t schreef op donderdag 01 mei 2008 @ 19:02:
[...]


Het maakt voor je programma niet uit of je iFixedTimeStep gebruikt, dat betekend slechts dat elke 16MS je update method gedraait wordt (60x per seconde)

Wat je zeker moet weten is dat je je DRAW en UPDATE methods goed gescheiden houd en dat je Update gewoon een goed grid oplevert wat je DrawMethod dan in 1x kan lezen en tekst + vakjes bij kan zetten.

Post anders is het stukje uit je draw method die ervoor zorgt dat de vakjes met juiste waarden op het scherm komen.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            for (int x = 0; x <= raster_width; x++)
            {

                for (int y = 0; y <= raster_height; y++)
                {
                    if (raster[x, y] == true)
                    {
                        sprites_batch.Draw(stone_black, new Vector2(x * 16, y * 16), Color.White);
                        sprites_batch.DrawString(font, Raster_neighbours[x, y].ToString(), new Vector2(x * 16, y * 16), Color.White);

                    }
                    else
                    {

                        sprites_batch.Draw(stone_white, new Vector2(x * 16, y * 16), Color.White);
                        sprites_batch.DrawString(font, Raster_neighbours[x, y].ToString(), new Vector2(x * 16, y * 16), Color.Black);

                    }
                }
            }


edit: @ Fiander: Ik gebruik die code sowieso niet meer: zie Verwijderd in "\[c#] Probleem met programmeren John Conw..."

[ Voor 5% gewijzigd door Synch op 01-05-2008 22:25 ]


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
ozakigames schreef op donderdag 01 mei 2008 @ 22:21:
[...]


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            for (int x = 0; x <= raster_width; x++)
            {

                for (int y = 0; y <= raster_height; y++)
                {
                    if (raster[x, y] == true)
                    {
                        sprites_batch.Draw(stone_black, new Vector2(x * 16, y * 16), Color.White);
                        sprites_batch.DrawString(font, Raster_neighbours[x, y].ToString(), new Vector2(x * 16, y * 16), Color.White);

                    }
                    else
                    {

                        sprites_batch.Draw(stone_white, new Vector2(x * 16, y * 16), Color.White);
                        sprites_batch.DrawString(font, Raster_neighbours[x, y].ToString(), new Vector2(x * 16, y * 16), Color.Black);

                    }
                }
            }


edit: @ Fiander: Ik gebruik die code sowieso niet meer: zie Verwijderd in "\[c#] Probleem met programmeren John Conw..."
Die code ziet er iig goed uit alleen zou (programma correct)
for (int x = 0; x <= raster_width; x++ anders moeten nl. for (int x = 0; x < raster_width; x++)
maar waarschijnlijk heb je de variabele raster_width gewoon de echte breedte -1 gedaan (ook zero based dus)

Ik vraag me wel een beetje af wat je opslaag in de variabele raster[] aangezien je
if (raster[x, y] == true) gebruikt, ik neem aan dat je in het rooster wilt opslaan wat de populatie is (0 of 1 als ik het goed begrijp)

Of heb je een nieuwe array gemaakt voor output naar het scherm? (wat opzich goed zou zijn natuurlijk, zo houd je update en draw zoveel mogenlijk gescheiden)

Misschien zit dan toch de fout in het berekenen van je neighbours en het raster in het volgende frame. Schrijf je de waarden direct weg naar het zelfde raster? (Dit kan natuurlijk niet immers heb je voor 9 berekeningen nog de oude waarde nodig)

Lastig om nu te zien waar het fout gaat zo.

~ Mijn prog blog!


  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
roy-t schreef op donderdag 01 mei 2008 @ 23:23:
[...]


Die code ziet er iig goed uit alleen zou (programma correct)
for (int x = 0; x <= raster_width; x++ anders moeten nl. for (int x = 0; x < raster_width; x++)
maar waarschijnlijk heb je de variabele raster_width gewoon de echte breedte -1 gedaan (ook zero based dus)

Ik vraag me wel een beetje af wat je opslaag in de variabele raster[] aangezien je
if (raster[x, y] == true) gebruikt, ik neem aan dat je in het rooster wilt opslaan wat de populatie is (0 of 1 als ik het goed begrijp)

Of heb je een nieuwe array gemaakt voor output naar het scherm? (wat opzich goed zou zijn natuurlijk, zo houd je update en draw zoveel mogenlijk gescheiden)

Misschien zit dan toch de fout in het berekenen van je neighbours en het raster in het volgende frame. Schrijf je de waarden direct weg naar het zelfde raster? (Dit kan natuurlijk niet immers heb je voor 9 berekeningen nog de oude waarde nodig)

Lastig om nu te zien waar het fout gaat zo.
Ik heb idd. raster_width--; en raster-height--; gedaan. Maar een < was makkelijker.

raster[,] is een boolarray, raster_next is ook een boolarray. Ik doe eerst countneighbours en dan schrijf ik alle nieuwe waarden weg naar raster_next. Als ik alle cellen heb gehad doe ik
raster = raster_next.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
ozakigames schreef op vrijdag 02 mei 2008 @ 09:23:
Ik heb idd. raster_width--; en raster-height--; gedaan. Maar een < was makkelijker.
Weet je het verschil tussen raster_width-- en raster_width - 1?

https://niels.nu


  • pkuppens
  • Registratie: Juni 2007
  • Laatst online: 17-11 23:50
Ik zou hier nog maar eens naar kijken. Misschien kopieer je wel de referentie in plaats van de inhoud.

  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Hydra schreef op vrijdag 02 mei 2008 @ 10:56:
[...]


Weet je het verschil tussen raster_width-- en raster_width - 1?
nee, het is beiden het zelfde. -,-
pkuppens schreef op vrijdag 02 mei 2008 @ 11:10:
[...]


Ik zou hier nog maar eens naar kijken. Misschien kopieer je wel de referentie in plaats van de inhoud.
Hmm, ik weet niet precies wat je hier mee bedoelt maar ik zal er wat over opzoeken.

In de tussentijd heb ik alle relevante code in een normaal console project gestopt. Dit is veel overzichtelijker.

edit: GAST, je bent geweldig. Met behulp van Array.Copy(raster_next,raster,raster.length); is het gelukt.

Allemaal heel erg bedankt!

[ Voor 9% gewijzigd door Synch op 02-05-2008 11:25 ]


  • Marcj
  • Registratie: November 2000
  • Nu online
ozakigames schreef op vrijdag 02 mei 2008 @ 11:21:
[...]
nee, het is beiden het zelfde. -,-
[...]
:X

x-- komt overeen met x = x - 1, en is dus een assignment. x - 1 is een expressie!

Lees de volgende artikelen maar eens door als je het verschil hiertussen niet snapt:
Expression
Assignment

  • Synch
  • Registratie: November 2006
  • Laatst online: 18-11 09:51
Okay, bedankt voor de uitleg.

edit: fiander: bedankt voor je mail nog!

[ Voor 43% gewijzigd door Synch op 02-05-2008 21:31 ]

Pagina: 1