Exemple #1
0
void flagSquares(struct sudokuboard* board){
    int cell;
    int row, col;
    int flags[9][9]; //[square][value]
    int i,j;
    
    //initialize each square's flags to 0
    for(i = 0; i < 9; i++)
        for(j = 0; j < 9; j++)
            flags[i][j] = FALSE;

    //find each square's flags
    for(row = 0; row < 9 ; row++){
        for(col = 0; col < 9; col++){
            if( board->cell[row][col].value != 0){
                flags[findSquare(row,col)][board->cell[row][col].value-1] = TRUE;
            }
        }
    }

    //copy square's flags to cell
    for(row = 0; row < 9 ; row++){
        for(col = 0; col < 9; col++){
            for(i = 0; i < 9; i++){
                if(flags[findSquare(row,col)][i] == TRUE){
                    board->cell[row][col].flag[i] = TRUE;
                }
            }
        }
    }
}
Exemple #2
0
void BoxContainer::mergeSquares() {
	s2 = findSquare(ok2);

	if (!ok2 || !ok1) {
		clrscr();
		cout << "\tNo such square. Cannot merge\n";
		std::this_thread::sleep_for(std::chrono::milliseconds(700));
		return;
	}
	if (s1 == s2) {
		clrscr();
		cout << "\tCan't merge with the same square. Nothing to do.\n";
		std::this_thread::sleep_for(std::chrono::milliseconds(700));
		return;
	}
	auto smaller = (s1->getLength() <= s2->getLength()) ? s1 : s2;
	auto bigger = (s1->getLength() < s2->getLength()) ? s2 : s1;

	if (*s1 < *s2)
		sqrList.erase(s1);
	else if (*s1 > *s2)
		sqrList.erase(s2);
	else if (s1->overlaps(*s2))
		sqrList.erase(bigger);
	else // they must be strangers
		sqrList.erase(smaller);

	reset1();
	reset2();
}
Exemple #3
0
int main()
{
	buf = (char*)malloc(MAXCHAR);
	memset(buf,0,MAXCHAR) ;
	getData("main.txt");
	int channel = 3 ;
	int xr = findSquare((totlen + channel - 1 ) /channel );
	int size = xr * xr * channel ;
	printf("xr = %d  totlen = %d\n",xr,totlen );
	BYTE* bytes = (BYTE *)malloc(sizeof(BYTE) * size);
	memset(bytes,0, size ) ;
	for(int i = 0; i < totlen ; i ++) bytes[i] = buf[i];

	BMPImage* bmp = (BMPImage*)malloc(sizeof(BMPImage));
	bmp->channels =  channel ;
	bmp->height = xr ;
	bmp->width = xr ;
	bmp->imageData = bytes ;

	save24BITImage("aaa.bmp",bmp);
	BMPImage*img = loadImage("aaa.bmp");
	printf("width = %d\n",img->width);
	printf("height = %d\n",img->height);
	int len = img->channels * img->height * img->width ;
	for(int i = 0 ; i < len ; i ++ ) {
		printf("%c",img->imageData[i]);
	}
	free(buf);
	
	return 0;
}
void ImageProcessor::drawAttack(CheckMatePosition position) {
  QPainter painter(image);
  RectArea BlackKing=findSquare(position.BlackKingX,position.BlackKingY);
  if (position.WhiteAttackerX!=-1) {
    RectArea WhiteAttacker=findSquare(position.WhiteAttackerX,position.WhiteAttackerY);
    painter.setPen(QPen(QBrush(0xff0000),5));
    painter.drawLine(BlackKing.x+BlackKing.width/2, BlackKing.y+BlackKing.height/2,
                   WhiteAttacker.x+WhiteAttacker.width/2,WhiteAttacker.y+WhiteAttacker.height/2);
  }
  
  if (position.EscapeX!=-1) {
    RectArea Escape=findSquare(position.EscapeX,position.EscapeY);
    painter.setPen(QPen(QBrush(0x00ff00),5));
    painter.drawLine(BlackKing.x+BlackKing.width/2, BlackKing.y+BlackKing.height/2,
                    Escape.x+Escape.width/2,Escape.y+Escape.height/2);
  }
  painter.end();
}
Exemple #5
0
bool BoxContainer::chooseSquare() {
	s1 = findSquare(ok1);
	if (!ok1) {
		square_found = false;
		return false;
	}
	else {
		square_found = true;
		return true;
	}
}
Exemple #6
0
bool TerrainBlock::castRayBlock(const Point3F &pStart, const Point3F &pEnd, const Point2I &aBlockPos, U32 aLevel, F32 invDeltaX, F32 invDeltaY, F32 aStartT, F32 aEndT, RayInfo *info, bool collideEmpty)
{
   F32 invBlockSize = 1 / F32(BlockSquareWidth);

   static TerrLOSStackNode stack[BlockShift * 3 + 1];
   U32 stackSize = 1;

   stack[0].startT = aStartT;
   stack[0].endT = aEndT;
   stack[0].blockPos = aBlockPos;
   stack[0].level = aLevel;
   
   if(!mTile && !aBlockPos.isZero())
      return false;

   while(stackSize--)
   {
      TerrLOSStackNode *sn = stack + stackSize;
      U32 level  = sn->level;
      F32 startT = sn->startT;
      F32 endT   = sn->endT;
      Point2I blockPos = sn->blockPos;

      GridSquare *sq = findSquare(level, Point2I(blockPos.x & BlockMask, blockPos.y & BlockMask));

      F32 startZ = startT * (pEnd.z - pStart.z) + pStart.z;
      F32 endZ = endT * (pEnd.z - pStart.z) + pStart.z;

      F32 minHeight = fixedToFloat(sq->minHeight);
      if(startZ <= minHeight && endZ <= minHeight)
      {
         //drawLineTest(startT, sn->endT, false);
         continue;
      }
      F32 maxHeight = fixedToFloat(sq->maxHeight);
      if(startZ >= maxHeight && endZ >= maxHeight)
      {
         //drawLineTest(startT, endT, false);
         continue;
      }
      if (!collideEmpty && (sq->flags & GridSquare::Empty) &&
      	  blockPos.x == (blockPos.x & BlockMask) && blockPos.y == (blockPos.y & BlockMask))
      {
         //drawLineTest(startT, endT, false);
         continue;
      }
      if(level == 0)
      {
         F32 xs = blockPos.x * invBlockSize;
         F32 ys = blockPos.y * invBlockSize;

         F32 zBottomLeft = fixedToFloat(getHeight(blockPos.x, blockPos.y));
         F32 zBottomRight= fixedToFloat(getHeight(blockPos.x + 1, blockPos.y));
         F32 zTopLeft =    fixedToFloat(getHeight(blockPos.x, blockPos.y + 1));
         F32 zTopRight =   fixedToFloat(getHeight(blockPos.x + 1, blockPos.y + 1));

         PlaneF p1, p2;
         PlaneF divider;
         Point3F planePoint;

         if(sq->flags & GridSquare::Split45)
         {
            p1.set(zBottomLeft - zBottomRight, zBottomRight - zTopRight, invBlockSize);
            p2.set(zTopLeft - zTopRight, zBottomLeft - zTopLeft, invBlockSize);
            planePoint.set(xs, ys, zBottomLeft);
            divider.x = 1;
            divider.y = -1;
            divider.z = 0;
         }
         else
         {
            p1.set(zTopLeft - zTopRight, zBottomRight - zTopRight, invBlockSize);
            p2.set(zBottomLeft - zBottomRight, zBottomLeft - zTopLeft, invBlockSize);
            planePoint.set(xs + invBlockSize, ys, zBottomRight);
            divider.x = 1;
            divider.y = 1;
            divider.z = 0;
         }
         p1.setPoint(planePoint);
         p2.setPoint(planePoint);
         divider.setPoint(planePoint);

         F32 t1 = p1.intersect(pStart, pEnd);
         F32 t2 = p2.intersect(pStart, pEnd);
         F32 td = divider.intersect(pStart, pEnd);

         F32 dStart = divider.distToPlane(pStart);
         F32 dEnd = divider.distToPlane(pEnd);

         // see if the line crosses the divider
         if((dStart >= 0 && dEnd < 0) || (dStart < 0 && dEnd >= 0))
         {
            if(dStart < 0)
            {
               F32 temp = t1;
               t1 = t2;
               t2 = temp;
            }
            if(t1 >= startT && t1 && t1 <= td && t1 <= endT)
            {
               info->t = t1;
               info->normal = p1;
               return true;
            }
            if(t2 >= td && t2 >= startT && t2 <= endT)
            {
               info->t = t2;
               info->normal = p2;
               return true;
            }
         }
         else
         {
            F32 t;
            if(dStart >= 0) {
               t = t1;
               info->normal = p1;
            }
            else {
               t = t2;
               info->normal = p2;
            }
            if(t >= startT && t <= endT)
            {
               info->t = t;
               return true;
            }
         }
         continue;
      }
      int subSqWidth = 1 << (level - 1);
      F32 xIntercept = (blockPos.x + subSqWidth) * invBlockSize;
      F32 xInt = calcInterceptX(pStart.x, invDeltaX, xIntercept);
      F32 yIntercept = (blockPos.y + subSqWidth) * invBlockSize;
      F32 yInt = calcInterceptY(pStart.y, invDeltaY, yIntercept);

      F32 startX = startT * (pEnd.x - pStart.x) + pStart.x;
      F32 startY = startT * (pEnd.y - pStart.y) + pStart.y;

      if(xInt < startT)
         xInt = MAX_FLOAT;
      if(yInt < startT)
         yInt = MAX_FLOAT;

      U32 x0 = (startX > xIntercept) * subSqWidth;
      U32 y0 = (startY > yIntercept) * subSqWidth;
      U32 x1 = subSqWidth - x0;
      U32 y1 = subSqWidth - y0;
      U32 nextLevel = level - 1;

      // push the items on the stack in reverse order of processing
      if(xInt > endT && yInt > endT)
      {
         // only test the square the point started in:
         stack[stackSize].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize].level = nextLevel;
         stackSize++;
      }
      else if(xInt < yInt)
      {
         F32 nextIntersect = endT;
         if(yInt <= endT)
         {
            stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
            stack[stackSize].startT = yInt;
            stack[stackSize].endT = endT;
            stack[stackSize].level = nextLevel;
            nextIntersect = yInt;
            stackSize++;
         }
         stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y0);
         stack[stackSize].startT = xInt;
         stack[stackSize].endT = nextIntersect;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = xInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
      else if(yInt < xInt)
      {
         F32 nextIntersect = endT;
         if(xInt <= endT)
         {
            stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
            stack[stackSize].startT = xInt;
            stack[stackSize].endT = endT;
            stack[stackSize].level = nextLevel;
            nextIntersect = xInt;
            stackSize++;
         }
         stack[stackSize].blockPos.set(blockPos.x + x0, blockPos.y + y1);
         stack[stackSize].startT = yInt;
         stack[stackSize].endT = nextIntersect;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = yInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
      else
      {
         stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
         stack[stackSize].startT = xInt;
         stack[stackSize].endT = endT;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = xInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
   }
   return false;
}
Exemple #7
0
bool TerrainBlock::buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return false;

   // Transform the bounding sphere into the object's coord space.  Note that this
   //  not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F::One, "Error, handle the scale transform on the terrain");

   // Setup collision state data
   polyList->setTransform(&getTransform(), getScale());
   polyList->setObject(this);

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   if (!mTile && xStart<0)
      xStart = 0;
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;
   xEnd = xStart + xExt;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0.0f)? 0.0f: floatToFixed(osBox.minExtents.z);

   // Index of shared points
   U32 bp[(MaxExtent + 1) * 2],*vb[2];
   vb[0] = &bp[0];
   vb[1] = &bp[xExt + 1];
   clrbuf(vb[1],xExt + 1);

   bool emitted = false;
   for (S32 y = yStart; y < yEnd; y++) 
   {
      S32 yi = y & BlockMask;

      swap(vb[0],vb[1]);
      clrbuf(vb[1],xExt + 1);
      //
      for (S32 x = xStart; x < xEnd; x++) 
      {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) || gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;
         emitted = true;

         // Add the missing points
         U32 vi[5];
         for (int i = 0; i < 4 ; i++) 
         {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            U32* vp = &vb[dy][x - xStart + dx];
            if (*vp == U32_MAX) 
            {
               Point3F pos;
               pos.x = (F32)((x + dx) * mSquareSize);
               pos.y = (F32)((y + dy) * mSquareSize);
               pos.z = fixedToFloat(getHeight(xi + dx, yi + dy));
               *vp = polyList->addPoint(pos);
            }
            vi[i] = *vp;
         }

         U32* vp = &vi[0];
         if (!(gs->flags & GridSquare::Split45))
            vi[4] = vi[0], vp++;

         BaseMatInstance* material = getMaterialInst( xi, yi );
         U32 surfaceKey = ((xi << 16) + yi) << 1;
         polyList->begin(material,surfaceKey);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[1]);
         polyList->vertex(vp[2]);
         polyList->plane(vp[0],vp[1],vp[2]);
         polyList->end();
         polyList->begin(material,surfaceKey + 1);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[2]);
         polyList->vertex(vp[3]);
         polyList->plane(vp[0],vp[2],vp[3]);
         polyList->end();
      }
   }
   return emitted;
}
Exemple #8
0
void TerrainBlock::buildConvex(const Box3F& box,Convex* convex)
{
   sTerrainConvexList.collectGarbage();

   //
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return;

   // Transform the bounding sphere into the object's coord space.  Note that this
   // not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F(1, 1, 1), "Error, handle the scale transform on the terrain");

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0)? 0: floatToFixed(osBox.minExtents.z);

   for (S32 y = yStart; y < yEnd; y++) {
      S32 yi = y & BlockMask;

      //
      for (S32 x = xStart; x < xEnd; x++) {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) ||
             gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;

         U32 sid = (x << 16) + (y & ((1 << 16) - 1));
         Convex* cc = 0;

         // See if the square already exists as part of the working set.
         CollisionWorkingList& wl = convex->getWorkingList();
         for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
            if (itr->mConvex->getType() == TerrainConvexType &&
                static_cast<TerrainConvex*>(itr->mConvex)->squareId == sid) {
               cc = itr->mConvex;
               break;
            }
         if (cc)
            continue;

         // Create a new convex.
         TerrainConvex* cp = new TerrainConvex;
         sTerrainConvexList.registerObject(cp);
         convex->addToWorkingList(cp);
         cp->halfA = true;
         cp->square = 0;
         cp->mObject = this;
         cp->squareId = sid;
         cp->material = getMaterial(xi,yi)->index;//RDTODO
         cp->box.minExtents.set((F32)(x * mSquareSize), (F32)(y * mSquareSize), fixedToFloat(gs->minHeight));
         cp->box.maxExtents.x = cp->box.minExtents.x + mSquareSize;
         cp->box.maxExtents.y = cp->box.minExtents.y + mSquareSize;
         cp->box.maxExtents.z = fixedToFloat(gs->maxHeight);
         mObjToWorld.mul(cp->box);

         // Build points
         Point3F* pos = cp->point;
         for (int i = 0; i < 4 ; i++,pos++) {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            pos->x = (F32)((x + dx) * mSquareSize);
            pos->y = (F32)((y + dy) * mSquareSize);
            pos->z = fixedToFloat(getHeight(xi + dx, yi + dy));
         }

         // Build normals, then split into two Convex objects if the
         // square is concave
         if ((cp->split45 = gs->flags & GridSquare::Split45) == true) {
            VectorF *vp = cp->point;
            mCross(vp[0] - vp[1],vp[2] - vp[1],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[2] - vp[3],vp[0] - vp[3],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[3] - vp[1],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
         else {
            VectorF *vp = cp->point;
            mCross(vp[3] - vp[0],vp[1] - vp[0],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[1] - vp[2],vp[3] - vp[2],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[2] - vp[0],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
      }
   }
}
void ImageProcessor::findPieces(std::vector<std::vector<PieceSquare> > &ChessDesk) {
  RectArea CurrentSquare=findSquare(0,0);

  // Finding min and max brightness for autocontrast.
  int MaxGrayPixel=0;
  int MinGrayPixel=255;

  for(int i=0;i<8;i++) {
    for(int j=0;j<8;j++) {
      CurrentSquare=findSquare(i,j);
      for(int k=0;k<CurrentSquare.width-1;k++) {
        for(int l=0;l<CurrentSquare.height-1;l++) {
          int CurrentGrayPixel=qGray(image->pixel(CurrentSquare.x+k,CurrentSquare.y+l));
          if (CurrentGrayPixel>MaxGrayPixel) {
            MaxGrayPixel=CurrentGrayPixel;
          }
          if (CurrentGrayPixel<MinGrayPixel) {
            MinGrayPixel=CurrentGrayPixel;
          }
        }
      }
    }
  }
  
  writeLog(QString(tr("Minimum brightness: %1; Maximium brightness: %2;")).arg(MinGrayPixel).arg(MaxGrayPixel));

  
  int a[256];

  for(int i=0;i<256;i++) {a[i]=0;}
  
  for(int i=0;i<8;i++) {
    for(int j=0;j<8;j++) {
      CurrentSquare=findSquare(i,j);

      if ((MaxGrayPixel-MinGrayPixel)<128) {
        filterAutoContrast(CurrentSquare, *image,MinGrayPixel,MaxGrayPixel);
        filterAverage(CurrentSquare, *image);
      }
      filterMedian(CurrentSquare, *image);

      for(int k=0;k<CurrentSquare.width-1;k++) {
        for(int l=0;l<CurrentSquare.height-1;l++) {
          a[qGray(image->pixel(CurrentSquare.x+k,CurrentSquare.y+l))]++;
        }
      }
      CurrentSquare.x--;
      CurrentSquare.y--;
      CurrentSquare.width++;
      CurrentSquare.height++;
      drawRect(CurrentSquare);
    }
  }

  int max=0;

  for(int i=0;i<256;i++) {
    if (a[i]>max) max=a[i];
    //writeLog(QString("G %1 %2").arg(i).arg(a[i]));
  }

  writeLog(QString("MAX %1").arg(max));
  for(int i=0;i<256;i++) {
    for(int j=0;j<static_cast<int>((static_cast<double>(a[i]))*500/max);j++) {
      //image->setPixel(i,j,0x0000ff);
    }
  }
  
  std::vector<int> sorta;
  for(int i=0;i<256;i++) {
    sorta.push_back(a[i]);
  }
  std::sort(&sorta[0], &sorta[sorta.size()]);
  std::vector<int> Maximums;
  for (int i=255;i>=0;i--) {
    int IsInsideExtr=0;
    int EnterExtr=0;
    int LastEnter=-10;
    for(int j=0;j<256;j++) {
      if ((a[j]>sorta[i]) && (!IsInsideExtr)) {
        IsInsideExtr=1;
        EnterExtr++;
        if (abs(LastEnter-j)<10) {
          IsInsideExtr=0;
          EnterExtr--;
          Maximums.pop_back();
        } else {
          LastEnter=j;
          Maximums.push_back(j);
          writeLog(QString("POS %1").arg(j));
        }
      }

      if ((a[j]<sorta[i]) && (IsInsideExtr)) {
        IsInsideExtr=0;
      }
    }
    writeLog(QString("EXT %1").arg(EnterExtr));
    if (EnterExtr>=2) {break;} else Maximums.clear();
  }
  
  std::sort(&Maximums[0], &Maximums[Maximums.size()]);

  while (a[Maximums[0]]>0){Maximums[0]--;}
  while (a[Maximums[1]]>0){Maximums[1]++;}
  writeLog(QString("M1 %1 M2 %2").arg(Maximums[0]).arg(Maximums[1]));
;

  /////////////////////////////////////!!!!!!!!!!!!!!!!!!!!!!!!
  
  for(int i=0;i<8;i++) {
    for(int j=0;j<8;j++) {
      CurrentSquare=findSquare(i,j);

      int AboveScale=0;
      int BelowScale=0;
      for(int k=0;k<CurrentSquare.width-1;k++) {
        for(int l=0;l<CurrentSquare.height-1;l++) {
          int current=qGray(image->pixel(CurrentSquare.x+k,CurrentSquare.y+l));
          if ((current<Maximums[0]) || (current>Maximums[1])) { 
            image->setPixel(CurrentSquare.x+k,CurrentSquare.y+l,0xffffff);
            if (current<Maximums[0]) BelowScale++;
            if (current>Maximums[1]) AboveScale++;
          } else 
          {
            image->setPixel(CurrentSquare.x+k,CurrentSquare.y+l,0x000000);
          }
        }
      }

      if (AboveScale>BelowScale) {
        ChessDesk[i][j].Color=1;
      } else {
        ChessDesk[i][j].Color=0;
      }
      
      writeLog(QString(tr("X %1 Y %2 C %3")).arg(i+1).arg(j+1).arg(ChessDesk[i][j].Color));

      if (DebugMode) {
        sendImage(*image);
        writeLog(QString(tr("Binarizing square X:%1 Y:%2.")).arg(i+1).arg(j+1));
      }
        
      approximateBorder(CurrentSquare, *image);

      if ((MaxGrayPixel-MinGrayPixel)<128) {
        filterDilation(CurrentSquare, *image);
        filterErosion(CurrentSquare, *image);
      }

      filterErosion(CurrentSquare, *image);
      filterDilation(CurrentSquare, *image);
      filterFigure(CurrentSquare, *image);
      recognizePiece(CurrentSquare, *image, ChessDesk[i][j]);
    }
  }
  
  for(int i=0;i<8;i++) {
    for(int j=0;j<8;j++) {
      if (ChessDesk[i][j].Type) {
        int type=ChessDesk[i][j].Type;
        int color=ChessDesk[i][j].Color;
        if (type==1 && color==0)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("Black King"));
        if (type==1 && color==1)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("White King"));
        if (type==2 && color==0)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("Black Queen"));
        if (type==2 && color==1)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("White Queen"));
        if (type==3 && color==0)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("Black Pawn"));
        if (type==3 && color==1)
          writeLog(QString("X %1 Y %2 F %3").arg(i+1).arg(j+1).arg("White Pawn"));
      }
    }
  }
  /////////////////////////////////////
  CheckMatePosition CurrentAttack=checkPosition(ChessDesk);

  delete image;
  image = new QImage(*source);
  drawRect(ChessArea,0xff0000);
  for(int i=0;i<8;i++) {
    for(int j=0;j<8;j++) {
      CurrentSquare=findSquare(i,j);
      if (ChessDesk[i][j].Type) {
        int type=ChessDesk[i][j].Type;
        int color=ChessDesk[i][j].Color;
        if (type==1 && color==0) //Black King
          drawRect(CurrentSquare,qRgb(30,89,19),5);
        if (type==1 && color==1) //White King
          drawRect(CurrentSquare,qRgb(121,11,11),5);
        if (type==2 && color==0) //Black Queen
          drawRect(CurrentSquare,qRgb(54,179,35),5);
        if (type==2 && color==1) //White Queen
          drawRect(CurrentSquare,qRgb(237,44,44),5);
        if (type==3 && color==0) //Black Pawn
          drawRect(CurrentSquare,qRgb(177,235,167),5);
        if (type==3 && color==1) //White Pawn
          drawRect(CurrentSquare,qRgb(250,192,192),5);
      }
    }
  }

  
  drawAttack(CurrentAttack);

  sendImage(*image);
}
void TerrainFile::updateGrid( const Point2I &minPt, const Point2I &maxPt )
{
   // here's how it works:
   // for the current terrain renderer we only care about
   // the minHeight and maxHeight on the GridSquare
   // so we do one pass through, updating minHeight and maxHeight
   // on the level 0 squares, then we loop up the grid map from 1 to
   // the top, expanding the bounding boxes as necessary.
   // this should end up being way, way, way, way faster for the terrain
   // editor

   PROFILE_SCOPE( TerrainFile_UpdateGrid );

   for ( S32 y = minPt.y - 1; y < maxPt.y + 1; y++ )
   {
      for ( S32 x = minPt.x - 1; x < maxPt.x + 1; x++ )
      {
         S32 px = x;
         S32 py = y;
         if ( px < 0 )
            px += mSize;
         if ( py < 0 )
            py += mSize;

         TerrainSquare *sq = findSquare( 0, px, py );
         sq->minHeight = 0xFFFF;
         sq->maxHeight = 0;

         // Update the empty state.
         if ( isEmptyAt( x, y ) )
            sq->flags |= TerrainSquare::Empty;
         else
            sq->flags &= ~TerrainSquare::Empty;

         getMinMax( sq->minHeight, sq->maxHeight, getHeight( x, y ) );
         getMinMax( sq->minHeight, sq->maxHeight, getHeight( x+1, y ) );
         getMinMax( sq->minHeight, sq->maxHeight, getHeight( x, y+1 ) );
         getMinMax( sq->minHeight, sq->maxHeight, getHeight( x+1, y+1 ) );
      }
   }

   // ok, all the level 0 grid squares are updated:
   // now update all the parent grid squares that need to be updated:
   for( S32 level = 1; level <= mGridLevels; level++ )
   {
      S32 size = 1 << level;
      S32 halfSize = size >> 1;  

      for( S32 y = (minPt.y - 1) >> level; y < (maxPt.y + size) >> level; y++ )
      {
         for ( S32 x = (minPt.x - 1) >> level; x < (maxPt.x + size) >> level; x++ )
         {
            S32 px = x << level;
            S32 py = y << level;

            TerrainSquare *sq = findSquare(level, px, py);
            sq->minHeight = 0xFFFF;
            sq->maxHeight = 0;
            sq->flags &= ~( TerrainSquare::Empty | TerrainSquare::HasEmpty );

            checkSquare( sq, findSquare( level - 1, px, py ) );
            checkSquare( sq, findSquare( level - 1, px + halfSize, py ) );
            checkSquare( sq, findSquare( level - 1, px, py + halfSize ) );
            checkSquare( sq, findSquare( level - 1, px + halfSize, py + halfSize ) );
         }
      }
   }
}
void TerrainFile::_buildGridMap()
{
   // The grid level count is the same as the
   // most significant bit of the size.  While 
   // we loop we take the time to calculate the
   // grid memory pool size.
   mGridLevels = 0;
   U32 size = mSize;
   U32 poolSize = size * size;
   while ( size >>= 1 )
   {
      poolSize += size * size;
      mGridLevels++;
   }

   mGridMapPool.setSize( poolSize ); 
   mGridMapPool.compact();
   mGridMap.setSize( mGridLevels + 1 );
   mGridMap.compact();

   // Assign memory from the pool to each grid level.
   TerrainSquare *sq = mGridMapPool.address();
   for ( S32 i = mGridLevels; i >= 0; i-- )
   {
      mGridMap[i] = sq;
      sq += 1 << ( 2 * ( mGridLevels - i ) );
   }

   for( S32 i = mGridLevels; i >= 0; i-- )
   {
      S32 squareCount = 1 << ( mGridLevels - i );
      S32 squareSize = mSize / squareCount;

      for ( S32 squareX = 0; squareX < squareCount; squareX++ )
      {
         for ( S32 squareY = 0; squareY < squareCount; squareY++ )
         {
            U16 min = 0xFFFF;
            U16 max = 0;
            U16 mindev45 = 0;
            U16 mindev135 = 0;

            // determine max error for both possible splits.

            const Point3F p1(0, 0, getHeight(squareX * squareSize, squareY * squareSize));
            const Point3F p2(0, (F32)squareSize, getHeight(squareX * squareSize, squareY * squareSize + squareSize));
            const Point3F p3((F32)squareSize, (F32)squareSize, getHeight(squareX * squareSize + squareSize, squareY * squareSize + squareSize));
            const Point3F p4((F32)squareSize, 0, getHeight(squareX * squareSize + squareSize, squareY * squareSize));

            // pl1, pl2 = split45, pl3, pl4 = split135
            const PlaneF pl1(p1, p2, p3);
            const PlaneF pl2(p1, p3, p4);
            const PlaneF pl3(p1, p2, p4);
            const PlaneF pl4(p2, p3, p4);

            bool parentSplit45 = false;
            TerrainSquare *parent = NULL;
            if ( i < mGridLevels )
            {
               parent = findSquare( i+1, squareX * squareSize, squareY * squareSize );
               parentSplit45 = parent->flags & TerrainSquare::Split45;
            }

            bool empty = true;
            bool hasEmpty = false;

            for ( S32 sizeX = 0; sizeX <= squareSize; sizeX++ )
            {
               for ( S32 sizeY = 0; sizeY <= squareSize; sizeY++ )
               {
                  S32 x = squareX * squareSize + sizeX;
                  S32 y = squareY * squareSize + sizeY;

                  if(sizeX != squareSize && sizeY != squareSize)
                  {
                     if ( !isEmptyAt( x, y ) )
                        empty = false;
                     else
                        hasEmpty = true;
                  }

                  U16 ht = getHeight( x, y );
                  if ( ht < min )
                     min = ht;
                  if( ht > max )
                     max = ht;

                  Point3F pt( (F32)sizeX, (F32)sizeY, (F32)ht );
                  U16 dev;

                  if(sizeX < sizeY)
                     dev = calcDev(pl1, pt);
                  else if(sizeX > sizeY)
                     dev = calcDev(pl2, pt);
                  else
                     dev = Umax(calcDev(pl1, pt), calcDev(pl2, pt));

                  if(dev > mindev45)
                     mindev45 = dev;

                  if(sizeX + sizeY < squareSize)
                     dev = calcDev(pl3, pt);
                  else if(sizeX + sizeY > squareSize)
                     dev = calcDev(pl4, pt);
                  else
                     dev = Umax(calcDev(pl3, pt), calcDev(pl4, pt));

                  if(dev > mindev135)
                     mindev135 = dev;
               }
            }

            TerrainSquare *sq = findSquare( i, squareX * squareSize, squareY * squareSize );
            sq->minHeight = min;
            sq->maxHeight = max;

            sq->flags = empty ? TerrainSquare::Empty : 0;
            if ( hasEmpty )
               sq->flags |= TerrainSquare::HasEmpty;

            bool shouldSplit45 = ((squareX ^ squareY) & 1) == 0;
            bool split45;

            //split45 = shouldSplit45;
            if ( i == 0 )
               split45 = shouldSplit45;
            else if( i < 4 && shouldSplit45 == parentSplit45 )
               split45 = shouldSplit45;
            else
               split45 = mindev45 < mindev135;

            //split45 = shouldSplit45;
            if(split45)
            {
               sq->flags |= TerrainSquare::Split45;
               sq->heightDeviance = mindev45;
            }
            else
               sq->heightDeviance = mindev135;

            if( parent )
               if (  parent->heightDeviance < sq->heightDeviance )
                     parent->heightDeviance = sq->heightDeviance;
         }
      }
   }

   /*
   for ( S32 y = 0; y < mSize; y += 2 )
   {
      for ( S32 x=0; x < mSize; x += 2 )
      {
         GridSquare *sq = findSquare(1, Point2I(x, y));
         GridSquare *s1 = findSquare(0, Point2I(x, y));
         GridSquare *s2 = findSquare(0, Point2I(x+1, y));
         GridSquare *s3 = findSquare(0, Point2I(x, y+1));
         GridSquare *s4 = findSquare(0, Point2I(x+1, y+1));
         sq->flags |= (s1->flags | s2->flags | s3->flags | s4->flags) & ~(GridSquare::MaterialStart -1);
      }
   }
   */
}
int main(int argc, char** argv) {  
  int failures = 0, successes = 0;
  int matrix_rows, matrix_cols, square_row, square_col, result;
  
  int** matrix = matrixiLoad(&matrix_rows, &matrix_cols, "./matrix_test_examples/matrix.txt");

  findSquare(&square_row, &square_col, matrix, matrix_rows, matrix_cols, 1, 6);
  printf("Input ");
  matrixiPrint(matrix, matrix_rows, matrix_cols); 
  printf("Searching for a square submatrix of dimension 1 containing values equal to 6\n");
  printf("Expected: -1, -1\n");
  printf("Result: %d, %d\n", square_row, square_col);      
  if(square_row == -1 && square_col == -1) { 
    printf("OK\n");
    successes++; 
  }
  else {
    printf("FAIL\n");
    failures++; 
  }
  printf("---------------------------------\n");

  findSquare(&square_row, &square_col, matrix, matrix_rows, matrix_cols, 1, 4);
  printf("Input ");
  matrixiPrint(matrix, matrix_rows, matrix_cols);
  printf("Searching for a square submatrix of dimension 1 containing values equal to 4\n");
  printf("Expected: 0, 2\n");
  printf("Result: %d, %d\n", square_row, square_col);      
  if(square_row == 0 && square_col == 2) { 
    printf("OK\n");
    successes++; 
  }
  else {
    printf("FAIL\n");
    failures++; 
  }
  printf("---------------------------------\n");

  findSquare(&square_row, &square_col, matrix, matrix_rows, matrix_cols, 3, 2);
  printf("Input ");
  matrixiPrint(matrix, matrix_rows, matrix_cols);
  printf("Searching for a square submatrix of dimension 3 containing values equal to 2\n");
  printf("Expected: 2, 0\n");
  printf("Result: %d, %d\n", square_row, square_col);
  if(square_row == 2 && square_col == 0) {
    printf("OK\n");
    successes++;
  }
  else {
    printf("FAIL\n");
    failures++;
  }
  printf("---------------------------------\n");

  findSquare(&square_row, &square_col, matrix, matrix_rows, matrix_cols, 2, 3);
  printf("Input ");
  matrixiPrint(matrix, matrix_rows, matrix_cols);
  printf("Searching for a square submatrix of dimension 2 containing values equal to 3\n");
  printf("Expected: 5, 0\n");
  printf("Result: %d, %d\n", square_row, square_col);
  if(square_row == 5 && square_col == 0) {
    printf("OK\n");
    successes++;
  }
  else {
    printf("FAIL\n");
    failures++;
  }
  printf("---------------------------------\n");

  findSquare(&square_row, &square_col, matrix, matrix_rows, matrix_cols, 4, 1);
  printf("Input ");
  matrixiPrint(matrix, matrix_rows, matrix_cols);
  printf("Searching for a square submatrix of dimension 4 containing values equal to 1\n");
  printf("Expected: 2, 3\n");
  printf("Result: %d, %d\n", square_row, square_col);
  if(square_row == 2 && square_col == 3) {
    printf("OK\n");
    successes++;
  }
  else {
    printf("FAIL\n");
    failures++;
  }
  printf("---------------------------------\n");

  printf("Success rate: %0.02f\n", (float) successes * 100.0f / (successes + failures));

  return 0;
}