Jump to content

Recommended Posts

Posted

Deixo aqui as sources que usei para resolver um problema que surgiu na área de VB.

Estão lá as instruções sobre o problema e sobre as respectivas regras...

Sobre a resolução, decidi criar uma classe que resolve a questão... Dêem uma olhadela e alterem o que acharem por bem alterar...

A maior parte do código está comentado, mas se tiverem algumas duvidas, não tenham problemas em perguntar...

PS.: Demora um pedaço a apresentar o resultado... Se investigarem as sources percebem porquê, ou seja qual foi a minha ideia e porque demora tanto... Tem lá várias funções de Dump, para quem quiser investigar mais sobre o funcionamento...

Se puder esclarecer sobre este ou qualquer outra duvida, estejam à vontade... Ajudo no que puder...

Table.h

#pragma once

//-------------------------------------------------------------------

#define ALTURA	10
#define LARGURA 10
#define TOTAL	ALTURA * LARGURA

#define CELULA_VAZIA -1

//-------------------------------------------------------------------

enum DIRECTIONS
{
NORTE		= 0,
NORDESTE,	//1
ESTE,		//2
SUDESTE,	//3
SUL,		//4
SUDOESTE,	//5
OESTE,		//6
NOROESTE,	//7
NUM_DIRS	//8
};



class CTable
{
public:
CTable();
~CTable();

void PreencherTabela();

void DumpMainTable();
void DumpPossibilitiesTable();

private:

void ResetMainTable();
void ResetPossibilitiesTable();
bool GetOffset(DIRECTIONS direction, int* x, int* y);
void PutInTable(int x, int y, int value);
int GetOfTable(int x, int y);

bool FindInTable(int value, int* x, int* y);

bool GetNextStart(int* x, int* y);

private:

int m_table[LARGURA][ALTURA];

int m_Possibilities[TOTAL][NUM_DIRS];

int m_startX;
int m_startY;
};

Table.cpp

#include "stdafx.h"
#include "Table.h"

#include "f:\desenvolvimento\lib\rand.h"

#define MAX_TRIES	100

CTable::CTable()
{
m_startX = 0;
m_startY = 0;

//-------------------------------------------------------------------
Randomize();

ResetMainTable();
ResetPossibilitiesTable();

//-------------------------------------------------------------------
//Do the stuff
PreencherTabela();

//-------------------------------------------------------------------

}

CTable::~CTable()
{

}

void CTable::PreencherTabela()
{
int curNumber;
DIRECTIONS directionToGo;

int x = -1;
int y = 0;

int tempX;
int tempY;

int mainCounter = 0;

int startX = -1;
int startY = 0;

for (curNumber = 0; curNumber < 100 ; mainCounter++)
{
	if (curNumber == 0 || mainCounter == 5000000)
	{
		curNumber = 0;
		mainCounter = 0;

		ResetMainTable();
		ResetPossibilitiesTable();

		GetNextStart(&startX, &startY);
		printf("\nStarting from %d, %d", startX, startY);

		x = startX;
		y = startY;

		PutInTable(x, y, curNumber);

		curNumber++;

		continue;
	}

	//-------------------------------------------------------------------
	//Run through the several possibilities and choose one that is good
	int curDirection;
	for (curDirection = 0; curDirection < (int)NUM_DIRS; curDirection++)
	{
		//Check if this is a good posssibilitie...
		if (m_Possibilities[curNumber][curDirection] == 0)
		{
			//Choose another...
			continue;
		}

		tempX = x;
		tempY = y;

		//-------------------------------------------------------------------
		//This is an available direction... Must check the bounds and
		//if the cell is empty 
		if (GetOffset((DIRECTIONS)curDirection, &tempX, &tempY) == 0)
		{
			continue;
		}

		if (GetOfTable(tempX, tempY) != CELULA_VAZIA)
		{
			continue;
		}	

		//-------------------------------------------------------------------
		//Weeee! We can insert the number!!
		PutInTable(tempX, tempY, curNumber);

		m_Possibilities[curNumber][curDirection] = 0;

		x = tempX;
		y = tempY;

		//if (curNumber == 98)
		//{
		//	DumpMainTable();
		//}

		curNumber++;

		break;
	}

	//-------------------------------------------------------------------
	//Check if all directions were anavailable
	if (curDirection == NUM_DIRS)
	{
		//-------------------------------------------------------------------
		//Must say that all options of current number are available becouse
		//we are giving a step back...
		for (int i = 0; i < NUM_DIRS; i++)
		{
			m_Possibilities[curNumber][i] = 1;
		}

		//-------------------------------------------------------------------
		//Remove the previous number
		FindInTable(curNumber - 1, &x, &y);
		PutInTable(x, y, CELULA_VAZIA);

		//-------------------------------------------------------------------
		//Give the step backwards... 
		curNumber--;

		FindInTable(curNumber - 1, &x, &y);

		continue;
	}
}

//-------------------------------------------------------------------
//Hey Wake Up!!
Beep(1000, 1000);
DumpMainTable();
getchar();

return;

}

