//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdlib.h>
#include <stdio.h>

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::smaz(int k)      // tato funkce smaze prvek z pole G_VOLNY
{
	int	i;
	for(i=k ; g_volny[i].typ>0 ; i++)
		g_volny[i] = g_volny[i+1];
	g_stupen_volny--;
}

void __fastcall TForm1::napln_matici(void)
{
	int	i,j;
  // njdrive to cele vynulujeme
	for(i=0 ; i<=MAX_MX + 1; i++)
		for(j=0 ; j<=MAX_MY + 1; j++)
      g_matice[i][j] = 0;
  // pak naplnime podle pravidel
	for(i=0 ; i<=MAX_MX + 1; i++)
		for(j=0 ; j<=MAX_MY + 1; j++)
		{
      if (i==0 || j==0 || i == MAX_MX + 1 || j == MAX_MY + 1)
      {
        g_matice[i][j] = 100;
        continue;
      }
			if (i>0 && i<5)
			{
					if ( j+3*i-3 <= 17 ) g_matice[i][j]=100;
					if ( j-3*i+3 >= 37 ) g_matice[i][j]=100;
					if ( j+3*i-3 == 19 ) g_matice[i][j]=30;
					if ( j-3*i+3 == 35 ) g_matice[i][j]=90;
					if ( j+3*i-3 == 18 ) g_matice[i][j]=85;
					if ( j-3*i+3 == 36 ) g_matice[i][j]=25;
					continue;
			}
			if ( i>4 && i<12 )
			{
					if ( j+i-5 <= 7  ) g_matice[i][j]=100;
					if ( j-i+5 >= 47 ) g_matice[i][j]=100;
					continue;
			}
			if ( i>11 && i<20 )
			{
					if ( i % 2 == 0 && j==1 ) g_matice[i][j]=5;
					if ( i % 2 == 0 && j==53) g_matice[i][j]=95;
					if ( i % 2 != 0 && j==1 ) g_matice[i][j]=80;
					if ( i % 2 != 0 && j==53) g_matice[i][j]=20;
					continue;
			}
			if ( i>19 && i<27)
			{
					if ( j-i+20 <= 1 )  g_matice[i][j]=100;
					if ( j+i-20 >= 53 ) g_matice[i][j]=100;
					continue;
			}
			if ( i>26 && i<31 )
			{
					if ( j-3*(i-27) <= 8 )  g_matice[i][j]=100;
					if ( j+3*(i-27) >= 46 ) g_matice[i][j]=100;
					if ( j-3*(i-27) == 9 )  g_matice[i][j]=10;
					if ( j+3*(i-27) == 45 ) g_matice[i][j]=70;
					if ( j-3*(i-27) == 10 ) g_matice[i][j]=75;
					if ( j+3*(i-27) == 44 ) g_matice[i][j]=15;
					continue;
			}
			g_matice[i][j]=0;
		}
}

/*void __fastcall TForm1::napln_matici(void) // Tato funkce smaze celou matici
{
	int	i,j;
	for(i=0 ; i<=MAX_MX+1 ; i++)
		for(j=0 ; j<=MAX_MY+1 ; j++)
			if (i==0 || j==0 || i==MAX_MX+1 || j==MAX_MY+1) g_matice[i][j]=100;
			else g_matice[i][j]=0;
} */

