gCycleChatBot Class Reference

Collaboration diagram for gCycleChatBot:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 gCycleChatBot (gCycle *owner)
void FindHugReplacement (Sensor const &sensor)
REAL Distance (Sensor const &a, Sensor const &b)
bool CanMakeTurn (uActionPlayer *action)
void Activate (REAL currentTime)

Static Public Member Functions

static gCycleChatBotGet (gCycle *cycle)

Public Attributes

REAL nextChatAI_
 the next time the chat AI can be active

Private Member Functions

 gCycleChatBot ()

Private Attributes

REAL timeOnChatAI_
 the total time the player was on chat AI this round
short lastTurn_
 the last turn the chat AI made
REAL nextTurn_
 the next turn if one is planned
bool turnedRecently_
 whether the cycle was turned or almost turned recently
gCycleowner_
 owner of chatbot
WallHug hugLeft_
 the wall we like to have on our left side
WallHug hugRight_
 the wall we like to have on our right side
WallHug hugReplacement_
 a possible replacement candidate for one of the hugged walls

Classes

class  Sensor
class  WallHug


Detailed Description

Definition at line 325 of file gCycle.cpp.


Constructor & Destructor Documentation

gCycleChatBot::gCycleChatBot (  )  [private]

gCycleChatBot::gCycleChatBot ( gCycle owner  )  [inline]

Definition at line 458 of file gCycle.cpp.

00459             : nextChatAI_( 0 )
00460             , timeOnChatAI_( 0 )
00461             , lastTurn_( 0 )
00462             , nextTurn_ ( 0 )
00463             , turnedRecently_ ( 0 )
00464             , owner_ ( owner )
00465     {
00466     }


Member Function Documentation

void gCycleChatBot::FindHugReplacement ( Sensor const &  sensor  )  [inline]

Definition at line 483 of file gCycle.cpp.

References gSENSOR_SELF, gCycleChatBot::Sensor::hitOwner_, and gSensor::type.

00484     {
00485         gCycle const * owner = sensor.hitOwner_;
00486         if (!owner)
00487             return;
00488 
00489         // store as possible replacement
00490         if ( !hugReplacement_.owner_ && sensor.type != gSENSOR_SELF &&
00491                 owner != hugLeft_.owner_ &&
00492                 owner != hugRight_.owner_ )
00493         {
00494             hugReplacement_.owner_ = sensor.hitOwner_;
00495             hugReplacement_.lastTimeSeen_ = nextChatAI_;
00496         }
00497 
00498         // update timestamps
00499         if ( owner == hugLeft_.owner_ )
00500             hugLeft_.lastTimeSeen_ = nextChatAI_;
00501         if ( owner == hugRight_.owner_ )
00502             hugRight_.lastTimeSeen_ = nextChatAI_;
00503     }

REAL gCycleChatBot::Distance ( Sensor const &  a,
Sensor const &  b 
) [inline]

Definition at line 507 of file gCycle.cpp.

References eSensor::before_hit, eGameObject::Direction(), Distance(), fabsf(), gSENSOR_NONE, gSENSOR_RIM, gSENSOR_SELF, gCycleChatBot::Sensor::hitDistance_, gCycleChatBot::Sensor::hitOwner_, eSensor::lr, REAL, and gSensor::type.

