C# :: Aufgabe #47 :: Lösung #1

2 Lösungen Lösungen öffentlich
#47

Spiel: Schiffe versenken

Fortgeschrittener - C# von david_k - 06.01.2013 um 17:24 Uhr
Es soll ein Schiffe-Versenken Spiel (Konsole oder Gui) erstellt werden. Man solll gegen den Computer oder gegen einen Menschen spielen können.
#1
vote_ok
von dragonmaster (250 Punkte) - 08.01.2016 um 12:37 Uhr
Schiffe versenken in der Konsole.
ACHTUNG! Spiel nur gegen CPU, nicht gegen Menschen, da die Spieler in der Konsole gegenseitig ihre Felder sehen können.

Erwähnenswertes:
- Eigene Spielfeldgröße von 5-5 bis 15-15
- Flottengröße und Maximale Schiffgröße abhängig von der Spielfeldgröße
- Schiffe können direkt nebeneinander stehen
- minimale KI: CPU schißt zufällig auf noch nicht beschossene Felder

Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SchiffeVersenken_v2
{
    class Program
    {

        static Random rnd = new Random();
        static char[] Alphabet = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' };
        static void Main(string[] args)
        {
            /* Schiff S
             * Wasser .
             * Treffer X
             * Danaben O
             */

            int spielfeldBreite;
            int spielfeldHoehe;
            List<int> Flotte = new List<int>();
            bool anDerReihe = true;

            //Spielfeldgröße ermitteln
            Console.Write("Bitte Spielfeldgröße(y,x) definieren mit jeweils min 5 und max 15: ");
            while (true)
            {
                String S = Console.ReadLine();
                String[] S2 = S.Split(',');
                if (S2.Length < 2) continue;
                if (!Int32.TryParse(S2[0], out spielfeldBreite)) continue;
                if (!Int32.TryParse(S2[1], out spielfeldHoehe)) continue;
                if (spielfeldHoehe < 5 || spielfeldBreite < 5 || spielfeldHoehe > 15 || spielfeldBreite > 15) continue;
                break;
            }
            Console.WriteLine();

            char[,] FeldSpieler = spielfeldGenerieren(spielfeldHoehe, spielfeldBreite);
            char[,] FeldCPU = spielfeldGenerieren(spielfeldHoehe, spielfeldBreite);

            Flotte = flotteZusammenstellen(spielfeldHoehe, spielfeldBreite);

            for (int i = 0; i < Flotte.Count; i++)
            {
                ausgabe(FeldSpieler, FeldCPU);
                schiffHinzufuegen(ref FeldSpieler, Flotte[i], true);
                schiffHinzufuegen(ref FeldCPU, Flotte[i], false);
            }

            //Spielen
            while (true)
            {
                ausgabe(FeldSpieler, FeldCPU);
                if (anDerReihe)
                {
                    if (!schießen(ref FeldCPU, true))
                    {
                        anDerReihe = !anDerReihe;
                    }

                    if (ueberpruefungSieg(FeldCPU))
                    {
                        ausgabe(FeldSpieler, FeldCPU);
                        Console.WriteLine("Sie haben Gewonnen, Gratulation!");
                        break;
                    }
                }
                else
                {
                    Console.ReadKey();
                    if (!schießen(ref FeldSpieler, false))
                    {
                        anDerReihe = !anDerReihe;
                    }
                    if (ueberpruefungSieg(FeldSpieler))
                    {
                        ausgabe(FeldSpieler, FeldCPU);
                        Console.WriteLine("Sie haben Verloren; gegen zufälligen Beschuss! Du Pfeife ... tut mir leid, "
                            +"ich meinte Sie Pfeife!");
                        break;
                    }

                }
            }

        }
        static char[,] spielfeldGenerieren(int spielfeldHoehe, int spielfeldBreite)
        {
            char[,] Spielfeld = new char[spielfeldHoehe, spielfeldBreite];
            for (int i1 = 0; i1 < spielfeldHoehe; i1++)
            {
                for (int i2 = 0; i2 < spielfeldBreite; i2++)
                {
                    Spielfeld[i1, i2] = '.';
                }
            }

            return Spielfeld;
        }
        static void ausgabe(char[,] FeldSpieler, char[,] FeldCPU)
        {
            //Kopfzeile
            Console.Write("Spieler");
            for (int h1 = 0; h1 < (2 * FeldSpieler.GetLength(1) + 5); h1++)
            {
                Console.Write(" ");
            }
            Console.WriteLine("CPU");

            Console.Write("  ");
            for (int h2 = 0; h2 < FeldSpieler.GetLength(1); h2++)
            {
                Console.Write(" {0}", Alphabet[h2]);
            }
            Console.Write("            ");
            for (int h3 = 0; h3 < FeldSpieler.GetLength(1); h3++)
            {
                Console.Write(" {0}", Alphabet[h3]);
            }
            Console.WriteLine("");

            //Spielfelder
            for (int i1 = 0; i1 < FeldSpieler.GetLength(0); i1++)
            {
                Console.Write("{0:00}", i1 + 1);
                for (int i2 = 0; i2 < FeldSpieler.GetLength(1); i2++)
                {
                    Console.Write(" {0}", FeldSpieler[i1, i2]);
                }
                Console.Write("  {0:00}  ||  {0:00}", i1 + 1);
                for (int i2 = 0; i2 < FeldCPU.GetLength(1); i2++)
                {
                    if (FeldCPU[i1, i2] == 'S')
                    {
                        Console.Write(" .");
                    }
                    else
                    {
                        Console.Write(" {0}", FeldCPU[i1, i2]);
                    }
                }
                Console.WriteLine("  {0:00}", i1 + 1);
            }
            //Schlusszeile
            Console.Write("  ");
            for (int h2 = 0; h2 < FeldSpieler.GetLength(1); h2++)
            {
                Console.Write(" {0}", Alphabet[h2]);
            }
            Console.Write("            ");
            for (int h3 = 0; h3 < FeldSpieler.GetLength(1); h3++)
            {
                Console.Write(" {0}", Alphabet[h3]);
            }
            Console.WriteLine("\n");
        }
        static void schiffHinzufuegen(ref char[,] Spielfeld, int schiffslaenge, bool manuelleEingabe)
        {
            int[] BugKoordinate = new int[2];
            int[] HeckKoordinate = new int[2];
            int[] GesammtKoordinaten = new int[4];

            int tempKoordinate;

            while (true)
            {
                bool kollision = false;

                if (manuelleEingabe)
                {
                    Console.WriteLine("Ein Schiff der Länge {0} plazieren: \n", schiffslaenge);
                    BugKoordinate = koordinateLesen(Spielfeld.GetLength(0), Spielfeld.GetLength(1));
                    if (schiffslaenge != 1) HeckKoordinate = koordinateLesen(Spielfeld.GetLength(0), Spielfeld.GetLength(1));
                }
                else
                {
                    GesammtKoordinaten = koordinatenZufall(Spielfeld, schiffslaenge);
                    BugKoordinate[0] = GesammtKoordinaten[0];
                    BugKoordinate[1] = GesammtKoordinaten[1];
                    HeckKoordinate[0] = GesammtKoordinaten[2];
                    HeckKoordinate[1] = GesammtKoordinaten[3];
                }

                //Überprüfung Koordinaten & Kollision
                if (schiffslaenge == 1)
                {
                    if (Spielfeld[BugKoordinate[0], BugKoordinate[1]] != 'S')
                    {
                        Spielfeld[BugKoordinate[0], BugKoordinate[1]] = 'S';
                        break;
                    }
                    else continue;
                }
                if (BugKoordinate[0] == HeckKoordinate[0])
                {
                    if (BugKoordinate[1] - HeckKoordinate[1] == (schiffslaenge - 1) ||
                        BugKoordinate[1] - HeckKoordinate[1] == -(schiffslaenge - 1))
                    {
                        if (BugKoordinate[1] < HeckKoordinate[1])
                        {
                            tempKoordinate = BugKoordinate[1];
                        }
                        else
                        {
                            tempKoordinate = HeckKoordinate[1];
                        }

                        for (int i = tempKoordinate; i < (tempKoordinate + schiffslaenge); i++)
                        {
                            if (Spielfeld[BugKoordinate[0], i] != '.')
                            {
                                kollision = true;
                            }
                        }

                        if (!kollision)
                        {
                            for (int i = tempKoordinate; i < (tempKoordinate + schiffslaenge); i++)
                            {
                                Spielfeld[BugKoordinate[0], i] = 'S';
                            }
                        }
                        else
                        {
                            if (manuelleEingabe) Console.WriteLine("Schiff kollidiert! Bitte neu setzten!\n");
                            continue;
                        }
                        break;
                    }
                }
                else if (BugKoordinate[1] == HeckKoordinate[1])
                {
                    if (BugKoordinate[0] - HeckKoordinate[0] == (schiffslaenge - 1) ||
                        BugKoordinate[0] - HeckKoordinate[0] == -(schiffslaenge - 1))
                    {
                        if (BugKoordinate[0] < HeckKoordinate[0])
                        {
                            tempKoordinate = BugKoordinate[0];
                        }
                        else
                        {
                            tempKoordinate = HeckKoordinate[0];
                        }

                        for (int i = tempKoordinate; i < (tempKoordinate + schiffslaenge); i++)
                        {
                            if (Spielfeld[i, BugKoordinate[1]] != '.')
                            {
                                kollision = true;
                            }
                        }

                        if (!kollision)
                        {
                            for (int i = tempKoordinate; i < (tempKoordinate + schiffslaenge); i++)
                            {
                                Spielfeld[i, BugKoordinate[1]] = 'S';
                            }
                        }
                        else
                        {
                            if (manuelleEingabe) Console.WriteLine("Schiff kollidiert! Bitte neu setzten!\n");
                            continue;
                        }
                        break;
                    }
                }
                if (manuelleEingabe) Console.WriteLine("Koordianten scheinen nicht zueinender zu passen!\n");

            }
            if (manuelleEingabe) Console.Write("Spieler: ");
            else Console.Write("CPU: ");
            Console.WriteLine("Schiff der Länge {0} hinzugefügt!\n", schiffslaenge);
        }
        static int[] koordinateLesen(int spielfeldHoehe, int spielfeldBreite)
        {
            int[] koordinate = new int[2];
            bool buchstabeZuZahl = false;

            while (true)
            {
                String hoehe = "";
                String breite = "";
                Console.Write("Koordinate eingeben: ");
                String S = Console.ReadLine();
                Console.WriteLine();

                //Aufteilung des eingelesenen Strings in Buchstaben und Zahlen
                foreach (char c in S)
                {
                    if (Char.IsNumber(c))
                    {
                        //Ziffern aneinander reihen
                        hoehe += c;
                    }
                    else
                    {
                        breite += c;
                    }
                }
                if (hoehe.Length == 0) continue; // absicherung Crash;

                //Höhe-Koordiante 
                if (Convert.ToInt32(hoehe) <= spielfeldHoehe)
                {
                    koordinate[0] = Convert.ToInt32(hoehe) - 1;
                }
                else continue;

                //Breite-Koordinate
                if (breite.Length == 1)
                {
                    for (int i = 0; i < spielfeldBreite; i++)
                    {
                        if (Alphabet[i] == Char.ToUpper(Convert.ToChar(breite)))
                        {
                            koordinate[1] = i;
                            buchstabeZuZahl = true;
                            break;
                        }
                    }
                    if (!buchstabeZuZahl)
                    {
                        continue;
                    }
                }
                else continue;
                break;
            }
            Console.WriteLine("Koordinate gültig!\n");
            return koordinate;
        }
        static int[] koordinatenZufall(char[,] Spielfeld, int schiffslaenge)
        {
            //Zufälliges Koordinatenpaar in Abstand der Schiffslänge
            int[] BugKoordinate = new int[2];
            int[] HeckKoordinate = new int[2];
            BugKoordinate[0] = rnd.Next(0, Spielfeld.GetLength(0));
            BugKoordinate[1] = rnd.Next(0, Spielfeld.GetLength(1));

            int richtung = rnd.Next(4);

            switch (richtung)
            {
                case 0: //nord

                    if (BugKoordinate[0] < schiffslaenge - 1)
                    {
                        goto case 1;
                    }
                    HeckKoordinate[0] = BugKoordinate[0] - (schiffslaenge - 1);
                    HeckKoordinate[1] = BugKoordinate[1];
                    break;
                case 1: // west
                    if (BugKoordinate[1] < schiffslaenge - 1)
                    {
                        goto case 2;
                    }
                    HeckKoordinate[0] = BugKoordinate[0];
                    HeckKoordinate[1] = BugKoordinate[1] - (schiffslaenge - 1);
                    break;
                case 2: // süd
                    if (BugKoordinate[0] + schiffslaenge > Spielfeld.GetLength(0))
                    {
                        goto case 3;
                    }
                    HeckKoordinate[0] = BugKoordinate[0] + (schiffslaenge - 1);
                    HeckKoordinate[1] = BugKoordinate[1];
                    break;
                case 3: // ost
                    if (BugKoordinate[1] + schiffslaenge > Spielfeld.GetLength(1))
                    {
                        goto case 0;
                    }
                    HeckKoordinate[0] = BugKoordinate[0];
                    HeckKoordinate[1] = BugKoordinate[1] + (schiffslaenge - 1);
                    break;
            }
            int[] Koordinaten = { BugKoordinate[0], BugKoordinate[1], HeckKoordinate[0], HeckKoordinate[1] };
            return Koordinaten;

        }
        static bool schießen(ref char[,] Spielfeld, bool manuell)
        {
            int[] ZielKoordinate = new int[2];
            bool treffer = false;
            if (manuell)
            {
                Console.WriteLine("Bitte schießen!\n");
                ZielKoordinate = koordinateLesen(Spielfeld.GetLength(0), Spielfeld.GetLength(1));
            }
            else
            {
                while (true) //Minimal KI
                {
                    ZielKoordinate[0] = rnd.Next(0, Spielfeld.GetLength(0));
                    ZielKoordinate[1] = rnd.Next(0, Spielfeld.GetLength(1));
                    if (Spielfeld[ZielKoordinate[0], ZielKoordinate[1]].Equals('X') ||
                        Spielfeld[ZielKoordinate[0], ZielKoordinate[1]].Equals('O')) continue;
                    else
                    {
                        Console.Write("CPU schießt! ");
                        break;
                    }
                }
            }

            if (Spielfeld[ZielKoordinate[0], ZielKoordinate[1]].Equals('S'))
            {
                treffer = true;
                Spielfeld[ZielKoordinate[0], ZielKoordinate[1]] = 'X';
                Console.WriteLine("Schuss auf {0}|{1}, Treffer!\n", Alphabet[ZielKoordinate[1]], ZielKoordinate[0] + 1);
            }
            else
            {
                Spielfeld[ZielKoordinate[0], ZielKoordinate[1]] = 'O';
                Console.WriteLine("Schuss auf {0}|{1}, Daneben!\n", Alphabet[ZielKoordinate[1]], ZielKoordinate[0] + 1);
            }

            return treffer;
        }
        static bool ueberpruefungSieg(char[,] Spielfeld)
        {
            foreach (char c in Spielfeld)
            {
                if (c == 'S') return false;
            }
            return true;
        }
        static List<int> flotteZusammenstellen(int spielfeldHoehe, int spielfeldBreite)
        {
            //Ermittlung der größe der Flotte
            int schiffsTeile = (int)Math.Ceiling((double)((spielfeldBreite * spielfeldHoehe) / 8.0));

            //Ermittlung der maximalen Schiffgröße
            int schiffMaximum;
            if (spielfeldBreite > spielfeldHoehe) schiffMaximum = spielfeldBreite/2;
            else schiffMaximum = spielfeldHoehe/2;

            Console.WriteLine("Bitte Flotte zusammenstellen! Auf diesem Spielfeld haben Sie dafür {0} Schiffsteile " +
                "für Schiffe mit der Größe 2-{1}\n", schiffsTeile, schiffMaximum);
            List<int> Flotte = new List<int>();

            while (schiffsTeile > 1)
            {
                Console.Write("{0} Teile übrig: Schiff hinzufügen mit der Größe: ", schiffsTeile);
                int schiff = 0;
                if (!Int32.TryParse(Console.ReadLine(), out schiff)) continue;
                if (schiff > spielfeldBreite || schiff > spielfeldHoehe || schiff > schiffsTeile ||
                    schiff < 2 || schiff > schiffMaximum) continue;
                Flotte.Add(schiff);
                schiffsTeile -= schiff;
                Console.WriteLine();
            }

            if (schiffsTeile == 1)
            {
                Flotte.Add(1);
                Console.WriteLine("Aus dem letzten Schiffteil wurde der Flotte noch ein Schlauchboot hinzugefüget.\n");
                Console.ReadKey();
            }

            return Flotte;
        }
    }
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben