// project created on 02.12.2005 at 23:00
#define DEBUG_THE_HELL_OUT_OF_IT
using System;

class MainClass
{

    // das kann sich aendern (harharhar...)
    const int ANZAHL_SPIELER     =   2;
    // Feldgroesse ast auch variabel, aber quadratisch bleibts...
    const int SPIELFELD_SCHRITTE = 20;
    // Mindestnaehe fuer Spielende
    const int GEWINN_ABSTAND = 2;
    
    // unser Enumerationstyp fuer die Himmelsrichtungen
    enum Richtung {Keine, Nord, Ost, Sued, West};
    
//***********************************************************************************
    // Unser Hauptprogramm
    public static void Main(string[] args)
        {
        // Koordinaten der Spieler: haesslich modelliert, aber sehr prozedural(!)
        int[] anSpielerX = new int [ANZAHL_SPIELER];
        int[] anSpielerY = new int [ANZAHL_SPIELER];
    
        Console.Write("\n\f");
        Console.WriteLine("*************************");
        Console.WriteLine("*** Die blinden Kühe! ***");
        Console.WriteLine("*************************\n");

        SpielerPositionenBelegen(ref anSpielerX, ref anSpielerY);

        // jetzt kann das Spiel beginnen
        
        int nAktuellerSpieler = 0;
        int nVersuche         = 0;
        
        // Abstand des aktuellen Spielers vorab berechnen...
        int nAbstand = SpielerAbstandBerechnen(nAktuellerSpieler, ref anSpielerX, ref anSpielerY);
        
        do
            {
            Richtung eAktuelleRichtung;

#if DEBUG_THE_HELL_OUT_OF_IT        
        Console.WriteLine("Spieler 1 auf {0} / {1}", anSpielerX[0], anSpielerY[0]);
        Console.WriteLine("Spieler 2 auf {0} / {1}", anSpielerX[1], anSpielerY[1]);
#endif      
            Console.WriteLine("Der Abstand zum nächsten Spieler beträgt {0} Schritte", nAbstand);
                    
            eAktuelleRichtung = SchrittRichtungWaehlen(nAktuellerSpieler, 
                                                       ref anSpielerX, ref anSpielerY);
            // dann wirlkich "gehen"                                           
            SchrittInRichtungGehen(eAktuelleRichtung, nAktuellerSpieler, ref anSpielerX, ref anSpielerY);
            
            // dann zuletzt den Abstand nachrechnen
            nAbstand = SpielerAbstandBerechnen(nAktuellerSpieler, ref anSpielerX, ref anSpielerY);

            // stylishes inkrement mit wrap
            if (++nAktuellerSpieler >= ANZAHL_SPIELER)
                nAktuellerSpieler = 0;
            
            nVersuche++;
            }
        while (nAbstand > GEWINN_ABSTAND);
        
        Console.WriteLine("\n\n********* Ihr habt Euch nach {0} Versuchen gefunden! ***********", nVersuche);
        }
    
//***********************************************************************************
    // Zufallspositionen fuer alle Spieler
    static void SpielerPositionenBelegen(ref int[] anX, ref int[] anY)
        {
        Random rndGen = new Random();
        
        // hier geht foreach net, weil wir schreibend zugreifen wollen.
        for (int i = 0; i < anX.Length; i++)
            {
            // wir "hoffen", dass das Y-Array gleich gross ist
            anX[i] = rndGen.Next(SPIELFELD_SCHRITTE);
            anY[i] = rndGen.Next(SPIELFELD_SCHRITTE);
            }
        }

//***********************************************************************************
    // Abstand des Spielers von naehesten Kollegen
    static int SpielerAbstandBerechnen(int nSpieler, ref int[] anX, ref int[] anY)
        {
        int nMinAbstand = int.MaxValue; 
        
        // derzeit gibts nur zwei Spieler
        for (int i = 0; i < anX.Length; i++)
            {
            // mit mir selber brauch ich nicht zu vergleichen...
            if (i != nSpieler)
                {
                int nAbstand = (anX[i]-anX[nSpieler]) * (anX[i]-anX[nSpieler])
                
                             + (anY[i]-anY[nSpieler]) * (anY[i]-anY[nSpieler]);
                // das ist luxus. man koennte auch mit abstandsquadraten arbeiten...
                nAbstand = Convert.ToInt32(Math.Sqrt(nAbstand));
                
                if (nAbstand < nMinAbstand)
                     nMinAbstand = nAbstand;
                }
            }
        return nMinAbstand;
        }

//***********************************************************************************
    // Menue fuer Richtungswahl
    static Richtung SchrittRichtungWaehlen(int nSpieler, ref int[] anX, ref int[] anY)
        {
        Richtung eRichtung;
        
        do
            {
            Console.Write("Spieler {0}, welche Richtung wählst Du? ", nSpieler+1);
            
            string strRichtung = Console.ReadLine();
            
            switch (strRichtung)
                {
                case "n":
                case "N":
                    eRichtung = Richtung.Nord;
                    break;

                case "o":
                case "O":
                    eRichtung = Richtung.Ost;
                    break;
                    
                case "s":
                case "S":
                    eRichtung = Richtung.Sued;
                    break;
                    
                case "w":
                case "W":
                    eRichtung = Richtung.West;
                    break;

                default:
                    Console.WriteLine("Gültige Richtungen sind: N, O, S, W");
                    eRichtung = Richtung.Keine;
                    break;
                }
            }
        while (Richtung.Keine == eRichtung);            
        
        return eRichtung;
        }

//***********************************************************************************
    // Einen Schritt machen. Unser Koordinatensystem ist mathematisch Q1 => Y+ ist Nord und X+ ist Ost
    static Richtung SchrittInRichtungGehen(Richtung eRichtung, int nSpieler, ref int[] anX, ref int[] anY)
        {
        switch (eRichtung)
            {
            case Richtung.Nord:
                anY[nSpieler]++;
                // Wenn wir das Spielfeld verlassen, zurueckschubsen
                if (anY[nSpieler] >= SPIELFELD_SCHRITTE)
                    anY[nSpieler]  = SPIELFELD_SCHRITTE - 1;
                break;

            case Richtung.Sued:
                anY[nSpieler]--;
                // Wenn wir das Spielfeld verlassen, zurueckschubsen
                if (anY[nSpieler] < 0)
                    anY[nSpieler] = 0;
                break;

            case Richtung.Ost:
                anX[nSpieler]++;
                // Wenn wir das Spielfeld verlassen, zurueckschubsen
                if (anX[nSpieler] >= SPIELFELD_SCHRITTE)
                    anX[nSpieler]  = SPIELFELD_SCHRITTE - 1;
                break;                  
                
            case Richtung.West:
                anX[nSpieler]--;
                // Wenn wir das Spielfeld verlassen, zurueckschubsen
                if (anX[nSpieler] < 0)
                    anX[nSpieler] = 0;
                break;
            }
                    
        return eRichtung;
        }

} // class

syntax highlighted by Code2HTML, v. 0.9.1