00508     {
00509         // make sure a is left from b
00510         if ( a.Direction() * b.Direction() < 0 )
00511             return Distance( b, a );
00512 
00513         bool self = a.type == gSENSOR_SELF || b.type == gSENSOR_SELF;
00514         bool rim  = a.type == gSENSOR_RIM || b.type == gSENSOR_RIM;
00515 
00516         // avoid. own. walls.
00517         REAL selfHatred = 1;
00518         if ( a.type == gSENSOR_SELF )
00519         {
00520             selfHatred *= .5;
00521             if ( a.lr > 0 )
00522             {
00523                 selfHatred *= .5;
00524                 if ( b.type == gSENSOR_RIM )
00525                     selfHatred *= .25;
00526             }
00527         }
00528         if ( b.type == gSENSOR_SELF )
00529         {
00530             selfHatred *= .5;
00531             if ( b.lr < 0 )
00532             {
00533                 selfHatred *= .5;
00534                 if ( a.type == gSENSOR_RIM )
00535                     selfHatred *= .25;
00536             }
00537         }
00538 
00539         // some big distance to return if we don't know anything better
00540         REAL bigDistance = owner_->MaxWallsLength();
00541         if ( bigDistance <= 0 )
00542             bigDistance = owner_->GetDistance();
00543 
00544         if ( a.hitOwner_ != b.hitOwner_ )
00545         {
00546             // different owners? Great, there has to be a way through!
00547             REAL ret =
00548                 a.hitDistance_ + b.hitDistance_;
00549 
00550             if ( rim )
00551             {
00552                 ret = bigDistance * .001 + ret * .01 + ( a.before_hit - b.before_hit).Norm();
00553 
00554                 // we love going between the rim and enemies
00555                 if ( !self )
00556                     ret = bigDistance * 2;
00557             }
00558 
00559             // minimal factor should be 1, this path should never return something smaller than the
00560             // paths where only one cycle's walls are hit
00561             ret *= 16;
00562 
00563             // or empty space
00564             if ( a.type == gSENSOR_NONE || b.type == gSENSOR_NONE )
00565                 ret *= 2;
00566 
00567             return ret * selfHatred;
00568         }
00569         else if ( rim )
00570         {
00571             // at least one rim wall? Take the distance between the hit positions.
00572             return ( a.before_hit - b.before_hit).Norm() * selfHatred;
00573         }
00574         else if ( a.type == gSENSOR_NONE && b.type == gSENSOR_NONE )
00575         {
00576             // empty space! Woo!
00577             return owner_->GetDistance() * 256;
00578         }
00579         else if ( a.lr != b.lr )
00580         {
00581             // different directions? Also great!
00582             return ( fabsf( a.hitDistance_ - b.hitDistance_ ) + .25 * bigDistance ) * selfHatred;
00583         }
00584         /*
00585         else if ( - 2 * a.lr * (a.windingNumber_ - b.windingNumber_ ) > owner_->Grid()->WindingNumber() )
00586         {
00587             // this looks like a way out to me
00588             return fabsf( a.hitDistance_ - b.hitDistance_ ) * 10 * selfHatred;
00589         }
00590         */
00591         else
00592         {
00593             // well, the longer the wall segment between the two points, the better.
00594             return fabsf( a.hitDistance_ - b.hitDistance_ ) * selfHatred;
00595         }
00596 
00597         // default: hit distance
00598         return ( a.before_hit - b.before_hit).Norm() * selfHatred;
00599     }

Here is the call graph for this function:

static gCycleChatBot& gCycleChatBot::Get ( gCycle cycle  )  [inline, static]

Definition at line 601 of file gCycle.cpp.

References gCycle::chatBot_, and tASSERT.

Referenced by gCycle::Timestep().

00602     {
00603         tASSERT( cycle );
00604 
00605         // create
00606         if ( &(*cycle->chatBot_) == 0 )
00607             cycle->chatBot_ = std::auto_ptr< gCycleChatBot >( new gCycleChatBot( cycle ) );
00608 
00609         return *cycle->chatBot_;
00610     }

Here is the caller graph for this function:

bool gCycleChatBot::CanMakeTurn ( uActionPlayer action  )  [inline]

Definition at line 612 of file gCycle.cpp.

References eGameObject::se_turnRight.

00613     {
00614         return owner_->CanMakeTurn( ( action == &gCycle::se_turnRight ) ? 1 : -1 );
00615     }

void gCycleChatBot::Activate ( REAL  currentTime  )  [inline]

Definition at line 618 of file gCycle.cpp.

References eGameObject::Act(), eSensor::detect(), eGameObject::Direction(), Distance(), eCoord, EPS, tRandomizer::Get(), tReproducibleRandomizer::GetInstance(), gSENSOR_RIM, gSENSOR_SELF, eSensor::hit, gCycleChatBot::Sensor::hitOwner_, gCycleChatBot::Sensor::hitTime_, gCycleChatBot::Sensor::HitWallExtends(), nSTANDALONE, NULL, pos, REAL, gCycle::s_brake, eGameObject::se_turnLeft, eGameObject::se_turnRight, sg_brakeCycle, sg_chatBotDecay, sg_chatBotDelay, sg_chatBotMinTimestep, sg_chatBotRange, sg_cycleBrakeDeplete, sg_enemyChatbotTimePenalty, sg_RubberValues(), sn_GetNetState(), and gCycleChatBot::Sensor::windingNumber_.

