/*
I. 180.
fejlesztokornyezet: Dev-C++ 4.9.9.2 -el probaltam ki, de szerintem a kod szabvanyos, mashol is mukodik
Szabo Gabor
sotet mezo: sor+oszlop ps
vilagos mezo: sor+oszlop pt
*/
#include <iostream>
#include <fstream>

#define S_BASTYA 4            //sotet mezon allo bastyak szama
#define V_BASTYA 4            //vilagos mezon allo bastyak szama

typedef struct
{
      int sor;
      int oszlop;
} bastya;

bastya bastyak[S_BASTYA + V_BASTYA];

int szabad_sorok[V_BASTYA];				//azon sorok, ahova lehet a vilagoson allo bastyakat rakni

void sz_sorok(void);					//szabad sorok meghatarozasa

void leptet_s(int);						//n. soteten allo bastya lerakasa a lehetseges helyekre
void leptet_v(int);						//n. vilagos mezon allo bastya lerakasa a lehetseges helyekre

char table[25][25];

void reset_table(void);					//a tabla uresse varazsolasa
void set_table(int);					//k db bastya felhelyezese a tablara (csak a kimenet miatt)

std::ofstream of;							//kimeneti fajl

void write_to_file(void);				//megtalalt lehetoseget fajlba kiiro fv

int counter = 0; 						//talalalatok szamlaloja

int main(int argc, char *argv[])
	{
		char *filename = NULL;
		if (argc < 2)
			filename = "bastya.txt";
		else
			filename = argv[1];
		reset_table();
		of.open(filename);				//fajl megnyitasa, a sotet mezon allo bastyak felrakasanak inditasa
		leptet_s(1);
		of.close();
		return 0;
	}

void reset_table()
	{
		for (int i=0; i < 25; i++)
			for (int j=0; j < 25; j++)
				table[i][j] = '.';
	}

void set_table(int k)
	{

		for (int i=0; i < k; i++)
			table[ bastyak[i].sor ][ bastyak[i].oszlop ] = 'X';
	}

void write_to_file()
	{
		of << counter << '\n';
		for (int i=7; i >= 0; i--)
			{
			for (int j=0; j < 8; j++)
				of << table[i][j];
			of << '\n';
			}
		of << '\n';
	}

void leptet_s(int n)
	{
		bastyak[n-1].sor = (n == 1) ? 0 : (bastyak[n-2].sor + 1);						//a bastya kezdosora, ha ez az elso, akkor 0. sorbol indul, egyebkent az eggyel elotte levotol 1-gyel feljebbrol
		while (bastyak[n-1].sor < 8)								//minden bastyan vegigprobal minden oszlopot
		{
        	bastyak[n-1].oszlop = 0;
			while (bastyak[n-1].oszlop < 8)
				{
                	bool jomezo = true;												//az aktualis mezon uti-e egy masik bastya ?
					if ( (bastyak[n-1].oszlop + bastyak[n-1].sor) % 2 != 0 )		//ha nem sotet mezore raktuk
						jomezo = false;
					for (int i = 0; i < (n-1); i++ )								//ha vmelyik korabban felrakott bastya uti
						if (bastyak[i].oszlop == bastyak[n-1].oszlop)
							jomezo = false;
					if (jomezo)
						{
							if (n == S_BASTYA)										//ha az utolso sotet mezon levo bastya
								{
									sz_sorok();										//szabad sorok meghatarozasa, vilagos mezon allok felrakasanak inditasa
									leptet_v(1);
								}
							else
								leptet_s(n+1);										//rekurziv meghivas, a kovetkezo sotet mezon allo bastya felrakasas
						}
					bastyak[n-1].oszlop++;
				}
			bastyak[n-1].sor++;
		}
	}

void leptet_v(int n)
	{
		int k = n + 4;
		bastyak[k-1].sor = szabad_sorok[n-1];
		bastyak[k-1].oszlop = 0;
		while (bastyak[k-1].oszlop < 8)
			{
				bool jomezo = true;
				if ( (bastyak[k-1].oszlop + bastyak[k-1].sor) % 2 != 1 )		//ha nem vilagos mezore kerult
					jomezo = false;
				for (int i = 0; i < (k-1); i++)
					if (bastyak[k-1].oszlop == bastyak[i].oszlop)
						jomezo = false;
				if (jomezo)
					{
						if (n == V_BASTYA)
							{
								reset_table();
								set_table(V_BASTYA + S_BASTYA);
								counter++;
								write_to_file();
							}
						else
							leptet_v(n+1);
					}
				bastyak[k-1].oszlop++;
			}
	}

void sz_sorok()
	{
		int c = 0;
		for (int i = 0; i < 8; i++)										//vegignezi mely sorok nincsenek meg lefoglalva sotet mezon allokkal
			{
				bool szabadsor = true;
				for (int j = 0; j < S_BASTYA; j++)
					if (bastyak[j].sor == i)
						szabadsor = false;
				if (szabadsor)
					{
						szabad_sorok[c] = i;
						c++;
					}
			}
	}


