Exemple #1
0
std::vector<Move::UPtr> QueenRule::findMovesSafe(Piece &forPiece) const
{
    std::vector<Move::UPtr> result;
    Square *currentPosition = forPiece.atSquare();
    BaseRule::DirectionFunc dirFuncs[] = {&Square::left, &Square::top, &Square::right, &Square::bottom,
                                          &Square::bottomLeft, &Square::topLeft, &Square::topRight, &Square::bottomRight
                                         };
    for (BaseRule::DirectionFunc dirFunc : dirFuncs)
    {
        Square* nextSquare = nextMovement(currentPosition, dirFunc);
        while (nextSquare != nullptr)
        {
            if (nextSquare->isEmpty())
            {
                result.push_back(Move::create(Move::Movement, *nextSquare));
            }
            else
            {
                result.push_back(Move::create((nextSquare->piece()->color() == forPiece.color()) ? Move::Defend : Move::Attack, *nextSquare));
                break;
            }
            nextSquare = nextMovement(nextSquare, dirFunc);
        }
    }

    return result;
}
Exemple #2
0
std::vector<Move::UPtr> PawnRule::findMovesSafe(Piece &forPiece) const
{
    std::vector<Move::UPtr> result;
    Square *currentPosition = forPiece.atSquare();
    Square* rightAttack = nextRightAttack(forPiece.color(), currentPosition);
    if (rightAttack != nullptr && !rightAttack->isEmpty())
    {
        const Piece* piece = rightAttack->piece();
        result.push_back(Move::create((piece->color() == forPiece.color()) ? Move::Defend : Move::Attack, *rightAttack));
    }

    Square* leftAttack = nextLeftAttack(forPiece.color(), currentPosition);
    if (leftAttack != nullptr && !leftAttack->isEmpty())
    {
        const Piece* piece = leftAttack->piece();
        result.push_back(Move::create((piece->color() == forPiece.color()) ? Move::Defend : Move::Attack, *leftAttack));
    }

    Square* shortMovement = nextMovement(forPiece.color(), currentPosition);
    if (shortMovement == nullptr)
    {
        return result;
    }

    if (!shortMovement->isEmpty())
    {
        return result;
    }

    result.push_back(Move::create(Move::Movement, *shortMovement));

    if (forPiece.wasMoved())
    {
        // This pawn was already moved, so long movement is not possible
        return result;
    }

    Square* longMovement = nextMovement(forPiece.color(), shortMovement);
    if (longMovement == nullptr)
    {
        return result;
    }

    if (longMovement->isEmpty())
    {
        result.push_back(Move::create(Move::Movement, *longMovement));
    }

    return result;
}
Exemple #3
0
void MovementProvider::requestNextMovement()
{
    if (m_movements.isEmpty())
        return;
    emit nextMovement(m_movements.takeFirst());
}
Exemple #4
0
bool MoveAction::update(Entity * entity, int deltaTicks)
{
    bool correctDestination = false;
    bool returnValue = true;

    // Grab variables from entity to manipulate here, will update them at end
    double width = entity->width();
    double height = entity->height();
    double xPosition = entity->xPosition();
    double yPosition = entity->yPosition();
    double xVelocity = entity->xVelocity();
    double yVelocity = entity->yVelocity();
    double xAcceleration = entity->xAcceleration();
    double yAcceleration = entity->yAcceleration();
    double rotation = entity->rotation();

    if(started_ == false) {
        if(path_->size() <= 0) return false;
        started_ = true;
        currentMaxVelocity_ = Vector(entity->maximumSpeed(), (*current_)->vector().direction());
        xVelocity = currentMaxVelocity_.xComponent();
        yVelocity = currentMaxVelocity_.yComponent();
        entity->setXVelocity(xVelocity);
        entity->setYVelocity(yVelocity);

        //Vector acceleration(kEntityAcceleration, moveAction->current()->vector().direction());
        //xAcceleration_ = acceleration.xComponent();
        //yAcceleration_ = acceleration.yComponent();
    }

    if(deltaTicks <= 0) {
        return returnValue;
    }

    // Check rotation
    if(rotation != (*current_)->vector().direction()) {
        //Logger::write(Logger::ss << "Rotation: " << rotation << ", Direction: " << (*current_)->vector().direction());
        // Determine and set rotation direction
        double dir = (*current_)->vector().direction() - rotation;
        if((dir > 0) && (std::abs(dir) <= 180)) { (*current_)->setClockwise(false); }
        if((dir > 0) && (std::abs(dir) > 180)) { (*current_)->setClockwise(true); }
        if((dir < 0) && (std::abs(dir) <= 180)) { (*current_)->setClockwise(true); }
        if((dir < 0) && (std::abs(dir) > 180)) { (*current_)->setClockwise(false); }

        //dir += (dir > 180) ? -360 : (dir < -180) ? 360 : 0;
        if(dir > 180) {
            dir -= 360;
        }
        else if(dir < -180) {
            dir += 360;
        }

        (*current_)->setDegrees(std::abs(dir));

        double degrees  = kEntityRotationVelocity * (deltaTicks / 1000.f);
        // Turn CW
        if((*current_)->clockwise()) {
            rotation -= degrees;
        }
        // Turn CCW
        else {
            rotation += degrees;
        }

        // check if turned far enough
        (*current_)->setDegrees((*current_)->degrees() - degrees);
        if((*current_)->degrees() < 0) {
            rotation = (*current_)->vector().direction();
        }
    }
    else {

        // Accelerate
        // TODO(2014-07-25/JM): Change use of maximumVelocity calls here to use speed variable in Entity
        //if((std::abs(xVelocity) < std::abs((*current_)->maximumVelocity().xComponent())) || ( std::abs(yVelocity) < std::abs((*current_)->maximumVelocity().yComponent())) ) {
        //    xVelocity += xAcceleration * (deltaTicks / 1000.f);
        //    yVelocity += yAcceleration * (deltaTicks / 1000.f);
        //}

        // Move left/right and up/down
        //xPosition += xVelocity * (deltaTicks / 1000.f);
        //yPosition += yVelocity * (deltaTicks / 1000.f);

        // Debugging version of movement code
        double xMovementAmount = xVelocity * (deltaTicks / 1000.f);
        xPosition += xMovementAmount;
        double yMovementAmount = yVelocity * (deltaTicks / 1000.f);
        yPosition += yMovementAmount;
        //Logger::write(Logger::ss << "Moving: (" << xMovementAmount << ", " << yMovementAmount << ")");

        // Check collisions
        //TODO(2013-09-05/JM): Create a rectangle class like SDL_Rect to replace all instances outside SDL specific code with it

        /*
        SDL_Rect rect;
        if(game_->level()->touchesWall(this, &rect)) {
            fixCollision(rect);
            Logger::write("STOPPING: Collision with wall");
            // Go back
            // TODO(2013-09-05/JM): Change this to move 1 pixel away from the collided object
            xPosition -= xVelocity * (deltaTicks / 1000.f);
            yPosition -= yVelocity * (deltaTicks / 1000.f);

            // TODO(2014-08-08/JM): Replace repeated instances of these 4 assignments to 0 with a better functionality
            //entity->stop();
            xVelocity = 0;
            yVelocity = 0;
            xAcceleration = 0;
            yAcceleration = 0;
        }
        else {
            // TODO(2013-09-05/JM): Create function for checking renderer boundary collisions
            // Check left boundary
            if(xPosition - (width / 2) < 0) {
                Logger::write("STOPPING: Collision with LEFT renderer boundary");

                //entity->stop();
                xVelocity = 0;
                yVelocity = 0;
                xAcceleration = 0;
                yAcceleration = 0;

                xPosition = 0 + (width / 2);
            }
            // Check right boundary
            else if(xPosition + (width / 2) > game_->level()->width()) {
                Logger::write("STOPPING: Collision with RIGHT renderer boundary");

                //entity->stop();
                xVelocity = 0;
                yVelocity = 0;
                xAcceleration = 0;
                yAcceleration = 0;

                xPosition = game_->level()->width() - (width / 2);
            }

            // Check top boundary
            if(yPosition - (height / 2) < 0) {
                Logger::write("STOPPING: Collision with TOP renderer boundary");

                //entity->stop();
                xVelocity = 0;
                yVelocity = 0;
                xAcceleration = 0;
                yAcceleration = 0;

                yPosition = 0 + (height / 2);
            }
            // Check bottom boundary
            else if(yPosition + (height / 2) > game_->level()->height()) {
                Logger::write("STOPPING: Collision with BOTTOM renderer boundary");

                //entity->stop();
                xVelocity = 0;
                yVelocity = 0;
                xAcceleration = 0;
                yAcceleration = 0;

                yPosition = game_->level()->height() - (height / 2);
            }

        }
        */
        bool pastPoint = false;

        if((xVelocity > 0) && (yVelocity > 0)) {
            if((xPosition >= (*current_)->destination().x()) || (yPosition >= (*current_)->destination().y())) {
                //Logger::write("(x > 0) (y > 0)");
                pastPoint = true;
            }
        }
        else if((xVelocity > 0) && (yVelocity < 0)) {
            if((xPosition >= (*current_)->destination().x()) || (yPosition <= (*current_)->destination().y())) {
                //Logger::write("(x > 0) (y < 0)");
                pastPoint = true;
            }
        }
        else if((xVelocity < 0) && (yVelocity > 0)) {
            if((xPosition <= (*current_)->destination().x()) || (yPosition >= (*current_)->destination().y())) {
                //Logger::write("(x < 0) (y > 0)");
                pastPoint = true;
            }
        }
        else if((xVelocity < 0) && (yVelocity < 0)) {
            if((xPosition <= (*current_)->destination().x()) || (yPosition <= (*current_)->destination().y())) {
                //Logger::write("(x < 0) (y < 0)");
                pastPoint = true;
            }
        }
        else if(xVelocity == 0) {
            if(yVelocity > 0) {
                if(yPosition >= (*current_)->destination().y()) {
                    //Logger::write("(x == 0) (y > 0)");
                    pastPoint = true;
                }
            }
            else if(yVelocity < 0) {
                if(yPosition <= (*current_)->destination().y()) {
                    //Logger::write("(x == 0) (y < 0)");
                    pastPoint = true;
                }
            }
        }
        else if(yVelocity == 0) {
            if(xVelocity > 0) {
                if(xPosition >= (*current_)->destination().x()) {
                    //Logger::write("(x > 0) (y == 0)");
                    pastPoint = true;
                }
            }
            else if(xVelocity < 0) {
                if(xPosition <= (*current_)->destination().x()) {
                    //Logger::write("(x < 0) (y == 0)");
                    pastPoint = true;
                }
            }
        }

        if(pastPoint) {
            //Logger::write("STOPPING: Moved past point");

            xVelocity = 0;
            yVelocity = 0;
            xAcceleration = 0;
            yAcceleration = 0;

            if(correctDestination) {
                xPosition = (*current_)->destination().x();
                yPosition = (*current_)->destination().y();
            }
            //Logger::write(Logger::ss << "Destination:" << (*current_)->destination().toString());
        }

        if(entity->stopped()) {
            if(nextMovement()) {
                currentMaxVelocity_ = Vector(entity->maximumSpeed(), (*current_)->vector().direction());
                xVelocity = currentMaxVelocity_.xComponent();
                yVelocity = currentMaxVelocity_.yComponent();
            }
            else {
                returnValue = false;
                //Logger::write(Logger::ss << "Actual Dest: (" << xPosition << ", " << yPosition << ")");
            }
        }
    }
    // TODO(2014-08-14/JM): I believe the small pause we notice between Movements is because of going past the movement destination. We move back to the destination
    // and then don't utilitize all that wasted distance we moved during that frame
    //Logger::write(Logger::ss << "Current Pos: (" << xPosition << ", " << yPosition << ")");

    // Update new values of variables
    entity->setWidth(width);
    entity->setHeight(height);
    entity->setXPosition(xPosition);
    entity->setYPosition(yPosition);
    entity->setXVelocity(xVelocity);
    entity->setYVelocity(yVelocity);
    entity->setXAcceleration(xAcceleration);
    entity->setYAcceleration(yAcceleration);
    entity->setRotation(rotation);

    return returnValue;
}