tPrvek __fastcall TForm1::napln_prvek ( int cis, int rot )   // Tato funkce naplni
  // pozadovany prvek pro ruzne rotace
{
	int		i,j;
	tPrvek	prvek_pom, prvek_vys;

  // obe prvky vynulujeme
	for (i=0 ; i<=6 ; i++)
		for (j=0 ; j<=10 ; j++)
		{
			prvek_vys.pole[i][j] = 0;
			prvek_pom.pole[i][j] = 0;
		}
  // do prvek_pom nahrajeme co potrebujeme
	prvek_pom     = g_prvky[cis][1];
	prvek_vys.cis = prvek_pom.cis;
	prvek_vys.rot = rot;

  // tady se to zrcadlove otoci pro rot vetsi jak 6



  // tady je skonceni zrcadleni

	// pred otocenim zmenime u roseknutych hodnoty
	for (i=1 ; i<=6 ; i++)
		for (j=1 ; j<=10 ; j++)
			if ( prvek_pom.pole[i][j] != 0 && prvek_pom.pole[i][j] != 100)
				if (prvek_pom.pole[i][j] < 50)
				{
					prvek_pom.pole[i][j] = (rot-1)*5 + prvek_pom.pole[i][j];
					if ( prvek_pom.pole[i][j] > 30 )
						prvek_pom.pole[i][j] = prvek_pom.pole[i][j] - 30;
				}
				else
				{
					prvek_pom.pole[i][j] = - (rot-1)*5 + prvek_pom.pole[i][j];
					if ( prvek_pom.pole[i][j] < 70 )
						prvek_pom.pole[i][j] = prvek_pom.pole[i][j] + 30;
				}
	// ted to rozdelime podle rotaci
	switch(rot)
	{
		case 1:	for (i=1 ; i<=6 ; i++)
				for (j=1 ; j<=10 ; j++)
					prvek_vys.pole[i][j] = prvek_pom.pole[i][j];
			break;
		case 2:	prvek_vys.pole[5][2] = prvek_pom.pole[1][1];
			prvek_vys.pole[4][2] = prvek_pom.pole[1][2];
			prvek_vys.pole[4][3] = prvek_pom.pole[1][3];
			prvek_vys.pole[3][3] = prvek_pom.pole[1][4];
			prvek_vys.pole[3][4] = prvek_pom.pole[1][5];
			prvek_vys.pole[2][4] = prvek_pom.pole[1][6];
			prvek_vys.pole[2][5] = prvek_pom.pole[1][7];
			prvek_vys.pole[1][5] = prvek_pom.pole[1][8];
			//druha rada
			prvek_vys.pole[5][3] = prvek_pom.pole[2][1];
			prvek_vys.pole[5][4] = prvek_pom.pole[2][2];
			prvek_vys.pole[4][4] = prvek_pom.pole[2][3];
			prvek_vys.pole[4][5] = prvek_pom.pole[2][4];
			prvek_vys.pole[3][5] = prvek_pom.pole[2][5];
			prvek_vys.pole[3][6] = prvek_pom.pole[2][6];
			prvek_vys.pole[2][6] = prvek_pom.pole[2][7];
			prvek_vys.pole[2][7] = prvek_pom.pole[2][8];
			//treti rada
			prvek_vys.pole[6][5] = prvek_pom.pole[3][1];
			prvek_vys.pole[5][5] = prvek_pom.pole[3][2];
			prvek_vys.pole[5][6] = prvek_pom.pole[3][3];
			prvek_vys.pole[4][6] = prvek_pom.pole[3][4];
			prvek_vys.pole[4][7] = prvek_pom.pole[3][5];
			prvek_vys.pole[3][7] = prvek_pom.pole[3][6];
			prvek_vys.pole[3][8] = prvek_pom.pole[3][7];
			prvek_vys.pole[2][8] = prvek_pom.pole[3][8];
			//ctvrta rada
			prvek_vys.pole[6][6] = prvek_pom.pole[4][1];
			prvek_vys.pole[6][7] = prvek_pom.pole[4][2];
			prvek_vys.pole[5][7] = prvek_pom.pole[4][3];
			prvek_vys.pole[5][8] = prvek_pom.pole[4][4];
			prvek_vys.pole[4][8] = prvek_pom.pole[4][5];
			prvek_vys.pole[4][9] = prvek_pom.pole[4][6];
			prvek_vys.pole[3][9] = prvek_pom.pole[4][7];
			prvek_vys.pole[3][10]= prvek_pom.pole[4][8];
			break;
		case 3:
			prvek_vys.pole[6][6] = prvek_pom.pole[1][1];
			prvek_vys.pole[6][5] = prvek_pom.pole[1][2];
			prvek_vys.pole[5][5] = prvek_pom.pole[1][3];
			prvek_vys.pole[5][4] = prvek_pom.pole[1][4];
			prvek_vys.pole[4][4] = prvek_pom.pole[1][5];
			prvek_vys.pole[4][3] = prvek_pom.pole[1][6];
			prvek_vys.pole[3][3] = prvek_pom.pole[1][7];
			prvek_vys.pole[3][2] = prvek_pom.pole[1][8];
			//druha rada
			prvek_vys.pole[6][7] = prvek_pom.pole[2][1];
			prvek_vys.pole[5][7] = prvek_pom.pole[2][2];
			prvek_vys.pole[5][6] = prvek_pom.pole[2][3];
			prvek_vys.pole[4][6] = prvek_pom.pole[2][4];
			prvek_vys.pole[4][5] = prvek_pom.pole[2][5];
			prvek_vys.pole[3][5] = prvek_pom.pole[2][6];
			prvek_vys.pole[3][4] = prvek_pom.pole[2][7];
			prvek_vys.pole[2][4] = prvek_pom.pole[2][8];
			//treti rada
			prvek_vys.pole[5][9] = prvek_pom.pole[3][1];
			prvek_vys.pole[5][8] = prvek_pom.pole[3][2];
			prvek_vys.pole[4][8] = prvek_pom.pole[3][3];
			prvek_vys.pole[4][7] = prvek_pom.pole[3][4];
			prvek_vys.pole[3][7] = prvek_pom.pole[3][5];
			prvek_vys.pole[3][6] = prvek_pom.pole[3][6];
			prvek_vys.pole[2][6] = prvek_pom.pole[3][7];
			prvek_vys.pole[2][5] = prvek_pom.pole[3][8];
			//ctvrta rada
			prvek_vys.pole[5][10] = prvek_pom.pole[4][1];
			prvek_vys.pole[4][10] = prvek_pom.pole[4][2];
			prvek_vys.pole[4][9]  = prvek_pom.pole[4][3];
			prvek_vys.pole[3][9]  = prvek_pom.pole[4][4];
			prvek_vys.pole[3][8]  = prvek_pom.pole[4][5];
			prvek_vys.pole[2][8]  = prvek_pom.pole[4][6];
			prvek_vys.pole[2][7]  = prvek_pom.pole[4][7];
			prvek_vys.pole[1][7]  = prvek_pom.pole[4][8];
			break;
		case 4:	prvek_vys.pole[4][9] = prvek_pom.pole[1][1];
			prvek_vys.pole[4][8] = prvek_pom.pole[1][2];
			prvek_vys.pole[4][7] = prvek_pom.pole[1][3];
			prvek_vys.pole[4][6] = prvek_pom.pole[1][4];
			prvek_vys.pole[4][5] = prvek_pom.pole[1][5];
			prvek_vys.pole[4][4] = prvek_pom.pole[1][6];
			prvek_vys.pole[4][3] = prvek_pom.pole[1][7];
			prvek_vys.pole[4][2] = prvek_pom.pole[1][8];
			//druha rada
			prvek_vys.pole[3][9] = prvek_pom.pole[2][1];
			prvek_vys.pole[3][8] = prvek_pom.pole[2][2];
			prvek_vys.pole[3][7] = prvek_pom.pole[2][3];
			prvek_vys.pole[3][6] = prvek_pom.pole[2][4];
			prvek_vys.pole[3][5] = prvek_pom.pole[2][5];
			prvek_vys.pole[3][4] = prvek_pom.pole[2][6];
			prvek_vys.pole[3][3] = prvek_pom.pole[2][7];
			prvek_vys.pole[3][2] = prvek_pom.pole[2][8];
			//treti rada
			prvek_vys.pole[2][9] = prvek_pom.pole[3][1];
			prvek_vys.pole[2][8] = prvek_pom.pole[3][2];
			prvek_vys.pole[2][7] = prvek_pom.pole[3][3];
			prvek_vys.pole[2][6] = prvek_pom.pole[3][4];
			prvek_vys.pole[2][5] = prvek_pom.pole[3][5];
			prvek_vys.pole[2][4] = prvek_pom.pole[3][6];
			prvek_vys.pole[2][3] = prvek_pom.pole[3][7];
			prvek_vys.pole[2][2] = prvek_pom.pole[3][8];
			//ctvrta rada
			prvek_vys.pole[1][9] = prvek_pom.pole[4][1];
			prvek_vys.pole[1][8] = prvek_pom.pole[4][2];
			prvek_vys.pole[1][7] = prvek_pom.pole[4][3];
			prvek_vys.pole[1][6] = prvek_pom.pole[4][4];
			prvek_vys.pole[1][5] = prvek_pom.pole[4][5];
			prvek_vys.pole[1][4] = prvek_pom.pole[4][6];
			prvek_vys.pole[1][3] = prvek_pom.pole[4][7];
			prvek_vys.pole[1][2] = prvek_pom.pole[4][8];
			break;
		case 5:	prvek_vys.pole[2][10] = prvek_pom.pole[1][1];
			prvek_vys.pole[3][10] = prvek_pom.pole[1][2];
			prvek_vys.pole[3][9]  = prvek_pom.pole[1][3];
			prvek_vys.pole[4][9]  = prvek_pom.pole[1][4];
			prvek_vys.pole[4][8]  = prvek_pom.pole[1][5];
			prvek_vys.pole[5][8]  = prvek_pom.pole[1][6];
			prvek_vys.pole[5][7]  = prvek_pom.pole[1][7];
			prvek_vys.pole[6][7]  = prvek_pom.pole[1][8];
			//druha rada
			prvek_vys.pole[2][9] = prvek_pom.pole[2][1];
			prvek_vys.pole[2][8] = prvek_pom.pole[2][2];
			prvek_vys.pole[3][8] = prvek_pom.pole[2][3];
			prvek_vys.pole[3][7] = prvek_pom.pole[2][4];
			prvek_vys.pole[4][7] = prvek_pom.pole[2][5];
			prvek_vys.pole[4][6] = prvek_pom.pole[2][6];
			prvek_vys.pole[5][6] = prvek_pom.pole[2][7];
			prvek_vys.pole[5][5] = prvek_pom.pole[2][8];
			//treti rada
			prvek_vys.pole[1][7] = prvek_pom.pole[3][1];
			prvek_vys.pole[2][7] = prvek_pom.pole[3][2];
			prvek_vys.pole[2][6] = prvek_pom.pole[3][3];
			prvek_vys.pole[3][6] = prvek_pom.pole[3][4];
			prvek_vys.pole[3][5] = prvek_pom.pole[3][5];
			prvek_vys.pole[4][5] = prvek_pom.pole[3][6];
			prvek_vys.pole[4][4] = prvek_pom.pole[3][7];
			prvek_vys.pole[5][4] = prvek_pom.pole[3][8];
			//ctvrta rada
			prvek_vys.pole[1][6] = prvek_pom.pole[4][1];
			prvek_vys.pole[1][5] = prvek_pom.pole[4][2];
			prvek_vys.pole[2][5] = prvek_pom.pole[4][3];
			prvek_vys.pole[2][4] = prvek_pom.pole[4][4];
			prvek_vys.pole[3][4] = prvek_pom.pole[4][5];
			prvek_vys.pole[3][3] = prvek_pom.pole[4][6];
			prvek_vys.pole[4][3] = prvek_pom.pole[4][7];
			prvek_vys.pole[4][2] = prvek_pom.pole[4][8];
			break;
		case 6:	prvek_vys.pole[1][6] = prvek_pom.pole[1][1];
			prvek_vys.pole[1][7] = prvek_pom.pole[1][2];
			prvek_vys.pole[2][7] = prvek_pom.pole[1][3];
			prvek_vys.pole[2][8] = prvek_pom.pole[1][4];
			prvek_vys.pole[3][8] = prvek_pom.pole[1][5];
			prvek_vys.pole[3][9] = prvek_pom.pole[1][6];
			prvek_vys.pole[4][9] = prvek_pom.pole[1][7];
			prvek_vys.pole[4][10]= prvek_pom.pole[1][8];
			//druha rada
			prvek_vys.pole[1][5] = prvek_pom.pole[2][1];
			prvek_vys.pole[2][5] = prvek_pom.pole[2][2];
			prvek_vys.pole[2][6] = prvek_pom.pole[2][3];
			prvek_vys.pole[3][6] = prvek_pom.pole[2][4];
			prvek_vys.pole[3][7] = prvek_pom.pole[2][5];
			prvek_vys.pole[4][7] = prvek_pom.pole[2][6];
			prvek_vys.pole[4][8] = prvek_pom.pole[2][7];
			prvek_vys.pole[5][8] = prvek_pom.pole[2][8];
			//treti rada
			prvek_vys.pole[2][3] = prvek_pom.pole[3][1];
			prvek_vys.pole[2][4] = prvek_pom.pole[3][2];
			prvek_vys.pole[3][4] = prvek_pom.pole[3][3];
			prvek_vys.pole[3][5] = prvek_pom.pole[3][4];
			prvek_vys.pole[4][5] = prvek_pom.pole[3][5];
			prvek_vys.pole[4][6] = prvek_pom.pole[3][6];
			prvek_vys.pole[5][6] = prvek_pom.pole[3][7];
			prvek_vys.pole[5][7] = prvek_pom.pole[3][8];
			//ctvrta rada
			prvek_vys.pole[2][2] = prvek_pom.pole[4][1];
			prvek_vys.pole[3][2] = prvek_pom.pole[4][2];
			prvek_vys.pole[3][3] = prvek_pom.pole[4][3];
			prvek_vys.pole[4][3] = prvek_pom.pole[4][4];
			prvek_vys.pole[4][4] = prvek_pom.pole[4][5];
			prvek_vys.pole[5][4] = prvek_pom.pole[4][6];
			prvek_vys.pole[5][5] = prvek_pom.pole[4][7];
			prvek_vys.pole[6][5] = prvek_pom.pole[4][8];
			break;
		}
	return(prvek_vys);
}