Referenced by gCycle::Timestep().

00619     {
00620         // is it already time for activation?
00621         if ( currentTime < nextChatAI_ )
00622             return;
00623 
00624         REAL lookahead = sg_chatBotRange;  // seconds to plan ahead
00625         REAL minstep   = sg_chatBotMinTimestep; // minimum timestep between thoughts in seconds
00626         REAL maxstep   = sg_chatBotMinTimestep * 4 * ( 1 + .1 * tReproducibleRandomizer::GetInstance().Get() );  // maximum timestep between thoughts in seconds
00627 
00628         // chat AI wasn't active yet, so don't start immediately
00629         if ( nextChatAI_ <= EPS )
00630         {
00631             nextChatAI_ = sg_chatBotDelay + currentTime;
00632             return;
00633         }
00634 
00635         timeOnChatAI_ += currentTime - nextChatAI_;
00636 
00637         // cylce data
00638         REAL speed = owner_->Speed();
00639         eCoord dir = owner_->Direction();
00640         eCoord pos = owner_->Position();
00641 
00642         // make chat AI worse over time
00643         if ( sn_GetNetState() != nSTANDALONE )
00644         {
00645             REAL qualityFactor = ( timeOnChatAI_ * sg_chatBotDecay );
00646             if ( qualityFactor > 1 )
00647             {
00648                 minstep *= qualityFactor;
00649                 // maxstep *= qualityFactor;
00650             }
00651         }
00652 
00653         REAL range= speed * lookahead;
00654         eCoord scanDir = dir * range;
00655 
00656         REAL frontFactor = .5;
00657 
00658         Sensor front(owner_,pos,scanDir);
00659         front.detect(frontFactor);
00660         owner_->enemyInfluence.AddSensor( front, sg_enemyChatbotTimePenalty, owner_ );
00661 
00662         REAL minMoveOn = 0, maxMoveOn = 0, moveOn = 0;
00663 
00664         // get extra time we get through rubber usage
00665         REAL rubberGranted, rubberEffectiveness;
00666         sg_RubberValues( owner_->player, speed, rubberGranted, rubberEffectiveness );
00667         REAL rubberTime = ( rubberGranted - owner_->GetRubber() )*rubberEffectiveness/speed;
00668         REAL rubberRatio = owner_->GetRubber()/rubberGranted;
00669 
00670         if ( front.ehit )
00671         {
00672             turnedRecently_ = false;
00673 
00674             // these checks can hit our last wall and fail. Temporarily set it to NULL.
00675             tJUST_CONTROLLED_PTR< gNetPlayerWall > lastWall = owner_->lastWall;
00676             owner_->lastWall = NULL;
00677 
00678             REAL narrowFront = 1;
00679 
00680             // cast four diagonal rays
00681             Sensor forwardLeft ( owner_, pos, scanDir.Turn(+1,+1 ) );
00682             Sensor backwardLeft( owner_, pos, scanDir.Turn(-1,+narrowFront) );
00683             forwardLeft.detect(1);
00684             backwardLeft.detect(1);
00685             Sensor forwardRight ( owner_, pos, scanDir.Turn(+1,-1 ) );
00686             Sensor backwardRight( owner_, pos, scanDir.Turn(-1,-narrowFront) );
00687             forwardRight.detect(1);
00688             backwardRight.detect(1);
00689 
00690             // do we have a hug replacement candiate? If so, take it.
00691             if ( hugReplacement_.owner_ && !hugLeft_.owner_ && !hugRight_.owner_ )
00692             {
00693                 // first time hugging? let the status quo decide.
00694                 int lr = 0;
00695                 if ( backwardLeft.hitOwner_ == hugReplacement_.owner_ )
00696                     lr--;
00697                 if ( forwardLeft.hitOwner_ == hugReplacement_.owner_ )
00698                     lr--;
00699                 if ( backwardRight.hitOwner_ == hugReplacement_.owner_ )
00700                     lr++;
00701                 if ( forwardRight.hitOwner_ == hugReplacement_.owner_ )
00702                     lr++;
00703 
00704                 if ( lr > 0 )
00705                     hugRight_ = hugReplacement_;
00706                 if ( lr < 0 )
00707                     hugLeft_ = hugReplacement_;
00708 
00709                 hugReplacement_.owner_ = 0;
00710             }
00711 
00712             if ( hugReplacement_.owner_ )
00713             {
00714                 if( hugLeft_.lastTimeSeen_ < hugRight_.lastTimeSeen_ )
00715                 {
00716                     if ( hugReplacement_.lastTimeSeen_ > hugLeft_.lastTimeSeen_ )
00717                         hugLeft_ = hugReplacement_;
00718                 }
00719                 else
00720                 {
00721                     if ( hugReplacement_.lastTimeSeen_ > hugRight_.lastTimeSeen_ )
00722                         hugRight_ = hugReplacement_;
00723                 }
00724                 hugReplacement_.owner_ = 0;
00725             }
00726 
00727             FindHugReplacement( front );
00728             FindHugReplacement( forwardLeft );
00729             FindHugReplacement( forwardRight );
00730             FindHugReplacement( backwardLeft );
00731             FindHugReplacement( backwardRight );
00732 
00733             // determine survival chances in the four directions
00734             REAL frontOpen = Distance ( forwardLeft, forwardRight );
00735             REAL leftOpen  = Distance ( forwardLeft, backwardLeft );
00736             REAL rightOpen = Distance ( forwardRight, backwardRight );
00737             REAL rearOpen = Distance ( backwardLeft, backwardRight );
00738 
00739             Sensor self( owner_, pos, scanDir.Turn(-1, 0) );
00740             // fake entries
00741             self.before_hit = pos;
00742             self.windingNumber_ = owner_->windingNumber_;
00743             self.type = gSENSOR_SELF;
00744             self.hitDistance_ = 0;
00745             self.hitOwner_ = owner_;
00746             self.hitTime_ = currentTime;
00747             self.lr = -1;
00748             REAL rearLeftOpen = Distance( backwardLeft, self );
00749             self.lr = 1;
00750             REAL rearRightOpen = Distance( backwardRight, self );
00751 
00752             /*
00753             // override: don't camp (too much)
00754             if ( forwardRight.type == gSENSOR_SELF &&
00755                     forwardLeft.type == gSENSOR_SELF &&
00756                     backwardRight.type == gSENSOR_SELF &&
00757                     backwardLeft.type == gSENSOR_SELF &&
00758                     front.type == gSENSOR_SELF &&
00759                     forwardRight.lr == front.lr &&
00760                     forwardLeft.lr == front.lr &&
00761                     backwardRight.lr == front.lr &&
00762                     backwardLeft.lr == front.lr &&
00763                     frontOpen + leftOpen + rightOpen < owner_->GetDistance() * .5 )
00764             {
00765                 turnedRecently_ = true;
00766                 if ( front.lr > 0 )
00767                 {
00768                     if ( leftOpen > minstep * speed )
00769                         // force a turn to the left
00770                         rightOpen = 0;
00771                     else if ( front.hit * range < 2 * minstep )
00772                         // force a preliminary turn to the right that will allow us to reverse
00773                         frontOpen = 0;
00774                 }
00775                 else
00776                 {
00777                     if ( rightOpen > minstep * speed )
00778                         // force a turn to the right
00779                         leftOpen = 0;
00780                     else if ( front.hit * range < 2 * minstep )
00781                         // force a preliminary turn to the left that will allow us to reverse
00782                         frontOpen = 0;
00783                 }
00784             }
00785             */
00786 
00787             // override rim hugging
00788             if ( forwardRight.type == gSENSOR_SELF &&
00789                     forwardLeft.type == gSENSOR_RIM &&
00790                     backwardRight.type == gSENSOR_SELF &&
00791                     backwardLeft.type == gSENSOR_RIM &&
00792                     // backwardLeft.hit < .1 &&
00793                     forwardRight.lr == -1 &&
00794                     backwardRight.lr == -1 )
00795             {
00796                 turnedRecently_ = true;
00797                 if ( rightOpen > speed * ( owner_->GetTurnDelay() - rubberTime * .8 ) )
00798                 {
00799                     owner_->Act( &gCycle::se_turnRight, 1 );
00800                     owner_->Act( &gCycle::se_turnRight, 1 );
00801                 }
00802                 else
00803                 {
00804                     owner_->Act( &gCycle::se_turnLeft, 1 );
00805                     owner_->Act( &gCycle::se_turnLeft, 1 );
00806                 }
00807             }
00808 
00809             if ( forwardLeft.type == gSENSOR_SELF &&
00810                     forwardRight.type == gSENSOR_RIM &&
00811                     backwardLeft.type == gSENSOR_SELF &&
00812                     backwardRight.type == gSENSOR_RIM &&
00813                     // backwardRight.hit < .1 &&
00814                     forwardLeft.lr == 1 &&
00815                     backwardLeft.lr == 1 )
00816             {
00817                 turnedRecently_ = true;
00818                 if ( leftOpen > speed * ( owner_->GetTurnDelay() - rubberTime * .8 ) )
00819                 {
00820                     owner_->Act( &gCycle::se_turnLeft, 1 );
00821                     owner_->Act( &gCycle::se_turnLeft, 1 );
00822                 }
00823                 else
00824                 {
00825                     owner_->Act( &gCycle::se_turnRight, 1 );
00826                     owner_->Act( &gCycle::se_turnRight, 1 );
00827                 }
00828             }
00829 
00830             // get the best turn direction
00831             uActionPlayer * bestAction = ( leftOpen > rightOpen ) ? &gCycle::se_turnLeft : &gCycle::se_turnRight;
00832             int             bestDir      = ( leftOpen > rightOpen ) ? 1 : -1;
00833             REAL            bestOpen     = ( leftOpen > rightOpen ) ? leftOpen : rightOpen;
00834             Sensor &        bestForward  = ( leftOpen > rightOpen ) ? forwardLeft : forwardRight;
00835             Sensor &        bestBackward = ( leftOpen > rightOpen ) ? backwardLeft : backwardRight;
00836 
00837             Sensor direct ( owner_, pos, scanDir.Turn( 0, bestDir) );
00838             direct.detect( 1 );
00839 
00840             // restore last wall
00841             owner_->lastWall = lastWall;
00842 
00843             // only turn if the hole has a shape that allows better entry after we do a zig-zag, or if we're past the good turning point
00844             // see how the survival chance is distributed between forward and backward half
00845             REAL forwardHalf  = Distance ( direct, bestForward );
00846             REAL backwardHalf = Distance ( direct, bestBackward );
00847 
00848             REAL forwardOverhang  = bestForward.HitWallExtends( bestForward.Direction(), pos );
00849             REAL backwardOverhang  = bestBackward.HitWallExtends( bestForward.Direction(), pos );
00850 
00851             // we have to move forward this much before we can hope to turn
00852             minMoveOn = bestBackward.HitWallExtends( dir, pos );
00853 
00854             // maybe the direct to the side sensor is better?
00855             REAL minMoveOnOther = direct.HitWallExtends( dir, pos );
00856 
00857             // determine how far we can drive on
00858             maxMoveOn      = bestForward.HitWallExtends( dir, pos );
00859             REAL maxMoveOnOther = front.HitWallExtends( dir, pos );
00860             if ( maxMoveOn > maxMoveOnOther )
00861                 maxMoveOn = maxMoveOnOther;
00862 
00863             if ( maxMoveOn > minMoveOnOther && forwardHalf > backwardHalf && direct.hitOwner_ == bestBackward.hitOwner_ )
00864             {
00865                 backwardOverhang  = direct.HitWallExtends( bestForward.Direction(), pos );
00866                 minMoveOn = minMoveOnOther;
00867             }
00868 
00869             // best place to turn
00870             moveOn = .5 * ( minMoveOn * ( 1 + rubberRatio ) + maxMoveOn * ( 1 - rubberRatio ) );
00871 
00872             // hit the brakes before you hit anything and if it's worth it
00873             bool brake = sg_brakeCycle > 0 &&
00874                          front.hit * lookahead * sg_cycleBrakeDeplete < owner_->GetBrakingReservoir() &&
00875                          sg_brakeCycle * front.hit * lookahead < 2 * speed * owner_->GetBrakingReservoir() &&
00876                          ( maxMoveOn - minMoveOn ) > 0 &&
00877                          owner_->GetBrakingReservoir() * ( maxMoveOn - minMoveOn ) < speed * owner_->GetTurnDelay();
00878             if ( frontOpen < bestOpen &&
00879                     ( forwardOverhang <= backwardOverhang || ( minMoveOn < 0 && moveOn < minstep * speed ) ) )
00880             {
00881                 // FindHugReplacement( direct );
00882                 // REAL expectedBackwardHalf = ( direct.before_hit - bestBackward.before_hit ).Norm();
00883 
00884                 // if ( ( ( forwardHalf + backwardHalf > bestOpen * 2 || backwardHalf > frontOpen * 10 || backwardHalf > expectedBackwardHalf * 1.01 ) && frontOpen < bestOpen ) ||
00885                 // rubberTime * .5 + minspace * lookahead < minstep )
00886                 //                {
00887                 turnedRecently_ = true;
00888 
00889                 minMoveOn = maxMoveOn = moveOn = 0;
00890 
00891                 /*
00892                 if (
00893                     ( ( ( bestBackward.type == gSENSOR_ENEMY || bestBackward.type == gSENSOR_TEAMMATE ) && bestBackward.hitDistance_ < bestBackward.hit * lookahead * speed ) ||
00894                       direct.hit * lookahead + rubberTime < owner_->GetTurnDelay() ) &&
00895                     ( bestBackward.hit * lookahead + rubberTime < owner_->GetTurnDelay() ||
00896                       bestForward.hit * lookahead + rubberTime < owner_->GetTurnDelay() )
00897                 )
00898                 {
00899                     // override: stupid turn into certain death, turn it around if that makes it less stupid
00900                     uActionPlayer * newBestAction = ( leftOpen > rightOpen ) ? &gCycle::se_turnLeft : &gCycle::se_turnRight;
00901                     Sensor newDirect ( owner_, pos, scanDir.Turn( 0, -bestDir) );
00902                     newDirect.detect( 1 );
00903                     if ( newDirect.hit > direct.hit ||
00904                             newDirect.hit * lookahead + rubberTime > owner_->GetTurnDelay() )
00905                         owner_->Act( newBestAction, 1 );
00906                 }
00907                 else
00908                 */
00909                 {
00910                     if ( !CanMakeTurn( bestAction ) )
00911                     {
00912                         nextChatAI_ = currentTime;
00913                         return;
00914                     }
00915 
00916                     owner_->Act( bestAction, 1 );
00917                 }
00918 
00919                 brake = false;
00920             }
00921             else
00922             {
00923                 // the best
00924                 REAL bestSoFar = frontOpen > bestOpen ? frontOpen : bestOpen;
00925                 bestSoFar *= ( 10 * ( 1 - rubberRatio ) + 1 );
00926 
00927                 if ( rearOpen > bestSoFar && ( rearLeftOpen > bestSoFar || rearRightOpen > bestSoFar ) )
00928                 {
00929                     brake = false;
00930                     turnedRecently_ = true;
00931 
00932                     bool goLeft = rearLeftOpen > rearRightOpen;
00933 
00934                     // dead end. reverse into the opposite direction of the front wall
00935                     uActionPlayer * bestAction = goLeft ? &gCycle::se_turnLeft : &gCycle::se_turnRight;
00936                     uActionPlayer * otherAction = !goLeft ? &gCycle::se_turnLeft : &gCycle::se_turnRight;
00937                     Sensor &        bestForward  = goLeft ? forwardLeft : forwardRight;
00938                     Sensor &        bestBackward  = goLeft ? backwardLeft : backwardRight;
00939                     Sensor &        otherForward  = !goLeft ? forwardLeft : forwardRight;
00940                     Sensor &        otherBackward  = !goLeft ? backwardLeft : backwardRight;
00941 
00942                     // space in the two directions available for turns
00943                     REAL bestHit = bestForward.hit > bestBackward.hit ? bestBackward.hit : bestForward.hit;
00944                     REAL otherHit = otherForward.hit > otherBackward.hit ? otherBackward.hit : otherForward.hit;
00945 
00946                     bool wait = false;
00947 
00948                     if ( !CanMakeTurn( bestAction ) )
00949                     {
00950                         nextChatAI_ = currentTime;
00951                         return;
00952                     }
00953 
00954                     // well, after a short turn to the right if space is tight
00955                     if ( bestHit * lookahead < owner_->GetTurnDelay() + rubberTime )
00956                     {
00957                         if ( otherHit < bestForward.hit * 2 && front.hit * lookahead > owner_->GetTurnDelay() * 2 )
00958                         {
00959                             // wait a bit, perhaps there will be a better spot
00960                             wait = true;
00961                         }
00962                         else
00963                         {
00964                             if ( !CanMakeTurn( otherAction ) )
00965                             {
00966                                 nextChatAI_ = currentTime;
00967                                 return;
00968                             }
00969 
00970                             owner_->Act( otherAction, 1 );
00971 
00972                             // there needs to be space ahead to finish the maneuver correctly
00973                             if ( maxMoveOn < speed * owner_->GetTurnDelay() )
00974                             {
00975                                 // there isn't. oh well, turn into the wrong direction completely, see if I care
00976                                 owner_->Act( otherAction, 1 );
00977                                 wait = true;
00978                             }
00979                         }
00980                     }
00981 
00982                     if ( !wait )
00983                     {
00984                         owner_->Act( bestAction, 1 );
00985                         owner_->Act( bestAction, 1 );
00986                     }
00987 
00988                     minMoveOn = maxMoveOn = moveOn = 0;
00989                 }
00990             }
00991 
00992             // execute brake command
00993             owner_->Act( &gCycle::s_brake, brake ? 1 : -1 );
00994 
00995             // swap hugged walls if we're in fact grinding them the other way round
00996             if ( hugLeft_.owner_ == backwardRight.hitOwner_ ||
00997                     hugRight_.owner_ == backwardLeft.hitOwner_ )
00998             {
00999                 WallHug swap = hugRight_;
01000                 hugRight_ = hugLeft_;
01001                 hugLeft_ = swap;
01002             }
01003         }
01004 
01005         // REAL mintime = minspace * lookahead;
01006 
01007         // try again soon
01008         //        REAL newmintime = mintime * .5 - minstep * .2 * tReproducibleRandomizer::GetInstance().Get();
01009 
01010         // clamp
01011         // if ( newmintime < minstep )
01012         // newmintime = minstep;
01013 
01014         // add slack, acceleration and rubber
01015         // if ( owner_->acceleration > 0 )
01016         // mintime -= owner_->acceleration * mintime * mintime / speed;
01017         // mintime -= .1 * minstep - rubberTime * .3;
01018 
01019         // if the next step gets us too close to the wall to do anything useful,
01020         // bring us really close right away.
01021         // if ( mintime - newmintime > minstep )
01022         // {
01023         // mintime = newmintime;
01024         // }
01025 
01026         REAL space = moveOn;
01027         REAL minTime = space/speed;
01028 
01029         if ( turnedRecently_ )
01030             minTime = owner_->GetTurnDelay();
01031 
01032         if ( minTime < minstep )
01033             minTime = minstep;
01034         if ( minTime > maxstep + minstep * 1.5 )
01035         {
01036             minTime = maxstep;
01037         }
01038         // minTime = 0;
01039 
01040         nextChatAI_ = currentTime + minTime;
01041         timeOnChatAI_ += minTime;
01042     }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

