Beispiel #1
0
//all threads are initialized to run this function, it just takes the void* data type and breaks
//everything out to run the standard version above.
int threadCheckRows(void *data)
{
    //get it in a usable type
    threadData *dat = (threadData*) data;
    checkRows(dat->by, dat->ey, dat->w, dat->curLevel, dat->mut, dat->outHood, dat->inHoodPyramid, dat->inPyramid, dat->bestHood, dat->lastMatch, dat->color, dat->bestX, dat->bestY);

    //everything a ok
    return 0;
}
bool TicTacToeGame::isGameOver() const
{
    displayBoard();
    
    bool bGameOver = checkColumns();
    bGameOver |= checkRows();
    bGameOver |= checkDiagonals();
    return bGameOver;
}
Beispiel #3
0
void checkRows_returns_negative_one_if_no_winner(CuTest *tc) {
  int board[4][4];
  ct_initialize(4, 4, board);
  board[3][0] = 1;
  board[3][1] = -1;
  board[3][2] = 1;
  board[3][3] = 1;

  int answer = checkRows(4, 4, board, 4);
  CuAssertIntEquals_Msg(tc, "No winner", -1, answer);
}
Beispiel #4
0
void checkRows_returns_winner_if_exists(CuTest *tc) {
  int board[4][4];
  ct_initialize(4, 4, board);
  board[3][0] = 1;
  board[3][1] = 1;
  board[3][2] = 1;
  board[3][3] = 1;

  int answer = checkRows(4, 4, board, 4);
  CuAssertIntEquals_Msg(tc, "Player 1.", 1, answer);
}
Beispiel #5
0
	bool checkGood(const Sudoku &i, const Sudoku &s)
	{
		if (!checkSize(s)) {
			m_tested += 4;
			return false;
		}

		return checkTests({
				checkInput(i,s),
				checkRows(s),
				checkCols(s),
				checkSquares(s),
				});
	}
Beispiel #6
0
void CLlinesDoc::afterMove(int x, int y) {
      int numRows = checkRows(x, y);

        if (numRows > 0)
		{
           bonusMove = true;
         //   Toolkit.getDefaultToolkit().beep();
           // pView->drawCell(pDC,x, y);
            removeRows(x, y);
        }
		else 
		{
            bonusMove = false;
        }
    }
Beispiel #7
0
BYTE CLlinesDoc::throwBall(int i ,BYTE x ,BYTE y)
{

   if (numFree <= 0)
        return END;

   if (GetSquare(x,y) != EMPTY)
		return 	FAIL;
	 //GetView();			//initialize pView
     //pView->drawBall(pDC,x, y);
	 m_grid[x][y] = i;
     userMove = false;
	 numBalls++;
     numFree--;
    if (checkRows(x, y) > 0) 
	 {
		removeRows(x, y);
     }
	 
	
	return SUCCESS;
}
Beispiel #8
0
	std::string win(std::vector<std::string> b)
	{
		std::vector<std::pair<int,int>>coordList;
		// find coordinates for 'o'
		int row = 0;
		for (auto r : b)
		{
			for (int col = 0; col < r.size(); ++col)
			{
				if (r[col] == 'o')
				{
					coordList.push_back(std::make_pair(row, col));
					std::cout << "o found at " << row << " , " << col << "\n";
				}
			}
			++row;
		}
		//test all rows same for 5
		int count = 0;
		count = checkRows(coordList);
		if (count >= 5)
			return "found";
		//test all cols same for 5
		count = checkCols(coordList);
		if (count >= 5)
			return "found";
		//test rowid == colid for 5
		count = checkDiag(coordList);
		if (count >= 5)
			return "found";		
		//test reverse diagonal (rowMax - rowId == colId) for 5
		count = checkRevDiag(coordList);
		if (count >= 5)
			return "found";

	return "not found";
	}
