Elegante Lösung für Diagonale und Nachbarn in C?

2 Antworten

Nutze Schleifen, um die relevanten Felder zu prüfen. Beim ersten Treffer brichst du den Lauf ab. Optimalerweise wird diese gesamte Prüfung in eine eigene Funktion ausgelagert, die wahr / falsch (also 1 / 0) als Rückgabewert liefert.

Du kannst die relativen Koordinaten einer Umgebung als array speichern und darüber iterieren:

typedef /* Typ von spielfeld[i][j] */ Feld;

typedef struct { int i, j; } Punkt, Umgebung[8];

static Feld spielfeld[NI][NJ];

static const Umgebung nachbarn = {
  {-1,-1}, {-1, 0}, {-1,+1},
  { 0,-1}, /* -- */ { 0,+1},
  {+1,-1}, {+1, 0}, {+1,+1},
};

bool umgebung_enthaelt_sich ( int i, int j )
{
  assert( i>0 && i<NI-1 );
  assert( j>0 && j<NJ-1 );

  const Feld wert = spielfeld[i][j];
  for ( int n=0; n<8; ++n )
    if (wert==spielfeld[i+nachbarn[n].i][j+nachbarn[n].j])
      return true;
  return false;
}

Dein Code wird dann zu:

if ( umgebung_enthaelt_sich(i, j) )
  ...

Allerdings sehe ich im Game of Life keine Verwendung für Deine Abfrage. Es geht doch eigentlich immer darum, die Nachbarfelder zu zählen:

int umgebung_zaehlen ( int i, int j )
{
  int summe = 0;
  for ( int n=0; n<8; ++n )
    summe += spielfeld[i+nachbarn[n].i][j+nachbarn[n].j];
  return summe;
}

Schöner wäre es, wenn „spielfeld“ keine globale Variable ist. Dann musst Du es aber als weiteren Parameter übergeben. Bei zweidimensionalen Arrays ist das etwas knifflig:

int umgebung_zaehlen ( Feld const * const spielfeld, int NJ
                     , int i, int j )
{
  ...
    summe += spielfeld[(i+nachbarn[n].i)*NJ
                       + j+nachbarn[n].j];
  ...
}

Ein Aufruf sieht dann so aus:

  const int n = umgebung_zaehlen( *spielfeld, NJ, i, j );