int __fastcall TForm1::kontrola( tPrvek prvek )//Tato fun. zkontoluje zda lze prvek ulozit
{
	int i,j,k;
	int pokracuj;
  int volna_mista;
  // zde nastavime hodnotu ktera po celou dobu bude TRUE pokud prvek nesplni
  // nekterou s podminek nastavise na FALSE a test skonci
	pokracuj = TRUE;
	// zkusime zda pridani tohoto prvku nesmaze cely g_volny
  //zde zjistime kolik mist v g_volny je skutecne moznych
  volna_mista = 0;
  for (i=1;g_volny[i].typ>0;i++)
    if (!(g_volny[i].zalepeno)) volna_mista++;
  // nejdrive se vyzkousi jestli pridany prvek nezakryje nektere prvky z g_volny
	for(i=prvek.x;i<=MAX_X;i++)
		for(j=1;j<=MAX_Y;j++)
      if (prvek.pole[i][j]!=0)
        for (k=1;k<=300 && g_volny[k].typ>0;k++)
   		  	if (!(g_volny[k].zalepeno) && ((g_nej.x + i - prvek.x == g_volny[k].x) && (g_nej.y + j - prvek.y == g_volny[k].y)))
              volna_mista--;
  // pokud v g_volny po pridani nezustane alespon jedno volne misto musime zkontrolovat
  // zda nejake volne misto neprinasi prvek
  if (volna_mista==0)
  {
    // ted projedeme vsechny diry na prvku a pokud alespon jedna bude po prilepeni ne
    // nezalepena muzeme pokracovat
    pokracuj = FALSE;
    for (i=1;prvek.diry[i].typ>0 && !pokracuj;i++)
      if ((g_matice[g_nej.x + prvek.diry[i].x - prvek.x][g_nej.y + prvek.diry[i].y - prvek.y]==0)
       && (g_nej.x + prvek.diry[i].x - prvek.x <= konec_x)
       && (g_nej.y + prvek.diry[i].y - prvek.y <= konec_y)
       && (g_nej.x + prvek.diry[i].x - prvek.x > zacatek_x)
       && (g_nej.y + prvek.diry[i].y - prvek.y > zacatek_y)) pokracuj = TRUE;
  }
	// no a ted zkontrolujeme postupne vsechny prvky
	if ( pokracuj )
	{
		for ( i=prvek.x ; i<=MAX_X ; i++ )
		{
			for ( j=1 ; j<=MAX_Y ; j++ )
			{
				// toto vsechno se provede jenom jestli je co ukladat - neni tam prazdne misto
				if ( prvek.pole[i][j] )
				{
					// nejdrive kontrola zda nejsme mimo hraci plochu
					if ( g_nej.y+j-prvek.y > MAX_MY || g_nej.y+j-prvek.y < 1 || g_nej.x+i-prvek.x > MAX_MY )
						pokracuj = FALSE;
					else
						// ted kontrola presahu
						if ( !((prvek.pole[i][j] + g_matice[g_nej.x+i-prvek.x][g_nej.y+j-prvek.y] == 100) || (g_matice[g_nej.x+i-prvek.x][g_nej.y+j-prvek.y] == 0)))
							pokracuj = FALSE;
				}
				if (!pokracuj) break;
			}
			if (!pokracuj) break;
		}
	}
	// ted jeste zkontrolujeme volne misto okolo

	if ( pokracuj )
	{
		// a ted projedeme volna policka
		for ( i=1 ; i<=6 ; i++)
		{
			for ( j=1 ; j<=10 ; j++ )
			{
				if ( !((i+j) % 2) )
				{
					// nejdrive kontrola zda nejsme mimo hraci plochu
					if ((g_nej.y+j-prvek.y<=MAX_MY) && (g_nej.y+j-prvek.y>0) && (g_nej.x+i-prvek.x>0) && (g_nej.x+i-prvek.x<=MAX_MX))
						if (g_matice[g_nej.x+i-prvek.x][g_nej.y+j-prvek.y] + prvek.pole[i][j] != 100 )
							switch (g_matice[g_nej.x+i-prvek.x][g_nej.y+j-prvek.y] + prvek.pole[i][j])
							{
								case 0:	if (!((
										 ( g_matice[g_nej.x + i - prvek.x + 1][g_nej.y + j - prvek.y    ] + prvek.pole[i + 1][j]     == 0)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][g_nej.y + j - prvek.y    ] + prvek.pole[i + 1][j]     == 70)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][g_nej.y + j - prvek.y    ] + prvek.pole[i + 1][j]     == 10))
									|| ((g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y - 1] + prvek.pole[i    ][j - 1] == 0)
									|| ( g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y - 1] + prvek.pole[i    ][j - 1] == 80)
									|| ( g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y - 1] + prvek.pole[i    ][j - 1] == 30))
									|| ((g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y + 1] + prvek.pole[i    ][j + 1] == 0)
									|| ( g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y + 1] + prvek.pole[i    ][j + 1] == 90)
									|| ( g_matice[g_nej.x + i - prvek.x    ][g_nej.y + j - prvek.y + 1] + prvek.pole[i    ][j + 1] == 20)
									))) pokracuj = FALSE;
									break;
		//----------------------------------------------------------------------------------------------
								case 5:	if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 90)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 80)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 2] + prvek.pole[i]    [j + 2] == 25)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 2] + prvek.pole[i]    [j + 2] == 0)
									)))) pokracuj = FALSE;
									break;
		//----------------------------------------------------------------------------------------------
								case 15:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 80)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i - 1][j - 1] == 5)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i - 1][j - 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 70)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									)))) pokracuj = FALSE;
									break;
		  //----------------------------------------------------------------------------------------------
								case 25:if (!(
										 ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 0)
									|| ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 70)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i + 1][j - 1] == 15)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i + 1][j - 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 90)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									)))) pokracuj = FALSE;
									break;
		//----------------------------------------------------------------------------------------------
								case 75:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 20)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i - 1][j + 1] == 95)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i - 1][j + 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 10)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									)))) pokracuj = FALSE;
									break;
		//----------------------------------------------------------------------------------------------
								case 85:if (!(
										 ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 0)
									|| ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 10)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i + 1][j + 1] == 75)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i + 1][j + 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 30)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									)))) pokracuj = FALSE;
									break;
		//----------------------------------------------------------------------------------------------
								case 95:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 30)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 20)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y]     + prvek.pole[i + 1][j]     == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 2] + prvek.pole[i]    [j - 2] == 85)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 2] + prvek.pole[i]    [j - 2] == 0)
									)))) pokracuj = FALSE;
									break;
							}
				}
				else
					// nejdrive kontrola zda nejsme mimo hraci plochu
					if ( (g_nej.y + j - prvek.y <=MAX_MY) && (g_nej.y + j - prvek.y > 0) && (g_nej.x + i - prvek.x > 0) && (g_nej.x + i - prvek.x <= MAX_MX) )
						if ( g_matice[g_nej.x + i - prvek.x][g_nej.y + j - prvek.y] + prvek.pole[i][j] != 100 )
							switch (g_matice[g_nej.x + i - prvek.x][g_nej.y + j - prvek.y] + prvek.pole[i][j])
							{
								case 0:	if (!((
										 ( g_matice[g_nej.x + i - prvek.x - 1][g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 0)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 25)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 85))
									|| ((g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									|| ( g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 75)
									|| ( g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 55))
									|| ((g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									|| ( g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 95)
									|| ( g_matice[g_nej.x + i - prvek.x]    [g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 15)
									))) pokracuj = FALSE;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 10:if (!(
										 ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 0)
									|| ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 85)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i - 1][j + 1] == 30)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i - 1][j + 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 75)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									)))) pokracuj = FALSE;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 20:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 75)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 95)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 2] + prvek.pole[i][j - 2]     == 10)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 2] + prvek.pole[i][j - 2]     == 0)
									)))) pokracuj = FALSE;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 30:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 95)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i + 1][j + 1] == 20)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y + 1] + prvek.pole[i + 1][j + 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 85)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									)))) pokracuj = FALSE;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 70:if (!(
										 ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 0)
									|| ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 25)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i - 1][j - 1] == 90)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i - 1][j - 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 15)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									)))) pokracuj = FALSE;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 80:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 15)
									&& ((g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 5)
									|| ( g_matice[g_nej.x + i - prvek.x - 1][ g_nej.y + j - prvek.y]     + prvek.pole[i - 1][j]     == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 2] + prvek.pole[i]    [j + 2] == 70)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 2] + prvek.pole[i]    [j + 2] == 0)
									)))) pokracuj = FALSE ;
									break;
	      //-------------------------------------------------------------------------------------------------------------
								case 90:if (!(
										 ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 0)
									|| ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y - 1] + prvek.pole[i]    [j - 1] == 5)
									&& ((g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i + 1][j - 1] == 80)
									|| ( g_matice[g_nej.x + i - prvek.x + 1][ g_nej.y + j - prvek.y - 1] + prvek.pole[i + 1][j - 1] == 0))
									&& ((g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 25)
									|| ( g_matice[g_nej.x + i - prvek.x]    [ g_nej.y + j - prvek.y + 1] + prvek.pole[i]    [j + 1] == 0)
									)))) pokracuj = FALSE;
									break;
							}
				if (!pokracuj) break;
			}
			if (!pokracuj) break;
		}
	}
	// no a ted bude nejdelsi kontrola kde zjistime zda novych poli se daji strcit nove prvky
	return(pokracuj);
}

