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
2 Kommentare
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:

demir168

Punkte: 0



1 Kommentare

#1
22.11.2021 um 11:05 Uhr
servus,
habe eine frage.
kann man das auch in C++ Programmieren oder gibt es unterschiede muss man auf irgendetwas achten
post_arrow
718 0

dragonmaster

Punkte: 250


6 Lösungen
1 Kommentare

#2
22.11.2021 um 17:20 Uhr
servus demir168,

leider kann ich dir da nicht weiterhelfen, da ich selbst noch kein c++ programmiert habe
post_arrow
719 0
Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben
2093951

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.