예제 #1
0
int StoneHandler::countLibertiesOnMatrix(Group *group, Matrix *m)    
{
	CHECK_PTR(group);
	CHECK_PTR(m);
	
	int liberties = 0;
	Q3ValueList<int> libCounted;
	
	// Walk through the horizontal and vertial directions, counting the
	// liberties of this group.
	for (unsigned int i=0; i<group->count(); i++)
	{
		Stone *tmp = group->at(i);
		CHECK_PTR(tmp);
		
		int x = tmp->posX(),
			y = tmp->posY();
		
		// North
		checkNeighbourLibertyOnMatrix(x, y-1, libCounted, liberties, m);
		
		// West
		checkNeighbourLibertyOnMatrix(x-1, y, libCounted, liberties, m);
		
		// South
		checkNeighbourLibertyOnMatrix(x, y+1, libCounted, liberties, m);
		
		// East
		checkNeighbourLibertyOnMatrix(x+1, y, libCounted, liberties, m);
	}
	return liberties;
}
예제 #2
0
파일: group.cpp 프로젝트: alserkli/q4Go
bool Group::isAttachedTo(Stone *s)
{
	CHECK_PTR(s);

	int stoneX = s->posX();
	int stoneY = s->posY();
	int x, y;
	StoneColor col = s->getColor(), c;
	Stone *tmp;

	if (isEmpty())
		return false;

	for (unsigned int i=0; i<size(); i++)
	{
		tmp = at(i);
		x = tmp->posX();
		y = tmp->posY();
		c = tmp->getColor();
		if (((stoneX == x && (stoneY == y-1 || stoneY == y+1)) ||
		     (stoneY == y && (stoneX == x-1 || stoneX == x+1))) &&
		    c == col)
			return true;
	}    

	return false;
}
예제 #3
0
파일: group.cpp 프로젝트: alserkli/q4Go
void Group::debug()
{
	qDebug(QString("Count: %1 - Liberties: %2").arg(count()).arg(liberties));

	const_iterator i;
	for (i = constBegin(); i != constEnd(); i++)
	{
		Stone *s = *i;
		qDebug(" (%d, %d) %s", s->posX(), s->posY(),
		s->getColor() == stoneBlack ? "B" : "W");
	}	
}
예제 #4
0
//bool StoneHandler::checkPosition(Stone *stone)
bool StoneHandler::checkPosition(Stone *stone, Matrix *m, bool koStone)
{
	//CHECK_PTR(stone);
 // CHECK_PTR(m); // SL added eb 8
 
	if (!stone->isVisible())
		return true;
	
	Group *active = NULL;
	
	// No groups existing? Create one.
	if (groups->isEmpty())
	{
		Group *g = assembleGroup(stone,m);
		CHECK_PTR(g);
		groups->append(g);
		active = g;
	}
	// We already have one or more groups.
	else
	{
		bool flag = false;
		Group *tmp;
		
		for (unsigned int i=0; i<groups->count(); i++)
		{
			tmp = groups->at(i);
			//CHECK_PTR(tmp);
			
			// Check if the added stone is attached to an existing group.
			// If yes, update this group and replace the old one.
			// If the stone is attached to two groups, remove the second group.
			// This happens if the added stone connects two groups.
			if (tmp->isAttachedTo(stone))
			{
				// Group attached to stone
				if (!flag)
				{
					if (!groups->remove(i))
						qFatal("StoneHandler::checkPosition(Stone *stone):"
						"Oops, removing an attached group failed.");
					active = assembleGroup(stone,m);
					groups->insert(i, active);
					flag = true;
				}
				// Groups connected, remove one
				else
				{
					if (active != NULL && active == groups->at(i))
						active = tmp;
					if (!groups->remove(i))
						qFatal("StoneHandler::checkPosition(Stone *stone): "
						"Oops, removing a connected group failed.");
					i--;
				}
			}
		}
		
		// The added stone isnt attached to an existing group. Create a new group.
		if (!flag)
		{
			Group *g = assembleGroup(stone,m);
			CHECK_PTR(g);
			groups->append(g);
			active = g;
		}
	}
	
	// active->debug();
	
	
	// Now we have to sort the active group as last in the groups QPtrList,
	// so if this one is out of liberties, we beep and abort the operation.
	// This prevents suicide moves.
	groups->append(groups->take(groups->findRef(active)));
	
	// Check the liberties of every group. If a group has zero liberties, remove it.
	for (unsigned int i=0; i<groups->count(); i++)
	{
		Group *tmp = groups->at(i);
		//CHECK_PTR(tmp);


 		tmp->setLiberties(countLiberties(tmp, m));          //SL added eb 8

    
		// qDebug("Group #%d with %d liberties:", i, tmp->getLiberties());
		// tmp->debug();
		
		// Oops, zero liberties.
 		if (tmp->getLiberties() == 0)
		{
			// Suicide move?
			if (tmp == active)
			{
				if (active->count() == 1)
				{
					groups->remove(i);
					removeStone(stone->posX(), stone->posY(), false);
				}
				return false;
			}
			
			//was it a forbidden ko move ?
			if ((tmp->count() == 1) && koStone && ((countLiberties(active, m) == 0)))
			{
				active->debug();
				groups->remove(groups->findRef(active));
				removeStone(stone->posX(), stone->posY(), false);
				return false ;
			}

			int stoneCounter = 0;
			
			// Erase the stones of this group from the stones table.
			QListIterator<Stone *> it(*tmp);
			while (it.hasNext())
			{
				Stone *s = it.next();
				CHECK_PTR(s);
				if (workingOnNewMove)
					boardHandler->updateCurrentMatrix(stoneNone, s->posX(), s->posY());
				removeStone(s->posX(), s->posY());
				stoneCounter ++;
			}
			
			// Remove the group from the groups list.
			// qDebug("Oops, a group got killed. Removing killed group #%d", i);
			if (tmp == active)
				active = NULL;
			if (!groups->remove(i))
				qFatal("StoneHandler::checkPosition(Stone *stone): "
				"Oops, removing a killed group failed.");
			i--;
			
			// Tell the boardhandler about the captures
			boardHandler->setCaptures(stone->getColor(), stoneCounter);
		}
	}
	
	return true;
}