ProjectorData::ProjectorData( const QgsRectangle &extent, int width, int height, QgsRasterInterface *input, const QgsCoordinateTransform &inverseCt, QgsRasterProjector::Precision precision )
  : mApproximate( false )
  , mInverseCt( inverseCt )
  , mDestExtent( extent )
  , mDestRows( height )
  , mDestCols( width )
  , mDestXRes( 0.0 )
  , mDestYRes( 0.0 )
  , mSrcRows( 0 )
  , mSrcCols( 0 )
  , mSrcXRes( 0.0 )
  , mSrcYRes( 0.0 )
  , mDestRowsPerMatrixRow( 0.0 )
  , mDestColsPerMatrixCol( 0.0 )
  , mHelperTopRow( 0 )
  , mCPCols( 0 )
  , mCPRows( 0 )
  , mSqrTolerance( 0.0 )
  , mMaxSrcXRes( 0 )
  , mMaxSrcYRes( 0 )
{
  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );

  // Get max source resolution and extent if possible
  if ( input )
  {
    QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider *>( input->sourceInput() );
    if ( provider )
    {
      if ( provider->capabilities() & QgsRasterDataProvider::Size )
      {
        mMaxSrcXRes = provider->extent().width() / provider->xSize();
        mMaxSrcYRes = provider->extent().height() / provider->ySize();
      }
      // Get source extent
      if ( mExtent.isEmpty() )
      {
        mExtent = provider->extent();
      }
    }
  }

  mDestXRes = mDestExtent.width() / ( mDestCols );
  mDestYRes = mDestExtent.height() / ( mDestRows );

  // Calculate tolerance
  // TODO: Think it over better
  // Note: we are checking on matrix each even point, that means that the real error
  // in that moment is approximately half size
  double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
  mSqrTolerance = myDestRes * myDestRes;

  if ( precision == QgsRasterProjector::Approximate )
  {
    mApproximate = true;
  }
  else
  {
    mApproximate = false;
  }

  // Always try to calculate mCPMatrix, it is used in calcSrcExtent() for both Approximate and Exact
  // Initialize the matrix by corners and middle points
  mCPCols = mCPRows = 3;
  for ( int i = 0; i < mCPRows; i++ )
  {
    QList<QgsPointXY> myRow;
    myRow.append( QgsPointXY() );
    myRow.append( QgsPointXY() );
    myRow.append( QgsPointXY() );
    mCPMatrix.insert( i, myRow );
    // And the legal points
    QList<bool> myLegalRow;
    myLegalRow.append( bool( false ) );
    myLegalRow.append( bool( false ) );
    myLegalRow.append( bool( false ) );
    mCPLegalMatrix.insert( i, myLegalRow );
  }
  for ( int i = 0; i < mCPRows; i++ )
  {
    calcRow( i, inverseCt );
  }

  while ( true )
  {
    bool myColsOK = checkCols( inverseCt );
    if ( !myColsOK )
    {
      insertRows( inverseCt );
    }
    bool myRowsOK = checkRows( inverseCt );
    if ( !myRowsOK )
    {
      insertCols( inverseCt );
    }
    if ( myColsOK && myRowsOK )
    {
      QgsDebugMsgLevel( QStringLiteral( "CP matrix within tolerance" ), 4 );
      break;
    }
    // What is the maximum reasonable size of transformatio matrix?
    // TODO: consider better when to break - ratio
    if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
      //if ( mCPRows * mCPCols > mDestRows * mDestCols )
    {
      QgsDebugMsgLevel( QStringLiteral( "Too large CP matrix" ), 4 );
      mApproximate = false;
      break;
    }
  }
  QgsDebugMsgLevel( QStringLiteral( "CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ), 4 );
  mDestRowsPerMatrixRow = static_cast< float >( mDestRows ) / ( mCPRows - 1 );
  mDestColsPerMatrixCol = static_cast< float >( mDestCols ) / ( mCPCols - 1 );

  QgsDebugMsgLevel( QStringLiteral( "CPMatrix:" ), 5 );
  QgsDebugMsgLevel( cpToString(), 5 );

  // init helper points
  pHelperTop = new QgsPointXY[mDestCols];
  pHelperBottom = new QgsPointXY[mDestCols];
  calcHelper( 0, pHelperTop );
  calcHelper( 1, pHelperBottom );
  mHelperTopRow = 0;

  // Calculate source dimensions
  calcSrcExtent();
  calcSrcRowsCols();
  mSrcYRes = mSrcExtent.height() / mSrcRows;
  mSrcXRes = mSrcExtent.width() / mSrcCols;
}
Beispiel #10
0
void TableWidget::contextMenu(const QPoint &p, bool init ){

    /*
    QModelIndex index = this->indexAt(p);
    int col = index.column();
    //int row = index.row();
    QString str = "file";
    ColumnType t = ORIGIN;
    if(col==TRACK || col==TITLE){
        str = "result";
        t = RESULT;
    }
    */


    QMenu *c = new QMenu(this);


    QAction* selectAction = new QAction("Check selected rows", this);
    selectAction->setData(true);
    connect(selectAction, SIGNAL(triggered()), this, SLOT(checkRows()));
    QAction* deselectAction = new QAction("Uncheck selected rows", this);
    deselectAction->setData(false);
    connect(deselectAction, SIGNAL(triggered()), this, SLOT(checkRows()));

    //move up/down actions for this
    QAction* moveResultUpAction = new QAction("Move result up", this);
    moveResultUpAction->setData(RESULT); moveResultUpAction->setShortcut(tr("Ctrl+U"));
    connect(moveResultUpAction, SIGNAL(triggered()), this, SLOT(moveRowUp()));
    QAction* moveResultDownAction = new QAction("Move result down", this);
    moveResultDownAction->setData(RESULT); moveResultDownAction->setShortcut(tr("Ctrl+D"));
    connect(moveResultDownAction, SIGNAL(triggered()), this, SLOT(moveRowDown()));
    QAction* moveResultToAction = new QAction("Move result to...", this);
    moveResultToAction->setData(RESULT); moveResultToAction->setShortcut(tr("Ctrl+T"));
    connect(moveResultToAction, SIGNAL(triggered()), this, SLOT(moveRowTo()));

    QAction* moveOriginUpAction = new QAction("Move file up", this);
    moveOriginUpAction->setData(ORIGIN); moveOriginUpAction->setShortcut(tr("Ctrl+Alt+U"));
    connect(moveOriginUpAction, SIGNAL(triggered()), this, SLOT(moveRowUp()));
    QAction* moveOriginDownAction = new QAction("Move file down", this);
    moveOriginDownAction->setData(ORIGIN); moveOriginDownAction->setShortcut(tr("Ctrl+Alt+D"));
    connect(moveOriginDownAction, SIGNAL(triggered()), this, SLOT(moveRowDown()));
    QAction* moveOriginToAction = new QAction("Move file to...", this);
    moveOriginToAction->setData(ORIGIN); moveOriginToAction->setShortcut(tr("Ctrl+Alt+T"));
    connect(moveOriginToAction, SIGNAL(triggered()), this, SLOT(moveRowTo()));

    QAction* sortEnabledAction = new QAction(tr("Sorting enabled"), this);
    sortEnabledAction->setCheckable(true); sortEnabledAction->setChecked( this->isSortingEnabled() );
    connect(sortEnabledAction, SIGNAL(toggled(bool)), this, SLOT(enableSorting(bool)));

    resizeColumnAction->setShortcut(tr("Ctrl+R"));
    connect(resizeColumnAction, SIGNAL(toggled(bool)), this, SLOT(resizeColumns(bool)));

    connect(resizeRowAction, SIGNAL(toggled(bool)), this, SLOT(resizeRows(bool)));
    QAction* deleteAction = new QAction(tr("Delete selected cells"), this);
    deleteAction->setShortcut(tr("Ctrl+Del"));
    connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteCells()));

    QAction* insertBlankFileAction = new QAction("Insert empty file", this);
    insertBlankFileAction->setData(ORIGIN);
    connect(insertBlankFileAction, SIGNAL(triggered()), this, SLOT(insertBlankRow()));
    QAction* insertBlankResultAction = new QAction("Insert empty result", this);
    insertBlankResultAction->setData(RESULT);
    connect(insertBlankResultAction, SIGNAL(triggered()), this, SLOT(insertBlankRow()));

    QAction* copyAction = new QAction(tr("Copy"), this);
    copyAction->setShortcut(tr("Ctrl+C"));
    connect(copyAction, SIGNAL(triggered()), this, SLOT(copyCells()));

    QAction* pasteAction = new QAction(tr("Paste"), this);
    pasteAction->setShortcut(tr("Ctrl+V"));
    connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste()));

    QAction* resetAction = new QAction(tr("Reset"), this);
    connect(resetAction, SIGNAL(triggered()), this, SLOT(resetTable()));

    QMenu* matchByMenu = new QMenu(tr("Match results by..."), this);
    connect(matchByTrackAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));
    connect(matchByTitleAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));
    connect(dontMatchAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));
    connect(matchByTrackTitleAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));
    connect(matchByTitleTrackAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));
    connect(matchByFileNameAction, SIGNAL(triggered(bool)), this, SLOT(matchBy(bool)));

    matchByMenu->addAction( dontMatchAction );
    matchByMenu->addAction( matchByTitleAction );
    matchByMenu->addAction( matchByTrackAction );
    matchByMenu->addAction( matchByTrackTitleAction );
    matchByMenu->addAction( matchByTitleTrackAction );
    matchByMenu->addAction( matchByFileNameAction );

    c->addMenu(matchByMenu);
    c->addSeparator();
    //if(col==FILE_NAME){
    c->addAction(deselectAction);
    c->addAction(selectAction);
    c->addSeparator();
    //}
    c->addAction(moveResultUpAction);
    c->addAction(moveResultDownAction);
    c->addAction(moveResultToAction);
    c->addAction(moveOriginUpAction);
    c->addAction(moveOriginDownAction);
    c->addAction(moveOriginToAction);
    c->addSeparator();
    c->addAction(resizeColumnAction);
    c->addAction(resizeRowAction);
    c->addAction(sortEnabledAction);
    c->addSeparator();
    c->addAction(copyAction);
    c->addAction(pasteAction);
    c->addAction(deleteAction);
    c->addSeparator();
    c->addAction(insertBlankFileAction);
    c->addAction(insertBlankResultAction);    
    c->addSeparator();
    c->addAction(resetAction);


    QPoint globalPos = this->mapToGlobal(p);
    //menu->exec( globalPos );
    if(!init){
        c->exec(globalPos);
    }else{
        this->addAction( dontMatchAction );
        this->addAction( matchByTitleAction );
        this->addAction( matchByTrackAction );
        this->addAction( matchByTrackTitleAction );
        this->addAction( matchByTitleTrackAction );
        this->addAction( matchByFileNameAction );

        this->addAction(deselectAction);
        this->addAction(selectAction);

        this->addAction(moveResultUpAction);
        this->addAction(moveResultDownAction);
        this->addAction(moveResultToAction);
        this->addAction(moveOriginUpAction);
        this->addAction(moveOriginDownAction);
        this->addAction(moveOriginToAction);

        this->addAction(resizeColumnAction);
        this->addAction(resizeRowAction);
        this->addAction(sortEnabledAction);

        this->addAction(copyAction);
        this->addAction(pasteAction);
        this->addAction(deleteAction);

        this->addAction(insertBlankFileAction);
        this->addAction(insertBlankResultAction);

    }
}
Beispiel #11
0
void QgsRasterProjector::calc()
{
    QgsDebugMsg( "Entered" );
    mCPMatrix.clear();
    mCPLegalMatrix.clear();
    delete[] pHelperTop;
    pHelperTop = 0;
    delete[] pHelperBottom;
    pHelperBottom = 0;

    // Get max source resolution and extent if possible
    mMaxSrcXRes = 0;
    mMaxSrcYRes = 0;
    if ( mInput )
    {
        QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
        if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) )
        {
            mMaxSrcXRes = provider->extent().width() / provider->xSize();
            mMaxSrcYRes = provider->extent().height() / provider->ySize();
        }
        // Get source extent
        if ( mExtent.isEmpty() )
        {
            mExtent = provider->extent();
        }
    }

    mDestXRes = mDestExtent.width() / ( mDestCols );
    mDestYRes = mDestExtent.height() / ( mDestRows );

    // Calculate tolerance
    // TODO: Think it over better
    // Note: we are checking on matrix each even point, that means that the real error
    // in that moment is approximately half size
    double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
    mSqrTolerance = myDestRes * myDestRes;

    const QgsCoordinateTransform* ct = QgsCoordinateTransformCache::instance()->transform( mDestCRS.authid(), mSrcCRS.authid(), mDestDatumTransform, mSrcDatumTransform );

    // Initialize the matrix by corners and middle points
    mCPCols = mCPRows = 3;
    for ( int i = 0; i < mCPRows; i++ )
    {
        QList<QgsPoint> myRow;
        myRow.append( QgsPoint() );
        myRow.append( QgsPoint() );
        myRow.append( QgsPoint() );
        mCPMatrix.insert( i,  myRow );
        // And the legal points
        QList<bool> myLegalRow;
        myLegalRow.append( bool( false ) );
        myLegalRow.append( bool( false ) );
        myLegalRow.append( bool( false ) );
        mCPLegalMatrix.insert( i,  myLegalRow );
    }
    for ( int i = 0; i < mCPRows; i++ )
    {
        calcRow( i, ct );
    }

    while ( true )
    {
        bool myColsOK = checkCols( ct );
        if ( !myColsOK )
        {
            insertRows( ct );
        }
        bool myRowsOK = checkRows( ct );
        if ( !myRowsOK )
        {
            insertCols( ct );
        }
        if ( myColsOK && myRowsOK )
        {
            QgsDebugMsg( "CP matrix within tolerance" );
            mApproximate = true;
            break;
        }
        // What is the maximum reasonable size of transformatio matrix?
        // TODO: consider better when to break - ratio
        if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
        {
            QgsDebugMsg( "Too large CP matrix" );
            mApproximate = false;
            break;
        }
    }
    QgsDebugMsg( QString( "CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ) );
    mDestRowsPerMatrixRow = ( float )mDestRows / ( mCPRows - 1 );
    mDestColsPerMatrixCol = ( float )mDestCols / ( mCPCols - 1 );

    QgsDebugMsgLevel( "CPMatrix:", 5 );
    QgsDebugMsgLevel( cpToString(), 5 );

    // Calculate source dimensions
    calcSrcExtent();
    calcSrcRowsCols();
    mSrcYRes = mSrcExtent.height() / mSrcRows;
    mSrcXRes = mSrcExtent.width() / mSrcCols;

    // init helper points
    pHelperTop = new QgsPoint[mDestCols];
    pHelperBottom = new QgsPoint[mDestCols];
    calcHelper( 0, pHelperTop );
    calcHelper( 1, pHelperBottom );
    mHelperTopRow = 0;
}
QgsRasterProjector::QgsRasterProjector(
  QgsCoordinateReferenceSystem theSrcCRS,
  QgsCoordinateReferenceSystem theDestCRS,
  QgsRectangle theDestExtent,
  int theDestRows, int theDestCols,
  double theMaxSrcXRes, double theMaxSrcYRes,
  QgsRectangle theExtent )
    : mSrcCRS( theSrcCRS )
    , mDestCRS( theDestCRS )
    , mCoordinateTransform( theDestCRS, theSrcCRS )
    , mDestExtent( theDestExtent )
    , mExtent( theExtent )
    , mDestRows( theDestRows ), mDestCols( theDestCols )
    , mMaxSrcXRes( theMaxSrcXRes ), mMaxSrcYRes( theMaxSrcYRes )
{
  QgsDebugMsg( "Entered" );
  QgsDebugMsg( "theDestExtent = " + theDestExtent.toString() );

  mDestXRes = mDestExtent.width() / ( mDestCols );
  mDestYRes = mDestExtent.height() / ( mDestRows );

  // Calculate tolerance
  // TODO: Think it over better
  // Note: we are checking on matrix each even point, that means taht the real error
  // in that moment is approximately half size
  double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
  mSqrTolerance = myDestRes * myDestRes;

  // Initialize the matrix by corners and middle points
  mCPCols = mCPRows = 3;
  for ( int i = 0; i < mCPRows; i++ )
  {
    QList<QgsPoint> myRow;
    myRow.append( QgsPoint() );
    myRow.append( QgsPoint() );
    myRow.append( QgsPoint() );
    mCPMatrix.insert( i,  myRow );
  }
  for ( int i = 0; i < mCPRows; i++ )
  {
    calcRow( i );
  }

  while ( true )
  {
    bool myColsOK = checkCols();
    if ( !myColsOK )
    {
      insertRows();
    }
    bool myRowsOK = checkRows();
    if ( !myRowsOK )
    {
      insertCols();
    }
    if ( myColsOK && myRowsOK )
    {
      QgsDebugMsg( "CP matrix within tolerance" );
      mApproximate = true;
      break;
    }
    // What is the maximum reasonable size of transformatio matrix?
    // TODO: consider better when to break - ratio
    if ( mCPRows * mCPCols > 0.0625 * mDestRows * mDestCols )
    {
      QgsDebugMsg( "Too large CP matrix" );
      mApproximate = false;
      break;
    }

  }
  QgsDebugMsg( QString( "CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ) );
  mDestRowsPerMatrixRow = ( float )mDestRows / ( mCPRows - 1 );
  mDestColsPerMatrixCol = ( float )mDestCols / ( mCPCols - 1 );

  //QgsDebugMsg( "CPMatrix:\n" + cpToString() );

  // Calculate source dimensions
  calcSrcExtent();
  calcSrcRowsCols();
  mSrcYRes = mSrcExtent.height() / mSrcRows;
  mSrcXRes = mSrcExtent.width() / mSrcCols;

  // init helper points
  pHelperTop = new QgsPoint[mDestCols];
  pHelperBottom = new QgsPoint[mDestCols];
  calcHelper( 0, pHelperTop );
  calcHelper( 1, pHelperBottom );
  mHelperTopRow = 0;
}
Beispiel #13
0
//a searching function used by textureSynthesis() to determine output pixel values
//returns the color to assign that pixel
Uint32 findBestMatch(hood_pyramid *inHoodPyramid, gauss_pyramid *inPyramid, gauss_pyramid *outPyramid, int curLevel, int x, int y)
{
	verboseDebug("\t\t\tBuilding output position neighborhood\n");
	hood *outHood = new hood(outPyramid, curLevel, x, y);

	//best match stuff
	hood *bestHood = NULL;
	double lastMatch = 999999999.9;
	Uint32 color = 0;
	int bestX = 0, bestY = 0;

	//others
	int w = inPyramid->getLevel(curLevel)->w, h = inPyramid->getLevel(curLevel)->h;

	verboseDebug("\t\t\tComparing neighborhoods\n");
    //Start with the multithreading stuff
	if (TEX_SYN_THREADS > 0)
	{
		SDL_mutex *mut = SDL_CreateMutex();

		//this is to make sure that no more than height threads are used
		int numThreads = (TEX_SYN_THREADS <= h) ? TEX_SYN_THREADS : h;

		//calculate how many rows to give to each thread. the first threads get the floor of the division,
		//the last one gets the remaining rows
		int firstThreadsRows = floor(float(h) / numThreads);

		//create the threads
		SDL_Thread **threads = new SDL_Thread*[TEX_SYN_THREADS];
		threadData **datas = new threadData*[TEX_SYN_THREADS];
		for( int t = 0; t < numThreads; t++)
		{
			//figure out what rows it needs to generate
			int from = firstThreadsRows * t;
			int to = firstThreadsRows * (t + 1);
			if(t == numThreads)
			{
				from = firstThreadsRows * t;
				to = h;
			}
			verboseDebug("\t\t\tthread #%d will check rows [%d, %d)\n", t, from, to);

			//create the data structure
			datas[t] = new threadData(from, to, w, curLevel, mut, outHood, inHoodPyramid, inPyramid, bestHood, &lastMatch, &color, &bestX, &bestY);
			//make the thread
			threads[t] = SDL_CreateThread(threadCheckRows, (void*)datas[t]);
		}

		//wait for them to finish
		for(int t = 0; t<numThreads; t++)
		{
			int rs = 0;
			SDL_WaitThread(threads[t], &rs);

			//my thread function will never return anything but 0 so this will never happen... I don't think anyway
			if(rs != 0)
				debug("WARNING: thread #%d returned status %d!\n", t, rs);

			//delete the data it used
			delete datas[t];
		}

		//delete the threads and datas arrays
		delete threads;
		delete datas;

		//clean it up
		SDL_DestroyMutex(mut);
	}
	else
		checkRows(0, h, w, curLevel, NULL, outHood, inHoodPyramid, inPyramid, bestHood, &lastMatch, &color, &bestX, &bestY);

	delete outHood;
	verboseDebug("\t\t\t\tBest match was %x at (%d, %d)\n", color, bestX, bestY);
	verboseDebug("\t\t\tDone\n");
	return color;
}