コード例 #1
0
ファイル: remap32.cpp プロジェクト: 86400/scummvm
bool SingleRemap::apply() {
	const GfxRemap32 *const gfxRemap32 = g_sci->_gfxRemap32;
	const uint8 remapStartColor = gfxRemap32->getStartColor();

	// Blocked colors are not allowed to be used as target
	// colors for the remap
	bool blockedColors[236];
	Common::fill(blockedColors, blockedColors + remapStartColor, false);

	const bool *const paletteCycleMap = g_sci->_gfxPalette32->getCycleMap();

	const int16 blockedRangeCount = gfxRemap32->getBlockedRangeCount();
	if (blockedRangeCount) {
		const uint8 blockedRangeStart = gfxRemap32->getBlockedRangeStart();
		Common::fill(blockedColors + blockedRangeStart, blockedColors + blockedRangeStart + blockedRangeCount, true);
	}

	for (uint i = 0; i < remapStartColor; ++i) {
		if (paletteCycleMap[i]) {
			blockedColors[i] = true;
		}
	}

	// NOTE: SSCI did a loop over colors here to create a
	// new array of updated, unblocked colors, but then
	// never used it

	bool updated = false;
	for (uint i = 1; i < remapStartColor; ++i) {
		int distance;

		if (!_idealColorsChanged[i] && !_originalColorsChanged[_remapColors[i]]) {
			continue;
		}

		if (
			_idealColorsChanged[i] &&
			_originalColorsChanged[_remapColors[i]] &&
			_matchDistances[i] < 100 &&
			colorDistance(_idealColors[i], _originalColors[_remapColors[i]]) <= _matchDistances[i]
		) {
			continue;
		}

		const int16 bestColor = matchColor(_idealColors[i], _matchDistances[i], distance, blockedColors);

		if (bestColor != -1 && _remapColors[i] != bestColor) {
			updated = true;
			_remapColors[i] = bestColor;
			_matchDistances[i] = distance;
		}
	}

	return updated;
}
コード例 #2
0
void moFlatlandColorPairFinderModule::applyFilter(IplImage *src) {

/////////////////////////////////////////////////////////////////////////////////////
	//Step 1 get gray version of input, retain colored version

/////////////////////////////////////////////////////////////////////////////////////
	//Step 2 pass gray along normally to contour finder.

	this->clearBlobs();
	
	//imagePreprocess(src);
	//cvCopy(src, this->output_buffer);
	cvCvtColor(src, this->output_buffer, CV_RGB2GRAY);
	
	    CvSeq *contours = 0;
	cvFindContours(this->output_buffer, this->storage, &contours, sizeof(CvContour), CV_RETR_CCOMP);

    cvDrawContours(this->output_buffer, contours, cvScalarAll(255), cvScalarAll(255), 100);

    //cvCircle(this->output_buffer,                       /* the dest image */
    //         cvPoint(110, 60), 35,      /* center point and radius */
    //         cvScalarAll(255),    /* the color; red */
      //       1, 8, 0); 


	// Consider each contour a blob and extract the blob infos from it.
	int size;
	int min_size = this->property("min_size").asInteger();
	int max_size = this->property("max_size").asInteger();
	CvSeq *cur_cont = contours;

	
		
/////////////////////////////////////////////////////////////////////////////////////
	//Step 3 check window around contour centers and find color

	//clear the console?
	//system("cls");
	//system("clear");
	//clrscr();
	//printf("\033[2J");
	//std::cout << std::string( 100, '\n' );	

	std::vector<ColoredPt> cPts;	

	//printf("==================================\n");
	int blobi = 0;
	while (cur_cont != 0) 
	{
		CvRect rect	= cvBoundingRect(cur_cont, 0);
		size = rect.width * rect.height;
		//printf(":: %d\n", size);
		if ((size >= min_size) && (size <= max_size)) {

			//TODO use a Vector
			double red = 0;
			double green = 0;
			double blue = 0;
			int blobColor = 0;
			//in reality, probably could filter heavily and just look at 1 pixel, or at least a very small window
			
			// [!!!] 			
			for (int x = rect.x; x < rect.x + rect.width; x++)
			{
				for (int y = rect.y; y < rect.y + rect.height; y++)
				{
					int blueVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+0] );
					int greenVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+1] );
					int redVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+2] );
					
					double colorNorm = 1.0;//sqrt((blueVal*blueVal) + (greenVal*greenVal) + (redVal * redVal));

					//weight dark pixels less					
					double weight = 1.0;//(1.0*blueVal + greenVal + redVal) / (1.5 * 255.0);
					if (weight > 1) 
					{
						weight = 1;
					}
					
					if (colorNorm > 0)
					{
						red += weight*redVal/colorNorm;
						green += weight*greenVal/colorNorm;
						blue += weight*blueVal/colorNorm;
					}
				}
			}

			//the channel totals
			//printf("%d : %f\n%f\n%f\n\n",blobi , red, green, blue);
			blobi++;

			if (red > green && red > blue)
			{
				blobColor = RED;
			}

			if (blue > green && blue > red)
			{
				blobColor = BLUE;
			}

			if (green > red && green > blue)
			{
				blobColor = GREEN;
			}
			

			blobColor = matchColor(red, green, blue);			

			

		// Draw a letter corresponding to the LED color
		CvFont font;
		cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, .7f, .7f, 0, 1, CV_AA);
	
		if (blobColor == RED)
		{
    			cvPutText(this->output_buffer, "R", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0),  &font, cvScalar(255, 255, 255, 0));
		} 
		else 	if (blobColor == GREEN)
		{
    			cvPutText(this->output_buffer, "G", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0),  &font, cvScalar(255, 255, 255, 0));
		} 
			else if (blobColor == BLUE)
		{
    			cvPutText(this->output_buffer, "B", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0),  &font, cvScalar(255, 255, 255, 0));
		} 
		else if (blobColor == WHITE)
		{
    			cvPutText(this->output_buffer, "Y", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0),  &font, cvScalar(255, 255, 255, 0));
		}


		/*moDataGenericContainer *blob = new moDataGenericContainer();
		blob->properties["implements"] = new moProperty("pos,size");
			blob->properties["x"] = new moProperty((rect.x + rect.width / 2) / (double) src->width
			);
			blob->properties["y"] = new moProperty((rect.y + rect.height / 2) / (double) src->height
			);
			blob->properties["width"] = new moProperty(rect.width);
			blob->properties["height"] = new moProperty(rect.height);
			blob->properties["color"] = new moProperty(blobColor);


			this->blobs->push_back(blob);*/

			struct ColoredPt thisPt;
			thisPt.x = (rect.x + rect.width / 2);// / (double) src->width;
			thisPt.y = (rect.y + rect.height / 2);// / (double) src->height;
			thisPt.color = blobColor;	

			cPts.push_back(thisPt);

		}
		cur_cont = cur_cont->h_next;
	}