void CTable::DumpMainTable()
{
printf("\n//----------------------------------------\n");
for(int i = 0; i < ALTURA; i++)
{
	for (int j = 0; j < LARGURA; j++)
	{
		if (GetOfTable(i, j) != CELULA_VAZIA)
			printf("%4d", GetOfTable(i, j));
		else
			printf("%4s", " ");
	}
	printf("\n");
}
printf("//----------------------------------------\n");
}

//-------------------------------------------------------------------

void CTable::DumpPossibilitiesTable()
{

for (int curDirection = 0; curDirection < NUM_DIRS; curDirection++)
{
	for (int i = 0; i < TOTAL; i++)
	{
		printf("%d", m_Possibilities[i][curDirection]);
	}
	printf("\n");
}
}

//-------------------------------------------------------------------

void CTable::ResetMainTable()
{
for(int i = 0; i < LARGURA; i++)
{
	for (int j = 0; j < ALTURA; j++)
	{
		PutInTable(j, i, CELULA_VAZIA);
	}
}
return;
}

void CTable::ResetPossibilitiesTable()
{
for(int i = 0; i < TOTAL; i++)
{
	for (int j = 0; j < NUM_DIRS; j++)
	{
		m_Possibilities[i][j] = 1;
	}
}
return;
}

//-------------------------------------------------------------------

bool CTable::GetOffset(DIRECTIONS direction, int* x, int* y)
{
if (!x) return 0;
if (!y) return 0;

switch (direction)
{
case NORTE:
	*y -= 3;
	break;
case NORDESTE:
	*x += 2;
	*y -= 2;
	break;
case ESTE:
	*x += 3;
	break;
case SUDESTE:
	*x += 2;
	*y += 2;
	break;
case SUL:
	*y += 3;
	break;
case SUDOESTE:
	*x -= 2;
	*y += 2;
	break;
case OESTE:
	*x -= 3;
	break;
case NOROESTE:
	*x -= 2;
	*y -= 2;
	break;
default:
	return 0;
}

if ((*x < 0) || (*x >= LARGURA)) return 0;
if ((*y < 0) || (*y >=ALTURA)) return 0;

return 1;

}

void CTable::PutInTable(int x, int y, int value)
{
m_table[x][y] = value;
}

int CTable::GetOfTable(int x, int y)
{
return m_table[x][y];
}

bool CTable::FindInTable(int value, int* x, int* y)
{
for(int curX = 0; curX < LARGURA; curX++)
{
	for (int curY = 0; curY < ALTURA; curY++)
	{
		if (GetOfTable(curX, curY) == value)
		{
			*x = curX;
			*y = curY;

			return 1;
		}
	}
}	
return 0;
}

bool CTable::GetNextStart(int* x, int* y)
{
if (*x < LARGURA - 1)
{
	(*x)++;
	return 1;
}

if (*y < ALTURA - 1)
{
	(*y)++;
	*x = 0;
	return 1;
}

return 0;
}
Posted

A Rand.h é um ficheiro meu que actualmente já não é necessário. Assim como a chamada da função Randomize();

O include do stdafx.h tb pode ser retirado...

Se der erros de compilação deve ser por falta dos ficheiros stdio.h, stdlib.h ou conio.h...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.