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 gCycleChatBot & | Get (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 | |
gCycle * | owner_ |
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 |
Definition at line 325 of file gCycle.cpp.
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 }
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 }
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 }
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 }
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 }
REAL gCycleChatBot::timeOnChatAI_ [private] |
short gCycleChatBot::lastTurn_ [private] |
REAL gCycleChatBot::nextTurn_ [private] |
bool gCycleChatBot::turnedRecently_ [private] |
gCycle* gCycleChatBot::owner_ [private] |
WallHug gCycleChatBot::hugLeft_ [private] |
WallHug gCycleChatBot::hugRight_ [private] |
WallHug gCycleChatBot::hugReplacement_ [private] |
a possible replacement candidate for one of the hugged walls
Definition at line 1054 of file gCycle.cpp.