Česky
Kamil Dudka

Tiny programs (C, C++, C#, ...)

File detail

Name:Downloadproj3.c [Download]
Location: tiny > IZP > proj3
Size:18.2 KB
Last modification:2009-12-21 17:54

Source code

/*
 * Soubor:  proj3.c
 * Datum:   8.12.2004
 * Autor:   Kamil Dudka, xdudka00@stud.fit.vutbr.cz
 * Projekt: IZP c. 3 - Maticove oprace
 * Popis:   viz. Dokumentace
 *
 * Prosím, neodevzdávejte zdrojové kódy, které jsou zde k dispozici,
 * jako Vaše školní projekty. Děkuji :-)
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
	// Umoznovane oprace s maticemi - poradi je dulezite
typedef enum
{
	MOPER_NULL,
	MOPER_ADD,
	MOPER_MULT,
	MOPER_MONO,
	MOPER_SPIRAL,
	MOPER_DB,
	MOPER_WORM
} TypOperace;
 
	// Charakterizuje monotonost
typedef enum
{
	MONO_KLESA = -1,
	MONO_NULL,
	MONO_ROSTE
} TypMono, *PTypMono;
 
	// Struktura charakterizujici matici
typedef struct
{
	unsigned int rows, cols;	// Rozmery matice
	int *matrix;			// Ukazatel na prvni prvek matice
} TMatrix, *PTMatrix;
 
	// Vypise se na stdout pokud operace nema legalni vysledek
const char MatrixIllegal[] = "#\n";
 
	// Vypise se na stdout, je-li matice monotoni
const char MatrixMono[] = "1\n";
 
	// Funkce jsou popsany nize (a take v dokumentaci)
int ctiMatici (PTMatrix, const char *);
int tiskniMatici (const PTMatrix);
int prictiMatici (const PTMatrix, const PTMatrix);
int nasobMatice (PTMatrix, const PTMatrix, const PTMatrix);
int monoMatice (const PTMatrix);
inline int monoCheck (PTypMono, const int *, const int *);
int vypisSpiralu (const PTMatrix);
int vypisTerc (const PTMatrix);
int wormTrans (const PTMatrix);
void wormTransOne (const PTMatrix, int);
 
// Vyctovy typ errNum - konstanty predstavuji cislo chyby
typedef enum errN
{
	ERR_NULL,
	ERR_NOARG,
	ERR_BADARG1,
	ERR_MISSARG,
	ERR_MATRIX1,
	ERR_MATRIX2
} errNum;
 
// Vlastni chybove hlasky
const char *err_msg[] =
{
	"",
	"Nebyly zadany parametry. Pro vypis napovedy zadejte parametr -h\n",
	"Neznama operace\n",
	"Nebyl zadan povinny parametr\n",
	"Nelze nacist matici 1\n",
	"Nelze nacist matici 2\n"
};
 
// Vypise chybovou hlasku na stderr
inline void printError (errNum n)
{
	fprintf (stderr,err_msg[n]);
}
 
// Vypise help na standartni vystup
inline void printHelp()
{
	printf (
		"Program Maticove operace\n"
		"Autor: Kamil Dudka\n"
		"Tento program provadi ruzne operace s maticemi. Podrobny popis techto opreaci je\n"
		"uveden v prilozene dokumentaci ve formatu pdf.\n"
		"Pouziti: proj3 -h\n"
		"         proj3 -add|-mult M1 M2\n"
		"         proj3 -mono|-spiral|-dartboard|-worm M1\n"
		"Popis parametru:\n"
		"  -h           Vypise tuto obrazovku s napovedou.\n"
		"  -add         Secte matice M1 a M2 a vysledek vypise na stdout.\n"
		"  -mult        Vynasobi matice M1 a M2 a vysledek vypise na stdout.\n"
		"  -mono        Pokud je matice M1 monotoni, vypise 1, jinak vypise #.\n"
		"  -spiral      Vypise prvky matice M1 ve tvaru spiraly.\n"
		"  -dartboard   Spocita aritmeticky prumer prvku na kruznicich terce matice M1\n"
		"  -worm        Provede transformaci typu \"zizala\" matice M1 a vypise na stdout.\n"
		"  M1           Jmeno souboru pro nacteni matice 1\n"
		"  M2           Jmeno souboru pro nacteni matice 2\n"
		);
}
 
	// Hlavni program
int main (int argc, char *argv[])
{
		// Provadena operace zadana prvnim parametrem programu
		// (vyctovy typ)
	TypOperace operace;
 
		// Defnice struktur typu matice
		// Pametovy prostor pro vlastni prvky matic
		// se zatim nealokuje !!!
	TMatrix m1, m2, m3;
 
		// Inicializace ukazatelu zabrani
		// volani free() na konci programu
		// pro matice, ktere nebyly alokovany
	m1.matrix = NULL;
	m2.matrix = NULL;
	m3.matrix = NULL;
 
	if (argc<2)
	{	// Program spusten bez parametru
		printError(ERR_NOARG);
		return EXIT_FAILURE;
	}
 
	if (strcmp(argv[1], "-h")==0)
	{	// Vypis napovedy
		printHelp();
		return EXIT_SUCCESS;
	}
 
	// Rozpoznani typu operace z prvniho parametru
	if (strcmp(argv[1], "-add")==0) operace=MOPER_ADD;
	else if (strcmp(argv[1], "-mult")==0) operace=MOPER_MULT;
	else if (strcmp(argv[1], "-mono")==0) operace=MOPER_MONO;
	else if (strcmp(argv[1], "-spiral")==0) operace=MOPER_SPIRAL;
	else if (strcmp(argv[1], "-dartboard")==0) operace=MOPER_DB;
	else if (strcmp(argv[1], "-worm")==0) operace=MOPER_WORM;
	else
	{	// Parametr 1 nerozpoznan
		printError(ERR_BADARG1);
		return EXIT_FAILURE;
	}
 
	// Kontrola zadani nazvu matic (pritomnost 2. a 3. parametru)
	if ((argc<3)||((operace<=MOPER_MULT)&&(argc<4)))
	{
		printError(ERR_MISSARG);
		return EXIT_FAILURE;
	}
 
	// Nacteni prvni matice ze souboru
	if (EXIT_SUCCESS!=ctiMatici(&m1,argv[2]))
	{	// Chyba pri nacitani 1. matice
		printError(ERR_MATRIX1);
		return EXIT_FAILURE;
	}
 
	if (operace<=MOPER_MULT)
		// Nacteni druhe matice ze souboru
		if (EXIT_SUCCESS!=ctiMatici(&m2,argv[3]))
		{	// Chyba pri nacitani 2. matice
			printError(ERR_MATRIX2);
			free(m1.matrix);
			return EXIT_FAILURE;
		}
 
	// Provede se pozadovana operace volanim prislusne funkce
	switch (operace)
	{
		case MOPER_ADD:
			if (EXIT_SUCCESS==prictiMatici (&m1, &m2))
				tiskniMatici(&m1);
			else
				printf(MatrixIllegal);
			break;
 
		case MOPER_MULT:
			if (EXIT_SUCCESS==nasobMatice (&m3, &m1, &m2))
				tiskniMatici(&m3);
			else
				printf(MatrixIllegal);
			break;
 
		case MOPER_MONO:
			if (monoMatice(&m1))
				printf(MatrixMono);
			else
				printf(MatrixIllegal);
			break;
 
		case MOPER_SPIRAL:
			vypisSpiralu (&m1);
			break;
 
		case MOPER_DB:
			vypisTerc (&m1);
			break;
 
		case MOPER_WORM:
			wormTrans (&m1);
			tiskniMatici (&m1);				
 
		default: break;
	}
 
	// Uvolneni pameti alokovane pro matice
	if (NULL!=m1.matrix)
		free (m1.matrix);
	if (NULL!=m2.matrix)
		free (m2.matrix);
	if (NULL!=m3.matrix)
		free (m3.matrix);
 
	// Pokud nedojde k zadne chybe, program skonci normalne
	return EXIT_SUCCESS;
}
 
	// Funkce nacte ze souboru rozmer matice
	// Dynamicky alokuje potrebny pametovy prostor
	// A naplni prvky matice hodnotami ze souboru
	// Pokud dojde k chybe neni alokovana zadna pamet !!!
int ctiMatici (PTMatrix matice, const char* fileName)
{
	FILE *mFile;				// Ukazatel na otevreny soubor
	unsigned long pocetPrvku;
	register unsigned long prvek;		// Promenna cyklu
	register int *pPrvek;	// Ukazatel na aktualne nacitany prvek matice
 
	// Otevreni souboru s matici (v rezimu pouze pro cteni)
	if (NULL==(mFile=fopen(fileName,"r")))
		return EXIT_FAILURE;
 
	// Nacteni rozmeru matice
	if (2!=fscanf (mFile,"%u%u",&matice->rows,&matice->cols))
	{
		fclose (mFile);
		return EXIT_FAILURE;
	}
 
	// Vypocet celkoveho poctu prvku matice
	if (0==(pocetPrvku=matice->rows*matice->cols))
	{
		fclose (mFile);
		return EXIT_FAILURE;
	}
 
	// Alokace prostoru pro vlastni matici
	if (NULL==(matice->matrix = malloc (pocetPrvku*sizeof(int)) ))
	{
		fclose (mFile);
		return EXIT_FAILURE;
	}
 
	// Vlastni cyklus nacitajici prvky matice
	// Soubor otvira jako textovy a vyuziva io funkci vyssi urovne
	// Nerozlisuje rozlozeni prvku na jednotlivych radcich
	for (prvek=0,pPrvek=matice->matrix; prvek<pocetPrvku; prvek++,pPrvek++)
			if (1!=fscanf (mFile,"%i",pPrvek) )
			{	// Chyba behem vstupu
				free (matice->matrix);
				fclose (mFile);
				return (EXIT_FAILURE);
			}
 
	// Pokud je vse v poradku zavru otevreny soubor a vratim EXIT_SUCCESS
	fclose (mFile);
	return EXIT_SUCCESS;
}
 
	// Tiskne prvky matice na stdout
int tiskniMatici (const PTMatrix matice)
{
		// Ze struktury nacte pocet prvku a ukazatel na prvni prvek
	const unsigned long pocetPrvku = matice->rows * matice->cols;
	register int *pPrvek = matice->matrix;
 
		// Kontrola vstupnich hodnot
	if ((NULL==pPrvek)||(0==pocetPrvku))
		return EXIT_FAILURE;
 
		// Vytiskne radek s rozmery matice na stdout
	printf ("%u %u\n",matice->rows,matice->cols);
 
		// Cyklus vypisuje prvky sekvencne
	for (register unsigned long prvek=0; prvek<pocetPrvku; prvek++,pPrvek++)
	{
		printf ("%i", *pPrvek);
 
			// Pokud byl vypsan posledni prvek na radku
			// odradkuje se; jinak se vytiskne mezera
		if ((prvek+1)%(matice->cols))
			printf (" ");
		else
			printf ("\n");
	}
 
	return EXIT_SUCCESS;
}
 
	// Ke kazdemu prvku z matice "dest"
	// pricte odpovidajici prvek z matice "src"
	// Matice musi mit stejny rozmer jinak vraci EXIT_FAILURE
int prictiMatici (const PTMatrix dest, const PTMatrix src)
{
	// Ze struktury nacte pocet prvku a ukazatele na prvni prvek
	const unsigned long pocetPrvku = dest->rows * dest->cols;
	int *pDest = dest-> matrix;
	int *pSrc = src-> matrix;
 
	// Kontrola vstupnich hodnot
	if ( 
			(0==pocetPrvku) ||
			(dest->rows!=src->rows) ||
			(dest->cols!=src->cols) )
		return EXIT_FAILURE;
 
	// Vlastni cyklus pricitajici matici src k matici dest
	for (unsigned long prvek=0; prvek<pocetPrvku; prvek++, pDest++, pSrc++)
		*pDest += *pSrc;
 
	return EXIT_SUCCESS;
}
 
	// Funkce nasobi matice "m1" a "m2" (v tomto poradi)
	// Automaticky si alokuje pametovy prostor pro vyslednou matici
	// a ulozi do nej vysledek
	// Pokud dojde k chybe, neni alokovana zadna pamet !!!
int nasobMatice (PTMatrix dest, const PTMatrix m1, const PTMatrix m2)
{
	// Vypocet poctu prvku vysledne matice
	const unsigned long pocetPrvku = m1->rows * m2->cols;
 
	// Pracovni promenne jednotlivych cyklu
	// tj. radkovy, sloupcovy a skalarni soucin
	unsigned int row, col, i;
 
	// Ukazatele na aktualni prvky jednotlivych matic
	int *pDest, *pM1, *pM2;
 
	// Osetreni vstupnich hodnot
	if (
			(0==pocetPrvku) ||
		       	(0==m1->cols) ||
			(m1->cols != m2->rows) )
		return EXIT_FAILURE;
 
	// Alokace pametoveho prostoru pro vyslednou matici
	if (NULL==(dest->matrix = malloc(pocetPrvku*sizeof(int)) ))
		return EXIT_FAILURE;
 
	// Inicializace rozmeru nove matice
	dest->rows = m1->rows;
	dest->cols = m2->cols;
 
	// Nasledujici dva vnorene cykly prochazi
	// jednotlive prvky matice "dest"
	for (row=0, pDest= dest->matrix; row< dest->rows; row++)
		for (col=0; col< dest->cols; col++, pDest++)
		{
			// Nastaveni ukazatelu do zdrojovych matic
			// na zaklade aktualniho prvku
			// pro vypocet skalarniho soucinu
			pM1 = m1->matrix + (row * m1->cols);
			pM2 = m2->matrix + col;
 
			// Vypocet skalarniho soucinu
			*pDest = 0;
			for (i=0; i< m1->cols; i++, pM1++, pM2 += m2->cols)
				*pDest += (*pM1) * (*pM2);
		}
 
	return EXIT_SUCCESS;
}
 
	// Funkce vraci nenulovou hodnotu pokud je matice monotoni
int monoMatice (const PTMatrix m)
{
	unsigned int row,col;	// pracovni promenne cyklu
	register int *pM;	// ukazatel na aktualni prvek
	TypMono mono;		// promenna charakterizujici monotonost
 
	// Scanovani po radcich - viz. funkce monoCheck()
	pM = m->matrix;
	mono = MONO_NULL;
	for (row=0; row< m->rows; row++)
	{
		pM++;
		for (col=1; col< m->cols; col++, pM++)
			if (monoCheck (&mono, pM, pM-1))
				// Matice neni monotoni
				return 0;
	}
 
	// Scanovani po sloupcich - viz. funkce monoCheck()
	mono = MONO_NULL;
	for (col=0; col< m->cols; col++)
	{
		pM = m->matrix + m->cols + col;
		for (row=1; row< m->rows; row++, pM += m->cols) 
			if (monoCheck (&mono, pM, pM - m->cols))
				// Matice neni monotoni
				return 0;
	}
 
	// Pokud nebyla nalezena zadna odchylka tak je matice monotoni
	return 1;
}
 
	// Funkce testuje monotonost dvou prvku
	// a srovnava ji s monotonosti predchozich prvku
	// Vraci 0 pokud se monotonost shoduje
	// nebo 1 pokud se monotonost neshoduje
	// pouziva vyctovy typ TypMono
inline int monoCheck (PTypMono mono, const int *aktualni, const int *predchozi)
{
	switch (*mono)
	{
		case MONO_ROSTE:
			// Monotonost dvou prvku
			// musi byt take rostouci
			return (*predchozi > *aktualni);
 
		case MONO_KLESA:
			// Monotonost dvou prvku
			// musi byt take klesajici
			return (*predchozi < *aktualni);
 
		case MONO_NULL:
			// Predchozi prvky byly stejne
			// nebo se jedna o prvni dvojici
			// Hodnota "mono" se inicializuje
			// pro dalsi krok
			if (*predchozi < *aktualni)
				*mono = MONO_ROSTE;
			else if (*aktualni < *predchozi)
				*mono = MONO_KLESA;
 
		default:return 0;
	}
}
 
// Funkce vypise vsechny prvky matice
// v poradi danem spiralou - viz. zadani
int vypisSpiralu (const PTMatrix m)
{
// Tato tabulka charakterizuje periodickou zmenu smeru pohybu
// pri cteni prvku matice ve tvaru spiraly
// Levy sloupec udava radkovy prirustek
// Pravy sloupec udava sloupcovy prirustek
const int spiralPeriod[4][2] =
{
	{0,1},
	{-1,0},
	{0,-1},
	{1,0}
};
 
// Promenne cyklu
register long int row, col;
long int i=0, dir=0, rowLimit=0, colLimit=0;
 
// Kontrola vstupnich hodnot
if ( (0==m->rows) || (0==m->cols) )
	return EXIT_FAILURE;
 
// Inicializace nastavi promenne tak
// aby ukazatel v prvni iteraci ukazoval
// na levy dolni roh matice - viz. zadani
row = m->rows - 1;
col = 0;
 
// Vlastni cyklus vypisujici prvky matice
do {
	// Vypis aktualniho prvku daneho
	// souradnicemi (row,col)
	printf ("%i ", *(m->matrix + row*m->cols + col));
 
	// Podminka pro zmenu smeru pohybu
	if (
		(row+spiralPeriod[dir][0] >= (signed)m->rows-rowLimit)||
		(row+spiralPeriod[dir][0] < rowLimit)||
		(col+spiralPeriod[dir][1] >= (signed)m->cols-colLimit)||
		(col+spiralPeriod[dir][1] < colLimit)
		)
	{
		// Inkrementace citace - zmena smeru pohybu
		i++;
 
		// Promenna pro indexaci tabulky spiralPeriod
		dir = i&3;
 
		// Orezavani radku a sloupcu matice,
		// ktere uz byly vypsany
		rowLimit = (i+1) >> 2;
		colLimit = i >> 2;
	}
 
	// Pricteni radkoveho a sloupcoveho prirustku
	// (vypocet souradnic nasledujiciho prvku)
	row += spiralPeriod[dir][0];
	col += spiralPeriod[dir][1];
 
} while (!(
			// Podminka kontroluje zdali je mozne
			// v nasledujici iteraci vypsat prvek
			// ktery jeste vypsan nebyl
		(row >= (signed) m->rows-rowLimit)||
		(row < rowLimit)||
		(col >= (signed) m->cols-colLimit)||
		(col < colLimit) ));
 
// Po vypsani vsech prvku odradkuje
printf ("\n");
 
return EXIT_SUCCESS;
}
 
// Funkce vypise posloupnost aritmetickych prumeru
// soustrednych kruznic prvku smerem od okraje matice
// viz. Dokumentace
int vypisTerc (const PTMatrix m)
{
	// Tato tabulka charakterizuje periodickou zmenu smeru pohybu
	// pri cteni prvku matice ve tvaru terce
	// Levy sloupec udava radkovy prirustek
	// Pravy sloupec udava sloupcovy prirustek
	const int dartPeriod [4][2] =
	{
		{1,0},
		{0,1},
		{-1,0},
		{0,-1}
	};
 
	// Kontrola vstupnich hodnot
	if ( (0==m->rows) || (0==m->cols) )
		return EXIT_FAILURE;
 
	// Promenne cyklu
	register long int row=0, col=0;
	long int i=0, dir=0, limit=0;
	double suma=0.0;
 
	// Cyklus prochazi postupne vsechny prvky matice
	do 
	{
		// Pricteni aktualniho prvku a inkrementace pocitadla
		// Tyto dve promenne vyuziju pozdeji k vypoctu prumeru
		suma += *(m->matrix + row*m->cols + col);
		i++;
 
		// Podmika pro zmenu smeru pohybu
		if (
			(row+dartPeriod[dir][0] >= (signed)m->rows-limit)||
			(row+dartPeriod[dir][0] < limit)||
			(col+dartPeriod[dir][1] >= (signed)m->cols-limit)||
			(col+dartPeriod[dir][1] < limit)
			)
		{
			// Zmena smeru pohybu
			dir ++;
			if (dir>3)
			{
				// Ted odectu posledni prvek
				// abych ho nepocital dvakrat
				// (na zacatku a na konci cyklu)
				suma -= *(m->matrix + row*m->cols + col);
				i --;
 
				// Vypise prumer nactenych prvku
				printf ("%.5lf ", suma/i);
 
				// Inicializace promennych pro vypocet
				// prumeru dalsich prvku
				suma = 0.0;
				i = dir = 0;
 
				// Orezani jiz nactenych radku a sloupcu
				row = limit;
				limit ++;
				col = limit;
			}
		}				
 
		// Pricteni radkoveho a sloupcoveho prirustku
		// (vypocet souradnic nasledujiciho prvku)
		row += dartPeriod[dir][0];
		col += dartPeriod[dir][1];
 
	} while (!(	// Podminka kontroluje zdali je mozne
			// v nasledujici iteraci nacist prvek
			// ktery jeste nacten nebyl
			(row >= (signed)m->rows-limit)||
			(row < limit)||
			(col >= (signed)m->cols-limit)||
			(col < limit)
			));
 
	// Pokud matice neni ctvercova, nebyl jeste vypsan prumer
	// poslednich prvku - je na case to udelat..
	if (i)
		printf ("%.5lf",suma/i);
 
	// Po vypsani vsech prvku odradkuje
	printf ("\n");
 
	return EXIT_SUCCESS;
}
 
// Funkce na zaklade prvniho prvku matice opakovane
// vola funkci wormTransOne, ktera provadi vlastni
// zizali transformaci matice - viz. Dokumentace
int wormTrans (const PTMatrix m)
{
	// Vypocet poctu prvku a nacteni hodnoty, o kterou se bude posouvat
	const long int pocetPrvku = (signed) (m->rows * m->cols);
	register long int posunKolik = (long) *(m->matrix);
 
	// Udava smer transformace, ktery je pozdeji predan
	// funkci wormTransOne jako druhy parametr
	const int WormForward = 0;
	const int WormBack = 1;
 
	// Kontrola, jestli matice neni prazdna
	if (pocetPrvku==0)
		return EXIT_FAILURE;
 
	// Vypocet nejmensiho mozneho poctu transformaci
	// aby byl vysledek ekvivalentni
	posunKolik %= pocetPrvku;
 
	// Zjisteni smeru posuvu, volani funkce s paramtrem udavajicim smer
	if (posunKolik>0)
		for (;posunKolik; posunKolik--)
			wormTransOne (m,WormForward);
	else
		for (;posunKolik; posunKolik++)
			wormTransOne (m,WormBack);
 
	return EXIT_SUCCESS;
}
 
// Funcke posune prvky matice ve tvaru zizaly
// dopredu nebo dozadu; vzdy pouze o jeden prvek
void wormTransOne (const PTMatrix m, int reverse)
{
	// Vypocet poctu prvku dane matice
	const unsigned long pocetPrvku = m->rows * m->cols;
 
	// Promenne cyklu
	int tmp, *pNow;
	unsigned char dir;
 
	// Aktualni pozice pri pruchodu matici
	struct prvekXY
	{
		int row;
		int col;
	} now;
 
	// Tabulka charakterizuje zmenu smeru pohybu
	// ve tvaru zizaly - viz. zadani ulohy
	// (v teto podobe jde o pohyb dopredu)
	struct prvekXY wormPeriod[]=
	{
		{0,1},
		{1,0},
		{0,-1},
		{1,0}
	};
 
	// Zjisti jestli je pocet radku sudy nebo lichy
	// podle toho lze stanovit jestli cerv skonci vlevo nebo vparvo
	dir = m->rows&1;
 
	// Nastaveni pozice na posledni prvek zizaly
	now.row = m->rows-1;
	now.col = (dir) ? m->cols-1 : 0;
 
	// Nasledujici kod je rozlisen na dve casti
	// pohyb ve smeru zizaly dopredu a dozadu
	if (reverse)
	{
		// Nastavi smer pruchodu matici zespodu nahoru
		wormPeriod[1].row = -1;
		wormPeriod[3].row = -1;
 
		// Inicializace promennych cyklu pro prevraceny smer
		// do tmp se ulozi prvni prvek zizaly
		tmp = *(m->matrix);
		dir <<= 1;
	}
	else
	{
		// Inicializace promennych cyklu pro smer dopredu
		// do tmp se ulozi posledni prvek zizaly
		tmp = *(m->matrix + now.row*m->cols + now.col);
		now.row = now.col = dir = 0;
	}
 
	// Cyklus provadejici transformaci
	for (register unsigned int i=pocetPrvku; i; i--)
	{
		// Vymena aktualniho prvku s tmp
		pNow = (m->matrix + now.row*m->cols + now.col);
		*pNow ^= tmp;
		tmp ^= *pNow;
		*pNow ^= tmp;
 
		// Podminka pro zmenu smeru pohybu
		if (
				(dir&1) ||
				( (dir==0) && (now.col>=(signed)m->cols-1) ) ||
				( (dir==2) && (now.col==0) )
				)
			dir ++;
 
		// Smery jsou jen ctyri takze mi budou stacit
		// posledni dva bity promenne dir
		dir &=3;
 
		// Pricteni smeroveho prirustku k souradnicim prvku
		now.row += wormPeriod [dir].row;
		now.col += wormPeriod [dir].col;
	}
}