REAL gCycleChatBot::nextChatAI_

the next time the chat AI can be active

Definition at line 1044 of file gCycle.cpp.

REAL gCycleChatBot::timeOnChatAI_ [private]

the total time the player was on chat AI this round

Definition at line 1046 of file gCycle.cpp.

short gCycleChatBot::lastTurn_ [private]

the last turn the chat AI made

Definition at line 1047 of file gCycle.cpp.

REAL gCycleChatBot::nextTurn_ [private]

the next turn if one is planned

Definition at line 1048 of file gCycle.cpp.

bool gCycleChatBot::turnedRecently_ [private]

whether the cycle was turned or almost turned recently

Definition at line 1049 of file gCycle.cpp.

gCycle* gCycleChatBot::owner_ [private]

owner of chatbot

Definition at line 1050 of file gCycle.cpp.

WallHug gCycleChatBot::hugLeft_ [private]

the wall we like to have on our left side

Definition at line 1052 of file gCycle.cpp.

WallHug gCycleChatBot::hugRight_ [private]

the wall we like to have on our right side

Definition at line 1053 of file gCycle.cpp.

WallHug gCycleChatBot::hugReplacement_ [private]

a possible replacement candidate for one of the hugged walls

Definition at line 1054 of file gCycle.cpp.


The documentation for this class was generated from the following file:
Generated on Sat Mar 15 23:36:20 2008 for Armagetron Advanced by  doxygen 1.5.4