Schiffe Versenken



  • Hallo zusammen,

    Wir haben von der Schule ein Projekt bekommen ein Programm zu erstellen.
    Ich habe mir Schiffe versenken ausgesucht.
    - Ich habe schon das Spielfeld erstellt
    - Die Schiffe zufällig gesetzt
    - Eingabe Buchstaben und ungültiger Zahlen verhindert
    - Abfrage ob getroffen oder nicht erstellt

    Meine weiteren Ziele sind:

    -Die Array Größe variabel zu gestalten.
    -Eine Grenzabfrage zu machen, ob die Schiffe über den Arrayrand hinaus gehen und dies verhindern
    - Die While Schleife in der Main Funktion abbrechen, wenn alle zufällig gesetzten Schiffe getroffen sind.

    Alles andere werde ich wieder versuchen erst mal selbst zu coden. Z.B. Die CPU greift mich an oder Schiffe selber setzen.

    Es wäre toll wenn, wenn mir jemand Tipps oder Beispiele geben kann, wie ich das realisieren kann.

    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <string>
    #include <windows.h>
    
    using namespace std;
    
    const int size = 10; //
    char ansicht[size][size]; //Ansichten Feld, wird angezeigt 
    int computer[size][size];// Computer Feld, wird nicht angezeigt
    
    #define BLACK 0
    #define BLUE 1
    #define GREEN 2
    #define CYAN 3
    #define RED 4
    #define MAGENTA 5
    #define BROWN 6
    #define LIGHTGREY 7
    #define DARKGREY 8
    #define LIGHTBLUE 9
    #define LIGHTGREEN 10
    #define LIGHTCYAN 11
    #define LIGHTRED 12
    #define LIGHTMAGENTA 13
    #define YELLOW 14
    #define WHITE 15
    #define BLINK 128
    
    int Randomzahl(int wert)
    {
    	int randomwert = rand() % wert;
    	return randomwert;
    }
    
    void Farbe(int x, int y, char zeichen1, char zeichen2, char zeichen3)
    {
    	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    	WORD farbattr;
    	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    
    	GetConsoleScreenBufferInfo(h, &csbiInfo);
    	farbattr = csbiInfo.wAttributes;
    
    	if (ansicht[x][y] == zeichen1)
    	{
    		SetConsoleTextAttribute(h, GREEN); 
    		cout << ansicht[x][y];
    		SetConsoleTextAttribute(h, farbattr);
    	}
    	else if (ansicht[x][y] == zeichen2)
    	{
    		SetConsoleTextAttribute(h, YELLOW);
    		cout << ansicht[x][y];
    		SetConsoleTextAttribute(h, farbattr);
    	}
    	else if (ansicht[x][y] == zeichen3)
    	{
    		SetConsoleTextAttribute(h, WHITE);
    		cout << ansicht[x][y];	
    		SetConsoleTextAttribute(h, farbattr);
    	}
    }
    
    void FarbeComputer(int x, int y, char zeichen1, char zeichen2)
    {
    	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    	WORD farbattr;
    	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
    
    	GetConsoleScreenBufferInfo(h, &csbiInfo);
    	farbattr = csbiInfo.wAttributes;
    
    	if (computer[x][y] == zeichen1)
    	{
    		SetConsoleTextAttribute(h, GREEN);
    		cout << computer[x][y];
    		SetConsoleTextAttribute(h, farbattr);
    	}
    	else if (computer[x][y] == zeichen2)
    	{
    		SetConsoleTextAttribute(h, YELLOW);
    		cout << computer[x][y];
    		SetConsoleTextAttribute(h, farbattr);
    	}
    	else
    	{
    		cout << computer[x][y];
    	}
    }
    void RandomSchiff(int groesse)
    {
    	int xpos, ypos, entscheidung;
    	xpos = Randomzahl(10);
    	ypos = Randomzahl(10);
    
    	entscheidung = Randomzahl(5);
    
    	if (entscheidung == 0)
    	{
    		for (int i = 0; i < groesse; i++)
    		{
    			computer[xpos][ypos] = 1;
    			ypos++;
    		}
    	}
    	else if (entscheidung == 1)
    	{
    		for (int i = 0; i < groesse; i++)
    		{
    			computer[xpos][ypos] = 1;
    			xpos++;
    		}
    	}
    	else if (entscheidung == 2)
    	{
    		for (int i = 0; i < groesse; i++)
    		{
    			computer[xpos][ypos] = 1;
    			ypos--;
    		}
    	}
    	else
    	{
    		{
    			for (int i = 0; i < groesse; i++)
    			{
    				computer[xpos][ypos] = 1;
    				xpos--;
    			}
    		}
    	}
    }
    
    //void GrenzAbfrage(int x, int y)
    //{
    //	int xpos, ypos;
    //}
    void AnsichtComputer(int x, int y)
    {
    	cout << "\n\tS-C-H-I-F-F-E_V-E-R-S-E-N-K-E-N" << endl;
    	cout << "\t-------------------------------\n" << endl;
    	cout << "\t" << " ";
    	for (int i = 0; i<size; i++) //Nummerierung Horizontal 
    	{
    		cout << "  " << i;
    	}
    	cout << "\n" << endl;
    
    	for (int x = 0; x<size; x++) //Nummerierung Vertikal 
    	{
    		cout << "\t";
    		cout << x;
    		cout << " ";
    
    		for (int y = 0; y<size; y++)//Spielfeld Ansicht 
    		{
    			cout << "[";
    			FarbeComputer(x, y, 'X', '-'); //Ausgabe Feld in der Konsole 
    			cout << "]";
    		}
    		cout << endl;
    	}
    }
    
    void Ansicht(int x, int y)
    {
    	cout << "\n\tS-C-H-I-F-F-E_V-E-R-S-E-N-K-E-N" << endl;
    	cout << "\t-------------------------------\n" << endl;
    	cout << "\t" << " ";
    	for (int i = 0; i<size; i++) //Nummerierung Horizontal 
    	{
    		cout << "  " << i;
    	}
    	cout << "\n" << endl;
    
    	for (int x = 0; x<size; x++) //Nummerierung Vertikal 
    	{
    		cout << "\t";
    		cout << x;
    		cout << " ";
    
    		for (int y = 0; y<size; y++)//Spielfeld Ansicht 
    		{
    			cout << "[";
    			Farbe(x,y, 'X', '-', 'W'); //Ausgabe Feld in der Konsole 
    			cout << "]";
    		}
    		cout << endl;
    	}
    }
    int Eingabe(string text1)
    {
    	int zahl = -1;
    	while (zahl < 0 || zahl > size)
    	{
    
    		cout << "\nBitte geben sie die Koordinaten ein. (0-" << (size - 1) << " eingeben)" << endl;
    		cout << text1;
    		cin >> zahl;
    		cin.clear();
    		cin.ignore(10, '\n');
    		if (zahl < 0 || zahl > size)
    		{
    			cout << "Ungueltige Eingabe. Falsche Koordinate (0-" << (size - 1) << " eingeben)" << endl;
    		}
    	}
    
    	return zahl;
    }
    
    void Abfrage(int x, int y)
    {
    	if (computer[x][y] == 1)//Feststellung ob getroffen oder nicht 
    	{
    		cout << "\nG-E-T-R-O-F-F-E-N!" << endl;
    		cout << "-----------------\n";
    		ansicht[x][y] = 'X';
    		computer[x][y] = 3;
    	}
    
    	else
    	{
    		cout << "\nN-I-C-H-T--G-E-T-R-O-F-F-E-N!" << endl;
    		cout << "-----------------------------\n";
    		ansicht[x][y] = '-';
    
    	}
    	cout << endl;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int xpos = -1, ypos = -1; //Koordinaten; Position
    
    	srand(unsigned(time(NULL)));
    
    	for (int i = 0; i < size; i++)
    	{
    		for (int j = 0; j < size; j++)
    		{
    			ansicht[i][j] = 'W';
    			computer[i][j] = 0;
    		}
    	}
    
    	Ansicht(xpos, ypos);
    
    	RandomSchiff(2);
    	RandomSchiff(3);
    
    	bool abort = false; // kein Abbruch 
    
    	while (!abort)
    	{
    		cout << "\nBitte geben sie Ihre Koordinaten ein." << endl;
    		cout << "Durch die Eingabe von Koordinaten, koennen sie bestimmen, welches Feld sie abschiessen wollen." << endl;
    		cout << "\nEs sind nur Nummern von 0-9 als Eingabe gueltig\n" << endl;
    
    		xpos = Eingabe("Koordinate X:");
    		ypos = Eingabe("Koordinate Y:");
    
    		system("cls");
    
    		Abfrage(xpos, ypos);
    		Ansicht(xpos, ypos);
    		AnsichtComputer(xpos, ypos);
    
    		//if (RandomSchiff(2) == 3)//Wenn alle Schiffe getroffen, Spiel beendet
    		//{
    		//	if(RandomSchiff(3) == 3)
    		//	{
    		//		cout << "\nSie haben das Schiff versenkt!\n" << endl;
    		//		cout << "\nSpiel beendet" << endl;
    		//		abort = true;
    		//	}
    		//}
    	}
    
    	_getch();
    	return 0;
    }
    


  • Das ist alles ein widerlicher Mischmasch aus C und C++, mit windows.h , iostream UND stdlib.h !

    Wenn die Größe Variable sein soll, wirst du um dynamische Speicherverwaltung und Zeigern nicht drumrumkommen. Ich vermute aber mal stark, dass du davon noch so sehr entfernt bist, dass du das Projekt erst mal auf Halde legen solltest, bis ihr das im Unterricht lernt.

    Wenn du einer von den Fitteren bist, kannst du versuchen, es dir selbst beizubringen, gibt genug Informationen darüber (Stichwörter: für C malloc / free , für C++ new / delete - muss man ja angeben, da wir nicht wissen, was GENAU du machst).



  • LarsVegas schrieb:

    Die Array Größe variabel zu gestalten.
    -Eine Grenzabfrage zu machen, ob die Schiffe über den Arrayrand hinaus gehen und dies verhindern
    - Die While Schleife in der Main Funktion abbrechen, wenn alle zufällig gesetzten Schiffe getroffen sind.

    Wie variabel soll die Array-Größe denn sein? mehr als (Vermutung, ich habe es nicht geprüft) 80x25 hast du insgesamt normaler Weise nicht. Also char array[25][80] und gut ist. Den durchschnittlichen Computer sollte es wenig jucken, ob du 2MB belegst, oder weniger.

    Für die Grenzabfrage musst du halt überprüfen, ob "Anfangskoordinaten + Schifflänge" größer als diese Grenzen wird und das dann horizontal und/oder vertikal.

    Die while-Schleife brichst du mit einer Bedingung ab, also z.b.

    while(schiffe_platziert!=5)
    {
    //Schiff platzieren
    schiffe_platziert++
    }
    

    Aber es stimmt schon, dass du nicht zig Bibliotheken einbinden solltest, die das Gleiche bewirken könnten



  • Wie variabel soll die Array-Größe denn sein? mehr als (Vermutung, ich habe es nicht geprüft) 80x25 hast du insgesamt normaler Weise nicht. Also char array[25][80] und gut ist. Den durchschnittlichen Computer sollte es wenig jucken, ob du 2MB belegst, oder weniger.

    Ich möchte im Prinzip nur, dass wenn ich 20 eingebe Array[20][20] ist oder bei 5 Array[5][5]. Natürlich würde ich dann auch wahrscheinlich einfügen, dass die Array Größe nicht mehr als 15 betragen darf. Es soll einfach nur dazu dienen als Auswahl.
    Danke für deine restlichen Tipps.



  • Da du sowieso einen C++ Compiler verwendest, nimm dann vector<T> bzw. vector<vector<T>> für zur Laufzeit dynamische Arrays.
    Aber wenn du bisher damit keine Erfahrung hast, dann solltest du den Tipp von HansKlaus beachten, also das Array maximal definieren und zur Laufzeit dann die Grenzen entsprechend abfragen.



  • Die Verwendung von globalen Variablen oder VLA ist jeweils schon Anfängerunsinn, für beides kombiniert gehörst du gesteinigt.



  • Ich würde vorschlagen, diesen Thread nach C++ zu verschieben...



  • Und ich schlage vor, das ich mich abmelde und nie wieder in dieses Forum gehe.
    Hier hin zu kommen ist, wie der Hells Angels Gang beizutreten.
    Man wird aus Unwissenheit angefeindet und mit dem Tod bedroht.
    Das klingt sehr logisch und sympathisch.

    Schade das hier anscheinend nur jeder zehnte vielleicht richtige Tipps, Beispiele oder Anregungen geben möchte.
    Es ist wahrscheinlich spaßiger, ein elitäres Dasein zu bestreiten und andere fertig zu machen.

    Man sieht sich im echten Leben liebe Mitglieder 🙂



  • Na, na , na. Fang nicht an zu weinen, hier ist noch jedem ernsthaft Hilfesuchendem geholfen worden.

    Wenn du ne Antwort àla "Dein Programm ist so wie es ist spitze, mach weiter so!!! " suchst, bist du hier allerdings wirklich falsch.



  • Ich bin der Meinung, dass man nie mit Steinigung drohen sollte. Eher sollte man allen Leuten, die damit drohen, mit Erschießung drohen 😉

    Aber mal im Ernst: ist dir (LarsVegas) mal aufgefallen, dass zum Beispiel deine Funktion "Ansicht" und "AnsichtComputer" durchaus sehr ähnlichen Code enthalten? Sie unterscheiden sich nur in einer einzigen Zeile. Ebenso sind "Farbe" und "FarbeComputer" von der Logik her praktisch identisch. Es ist lediglich ein Unterschied, ob auf (die globalen Variablen) "ansicht" oder "computer" zugegriffen wird (besser Name für "ansicht" wäre "spieler"). Ich würde jetzt als ersten Schritt vorschlagen, zunächst diese Funktionen so abzuändern, dass sie "ansicht" bzw. "computer" als Parameter übergeben bekommen, sodass du dann nur noch eine "Ansicht" und eine "Farbe"-Funktion hast.

    Allgemein: wenn du 2x (fast) denselben Code schreibst, dann gibt es bestimmt einen besseren Weg!


Log in to reply