/* Beispiel: Schiffe versenken (Strukturen, Schleifen, Funktionen, Zufallszahlen)
   Filename: main.cpp
   Author: Lahmer
   Title: Schiffe versenken 
   Description: Es soll eine weitere Variation vom Spiel Schiffe versenken erstellt werden, wo die Schiffe automatisch gesetzt werden. 
   Last Change: 30.01.2018
*/
 
 
#include <iostream>
#include <time.h> 		//Bibliothek für time(NULL)
#include <stdlib.h>		//Bibliothek für rand(), srand()
#include <windows.h>
#include <string>	
#include <conio.h>	
#include <fstream>
 
using namespace std;
 
//GLOBALE VARIABLEN
#define ZEILEN 10
#define SPALTEN 10
#define LAENGE 3
#define RICHTUNGEN 4
#define ANZSCHIFFE 5
 
void intializeArray(char array[ZEILEN][SPALTEN]);	//initialisiere Array-Elemente mit #
void printArray(char array[ZEILEN][SPALTEN]);		//gib Array aus
int check(char Schiff[ZEILEN][SPALTEN], char Feld[ZEILEN][SPALTEN], int y, int x); //Prüfe Array ob Schiff getroffen wurde
bool setzeSchiff(char Schiff[ZEILEN][SPALTEN], struct SchiffInfo schiff1);//Setze Schiff zufällig
 
struct SchiffInfo{
	int laenge;		//Länge von 2-5 
	int startX;		//Anfangsposition auf der X-Achse
	int startY;		//Anfangsposition auf der Y-Achse
	int richtung;	//0->oben, 1->rechts oben, 2->rechts, 3->rechts unten,4->unten, 5->links unten, 6->links, 7-> links oben
};
 
 
 
int main(int argc, char** argv) {
 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
 
	//LOKALE VARIABLEN	
	char feld[ZEILEN][SPALTEN];		//Deklaration eines mehrdimensionalen Arrays
	char schiff[ZEILEN][SPALTEN];	//Deklaration eines mehrdimensionalen Arrays
	int zeile=0, spalte=0, zaehler=0, versuche=0;
	int schiffselemente=0;
	bool Schiffversteckt=false;
	int schiffanz=ANZSCHIFFE;
	string name;
 
	do{
 
		cout << "Geben Sie Ihren Namen ein: ";
		cin >> name;
 
		cout << endl << "Geben Sie die Anzahl der zu platzierenden Schiffe ein: ";
		cin >> schiffanz;
 
		system("cls");
 
 
		intializeArray(feld);		//Array namens feld initialisieren
		intializeArray(schiff);		//Array namens schiff initialisieren
 
		struct SchiffInfo s1;
		srand(time(NULL));
 
		do {
			s1.laenge=rand()%4+2;		//Bestimmen der Schiffslänge
			s1.startX=rand()%SPALTEN;	//Bestimmen der Startposition auf der X-Achse
			s1.startY=rand()%ZEILEN;	//Bestimmen der Startposition auf der Y-Achse
			s1.richtung=rand()%RICHTUNGEN;	//Bestimmen der Setzrichtung des Schiffes
 
			cout << "Laenge: "<< s1.laenge << endl;
			cout << "StartY: "<< s1.startY << endl;	
			cout << "StartX: "<< s1.startX << endl;	
			cout << "Richtung: "<< s1.richtung << endl;	
 
			//Schiff verstecken
			Schiffversteckt=setzeSchiff(schiff,s1);
 
		/* Anzahl Schiffe */
			if(Schiffversteckt)
			{
				schiffanz--;
				schiffselemente=schiffselemente+s1.laenge;
			}
 
		}while(schiffanz>0);		//Solange Anzahl der Schiffe > 0
 
		printArray(feld);		//Array feld ausgeben	
		printArray(schiff);		//Array schiff ausgeben
 
		do{
 
			cout << endl << "Geben Sie bitte die Zeilennummer ein:";
			cin >> zeile;
			cout << endl << "Geben Sie bitte die Spaltennummer ein:";
			cin >> spalte;
 
			system("cls");		//Löscht die Konsolenausgabe
 
			zaehler=zaehler+check(schiff, feld, zeile, spalte);		//Prüfen ob Schiff getroffen wurde
			versuche++;		//Zählen der Versuche
 
			printArray(feld);		//Array namens feld ausgeben
 
		}while(zaehler<schiffselemente);
 
		cout << endl<< "Sie haben das Schiff/die Schiffe nach insgesamt " << versuche << " Versuch(en) versenkt!! GRATULATION!!" << endl;
		cout << endl << "Sie haben eine Trefferwahrscheinlichkeit von " << float(schiffselemente)/float(versuche) << endl;
 
		ofstream fileout;
    	fileout.open("highscore.txt");
		fileout << name << ": " << float(schiffselemente)/float(versuche);
        fileout.close();
 
		cout << endl << "Wollen Sie das Spiel nochmals spielen (j/n)?";
	}while(getch()=='j');
 
	return 0;
}
 