/////////////////////////////////////////////////////////////////////////////////////
	//Step 4 iterate over blobs again, to find close pairs

//TODO Currently, this algorithm assumes the best, and does nothing to ensure robustness/smoothness
//e.g. add a distance threshold (would need to be "settable" in a Gui)

	int nPlayersFound = 0;
	//Init the adjacency list	

	int MAX_N_LIGHTS = 20; // TODO! more lights may need to be identified for field markers!
		
	int pairs[MAX_N_LIGHTS];
	for ( int i = 0; i < MAX_N_LIGHTS; i++ )
	{
		pairs[i] = -1;
	}
	
	//printf("+++++++++++++++++++++++++++++++++++++++++\n");
	// map out closest pairs of lights.

	//TODO need to iterate through blobs and throw out obviously non-player-light blobs. (big blobs)

	//TODO
	//TODO
	//TODO
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	// In more realistic scenarios, an arbitrary number of lights is likely to appear!
	// Need to account for this!
	//! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 
	for ( int i = 0; i < cPts.size() && i < MAX_N_LIGHTS; i++ ) // dynamically allocate pairs based on number of lights?
	{

		if(pairs[i] == -1)
		{
			double minDist = 1000000;//distances are < 1, so should be OK.
			int closestIdx = -1;
			for ( int j = i; j < cPts.size() && j < MAX_N_LIGHTS; j++ )
			{
				if (j != i)
				{
				double x1 = cPts[i].x;
				double y1 = cPts[i].y;

				double x2 = cPts[j].x;
				double y2 = cPts[j].y;
				
				double distance = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
				if (distance < minDist)
				{
					minDist = distance;
					closestIdx = j;
				}
				}
			}
				if (closestIdx >= 0)
				{
				pairs[i] = closestIdx;
				pairs[closestIdx] = -9999; //designate as 'slave' point.
				nPlayersFound ++;
				//printf("%d ___ %d\n",i, pairs[i]);
				}
		}
		else
		{
		
		}
	}

	//printf("==================================\n");
	//for ( int i = 0; i < cPts.size(); i++ )
	//{
	//	printf("%d ___ %d\n", i, pairs[i]);
	//}

	///////////////////////////////////////
	// Clear the player list //////////////
	
	moDataGenericList::iterator pit;
	for ( pit = this->players->begin(); pit != this->players->end(); pit++ )
	{
		delete (*pit);
	}	
	this->players->clear();
	

	// look at pair colors and determine player number
	for (int i = 0; i < MAX_N_LIGHTS; i++)
	{
		if (pairs[i] >= 0)
		{
			//printf("%d ___ %d\n",pairs[i], pairs[i]);
			int color1 = cPts[i].color;
			int color2 = cPts[pairs[i]].color;

			//write a function to choose the player

			int playerIdx = getPlayerIndex(color1, color2);
			std::ostringstream labelStream;
			labelStream << playerIdx;

			/*if ((color1 == 0 && color2 == 2) || (color2 == 0 && color1 == 2)) //red and blue
			{
				label = "1";
			}
			else if ((color1 == 0 && color2 == 1) || (color2 == 0 && color1 == 1)) //red and green
			{
				label = "2";
			}*/
			
			double avX = (cPts[i].x + cPts[pairs[i]].x)/2;
			double avY = (cPts[i].y + cPts[pairs[i]].y)/2;	
			
			CvFont font;
			cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.7f, 1.7f, 0, 1, CV_AA);			

			cvPutText(this->output_buffer, labelStream.str().c_str(), cvPoint(avX, avY),  &font, cvScalar(255, 255, 255, 0));
			

			/*moDataGenericContainer *player = new moDataGenericContainer();
			player->properties["implements"] = new moProperty("pos");
			player->properties["x"] = new moProperty(avX / src->width);
			player->properties["y"] = new moProperty(avY / src->height);
			player->properties["blob_id"] = new moProperty(playerIdx);

			std::string implements = player->properties["implements"]->asString();
			// Indicate that the blob has been tracked, i.e. blob_id exists.
			implements += ",tracked";
			player->properties["implements"]->set(implements);

			this->players->push_back(player);*/

			//->properties["blob_id"]->set(old_id);
		}
	}
	
	//Add in some fake players, so I don't have to have the lights out to test the connection.
			double debugX = .5 + .25 * sin(2*3.14 * frameCounter / 200);			
			
			if (frameCounter % 2 == 0)
			{
			moDataGenericContainer *player = new moDataGenericContainer();
			player->properties["implements"] = new moProperty("pos");
			player->properties["x"] = new moProperty(debugX);
			player->properties["y"] = new moProperty(.75);
			player->properties["blob_id"] = new moProperty(0);

			std::string implements = player->properties["implements"]->asString();
			// Indicate that the blob has been tracked, i.e. blob_id exists.
			implements += ",tracked";
			player->properties["implements"]->set(implements);


			moDataGenericContainer *player2 = new moDataGenericContainer();
			player2->properties["implements"] = new moProperty("pos");
			player2->properties["x"] = new moProperty(1 - debugX);
			player2->properties["y"] = new moProperty(.75);
			player2->properties["blob_id"] = new moProperty(1);


			player2->properties["implements"]->set(implements);

				this->players->push_back(player);
				this->players->push_back(player2);
			}
			frameCounter = (frameCounter + 1) % 200;
			
    this->output_data->push(this->players);
}
TestCase::IterateResult ReadPixelsCase::iterate (void)
{
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
	tcu::PixelFormat			pixelFormat		= renderTarget.getPixelFormat();
	int							targetWidth		= renderTarget.getWidth();
	int							targetHeight	= renderTarget.getHeight();
	int							x				= 0;
	int							y				= 0;
	int							imageWidth		= 0;
	int							imageHeight		= 0;

	deRandom rnd;
	deRandom_init(&rnd, deInt32Hash(m_curIter));

	switch (m_curIter)
	{
		case 0:
			// Fullscreen
			x = 0;
			y = 0;
			imageWidth  = targetWidth;
			imageHeight = targetHeight;
			break;
		case 1:
			// Upper left corner
			x = 0;
			y = 0;
			imageWidth = targetWidth / 2;
			imageHeight = targetHeight / 2;
			break;
		case 2:
			// Lower right corner
			x = targetWidth / 2;
			y = targetHeight / 2;
			imageWidth = targetWidth - x;
			imageHeight = targetHeight - y;
			break;
		default:
			x = deRandom_getUint32(&rnd) % (targetWidth - 1);
			y = deRandom_getUint32(&rnd) % (targetHeight - 1);
			imageWidth = 1 + (deRandom_getUint32(&rnd) % (targetWidth - x - 1));
			imageHeight = 1 + (deRandom_getUint32(&rnd) % (targetHeight - y - 1));
			break;
	}

	Surface	resImage(imageWidth, imageHeight);
	Surface	refImage(imageWidth, imageHeight);
	Surface	diffImage(imageWidth, imageHeight);

	int r = (int)(deRandom_getUint32(&rnd) & 0xFF);
	int g = (int)(deRandom_getUint32(&rnd) & 0xFF);
	int b = (int)(deRandom_getUint32(&rnd) & 0xFF);

	tcu::clear(refImage.getAccess(), tcu::IVec4(r, g, b, 255));
	glClearColor(r/255.0f, g/255.0f, b/255.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	glu::readPixels(m_context.getRenderContext(), x, y, resImage.getAccess());
	GLU_CHECK_MSG("glReadPixels() failed.");

	RGBA colorThreshold = pixelFormat.getColorThreshold();
	RGBA matchColor(0, 255, 0, 255);
	RGBA diffColor(255, 0, 0, 255);
	bool isImageOk = true;

	for (int j = 0; j < imageHeight; j++)
	{
		for (int i = 0; i < imageWidth; i++)
		{
			RGBA		resRGBA		= resImage.getPixel(i, j);
			RGBA		refRGBA		= refImage.getPixel(i, j);
			bool		isPixelOk	= compareThreshold(refRGBA, resRGBA, colorThreshold);
			diffImage.setPixel(i, j, isPixelOk ? matchColor : diffColor);

			isImageOk = isImageOk && isPixelOk;
		}
	}

	if (isImageOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		TestLog& log = m_testCtx.getLog();
		log << TestLog::ImageSet("Result", "Resulting framebuffer")
			<< TestLog::Image("Result",		"Resulting framebuffer",	resImage)
			<< TestLog::Image("Reference",	"Reference image",			refImage)
			<< TestLog::Image("DiffMask",	"Failing pixels",			diffImage)
			<< TestLog::EndImageSet;
	}

	return (++m_curIter < m_numIters) ? CONTINUE : STOP;
}
コード例 #4
0
int16 GfxPalette::kernelFindColor(uint16 r, uint16 g, uint16 b) {
	return matchColor(r, g, b) & 0xFF;
}
コード例 #5
0
bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) {
	uint16 res;
	bool paletteChanged = false;

	for (int i = 1; i < 255; i++) {
		// skip unused colors
		if (!newPalette->colors[i].used)
			continue;

		// forced palette merging or dest color is not used yet
		if (force || (!_sysPalette.colors[i].used)) {
			_sysPalette.colors[i].used = newPalette->colors[i].used;
			if ((newPalette->colors[i].r != _sysPalette.colors[i].r) || (newPalette->colors[i].g != _sysPalette.colors[i].g) || (newPalette->colors[i].b != _sysPalette.colors[i].b)) {
				_sysPalette.colors[i].r = newPalette->colors[i].r;
				_sysPalette.colors[i].g = newPalette->colors[i].g;
				_sysPalette.colors[i].b = newPalette->colors[i].b;
				paletteChanged = true;
			}
			newPalette->mapping[i] = i;
			continue;
		}

		// is the same color already at the same position? -> match it directly w/o lookup
		//  this fixes games like lsl1demo/sq5 where the same rgb color exists multiple times and where we would
		//  otherwise match the wrong one (which would result into the pixels affected (or not) by palette changes)
		if ((_sysPalette.colors[i].r == newPalette->colors[i].r) && (_sysPalette.colors[i].g == newPalette->colors[i].g) && (_sysPalette.colors[i].b == newPalette->colors[i].b)) {
			newPalette->mapping[i] = i;
			continue;
		}

		// check if exact color could be matched
		res = matchColor(newPalette->colors[i].r, newPalette->colors[i].g, newPalette->colors[i].b);
		if (res & 0x8000) { // exact match was found
			newPalette->mapping[i] = res & 0xFF;
			continue;
		}

		int j = 1;

		// no exact match - see if there is an unused color
		for (; j < 256; j++) {
			if (!_sysPalette.colors[j].used) {
				_sysPalette.colors[j].used = newPalette->colors[i].used;
				_sysPalette.colors[j].r = newPalette->colors[i].r;
				_sysPalette.colors[j].g = newPalette->colors[i].g;
				_sysPalette.colors[j].b = newPalette->colors[i].b;
				newPalette->mapping[i] = j;
				paletteChanged = true;
				break;
			}
		}
	
		// if still no luck - set an approximate color
		if (j == 256) {
			newPalette->mapping[i] = res & 0xFF;
			_sysPalette.colors[res & 0xFF].used |= 0x10;
		}
	}

	if (!forceRealMerge)
		_sysPalette.timestamp = g_system->getMillis() * 60 / 1000;

	return paletteChanged;
}
コード例 #6
0
ファイル: GameLogic_match.cpp プロジェクト: joyfish/Bejeweled
bool GameLogic_match::matchColors(int pos,bool ishelp){
    m_match_ignore_pos.clear();
    m_match_clear_pos.clear();
    m_match_new_gem_type.clear();
    int color = m_gems[pos]->getColor();
    
    matchColor(pos);
    
    bool hasBombs = false;
    
    if (m_match_clear_pos.size()>0) {
        if (!ishelp) {
            Combo();
        }
        hasBombs = true;
    }
    
    if (m_match_new_gem_type.size()>1) {
        vector<NewSpcialGemInfos*>::iterator it;
        for ( it= m_match_new_gem_type.begin();it<m_match_new_gem_type.end();it++) {
            NewSpcialGemInfos* infos = *it;
            if (infos->gem_area_count==0) {
                m_match_new_gem_type.erase(it);
                it--;
            }
        }
    }
    
    for (unsigned int i=0; i<m_match_clear_pos.size();i++) {
        if (ishelp) {
            m_gems[m_match_clear_pos[i]]->showHelpAnim();
        }else{
            Bomb(m_match_clear_pos[i]);
        }
    }
    //        if (m_match_clear_pos.size()>0) {
    //            CCLOG("clear_count %ld",m_match_clear_pos.size());
    //        }
    //
    //        for (int i=0; i<m_match_new_gem_type.size(); i++) {
    //            cout<<"gem_v_count "<<m_match_new_gem_type[i]->gem_v_count
    //            <<" gem_h_count "<<m_match_new_gem_type[i]->gem_h_count
    //            <<" gem_area_count "<<m_match_new_gem_type[i]->gem_area_count
    //            <<" gem_magic_count "<<m_match_new_gem_type[i]->gem_magic_count
    //            <<" pos "<<m_match_new_gem_type[i]->pos;
    //        }
    
    // return hasBombs;
    
    if (ishelp) {
        return hasBombs;
    }
    
    for (unsigned int i=0; i< m_match_new_gem_type.size(); i++) {
        NewSpcialGemInfos* infos = m_match_new_gem_type[i];
        if (!m_gems[infos->pos]->isEmpty()) {
            continue;
        }
        
        if (!m_blocks[infos->pos]->canInsertGem()) {
            continue;
        }
        for (int j=0; j<infos->gem_area_count; j++) {
            int _p;
            if (m_gems[infos->pos]->isEmpty()) {
                _p = infos->pos;
            }else{
                _p = getEmptyPosRound(infos->pos);
            }
            if (_p!=-1) {
                m_gems[_p]->create(GEM_AREA*10+color);
                showSeaHurt(200, _p);
                if (G::g_game_mode == GAMEMODE_SEA) {
                    G::G_Add_Achievement_Complete(35);
                }
                achieve_count->combine_count++;
            }
        }
        for (int j=0; j<infos->gem_magic_count; j++) {
            int _p;
            if (m_gems[infos->pos]->isEmpty()) {
                _p = infos->pos;
            }else{
                _p = getEmptyPosRound(infos->pos);
            }
            if (_p!=-1) {
                m_gems[_p]->create(GEM_MAGIC*10+GEM_COLOR_NOCOLOR);
                G::G_Add_Achievement_Complete(8);
                achieve_count->create_magic_count++;
                achieve_count->combine_count++;
                showSeaHurt(200, _p);
                if (G::g_game_mode == GAMEMODE_SEA) {
                    G::G_Add_Achievement_Complete(35);
                }
            }
        }
        for (int j=0; j<infos->gem_h_count; j++) {
            int _p;
            if (m_gems[infos->pos]->isEmpty()) {
                _p = infos->pos;
            }else{
                _p = getEmptyPosRound(infos->pos);
            }
            if (_p!=-1) {
                m_gems[_p]->create(GEM_H*10+color);
                showSeaHurt(200, _p);
                if (G::g_game_mode == GAMEMODE_SEA) {
                    G::G_Add_Achievement_Complete(35);
                }
                achieve_count->combine_count++;
            }
        }
        for (int j=0; j<infos->gem_v_count; j++) {
            int _p;
            if (m_gems[infos->pos]->isEmpty()) {
                _p = infos->pos;
            }else{
                _p = getEmptyPosRound(infos->pos);
            }
            if (_p!=-1) {
                m_gems[_p]->create(GEM_V*10+color);
                showSeaHurt(200, _p);
                if (G::g_game_mode == GAMEMODE_SEA) {
                    G::G_Add_Achievement_Complete(35);
                }
                achieve_count->combine_count++;
            }
        }
    }
    
    m_match_ignore_pos.clear();
    m_match_clear_pos.clear();
    m_match_new_gem_type.clear();
    
    return hasBombs;
}
コード例 #7
0
ファイル: GameLogic_match.cpp プロジェクト: joyfish/Bejeweled
void GameLogic_match::matchColor(int pos){
    if (isMatchIgnorePos(pos)){
        return;
    }
    m_match_ignore_pos.push_back(pos);
    if (pos >= BLOCK_NUM_WH||pos<0) {
        return;
    }
    
    if (!m_blocks[pos]->isMatchColor()) {
        return;
    }
    
    if (m_gems[pos]->isEmpty()) {
        return;
    }
    
    if (m_gems[pos] ->IsMoving()) {
        return;
    }
    
    if (m_gems[pos]->HasBee())
    {
        return;
    }
    
    
    
    if (m_gems[pos]->getColor() == GEM_COLOR_NOCOLOR) {//无色宝石不参与匹配
        return;
    }
    
    vector<int> _hPos;
    vector<int> _vPos;
    _hPos.push_back(pos);
    _vPos.push_back(pos);
    
    int _ofx = -1;
    while (true) {//左
        int tmpx = pos%BLOCK_NUM_W;
        int tmpy = pos/BLOCK_NUM_W;
        tmpx += _ofx;
        if (tmpx<0) {
            break;
        }
        int tmpPos = tmpy*BLOCK_NUM_W+tmpx;
        if (!IsMatchColor(pos, tmpPos)) {
            break;
        }
        _hPos.push_back(tmpPos);
        //            _hcount++;
        //            hGems->addObject(m_gems[tmpPos]);
        _ofx--;
    }
    _ofx = 1;
    while (true) {//右
        int tmpx = pos%BLOCK_NUM_W;
        int tmpy = pos/BLOCK_NUM_W;
        tmpx += _ofx;
        if (tmpx>=BLOCK_NUM_W) {
            break;
        }
        int tmpPos = tmpy*BLOCK_NUM_W+tmpx;
        if (!IsMatchColor(pos, tmpPos)) {
            break;
        }
        _hPos.push_back(tmpPos);
        //            _hcount++;
        //            hGems->addObject(m_gems[tmpPos]);
        _ofx++;
    }
    
    int _ofy = -1;
    while (true) {//上
        int tmpx = pos%BLOCK_NUM_W;
        int tmpy = pos/BLOCK_NUM_W;
        tmpy += _ofy;
        if (tmpy<0) {
            break;
        }
        int tmpPos = tmpy*BLOCK_NUM_W+tmpx;
        
        if (!IsMatchColor(pos, tmpPos)) {
            break;
        }
        _vPos.push_back(tmpPos);
        //            _vcount++;
        //            vGems->addObject(m_gems[tmpPos]);
        _ofy--;
    }
    
    _ofy = 1;
    while (true) {//下
        int tmpx = pos%BLOCK_NUM_W;
        int tmpy = pos/BLOCK_NUM_W;
        tmpy += _ofy;
        if (tmpy>=BLOCK_NUM_H) {
            break;
        }
        int tmpPos = tmpy*BLOCK_NUM_W+tmpx;
        
        if (!IsMatchColor(pos, tmpPos)) {
            break;
        }
        _vPos.push_back(tmpPos);
        //            _vcount++;
        //            vGems->addObject(m_gems[tmpPos]);
        _ofy++;
    }
    
    if (_vPos.size()<3) {
        _vPos.clear();
    }
    if (_hPos.size()<3) {
        _hPos.clear();
    }
    
    
    AddMatchClearPos(_vPos);
    AddMatchClearPos(_hPos);
    
    NewSpcialGemInfos* infos = new NewSpcialGemInfos(pos);
    if (_vPos.size()>=3&&_hPos.size()>=3) {
        infos->gem_area_count++;
    }
    if (_vPos.size()>=5) {
        infos->gem_magic_count++;
    }else if(_vPos.size()>=4){
        infos->gem_h_count++;
    }
    if (_hPos.size()>=5) {
        infos->gem_magic_count++;
    }else if(_hPos.size()>=4){
        infos->gem_v_count++;
    }
    
    
    if (infos->hasNewSpecialGem()) {
        if (infos->gem_area_count==0) {
            if (m_match_new_gem_type.size()==0) {
                m_match_new_gem_type.push_back(infos);
            }
        }else{
            m_match_new_gem_type.push_back(infos);
        }
    }
    
    for (unsigned int i=0; i<_vPos.size(); i++) {
        matchColor(_vPos[i]);
    }
    for (unsigned int i=0; i<_hPos.size(); i++) {
        matchColor(_hPos[i]);
    }
    
    _vPos.clear();
    _hPos.clear();
}