void __fastcall TForm1::pridej_prvek ( tPrvek prvek )  // Tato funkce uklada prvek
{
	int 	i,j,k;

	// no a ted zapisem postupne vsechny prvky
	for ( i=prvek.x ; i<=6 ; i++)
		for ( j=1 ; j<=10 ; j++ )
      if (prvek.pole[i][j] != 0)
		  {
  			g_matice[g_nej.x + i - prvek.x][g_nej.y + j - prvek.y] = g_matice[g_nej.x + i - prvek.x][g_nej.y + j - prvek.y] + prvek.pole[i][j];
	  		// a jeste zkontrolujeme zda prvek nevyplnuje i jinou diru z g_volny
		  	for (k=1;g_volny[k].cis>0;k++)
  				if (g_nej.x + i - prvek.x == g_volny[k].x && g_nej.y + j - prvek.y == g_volny[k].y)
          {
            g_volny[k].zalepeno = TRUE;
            g_volny[k].cislo = prvek.cis;
          }
			}
	//zapiseme do reseni
	g_stupen++;
	g_reseni[g_stupen].cis = prvek.cis;
	g_reseni[g_stupen].x   = g_nej.x;
	g_reseni[g_stupen].y   = g_nej.y;
	g_reseni[g_stupen].rot = prvek.rot;
	//zapiseme do ulozeno
	g_ulozeno[prvek.cis] = TRUE;
	// postupne projedeme vsechna volna mista a zapiseme je do g_volny
	for (i=1;prvek.diry[i].typ > 0;i++)
		// nejdrive zkontrolujeme zda dira na prvku neni zalepena vlozenim
		if (g_matice[g_nej.x + prvek.diry[i].x - prvek.x][g_nej.y + prvek.diry[i].y - prvek.y] !=100  )
    // ted zkontrolujeme zda jsme nepresahli povolenou velikost a pokud ano
    // nic nezapiseme
      if (!(pouzivat_omez_pole) || ((g_nej.x + prvek.diry[i].x - prvek.x <= konec_x)
       && (g_nej.y + prvek.diry[i].y - prvek.y <= konec_y)
       && (g_nej.x + prvek.diry[i].x - prvek.x > zacatek_x)
       && (g_nej.y + prvek.diry[i].y - prvek.y > zacatek_y)))
  		{
        g_volny[1 + g_stupen_volny].typ = prvek.diry[i].typ;
        g_volny[1 + g_stupen_volny].cis = prvek.cis;
        g_volny[1 + g_stupen_volny].x = g_nej.x + prvek.diry[i].x - prvek.x;
        g_volny[1 + g_stupen_volny].y = g_nej.y + prvek.diry[i].y - prvek.y;
  			g_stupen_volny++;
	  	}
	// nastavime kde se bude zacinat
	g_cislo_posledniho_prvku = 1;
}

void __fastcall TForm1::odeber_prvek(void)
{
	int		i, j;
 	int prvni,druhy;
  int l_nej_typ, l_nej_x, l_nej_y;
	tPrvek	prvek;
	tDilek	dilek;
  prvni = 0;
  // toto budeme opakovat tak dlouho dokud nenejdeme diru do ktere se jeste
  // pude neco strcit
  do {
  	// Natahnem si posledni dilek
  	dilek = g_reseni[g_stupen];
  	//do prvku nahrajem tento dilek
  	prvek = g_prvky [dilek.cis][dilek.rot];
  	// no a ted odepisem postupne vsechny prvky
	  for ( i=prvek.x ; i<=6 ; i++)
		  for ( j=1 ; j<=10 ; j++ )
  			g_matice[dilek.x + i - prvek.x][dilek.y + j - prvek.y] = g_matice[dilek.x + i - prvek.x][dilek.y + j - prvek.y] - prvek.pole[i][j];
  	//vymazeme z reseni
  	g_reseni[g_stupen] = g_nula_d;
  	g_stupen--;
  	//zapiseme do ulozeno
  	g_ulozeno[prvek.cis] = FALSE;
  	//ted jeste upravit g_volny
  	for (i=1;g_volny[i].cis > 0;i++)
  		if (g_volny[i].cis == prvek.cis)
  		{
  			smaz(i);
        i--;
  		}
  	// pokud jsme odebrali prvni prvek je potreba skoncit
    if (g_reseni[1].cis != 0)
    {
    	// pridam diry, ktere jsem zalepil
     	for (i=1; g_volny[i].typ > 0;i++)
        if (g_volny[i].cislo == prvek.cis)
        {
    	    g_volny[i].zalepeno = FALSE;
          g_volny[i].cislo = 0;
        };
      // najdeme typ diry do ktere se v dalsim kroku pokusime ulozit
      for (i=1;i<=g_stupen_volny;i++)
       if (g_volny[i].zalepeno == FALSE)
       {
         l_nej_typ = g_volny[i].typ;
         l_nej_x = g_volny[i].x;
         l_nej_y = g_volny[i].y;
         break;
       }
      //pokud jsme odebrali posledni ulozitelny prvek je potreba odebrat dalsi
      // nejdrive urcime pozici odebiraneho prvku
    	for (i=1;g_hroty[l_nej_typ][i].cis > 0;i++)
    		if (g_hroty[l_nej_typ][i].cis == prvek.cis
         && g_hroty[l_nej_typ][i].rot == prvek.rot)
          if (g_hroty[l_nej_typ][i].x == l_nej_x - dilek.x + prvek.x
           && g_hroty[l_nej_typ][i].y == l_nej_y - dilek.y + prvek.y)
          {
            prvni = i;
            break;
          }
      // a pak najdeme posledni ulozitelny prvek
    	for (i = MAX_HROTY;i>=1;i--)
    		if ((g_hroty[l_nej_typ][i].cis != 0) && !(g_ulozeno[g_hroty[l_nej_typ][i].cis]))
        {
          druhy = i;
          break;
        }
    }
    else druhy = prvni + 1;
    // pokud jsou stejne jedna se o posledni ulozitelny prvek a je potreba
    // vzit dalsi
  } while (prvni == druhy);
  // a nastavime prvek kterym se bude pokracovat
  g_cislo_posledniho_prvku = prvni+1;
}

void __fastcall TForm1::pridej_hrot(int typ,int cis,int rot,int x,int y)  //funkci pro pridani prvku do hrotu
{
  int i;
  i = 1;
  for (i=1;g_hroty[typ][i].cis >= 0;i++)
    if (g_hroty[typ][i].cis == 0)
    {
      g_hroty[typ][i].cis = cis;
      g_hroty[typ][i].rot = rot;
      g_hroty[typ][i].x   = x;
      g_hroty[typ][i].y   = y;
      break;
    }
}

