void Noble::randomMove() { randomizeDirections(); for(int i=0;i<4;i++) { if(direction[i]==1 && moveInDirection(getX(),getY()-1))//move north { break; } else if(direction[i]==2 && moveInDirection(getX(),getY()+1))//move south { break; } else if(direction[i]==3 && moveInDirection(getX()+1,getY()))//move east { break; } else if(direction[i]==4 && moveInDirection(getX()-1,getY()))//move west { break; } } }
void keyboard(unsigned char key, int x, int y) { switch(key){ case 'w': moveInDirection(1); break; case 'a': if(theta < 2*PI){ theta = theta + turnSpeed*PI/180; }else{ theta = 0; } break; case 's': moveInDirection(-1); break; case 'd': if(theta > 0){ theta = theta - turnSpeed*PI/180; }else{ theta = 359*PI/180; } break; case 't': if (!topView) { glLoadIdentity(); gluLookAt(0.0, 0.0, 15.0, 0.0, 0.0, 9.0, 0.0, 1.0, 0.0); topView = 1; } else { topView = 0; } break; case 27: // exit if esc is pushed exit(0); break; } if (!topView) { glLoadIdentity(); gluLookAt(eyeX,eyeY,eyeZ,eyeX + cos(theta),eyeY + sin(theta),lookZ,0.0,0.0,1.0); } glutPostRedisplay(); }
bool Noble::moveTowardEnemy() { int range; if(castle->dx > castle->dy) range = castle->dx; else range = castle->dy; for(int i = 1; i< range;i++) { for(int ns = getX()-i;ns <= getX()+i; ns++) //check north and south sides of square in range { if(castle->isInBounds(getY()-i,ns) && cellPtr[getY()-i][ns]->type=="Villager") { return moveInDirection(getX(),getY()-1); } if(castle->isInBounds(getY()+i,ns) && cellPtr[getY()+i][ns]->type=="Villager") { return moveInDirection(getX(),getY()+1); } } for(int ew = getY()-i; ew <= getY()+i; ew++) //check east and west sides of square in range { if(castle->isInBounds(ew,getX()+i) && cellPtr[ew][getX()+i]->type=="Villager") { return moveInDirection(getX()+1,getY()); } if(castle->isInBounds(ew,getX()-i) && cellPtr[ew][getX()-i]->type=="Villager") { return moveInDirection(getX()-1,getY()); } } } return false; }
int main(int argc, const char * argv[]) { PathSegment *path = GenerateAdventure(); PrintPath(path); bool playing = true; char input[300]; int inputNumber; Player player; player.name = GetPlayerName(); Direction direction; while (playing) { PathSegment segment; player.health = 80; player.wealth = 100; player.currentPathSegment = path; printf("%s:Your health is %d\n, Your wealth is %d\n",player.name,player.health,player.wealth); printf("Please enter a direction: 0 for straight 1 for right and 2 for left\n"); scanf("%d",&direction); moveInDirection(&player, direction); printf("Your distance travelled is %d",player.distanceTraveled); if(player.health >= 100 || player.health <= 0) { printf("Game over"); break; } } FreeAllPathSegments(path); return 0; }
void Steering::update() { if (mSteeringEnabled) { if (mUpdateNeeded) { updatePath(); } auto entity = mAvatar.getEntity(); if (!mPath.empty()) { const auto& finalDestination = mPath.back(); auto entity3dPosition = entity->getViewPosition(); const WFMath::Point<2> entityPosition(entity3dPosition.x(), entity3dPosition.z()); //First check if we've arrived at our actual destination. if (WFMath::Distance(WFMath::Point<2>(finalDestination.x(), finalDestination.z()), entityPosition) < 0.1f) { //We've arrived at our destination. If we're moving we should stop. if (mLastSentVelocity.isValid() && mLastSentVelocity != WFMath::Vector<2>::ZERO()) { moveInDirection(WFMath::Vector<2>::ZERO()); } stopSteering(); } else { //We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot. WFMath::Point<2> nextWaypoint(mPath.front().x(), mPath.front().z()); if (WFMath::Distance(nextWaypoint, entityPosition) < 0.1f) { mPath.pop_front(); nextWaypoint = WFMath::Point<2>(mPath.front().x(), mPath.front().z()); } WFMath::Vector<2> velocity = nextWaypoint - entityPosition; WFMath::Point<2> destination; velocity.normalize(); if (mPath.size() == 1) { //if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived. //otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back destination = nextWaypoint; } //Check if we need to divert in order to avoid colliding. WFMath::Vector<2> newVelocity; bool avoiding = mAwareness.avoidObstacles(entityPosition, velocity * mSpeed, newVelocity); if (avoiding) { auto newMag = newVelocity.mag(); auto relativeMag = mSpeed / newMag; velocity = newVelocity; velocity.normalize(); velocity *= relativeMag; mUpdateNeeded = true; } bool shouldSend = false; if (velocity.isValid()) { if (mLastSentVelocity.isValid()) { //If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving. if (!entity->isMoving() && !mExpectingServerMovement) { shouldSend = true; } else { auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x()); auto newTheta = std::atan2(velocity.y(), velocity.x()); //If we divert too much from where we need to go we must adjust. if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) { shouldSend = true; } } } else { //If we've never sent a movement update before we should do that now. shouldSend = true; } } if (shouldSend) { //If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination. if (destination.isValid() && !avoiding) { moveToPoint(WFMath::Point<3>(destination.x(), entity3dPosition.y(), destination.y())); } else { moveInDirection(velocity); } } } } else { //We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement. //But we won't stop steering; perhaps we'll find a path later. if (mLastSentVelocity.isValid() && mLastSentVelocity != WFMath::Vector<2>::ZERO()) { moveInDirection(WFMath::Vector<2>::ZERO()); } } } }
void PlayerCharacterEntity::processNextInstruction() { if (m_insList.empty()) { return; } AIInstruction * ins = m_insList.front(); m_insList.pop_front(); switch (ins->m_type) { case AIInstruction::CREATE_ENTITY: { if (m_health < 15) { break; } // check if this tile already has a static entity bool staticAtLocation = this->staticEntityAtLocation(getTileX(), getTileY()); if (staticAtLocation) { // there is already a static entity // if this is an egg type required, move to nearest "empty" tile if ( ins->m_targetType == EGG1 || ins->m_targetType == EGG2 || ins->m_targetType == EGG3 || ins->m_targetType == EGG4 || ins->m_targetType == EGG5 ) { // find nearest empty tile and move there, replace instruction if (goToNearestEmptyTile(ins->m_targetTileX, ins->m_targetTileY)) { // can go to an empty tile AIInstruction * copiedIns = new AIInstruction(*ins); // put CREATE instruction after GOTO at head of list AIInstruction * goToIns = m_insList.front(); m_insList.pop_front(); m_insList.push_front(copiedIns); m_insList.push_front(goToIns); } else { // failed to find a nearby empty tile // forget this instruction for now } } else { // is a weapon/block type // probably not very helpful to move location // so forget this instruction } } else { // there isn't a static entity // if this is an egg, is it a safe enough location? // is this a weapon? if so, check desired spot if (ins->m_targetType == BOMB || ins->m_targetType == BLOCK || ins->m_targetType == MINE || ins->m_targetType == ROCKET_SPIN) { if (ins->m_targetType == BOMB || ins->m_targetType == MINE) { if (!safeLocationToBomb(m_tileX, m_tileY)) { break; } } if (ins->m_targetTileX == m_tileX && ins->m_targetTileY == m_tileY) { createEntity(ins->m_targetType); } } else { // check this location is safe for an egg bool bombOrMineFound = false; for (int i = 0; i < 4; ++i) { int x, y; x = m_tileX; y = m_tileY; switch (i) { case 0: x++; break; case 1: x--; break; case 2: y++; break; case 3: y--; break; } vector<EntityInfo> eiVec = AIGameView::getInstance()->getEntityInfoAtLocation(x, y); vector<EntityInfo>::iterator it; for (it = eiVec.begin(); it != eiVec.end(); ++it) { // even our team's bombs and mines are dangerous to eggs if (it->type == BOMB || it->type == MINE) { bombOrMineFound = true; break; } } if (bombOrMineFound) { break; } } // end for 0..3 if (!bombOrMineFound) { createEntity(ins->m_targetType); } else { // move elsewhere AIInstruction * copy = new AIInstruction(*ins); m_insList.push_front(copy); goNumTilesAway(3); } } } } break; case AIInstruction::GO_TO: { // check for simple 0 or 1 tile movement int xDist, yDist; xDist = m_tileX - ins->m_targetTileX; yDist = m_tileY - ins->m_targetTileY; bool moved = false; if (xDist == 0 && yDist == 0) { // in target tile, close enough to center? if (nearTileCenter()) { // finished this instruction break; } else { // keep moving in current direction DIRECTION dir = static_cast<DIRECTION>(m_currentAnimState - 1); moveInDirection(dir); moved = true; } } // only one tile to go? // check target tile isn't blocked if (Map::getInstance()->staticTileAt(ins->m_targetTileX, ins->m_targetTileY) != Map::EMPTY) { break; } if (xDist == -1 && yDist == 0) { moveInDirection(RIGHT); moved = true; } else if (xDist == 1 && yDist == 0) { moveInDirection(LEFT); moved = true; } else if (xDist == 0 && yDist == 1) { moveInDirection(UP); moved = true; } else if (xDist == 0 && yDist == -1) { moveInDirection(DOWN); moved = true; } if (moved) { // copy instruction AIInstruction * copyIns = new AIInstruction(*ins); m_insList.push_front(copyIns); incAnimFrame(); break; } // there is a multiple tile distance, use path finding // get next tile by pathfinding coord next = getNextTileFromPathfinding(ins->m_targetTileX, ins->m_targetTileY); // did pathfinding work? if (next.first == getTileX() && next.second == getTileY()) { // did not work, or we're already where we want to be } else { // copy instruction AIInstruction * copyIns = new AIInstruction(*ins); m_insList.push_front(copyIns); // add this tile as goto AIInstruction * newIns = new AIInstruction(AIInstruction::GO_TO, 0, getType(), next.first, next.second); m_insList.push_front(newIns); processNextInstruction(); } } break; case AIInstruction::MOVE_FROM_LOCATION: { goNumTilesAway(ins->m_targetAmount); } break; case AIInstruction::WAIT: { int waitAmount = ins->m_targetAmount - 1; if (waitAmount > 0) { AIInstruction * newIns = new AIInstruction(ins->m_type, waitAmount, ins->m_targetType, ins->m_targetTileX, ins->m_targetTileY); m_insList.push_front(newIns); } // else nothing more to do } break; } delete ins; }