//Initialisiert das übergebene Array mit #
void intializeArray(char array[ZEILEN][SPALTEN])
{
	for(int i=0;i<ZEILEN;i++)
	{
		for(int j=0;j<SPALTEN;j++)
		{
			array[i][j]='#';
		}
	}
 
}
//Gibt das übergebene Array aus
void printArray(char array[ZEILEN][SPALTEN]) 
{
 
	cout << endl << "Spielfeld: ";
	cout << endl << endl;
 
	cout << "  ";
	for(int i=0;i<SPALTEN;i++)
	{
		cout << i << " ";
	}
	cout << endl;
	for(int i=0;i<ZEILEN;i++)
	{
		cout << i << " ";
		for(int j=0;j<SPALTEN;j++)
		{
			if(array[i][j]=='X')
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
			}
			cout << array[i][j] << " ";
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
		}
		cout << endl;
	}
}
//Prüft ob Schiff getroffen wurde (1) oder nicht (0)
int check(char Schiff[ZEILEN][SPALTEN], char Feld[ZEILEN][SPALTEN], int y, int x)
{
	if(Schiff[y][x]=='X')
	{
		cout << endl << "!!!! TREFFER !!!!!" << endl;
		Feld[y][x]='X';
 
		return 1;
	}
	else {
		cout << endl << "!!!! KEIN TREFFER !!!!!" << endl;
		Feld[y][x]=' ';
 
		return 0;
	}
}
 
//Setze das übergebene schiff1 im Array namens Schiff, falls möglich
bool setzeSchiff(char Schiff[ZEILEN][SPALTEN], struct SchiffInfo schiff1)
{
	int zaehler=0;
	if(Schiff[schiff1.startY][schiff1.startX]!='X')
	{
		zaehler=1;	//Für jedes Schiffteil, welches platziert wird -> zähler++
		//Prüfen der Richtung 0 = nach links oben  (Y wird weniger, X wird weniger)
		if(schiff1.richtung==0)
		{
			if(schiff1.startY-(schiff1.laenge-1)>=0 && schiff1.startX-(schiff1.laenge-1)>=0)		//Prüft ob in Y- und X-Richtung genung Platz für das Schiff ist
			{
				//Schiff hat genug Platz
				for(int i=1;i<schiff1.laenge;i++)		//Prüft jede Koordinate ob bereits ein Schiff vorhanden ist
				{
					if(Schiff[schiff1.startY-i][schiff1.startX-i]!='X')
					{
						//cout << "Position ist frei";
						zaehler++;
					}
				}
			}
 
			if(zaehler==schiff1.laenge)
			{
				cout << "Schiff wird platziert - Zaehler: " << zaehler << endl;
				//Schiff wird erst jetzt platziert!!!				
				for(int i=0;i<schiff1.laenge;i++)
				{
					Schiff[schiff1.startY-i][schiff1.startX-i]='X';
 
				}	
				return true;
 
			}
			else
			{
				return false;	
			}
		}
 
		//Prüfen der Richtung 1 == nach oben (Y wird weniger, X bleibt gleich)
		zaehler=1;
		if(schiff1.richtung==1) 
		{
			if(schiff1.startY-(schiff1.laenge-1)>=0)
			{
				for(int i=schiff1.startY-1;i>schiff1.startY-schiff1.laenge;i--)
				{
					if(Schiff[i][schiff1.startX]!='X')
					{
						zaehler++;
					}
				}
			}
 
			if(zaehler==schiff1.laenge)
			{
				cout << "Schiff wird platziert - Zaehler: " << zaehler << endl;
				//Schiff wird erst jetzt platziert!!!				
				for(int i=0;i<schiff1.laenge;i++)
				{
					Schiff[schiff1.startY-i][schiff1.startX]='X';
 
				}	
				return true;
 
			}
			else
			{
				return false;	
			}	
		}
 
 
		//Prüfen der Richtung 2 == nach oben rechts (Y wird weniger, X wird mehr)
		zaehler=1;
		if(schiff1.richtung==2) 
		{
			if(schiff1.startY-(schiff1.laenge-1)>=0 && schiff1.startX+(schiff1.laenge-1)<SPALTEN)
			{
				for(int i=1;i<schiff1.laenge;i++)		//Prüft jede Koordinate ob bereits ein Schiff vorhanden ist
				{
					if(Schiff[schiff1.startY-i][schiff1.startX+i]!='X')
					{
						//cout << "Position ist frei";
						zaehler++;
					}
				}
			}
 
			if(zaehler==schiff1.laenge)
			{
				cout << "Schiff wird platziert - Zaehler: " << zaehler << endl;
				//Schiff wird erst jetzt platziert!!!				
				for(int i=0;i<schiff1.laenge;i++)
				{
					Schiff[schiff1.startY-i][schiff1.startX+i]='X';
 
				}	
				return true;
 
			}
			else
			{
				return false;	
			}
 
		}
 
		//Prüfen der Richtung 3 == nach rechts (Y bleibt gleich, X wird mehr)
		zaehler=1;
		if(schiff1.richtung==3) 
		{
			if(schiff1.startX+(schiff1.laenge-1)<SPALTEN)
			{
				for(int i=1;i<schiff1.laenge;i++)		//Prüft jede Koordinate ob bereits ein Schiff vorhanden ist
				{
					if(Schiff[schiff1.startY][schiff1.startX+i]!='X')
					{
						//cout << "Position ist frei";
						zaehler++;
					}
				}
			}
 
			if(zaehler==schiff1.laenge)
			{
				cout << "Schiff wird platziert - Zaehler: " << zaehler << endl;
				//Schiff wird erst jetzt platziert!!!				
				for(int i=0;i<schiff1.laenge;i++)
				{
					Schiff[schiff1.startY][schiff1.startX+i]='X';
 
				}	
				return true;
 
			}
			else
			{
				return false;	
			}
 
		}
	}
	return false;
 
}