void __fastcall TForm1::nacti_hroty(void)
{
  int i,j;
  int k,l;
  tPrvek prvek;
  //nejdrive hroty vynulejeme
  for (i=0;i<=36;i++)
    for (j=0;j<=MAX_HROTY;j++)
    {
      g_hroty[i][j].cis = 0;
      g_hroty[i][j].rot = 0;
      g_hroty[i][j].x = 0;
      g_hroty[i][j].y = 0;
    }
  //a ted budeme brat prvky po jednom a kuchat z nich hroty
  for (i=1;i<=POCET_PRVKU;i++)
    for (j=1;j<=ROTACE;j++)
      for (k=1;k<=MAX_X;k++)
        for (l=1;l<=MAX_Y;l++)
        {
          prvek = g_prvky[i][j];
          // dal to bude pokracovat pouze pokud to neni uplne prazdny policko
          if (prvek.pole[k][l] != 0)
          {
            // ted to rozdelime podle toho zda ma trojuhelnicek zakladnu dole
            if ((k + l) % 2 == 0)
            {
              // ted to rozdelime do jednotlivych kategorii
              switch (prvek.pole[k][l])
              {
  						  case 5 :
                  if (prvek.pole[k+1][l] == 0) pridej_hrot(7,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l-1] == 70) pridej_hrot(24,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l-1] == 0) || (prvek.pole[k-1][l-1] == 5))&& (prvek.pole[k][l-1] == 100)) pridej_hrot(4,prvek.cis,prvek.rot,k,l);
									break;
                case 15 :
                  if (prvek.pole[k][l+1] == 0) pridej_hrot(9,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k+1][l] == 90) pridej_hrot(20,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l-1] == 0) || (prvek.pole[k+1][l-1] == 15)) && (prvek.pole[k+1][l] == 100)) pridej_hrot(6,prvek.cis,prvek.rot,k,l);
									break;
                case 25 :
                  if (prvek.pole[k][l-1] == 0) pridej_hrot(11,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l+1] == 80) pridej_hrot(22,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l+2] == 0) || (prvek.pole[k][l+2] == 25)) && (prvek.pole[k][l+1] == 100)) pridej_hrot(2,prvek.cis,prvek.rot,k,l);
									break;
                case 75 :
                  if (prvek.pole[k][l-1] == 0) pridej_hrot(35,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l+1] == 0) || (prvek.pole[k+1][l+1] == 75))&& (prvek.pole[k+1][l] == 100)) pridej_hrot(14,prvek.cis,prvek.rot,k,l);
									break;
                case 85 :
                  if (prvek.pole[k][l+1] == 0) pridej_hrot(33,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l-2] == 0) || (prvek.pole[k][l-2] == 85))&& (prvek.pole[k][l-1] == 100)) pridej_hrot(18,prvek.cis,prvek.rot,k,l);
									break;
                case 95 :
                  if (prvek.pole[k+1][l] == 0) pridej_hrot(31,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l+1] == 0) || (prvek.pole[k-1][l+1] == 95))&&(prvek.pole[k][l+1] == 100)) pridej_hrot(16,prvek.cis,prvek.rot,k,l);
									break;
                case 100 :
                  if  (((prvek.pole[k] [l-1] == 0) || (prvek.pole[k]  [l-1] == 10))
                    &&((prvek.pole[k]  [l+1] == 0) || (prvek.pole[k]  [l+1] == 70))) pridej_hrot(29,prvek.cis,prvek.rot,k,l);
                  if  (((prvek.pole[k+1][l]  == 0) || (prvek.pole[k+1][l]   == 20))
                    &&((prvek.pole[k]  [l-1] == 0) || (prvek.pole[k]  [l-1] == 90))) pridej_hrot(25,prvek.cis,prvek.rot,k,l);
                  if  (((prvek.pole[k] [l+1] == 0) || (prvek.pole[k]  [l+1] == 30))
                    &&((prvek.pole[k+1][l]   == 0) || (prvek.pole[k+1][l]   == 80))) pridej_hrot(27,prvek.cis,prvek.rot,k,l);
									break;
              }
            }
            else
              // nebo nahore
            {
              // ted to rozdelime do jednotlivych kategorii
              switch (prvek.pole[k][l])
              {
  						  case 10 :
                  if (prvek.pole[k][l+1] == 0) pridej_hrot(8,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l-1] == 95) pridej_hrot(19,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l-2] == 0) || (prvek.pole[k][l-2] == 10))&& (prvek.pole[k][l-1] == 100)) pridej_hrot(5,prvek.cis,prvek.rot,k,l);
									break;
                case 20 :
                  if (prvek.pole[k-1][l] == 0) pridej_hrot(10,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l+1] == 85) pridej_hrot(21,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l+1] == 0) || (prvek.pole[k+1][l+1] == 20)) && (prvek.pole[k][l+1] == 100)) pridej_hrot(1,prvek.cis,prvek.rot,k,l);
									break;
                case 30 :
                  if (prvek.pole[k][l-1] == 0) pridej_hrot(12,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k-1][l] == 75) pridej_hrot(23,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l+1] == 0) || (prvek.pole[k-1][l+1] == 30)) && (prvek.pole[k-1][l] == 100)) pridej_hrot(3,prvek.cis,prvek.rot,k,l);
									break;
                case 70 :
                  if (prvek.pole[k][l-1] == 0) pridej_hrot(36,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l+2] == 0) || (prvek.pole[k][l+2] == 70))&& (prvek.pole[k][l+1] == 100)) pridej_hrot(15,prvek.cis,prvek.rot,k,l);
									break;
                case 80 :
                  if (prvek.pole[k-1][l] == 0) pridej_hrot(34,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l-1] == 0) || (prvek.pole[k+1][l-1] == 80))&& (prvek.pole[k][l-1] == 100)) pridej_hrot(13,prvek.cis,prvek.rot,k,l);
									break;
                case 90 :
                  if (prvek.pole[k][l+1] == 0) pridej_hrot(32,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l-1] == 0) || (prvek.pole[k-1][l-1] == 90))&&(prvek.pole[k-1][l] == 100)) pridej_hrot(17,prvek.cis,prvek.rot,k,l);
									break;
                case 100 :
                  if  (((prvek.pole[k]  [l-1] == 0) || (prvek.pole[k]  [l-1] == 85))
                     &&((prvek.pole[k]  [l+1] == 0) || (prvek.pole[k]  [l+1] == 25))) pridej_hrot(26,prvek.cis,prvek.rot,k,l);
                  if  (((prvek.pole[k-1][l]   == 0) || (prvek.pole[k-1][l]   == 95))
                     &&((prvek.pole[k]  [l-1] == 0) || (prvek.pole[k]  [l-1] == 15))) pridej_hrot(30,prvek.cis,prvek.rot,k,l);
                  if  (((prvek.pole[k]  [l+1] == 0) || (prvek.pole[k]  [l+1] == 75))
                     &&((prvek.pole[k-1][l]   == 0) || (prvek.pole[k-1][l]   == 5))) pridej_hrot(28,prvek.cis,prvek.rot,k,l);
									break;
              }
            }
          }
        }
}

void __fastcall TForm1::pridej_diru(int typ, int cis, int rot, int x,int y)  //funkci pro pridani diry do prvku
{
  int i;
  i = 1;
  for (i=1;g_prvky[cis][rot].diry[i].typ >= 0;i++)
    if (g_prvky[cis][rot].diry[i].typ == 0)
    {
      g_prvky[cis][rot].diry[i].typ = typ;
      g_prvky[cis][rot].diry[i].x   = x;
      g_prvky[cis][rot].diry[i].y   = y;
      break;
    }
}

