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; } } } } }
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(); }
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(); }
bool BoxContainer::chooseSquare() { s1 = findSquare(ok1); if (!ok1) { square_found = false; return false; } else { square_found = true; return true; } }
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; }
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; }
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; }