Exemple #1
0
//"рисует" одну линию поля из начальной точки PointB 
//с помощью функций работающих с Z-буфером
void LineField(HDC hdc,POINT3 PointB,COLORREF rgb, double force)
{

	VECTORS vect;	
	vect.x = PointB.x;
	vect.y = PointB.y;
	vect.z = PointB.z;
	
	//видовые координаты проецируемой точки
	double xe, ye, ze1, ze2;
	//координаты пикселов
	int x1,y1,x2,y2;

	double dt = force > 0 ? 0.1 : -0.1; //длина шага на линии поля
	double x, y, z, Hx, Hy, Hz, Ha;
	int k = 0;

	VECMAG mag;
	int step = 0;
	double xt1,yt1,zt1,xt2,yt2,zt2;
	do
	{
		step++;
		x = vect.x;
		y = vect.y;
		z = vect.z;

		mag = magn(x,y,z);

		Hx = mag.hx;
		Hy = mag.hy;
		Hz = mag.hz;

		Ha = sqrt(Hx*Hx + Hy*Hy + Hz*Hz);
		vect.dx = Hx/Ha;
		vect.dy = Hy/Ha;
		vect.dz = Hz/Ha;

		xt1 = vect.x; yt1 = vect.y; zt1 = vect.z;
		xt2 = xt1 + vect.dx*dt;
		yt2 = yt1 + vect.dy*dt;
		zt2 = zt1 + vect.dz*dt;

		xe = Xe(xt1, yt1, zt1);
		ye=Ye(xt1,yt1,zt1);
		ze1=Ze(xt1,yt1,zt1);
		x1=xn(xe);
		y1=ym(ye);

		xe = Xe(xt2, yt2, zt1);
		ye=Ye(xt2,yt2,zt2);
		ze2=Ze(xt2,yt2,zt2);
		x2=xn(xe);
		y2=ym(ye);

		//"рисуем" отрезок линии поля 
		ZbufLineWidth(hdc,x1,y1,x2,y2,ze1,ze2,3,rgb);

		vect.x = xt2;
		vect.y = yt2;
		vect.z = zt2;

		//после 10-и шагов на лини поля "рисуем" стрелку
		k++;
		if(k == 10)
		{
			arrowVector(hdc,x1,y1,x2,y2,ze2,RGB(0,0,255));
			k = 0;
		}

	//прекращаем рисовать линию поля на границе куба
	} while (step < 1000 && (x>-xmax) && (x<xmax) && (y>-ymax) && (y<ymax) && (z>-zmax) && (z<zmax));
}
void GraphicalBoardFrame::appendHandler(const QString &text, bool shiftPressed)
{
    if (!isOnBoard(m_arrowRoot))
        return;

    if (!hasCandidate())
        return;

    Quackle::LetterString appendedLetterString(QuackleIO::Util::encode(text));

    if (appendedLetterString.length() == 0 || Quackle::String::front(appendedLetterString) < QUACKLE_FIRST_LETTER)
        return;
    
    if (shiftPressed)
        appendedLetterString = Quackle::String::setBlankness(appendedLetterString);
    else
        appendedLetterString = Quackle::String::clearBlankness(appendedLetterString);

    Quackle::Move newCandidate(m_candidate);
    Quackle::LetterString newTiles(m_candidate.tiles() + appendedLetterString);
    if (!m_ignoreRack && !m_rack.contains(Quackle::String::usedTiles(newTiles)))
    {
        Quackle::LetterString blankedNewTiles(m_candidate.tiles() + Quackle::String::setBlankness(appendedLetterString));

        if (m_rack.contains(Quackle::String::usedTiles(blankedNewTiles)))
        {
            newTiles = blankedNewTiles;
        }
    }

    newCandidate.setTiles(newTiles);

    Quackle::LetterString hoppedTiles;

    QSize currentTile(m_arrowRoot);
    while (true)
    {
        const QSize nextTile = currentTile + arrowVector();

        bool stopHere = false;
        bool resetArrowAfter = false;

        if (!isOnBoard(nextTile))
        {
            stopHere = true;
        }
        else
        {
            Quackle::Board::TileInformation nextTileInformation(m_board.tileInformation(nextTile.height(), nextTile.width()));

            if (nextTileInformation.tileType != Quackle::Board::LetterTile)
                stopHere = true;
        }

        if (stopHere)
        {
            newCandidate.setTiles(newCandidate.tiles() + hoppedTiles);

            if (resetArrowAfter)
                resetArrow();
            else
                m_arrowRoot = nextTile;

            break;
        }

        hoppedTiles += QUACKLE_PLAYED_THRU_MARK;
        currentTile = nextTile;
    }

    prettifyAndSetLocalCandidate(newCandidate);
}
void GraphicalBoardFrame::tileClicked(const QSize &tileLocation, const QMouseEvent * /* event */)
{
    Quackle::Board::TileInformation info(m_board.tileInformation(tileLocation.height(), tileLocation.width()));
    if (info.tileType == Quackle::Board::LetterTile)
        return;

    if (m_arrowRoot == tileLocation)
    {
        ++m_arrowDirection;
        if (m_arrowDirection == ArrowWorm)
            m_arrowDirection = s_firstArrowDirection;
    }
    else
        m_arrowDirection = s_firstArrowDirection;

    m_arrowRoot = tileLocation;

    Quackle::Move originalMove;
    Quackle::LetterString hoppedTiles;

    QSize currentTile(tileLocation);
    while (true)
    {
        const QSize previousTile = currentTile - arrowVector();

        bool stopHere;

        if (!isOnBoard(previousTile))
            stopHere = true;
        else
        {
            Quackle::Board::TileInformation previousTileInformation(m_board.tileInformation(previousTile.height(), previousTile.width()));

            stopHere = previousTileInformation.tileType != Quackle::Board::LetterTile;
        }

        if (stopHere)
        {
            const bool horizontal = m_arrowDirection == ArrowRight;
            originalMove = Quackle::Move::createPlaceMove(currentTile.height(), currentTile.width(), horizontal, hoppedTiles);
            break;
        }

        hoppedTiles += QUACKLE_PLAYED_THRU_MARK;
        currentTile = previousTile;
    }

    prettifyAndSetLocalCandidate(originalMove);

    // TODO work some cleverness so we can do this!
    //emit setCandidateMove(Quackle::Move::createNonmove());

    for (QSize currentTile(0, 0); currentTile.height() < m_boardSize.height(); currentTile.setHeight(currentTile.height() + 1))
        for (currentTile.setWidth(0); currentTile.width() < m_boardSize.width(); currentTile.setWidth(currentTile.width() + 1))
            if (currentTile != tileLocation)
            {
                TileWidget *tile = tileAt(currentTile);
                if (!tile)
                    continue;

                tile->setArrowDirection(NoArrow);
            }

    prepare();
}
void GraphicalBoardFrame::backspaceHandler()
{
    unsigned int hoppedTiles = 0;
    QSize currentTile(m_arrowRoot);
    while (true)
    {
        const QSize previousTile = currentTile - arrowVector();

        bool stopHere;

        if (!isOnBoard(previousTile))
            stopHere = true;
        else
        {
            Quackle::Board::TileInformation previousTileInformation(m_board.tileInformation(previousTile.height(), previousTile.width()));

            stopHere = previousTileInformation.tileType != Quackle::Board::LetterTile;
        }

        ++hoppedTiles;

        if (stopHere)
        {
            m_arrowRoot = previousTile;
            break;
        }

        currentTile = previousTile;
    }

    Quackle::LetterString tiles(m_candidate.tiles());
    
    if (hoppedTiles > tiles.length())
        tiles = Quackle::LetterString();
    else
        tiles = Quackle::String::left(m_candidate.tiles(), m_candidate.tiles().length() - hoppedTiles);
    
    if (tiles.empty())
    {
        Quackle::Move originalMove;
        Quackle::LetterString hoppedLetters;

        currentTile = m_arrowRoot;
        while (true)
        {
            const QSize previousTile = currentTile - arrowVector();
    
            bool stopHere;

            if (!isOnBoard(previousTile))
                stopHere = true;
            else
            {
                Quackle::Board::TileInformation previousTileInformation(m_board.tileInformation(previousTile.height(), previousTile.width()));

                stopHere = previousTileInformation.tileType != Quackle::Board::LetterTile;
            }

            if (stopHere)
            {
                const bool horizontal = m_arrowDirection == ArrowRight;
                m_candidate = Quackle::Move::createPlaceMove(currentTile.height(), currentTile.width(), horizontal, hoppedLetters);
                break;
            }

            hoppedLetters += QUACKLE_PLAYED_THRU_MARK;
            currentTile = previousTile;
        }
    }
    else
    {
        m_candidate.setTiles(tiles);
    }

    ensureCandidatePlacedProperly();
    prettifyAndSetLocalCandidate(m_candidate);
}