void __fastcall TForm1::nacti_diry(void)  // nacte diry pro kazdy prvek
{
  int i,j;
  int k,l;
  tPrvek prvek;
//  tDira dira;
  //a ted budeme brat prvky po jednom a kuchat z nich diry
  for (i=1;i<=POCET_PRVKU;i++)
    for (j=1;j<=ROTACE;j++)
    {
      // nejdrive na prvku vynulejeme vsecky diry
      for (k=1;k<=4;k++)
      {
        g_prvky[i][j].diry[k].cis = i;
        g_prvky[i][j].diry[k].typ = 0;
        g_prvky[i][j].diry[k].x = 0;
        g_prvky[i][j].diry[k].y = 0;
        g_prvky[i][j].diry[k].zalepeno = FALSE;
        g_prvky[i][j].diry[k].cislo = 0;
      }
      prvek = g_prvky[i][j];
      for (k=1;k<=MAX_X;k++)
        for (l=1;l<=MAX_Y;l++)
        {
          // dal to bude pokracovat, pouze pokud to neni uplne zaplnene policko
          if (prvek.pole[k][l] != 100)
          {
            // ted to rozdelime podle toho zda ma trojuhelnicek zakladnu dole
            if ((k + l) % 2 == 0)
            {
              // ted to rozdelime do jednotlivych kategorii
              switch (100 - prvek.pole[k][l])
              {
  						  case 5 :
                  if (prvek.pole[k+1][l] == 100) pridej_diru(7,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l-1] == 30) pridej_diru(24,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l-1] == 100) || (prvek.pole[k-1][l-1] == 95))&& (prvek.pole[k][l-1] == 0)) pridej_diru(4,prvek.cis,prvek.rot,k,l);
									break;
                case 15 :
                  if (prvek.pole[k][l+1] == 100) pridej_diru(9,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k+1][l] == 10) pridej_diru(20,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l-1] == 100) || (prvek.pole[k+1][l-1] == 85)) && (prvek.pole[k+1][l] == 0)) pridej_diru(6,prvek.cis,prvek.rot,k,l);
									break;
                case 25 :
                  if (prvek.pole[k][l-1] == 100) pridej_diru(11,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l+1] == 20) pridej_diru(22,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l+2] == 100) || (prvek.pole[k][l+2] == 75)) && (prvek.pole[k][l+1] == 0)) pridej_diru(2,prvek.cis,prvek.rot,k,l);
									break;
                case 75 :
                  if (prvek.pole[k][l-1] == 100) pridej_diru(35,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l+1] == 100) || (prvek.pole[k+1][l+1] == 25))&& (prvek.pole[k+1][l] == 0)) pridej_diru(14,prvek.cis,prvek.rot,k,l);
									break;
                case 85 :
                  if (prvek.pole[k][l+1] == 100) pridej_diru(33,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l-2] == 100) || (prvek.pole[k][l-2] == 15))&& (prvek.pole[k][l-1] == 0)) pridej_diru(18,prvek.cis,prvek.rot,k,l);
									break;
                case 95 :
                  if (prvek.pole[k+1][l] == 100) pridej_diru(31,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l+1] == 100) || (prvek.pole[k-1][l+1] == 5))&&(prvek.pole[k][l+1] == 0)) pridej_diru(16,prvek.cis,prvek.rot,k,l);
									break;
                case 100 :
                  if (((prvek.pole[k]  [l-1] == 100) || (prvek.pole[k]  [l-1] == 90))
                    &&((prvek.pole[k]  [l+1] == 100) || (prvek.pole[k]  [l+1] == 30))) pridej_diru(29,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l]   == 100) || (prvek.pole[k+1][l]   == 80))
                    &&((prvek.pole[k]  [l-1] == 100) || (prvek.pole[k]  [l-1] == 10))) pridej_diru(25,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k]  [l+1] == 100) || (prvek.pole[k]  [l+1] == 70))
                    &&((prvek.pole[k+1][l]   == 100) || (prvek.pole[k+1][l]   == 20))) pridej_diru(27,prvek.cis,prvek.rot,k,l);
									break;
              }
            }
            else
              // nebo nahore
            {
              // ted to rozdelime do jednotlivych kategorii
              switch (100 - prvek.pole[k][l])
              {
  						  case 10 :
                  if (prvek.pole[k][l+1] == 100) pridej_diru(8,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l-1] == 5) pridej_diru(19,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l-2] == 100) || (prvek.pole[k][l-2] == 90))&& (prvek.pole[k][l-1] == 0)) pridej_diru(5,prvek.cis,prvek.rot,k,l);
									break;
                case 20 :
                  if (prvek.pole[k-1][l] == 100) pridej_diru(10,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k][l+1] == 15) pridej_diru(21,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l+1] == 100) || (prvek.pole[k+1][l+1] == 80)) && (prvek.pole[k][l+1] == 0)) pridej_diru(1,prvek.cis,prvek.rot,k,l);
									break;
                case 30 :
                  if (prvek.pole[k][l-1] == 100) pridej_diru(12,prvek.cis,prvek.rot,k,l);
                  if (prvek.pole[k-1][l] == 25) pridej_diru(23,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l+1] == 100) || (prvek.pole[k-1][l+1] == 70)) && (prvek.pole[k-1][l] == 0)) pridej_diru(3,prvek.cis,prvek.rot,k,l);
									break;
                case 70 :
                  if (prvek.pole[k][l-1] == 100) pridej_diru(36,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k][l+2] == 100) || (prvek.pole[k][l+2] == 30))&& (prvek.pole[k][l+1] == 0)) pridej_diru(15,prvek.cis,prvek.rot,k,l);
									break;
                case 80 :
                  if (prvek.pole[k-1][l] == 100) pridej_diru(34,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k+1][l-1] == 100) || (prvek.pole[k+1][l-1] == 20))&& (prvek.pole[k][l-1] == 0)) pridej_diru(13,prvek.cis,prvek.rot,k,l);
									break;
                case 90 :
                  if (prvek.pole[k][l+1] == 100) pridej_diru(32,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l-1] == 100) || (prvek.pole[k-1][l-1] == 10))&&(prvek.pole[k-1][l] == 0)) pridej_diru(17,prvek.cis,prvek.rot,k,l);
									break;
                case 100 :
                  if (((prvek.pole[k]  [l-1] == 100) || (prvek.pole[k]  [l-1] == 15))
                    &&((prvek.pole[k]  [l+1] == 100) || (prvek.pole[k]  [l+1] == 75))) pridej_diru(26,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k-1][l]   == 100) || (prvek.pole[k-1][l]   == 5 ))
                    &&((prvek.pole[k]  [l-1] == 100) || (prvek.pole[k]  [l-1] == 85))) pridej_diru(30,prvek.cis,prvek.rot,k,l);
                  if (((prvek.pole[k]  [l+1] == 100) || (prvek.pole[k]  [l+1] == 25))
                    &&((prvek.pole[k-1][l]   == 100) || (prvek.pole[k-1][l]   == 95))) pridej_diru(28,prvek.cis,prvek.rot,k,l);
									break;
              }
            }
          }
        }
    }
}

int __fastcall TForm1::nacti_prvky(void) // tato funkce na zacatku vypoctu nacte vsechny p.
{
	FILE	*zdroj;
	int	x,y;
	int	i,j, p,r;
	int	typ;
	int konec;
	int pom_x,pom_y;
	int mop_y;
  tPrvek prvek;
	tPrvek prvek_pom;

	for (i=0 ; i<= POCET_PRVKU ; i++)
		for (j=0 ; j<= ROTACE ; j++)
			for (x=0 ; x<= MAX_X ; x++)
				for (y=0 ; y<=MAX_Y ; y++)
					g_prvky[i][j].pole[x][y]=0;
	if ((zdroj = fopen(ZDROJ, "rt")) == NULL)
	{
		fprintf(stderr, "Nemohu otevrit zdrojovy soubor: '%s'\n",ZDROJ);
		return -1;
	}
	while (!feof(zdroj))
	{
		fscanf(zdroj,"%d%d%d%d",&i,&x,&y,&typ);
		g_prvky[i][1].pole[x][y]=typ;
		g_prvky[i][1].cis=i;
	}
	// tady se zacinaji naplnovat jednotlive prvky s umistenim prvniho bodu atd
	// provedem pro vsechny prvky a vsechny rotace
	for (p=1 ; p<= POCET_PRVKU ; p++)
  {
		for (r=ROTACE ; r>=1  ; r--)
    {
			//nejdrive vymazeme prvek  g_prvky[101][1]
			for ( i=0 ; i<=8 ; i++ )
				for ( j=0 ; j<=10 ; j++ )
					prvek.pole[i][j] = 0;
			prvek.cis = p;
			prvek.rot = r;
			prvek.x = 0;
			prvek.y = 0;
			// aby se to nepomichalo nejdrive vytvorime prvek_pom
      prvek_pom = prvek;
			// pak vytvorime rotaci
			prvek = napln_prvek(p,r);
			// ted posuneme prvek tak aby se nikde nedotykal okraju a zaroven prvni dilek byl na
			// druhem (nebop v nouzovem pripade na tretim)radku
			// zjistime prvni radek
			// Najdem prvni nenulovy radek
			konec = FALSE;
			for (i=1 ; i<=6 && !konec ; i++)
			{
				for (j=1 ; j<=10 && !konec ; j++)
					if (prvek.pole[i][j] )
					{
						pom_x = i;
						konec = TRUE;
					}
			}
			// pak prvni nenulovy sloupec
			konec = FALSE;
			for ( j=1 ; j<=10 && !konec  ; j++ )
				for ( i=1 ; i<=6 ; i++)
					if ( prvek.pole[i][j] )
					{
						pom_y = j;
						konec = TRUE;
					}
			// najdem posledni nenulovy sloupec
			konec = FALSE;
			for ( j=10 ; j>=1 && !konec ; j-- )
				for ( i=6 ; i>=1 ; i-- )
					if (prvek.pole[i][j])
					{
						mop_y = j;
						konec = TRUE;
					}
			// postupne prepisovat hodnoty
			// ted rozhodneme kam budeme posunovat
			if ((pom_x + pom_y)%2 == 1)
      {
				//postupne vlozime vsechny prvky
				for ( i=1 ; i<=6 ; i++ )
					for ( j=1 ; j<=10 ; j++)
						if ( prvek.pole[i][j] ) prvek_pom.pole[2+i-pom_x][3+j-pom_y] = prvek.pole[i][j];
      }
			else
      {
				//postupne vlozime vsechny prvky
				if ( mop_y-pom_y < 5 )
        {
					for ( i=1 ; i<=6 ; i++)
						for ( j=1 ; j<=10 ; j++)
							if (prvek.pole[i][j]) prvek_pom.pole[2+i-pom_x][4+j-pom_y] = prvek.pole[i][j];
        }
				else
        {
					for (i=1 ; i<=6 ; i++)
						for ( j=1 ; j<=10 ; j++)
							if ( prvek.pole[i][j] ) prvek_pom.pole[3+i-pom_x][3+j-pom_y] = prvek.pole[i][j];
        }
      }
			// Nakonec najdem prvni nenulovy element
			konec = FALSE;
			for ( i=1 ; i<=8  && !konec; i++ )
				for ( j=1 ; j<=10  && !konec; j++ )
					if ( prvek_pom.pole[i][j] )
					{
						prvek_pom.x     = i;
						prvek_pom.y     = j;
						konec = TRUE;
						break;
					}
			// a nakonec ulozime vysledek
			g_prvky[p][r] = prvek_pom;
    }
  }
  // a tady to konci
	fclose(zdroj);
	return 0;
}

int __fastcall TForm1::ulozit(char res[])  // Tato funkce ulozi vysledek do souboru
{
	int	i;//,j;
  int posun_x,posun_y;        //hodnoty posunu celeho obrazce
  //  int konec;
	FILE 	*out;

  if (res==NULL || res[0]==0)
  {
    strcpy(res,CIL);
  }
	if ((out = fopen(res, "wt")) == NULL)
	{
		fprintf(stderr, "Nemohu zapsat vysledny soubor: '%s'\n",CIL);
		return -1;
	}
  // toto by teoreticky melo byt netandartni ulozeni bez definovanych okraju
/*  // najdeme prvni nenulovy prvek v ose x a v ose y
  konec = FALSE;
  for (i=1;i<=MAX_MX;i++)
  {
    for (j=1;j<=MAX_MY;j++)
    {
      if (g_matice[i][j] != 0)
      {
        posun_x = (i/2)*2 - 3;
        konec = TRUE;
        break;
      }
    }
    if (konec) break;
  }
  konec = FALSE;
  for (j=1;j<=MAX_MY;j++)
  {
    for (i=1;i<=MAX_MX;i++)
    {
      if (g_matice[i][j] != 0)
      {
        posun_y = (j/2)*2;
        konec = TRUE;
        break;
      }
    }
    if (konec) break;
  }*/
  // toto je pouze pro ladeni
  posun_x = 0;
  posun_y = 0;
	for ( i=1 ; i<=g_stupen ; i++)
		fprintf(out,"%i %i %i %i\n",g_reseni[i].cis,g_reseni[i].x - posun_x,g_reseni[i].y - posun_y,g_reseni[i].rot);
	fclose(out);
	return 0;
}

int __fastcall TForm1::hledej(void)  // Tato funkce spusti samotne hledani
{
	int 	i,j;
	int		konec, muzes;
  char  s_pocet_kroku[20];
  char  s_pom[20];
	tPrvek	prvek;
  // zde nastavime pocatecni parametry
  // ted naplnime oblast kterou budeme plnit
  pouzivat_omez_pole = CheckBox1->Checked;
  zacatek_x = atoi(Edit4->Text.c_str());
  zacatek_y = atoi(Edit5->Text.c_str());
  konec_x = atoi(Edit2->Text.c_str());
  konec_y = atoi(Edit3->Text.c_str());
  dis_zac_x = atoi(Edit8->Text.c_str());
  dis_zac_y = atoi(Edit9->Text.c_str());
  dis_kon_x = atoi(Edit6->Text.c_str());
  dis_kon_y = atoi(Edit7->Text.c_str());
  poz_prv_dil_x = atoi(Edit10->Text.c_str());
  poz_prv_dil_y = atoi(Edit11->Text.c_str());
  // nastavime nejvyssi dosazeny stupen
  g_nej_stupen = 10000;
  // nastavime do pocet_kroku
  g_pocet_kroku = 0;
  // pokud zaciname od zacatku nebo pokud zaciname z nacteneho reseni
  if (g_reseni[1].cis == 0) g_prvni_prvek = 0;
  else g_prvni_prvek = g_reseni[1].cis;
	g_cislo_posledniho_prvku = 1;
  // oznamime zacatek hledani
  Label3->Caption = "Uz to zacalo !!!!";
  // a zacneme hledat
	while(g_stupen!=POCET_PRVKU && g_program_bezi)//&& g_pocet_kroku!=689 )
	{
    // ted zjistime zda plnime cely obrazec nebo jenom cast a zda je jiz tato cast plna
    if (pouzivat_omez_pole && plocha_naplnena(zacatek_x + dis_zac_x, zacatek_y + dis_zac_y, konec_x - dis_kon_x,konec_y - dis_kon_y))
    // pokud je to hotovy cely pole tak to vymazeme a zacneme znovu u jinyho prvku
    {
      // ulozim toto reseni
      itoa(g_pocet_kroku,s_pom,10);
      strcpy(s_pocet_kroku,"var_");
      strcat(s_pocet_kroku,s_pom);
      strcat(s_pocet_kroku,".txt");
      ulozit(s_pocet_kroku);
      // vymaz matici
      napln_matici();
      // vymaz reseni
    	for ( i=0 ; i <= POCET_PRVKU ; i++ )
    		g_reseni[i] = g_nula_d;
    	g_stupen = 0;
      // vynulujeme g_volny
      for ( i=0 ; i <= POCET_VOLNY ; i++)
        g_volny[i] = g_nula_volny;
      g_stupen_volny = 0;
      // vynulujeme ulozeno
    	for (i=0 ; i<=POCET_PRVKU ; i++)
    		g_ulozeno[i] = FALSE;
    }
    // pokud ukladame prvni prvek jdeme na to trochu jinak
    if (g_reseni[1].cis == 0)
    {
      // nejdrive vybereme cislo prvniho prvku tak aby mel alespon jednu diru
      // a pasoval na toto misto
      do {
        g_prvni_prvek++;
        // ukoncime celou srandu pokud jsme na konci
        if (g_prvni_prvek == 210) goto doprdele;
        // ted kontrolujeme, zda sedi
        muzes = FALSE;
        // nastavime do g_nej kam chceme ukladat
        g_nej.x = poz_prv_dil_x;
        g_nej.y = poz_prv_dil_y;
        for (i=1;i<=ROTACE;i++)
        {
          // nacteme ho
          prvek = g_prvky[g_prvni_prvek][i];
          if (kontrola(prvek))
          {
            muzes = TRUE;
            break;
          }
        }
      } while (!(prvek.diry[1].typ != 0 && muzes));
      //pak tento prvek pridame do matice
    	for ( i=prvek.x ; i<=6 ; i++)
		    for ( j=1 ; j<=10 ; j++ )
    			g_matice[poz_prv_dil_x + i - prvek.x][poz_prv_dil_y + j - prvek.y] = g_matice[poz_prv_dil_x + i - prvek.x][poz_prv_dil_y + j - prvek.y] + prvek.pole[i][j];
    	//zapiseme do reseni
    	g_stupen++;
    	g_reseni[g_stupen].cis = prvek.cis;
    	g_reseni[g_stupen].x   = poz_prv_dil_x;
    	g_reseni[g_stupen].y   = poz_prv_dil_y;
    	g_reseni[g_stupen].rot = prvek.rot;
    	//zapiseme do ulozeno
    	g_ulozeno[prvek.cis] = TRUE;
    	// postupne projedeme vsechna volna mista a zapiseme je do g_volny
    	for (i=1;prvek.diry[i].typ > 0;i++)
  		{
        g_volny[1 + g_stupen_volny].typ = prvek.diry[i].typ;
        g_volny[1 + g_stupen_volny].cis = prvek.cis;
        g_volny[1 + g_stupen_volny].x = poz_prv_dil_x + prvek.diry[i].x - prvek.x;
        g_volny[1 + g_stupen_volny].y = poz_prv_dil_y + prvek.diry[i].y - prvek.y;
			  g_stupen_volny++;
  		}
    	// nastavime kde se bude zacinat
    	g_cislo_posledniho_prvku = 1;
    }
    // nejdrive vytvorime g_nej.typ z pole G_VOLNY
    for (i=1;i<=g_stupen_volny;i++)
      if (g_volny[i].zalepeno == FALSE)
      {
        g_nej.x = g_volny[i].x;
        g_nej.y = g_volny[i].y;
        g_nej.typ = g_volny[i].typ;
        break;
      };
    // a ted zacneme projizdet pole odpovidajicich hrotu
		for (i=g_cislo_posledniho_prvku;g_hroty[g_nej.typ][i].cis > 0; i++ )
		{
			if (!g_ulozeno[g_hroty[g_nej.typ][i].cis])
      {
				prvek = g_prvky[g_hroty[g_nej.typ][i].cis][g_hroty[g_nej.typ][i].rot];
        // ted jeste prekopeme g_nej
        for (j=1;j<=g_stupen_volny;j++)
          if (!(g_volny[j].zalepeno))
          {
            g_nej.x = g_volny[j].x + prvek.x - g_hroty[g_nej.typ][i].x;
            g_nej.y = g_volny[j].y + prvek.y - g_hroty[g_nej.typ][i].y;
            break;
          }
        // a spustime kontrolu
    		if (kontrola(prvek))
        {
					konec=TRUE;
					pridej_prvek(prvek);
					break;
				}
      }
			if (konec) break;
		}
		if (!konec) odeber_prvek();
    // ---------------Toto je Konupova kontrola poctu kroku---------------
		konec=FALSE;
		g_pocet_kroku++;
    // ted vypiseme pokud je cas na obrazovku kolik toho mame uz hotovyho
		if ( g_pocet_kroku % SKOK == 0 )
		{
  	Label3->Caption = g_pocet_kroku;
    Label5->Caption = g_stupen;
		}
    // zde zkontrolujeme zda jiz neni cas ulozit
    // nejdrive prevedeme pocet kroku do stringu
    itoa(g_pocet_kroku,s_pom,10);
    strcpy(s_pocet_kroku,"res_");
    strcat(s_pocet_kroku,s_pom);
    strcat(s_pocet_kroku,".txt");
  	if ( g_pocet_kroku % (SKOK_ULOZIT) == 0 )	ulozit(s_pocet_kroku);
    // ---------------Toto je konec Konupovi kontroly poctu kroku---------------
    // ted si zjistime jestli nekdo nezmacknul tlacitko konec */
    Application->ProcessMessages();
	}
  // sem to skoci kdyz to na prvni misto uz nema co ulozit
  doprdele:
  // jeste se to naposled ulozi
  ulozit("");
  // pro jistotu se prepise napis na tlacitku
//  Button1->Caption = "Pust se do toho";
  g_program_bezi = FALSE;
  // a vypise hlaska
	if (g_stupen == 209) Label3->Caption = "Tak a je to tam !!!";
	if (g_prvni_prvek == 210) Label3->Caption = "Tak a je to v prdeli !!!";
	return 0;
}

void __fastcall TForm1::nacti_reseni( char res[] ) // Tato funkce nacte stare reseni by
{                                       // se mohlo pokracovat
	int		i,j,k,l;
	int		x,y;
	int		rot;
	int		cis;
	tPrvek      prvek;
	FILE		*resfile;
  // nejdrive vymazu matici
 	napln_matici();
	// nejdriv to cele smazu
	for ( i=0 ; i <= POCET_PRVKU ; i++ )
		g_reseni[i] = g_nula_d;
	g_stupen = 0;
  // vynulujeme g_volny
  for ( i=0 ; i <= POCET_VOLNY ; i++)
    g_volny[i] = g_nula_volny;
  g_stupen_volny = 0;

	if ((resfile = fopen(res, "rt")) == NULL)
	{
		fprintf(stderr, "Predesle reseni nelze nacist ('%s')\n",res);
	}
	while (!feof(resfile))
	{
		g_stupen++;
		fscanf(resfile,"%d%d%d%d",&cis,&x,&y,&rot);
		g_reseni[g_stupen].cis = cis;
		g_reseni[g_stupen].x   = x;
		g_reseni[g_stupen].y   = y;
		g_reseni[g_stupen].rot = rot;
	}

	for ( k=1 ; k<=g_stupen ; k++)
	{
		prvek = g_prvky[g_reseni[k].cis][g_reseni[k].rot];
		// a prvek zapiseme do g_matice
		for ( i=prvek.x ; i<=6 ; i++)
			for ( j=1 ; j<=10 ; j++)
				if ( prvek.pole[i][j] )
				{
					g_matice[g_reseni[k].x + i - prvek.x][g_reseni[k].y + j - prvek.y] =  g_matice[g_reseni[k].x + i - prvek.x][g_reseni[k].y + j - prvek.y] + prvek.pole[i][j];
					// a jeste zkontrolujeme zda prvek nevyplnuje i jinou diru z g_volny
					for (l=1;g_volny[l].typ;l++)
						if ((g_reseni[k].x + i - prvek.x == g_volny[l].x) && (g_reseni[k].y + j - prvek.y == g_volny[l].y))
				    {
              g_volny[l].zalepeno = TRUE;
              g_volny[l].cislo = prvek.cis;
            }
				}
		for (i=1;prvek.diry[i].typ > 0;i++)
			// postupne projedeme vsechna volna mista a zapiseme je do g_volny
  		// nejdrive zkontrolujeme zda dira na prvku neni zalepena vlozenim
  		if (g_matice[g_reseni[k].x + prvek.diry[i].x - prvek.x][g_reseni[k].y + prvek.diry[i].y - prvek.y] !=100  )
  		{
        g_volny[1 + g_stupen_volny].typ = prvek.diry[i].typ;
        g_volny[1 + g_stupen_volny].cis = prvek.cis;
        g_volny[1 + g_stupen_volny].x = g_reseni[k].x + prvek.diry[i].x - prvek.x;
        g_volny[1 + g_stupen_volny].y = g_reseni[k].y + prvek.diry[i].y - prvek.y;
  			g_stupen_volny++;
  		}
	}
  // zde naplnime matici ulozeno
	for (i=1 ; i<=g_stupen ; i++)
		g_ulozeno[g_reseni[i].cis] = TRUE;
	fclose(resfile);
}

void __fastcall TForm1::Button1Click(TObject *Sender) // Stik tlacitka
{
  if (g_program_bezi)
  {
    Button1->Caption = "Pust se do toho";
    g_program_bezi = FALSE;
  }
  else
  {
    Button1->Caption = "Zastav to";
    g_program_bezi = TRUE;
  	if (Edit1->Text != "") nacti_reseni(Edit1->Text.c_str());
  	hledej();

  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  int i;
  clrscr();
	napln_matici();
	nacti_prvky();
  nacti_hroty();
  nacti_diry();
  /*  // zde pouze pro odladeni zjistime pocty jednotlivych hrotu g_prvky[15][1]
  int j, k;
	FILE 	*out;
  out = fopen("diry.txt", "wt");
  for (i=1;i<=209;i++)
    for (j=1;j<=6;j++)
      for (k=1;k<=4;k++)
        if (g_prvky[i][j].diry[k].typ != 0)
      		fprintf(out,"%i %i %i %i %i %i\n", i, j, g_prvky[i][j].diry[k].typ, g_prvky[i][j].diry[k].x, g_prvky[i][j].diry[k].y, k);
	fclose(out);
  // zde konci ladeni*/
  // nastavime hodnotu behu programu
  g_program_bezi = FALSE;
  // zde vynulejeme pole G_ULOZENO
	for (i=0 ; i<=POCET_PRVKU ; i++)
		g_ulozeno[i] = FALSE;
  // zde vynulujeme pocet ulozenych pvku
  g_stupen = 0;
  // zde vynulujeme pocet dalsich der
  g_stupen_volny = 0;
  // zde vynulujeme nulovy prvek pro G_RESENI
	g_nula_d.cis=0;
	g_nula_d.x=0;
	g_nula_d.y=0;
	g_nula_d.rot=0;
  // zde vynulujeme nulovy prvek pro G_VOLNY
  g_nula_volny.cis = 0;
  g_nula_volny.typ = 0;
  g_nula_volny.x = 0;
  g_nula_volny.y = 0;
  g_nula_volny.zalepeno = 0;
  g_nula_volny.cislo = 0;
  // vynulujeme g_reseni
  for (i=1;i<=POCET_PRVKU;i++)
    g_reseni[i] = g_nula_d;
  // vynulujeme g_volny
  for (i=0;i<=POCET_VOLNY;i++)
    g_volny[i] = g_nula_volny;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::zapis_matici(void)  // Tato funkce ulozi matici do souboru
{
  int i,j;
  FILE *out;
  // pro odladeni vypiseme obsah g_matice
  out = fopen("matice.txt", "wt");
  for (i=0;i<=MAX_MX+1;i++)
    for (j=0;j<=MAX_MY+1;j++)
      if (j==MAX_MY+1)
      {
        if (g_matice[i][j]/10 == 0) fprintf(out,"   %i\n",g_matice[i][j]);
        else
        {
          if (g_matice[i][j]/100 == 0) fprintf(out,"  %i\n",g_matice[i][j]);
          else fprintf(out," %i\n",g_matice[i][j]);
        }
      }
      else
      {
        if (g_matice[i][j]/10 == 0) fprintf(out,"   %i",g_matice[i][j]);
        else
        {
          if (g_matice[i][j]/100 == 0) fprintf(out,"  %i",g_matice[i][j]);
          else fprintf(out," %i",g_matice[i][j]);
        }
      }
  fclose(out);
  // konec odladeni
}

void __fastcall TForm1::zapis_volny(void)  // Tato funkce ulozi matici do souboru
{
  int i;
  FILE *out;
  // pro odladeni vypiseme obsah g_matice
  out = fopen("volny.txt", "wt");
  for (i=0;i<=POCET_VOLNY+1;i++)
  {
    if (g_volny[i].cis/10 == 0) fprintf(out,"   %i",g_volny[i].cis);
    else
    {
      if (g_volny[i].cis/100 == 0) fprintf(out,"  %i",g_volny[i].cis);
      else  fprintf(out," %i",g_volny[i].cis);
    }
    if (g_volny[i].typ/10 == 0) fprintf(out,"  %i",g_volny[i].typ);
    else fprintf(out," %i",g_volny[i].typ);
    if (g_volny[i].x/10 == 0) fprintf(out,"  %i",g_volny[i].x);
    else fprintf(out," %i",g_volny[i].x);
    if (g_volny[i].y/10 == 0) fprintf(out,"  %i",g_volny[i].y);
    else fprintf(out," %i",g_volny[i].y);
    if (g_volny[i].zalepeno/10 == 0) fprintf(out,"  %i",g_volny[i].zalepeno);
    else fprintf(out," %i",g_volny[i].zalepeno);
    if (g_volny[i].cislo/10 == 0) fprintf(out,"   %i\n",g_volny[i].cislo);
    else
    {
      if (g_volny[i].cislo/100 == 0) fprintf(out,"  %i\n",g_volny[i].cislo);
      else  fprintf(out," %i\n",g_volny[i].cislo);
    }
  }
  fclose(out);
}

int __fastcall TForm1::plocha_naplnena(int a,int b,int x,int y)  // Tato funkce zjisti zda jsme naplnily zadanou oblast
{
  int i,j;
  int stupen;
  stupen = 0;
  for (i=1;i<=x-a;i++)
    for (j=1;j<=y-b;j++)
      if (g_matice[i + a][j + b]!= 100) stupen++;
  if (stupen == 0) return TRUE;
  else
  {
  //ted se podivame jestli neni nase reseni nejlepsi
    if (g_nej_stupen>stupen)
    {
      ulozit("big.txt");
      g_nej_stupen = stupen;
    }
    return FALSE;
  }
}


