public void clearState()
        {
            hasCarLeft  = false;
            hasCarRight = false;
            timeWhenChannelShouldBeClosed = DateTime.Now;
            channelLeftOpenTimerStarted   = false;
            nextMessageType           = NextMessageType.none;
            this.reportedOverlapLeft  = false;
            this.reportedOverlapRight = false;

            previousPositionAndVelocityData.Clear();
        }
Beispiel #2
0
 public void clearState()
 {
     hasCarLeft  = false;
     hasCarRight = false;
     timeWhenChannelShouldBeClosed = DateTime.Now;
     channelLeftOpenTimerStarted   = false;
     nextMessageType           = NextMessageType.none;
     timeToStartSpotting       = DateTime.Now;
     this.reportedOverlapLeft  = false;
     this.reportedOverlapRight = false;
     lastKnownOpponentState.Clear();
     lastKnownOpponentStateUseCounter.Clear();
     audioPlayer.closeChannel();
 }
Beispiel #3
0
 private void getNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
 {
     if (carsOnLeftCount == 0 && carsOnRightCount == 0 && hasCarLeft && hasCarRight)
     {
         Console.WriteLine("clear all round");
         nextMessageType = NextMessageType.clearAllRound;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount == 0 && hasCarLeft && ((carsOnRightCount == 0 && !hasCarRight) || (carsOnRightCount > 0 && hasCarRight)))
     {
         Console.WriteLine("clear left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the left - might still be a car right
         nextMessageType = NextMessageType.clearLeft;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnRightCount == 0 && hasCarRight && ((carsOnLeftCount == 0 && !hasCarLeft) || (carsOnLeftCount > 0 && hasCarLeft)))
     {
         Console.WriteLine("clear right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the right - might still be a car left
         nextMessageType = NextMessageType.clearRight;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount > 0 && (!hasCarLeft || !hasCarRight))
     {
         // new 'in the middle'
         Console.WriteLine("3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.threeWide;
         nextMessageDue  = now;
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount == 0 && !hasCarLeft && !hasCarRight)
     {
         Console.WriteLine("car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.carLeft;
         nextMessageDue  = now;
     }
     else if (carsOnLeftCount == 0 && carsOnRightCount > 0 && !hasCarLeft && !hasCarRight)
     {
         Console.WriteLine("car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.carRight;
         nextMessageDue  = now;
     }
 }
 private Boolean messageIsValid(NextMessageType nextMessageType, int carsOnLeftCount, int carsOnRightCount)
 {
     if (nextMessageType == NextMessageType.carLeft && carsOnLeftCount == 0)
     {
         return(false);
     }
     if (nextMessageType == NextMessageType.carRight && carsOnRightCount == 0)
     {
         return(false);
     }
     if (nextMessageType == NextMessageType.threeWide && (carsOnRightCount == 0 || carsOnLeftCount == 0))
     {
         return(false);
     }
     if (nextMessageType == NextMessageType.stillThere && carsOnRightCount == 0 && carsOnLeftCount == 0)
     {
         return(false);
     }
     return(true);
 }
        private void playNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
        {
            if (nextMessageType != NextMessageType.none && now > nextMessageDue)
            {
                if (messageIsValid(nextMessageType, carsOnLeftCount, carsOnRightCount))
                {
                    switch (nextMessageType)
                    {
                    case NextMessageType.threeWide:
                        audioPlayer.removeImmediateMessages(new String[] { folderStillThere, folderCarLeft, folderCarRight, folderClearAllRound, folderClearLeft, folderClearRight });
                        QueuedMessage inTheMiddleMessage = new QueuedMessage(folderInTheMiddle, 0, null);
                        inTheMiddleMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + inTheMiddleMessageExpiresAfter;
                        audioPlayer.playSpotterMessage(inTheMiddleMessage, true);
                        nextMessageType      = NextMessageType.stillThere;
                        nextMessageDue       = now.Add(repeatHoldFrequency);
                        reportedOverlapLeft  = true;
                        reportedOverlapRight = true;
                        wasInMiddle          = true;
                        break;

                    case NextMessageType.carLeft:
                        audioPlayer.removeImmediateMessages(new String[] { folderStillThere, folderInTheMiddle, folderCarRight, folderClearAllRound, folderClearLeft, folderClearRight });
                        QueuedMessage carLeftMessage = new QueuedMessage(folderCarLeft, 0, null);
                        carLeftMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                        audioPlayer.playSpotterMessage(carLeftMessage, true);
                        nextMessageType     = NextMessageType.stillThere;
                        nextMessageDue      = now.Add(repeatHoldFrequency);
                        reportedOverlapLeft = true;
                        break;

                    case NextMessageType.carRight:
                        audioPlayer.removeImmediateMessages(new String[] { folderStillThere, folderCarLeft, folderInTheMiddle, folderClearAllRound, folderClearLeft, folderClearRight });
                        QueuedMessage carRightMessage = new QueuedMessage(folderCarRight, 0, null);
                        carRightMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                        audioPlayer.playSpotterMessage(carRightMessage, true);
                        nextMessageType      = NextMessageType.stillThere;
                        nextMessageDue       = now.Add(repeatHoldFrequency);
                        reportedOverlapRight = true;
                        break;

                    case NextMessageType.clearAllRound:
                        if (reportedOverlapLeft || reportedOverlapRight)
                        {
                            QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                            clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearAllRoundMessageExpiresAfter;
                            audioPlayer.removeImmediateMessages(new String[] { folderCarLeft, folderStillThere, folderCarRight, folderInTheMiddle, folderClearLeft, folderClearRight });
                            audioPlayer.playSpotterMessage(clearAllRoundMessage, false);
                            nextMessageType = NextMessageType.none;
                        }

                        reportedOverlapLeft  = false;
                        reportedOverlapRight = false;
                        wasInMiddle          = false;
                        break;

                    case NextMessageType.clearLeft:
                        if (reportedOverlapLeft)
                        {
                            if (carsOnRightCount == 0 && wasInMiddle)
                            {
                                QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                                clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                                audioPlayer.removeImmediateMessages(new String[] { folderCarLeft, folderStillThere, folderCarRight, folderInTheMiddle, folderClearRight, folderClearLeft });
                                audioPlayer.playSpotterMessage(clearAllRoundMessage, false);
                                nextMessageType = NextMessageType.none;

                                reportedOverlapRight = false;
                                wasInMiddle          = false;
                            }
                            else
                            {
                                QueuedMessage clearLeftMessage = new QueuedMessage(folderClearLeft, 0, null);
                                clearLeftMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                                audioPlayer.removeImmediateMessages(new String[] { folderCarLeft, folderStillThere, folderCarRight, folderInTheMiddle, folderClearRight, folderClearAllRound });
                                if (wasInMiddle)
                                {
                                    audioPlayer.playSpotterMessage(clearLeftMessage, true);
                                    nextMessageType = NextMessageType.carRight;
                                    nextMessageDue  = now.Add(repeatHoldFrequency);
                                }
                                else
                                {
                                    audioPlayer.playSpotterMessage(clearLeftMessage, false);
                                    nextMessageType = NextMessageType.none;
                                }
                            }
                        }
                        reportedOverlapLeft = false;
                        break;

                    case NextMessageType.clearRight:
                        if (reportedOverlapRight)
                        {
                            if (carsOnLeftCount == 0 && wasInMiddle)
                            {
                                QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                                clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                                audioPlayer.removeImmediateMessages(new String[] { folderCarLeft, folderStillThere, folderCarRight, folderInTheMiddle, folderClearLeft, folderClearRight });
                                audioPlayer.playSpotterMessage(clearAllRoundMessage, false);
                                nextMessageType = NextMessageType.none;

                                reportedOverlapLeft = false;
                                wasInMiddle         = false;
                            }
                            else
                            {
                                QueuedMessage clearRightMessage = new QueuedMessage(folderClearRight, 0, null);
                                clearRightMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                                audioPlayer.removeImmediateMessages(new String[] { folderCarLeft, folderStillThere, folderCarRight, folderInTheMiddle, folderClearLeft, folderClearAllRound });
                                if (wasInMiddle)
                                {
                                    audioPlayer.playSpotterMessage(clearRightMessage, true);
                                    nextMessageType = NextMessageType.carLeft;
                                    nextMessageDue  = now.Add(repeatHoldFrequency);
                                }
                                else
                                {
                                    audioPlayer.playSpotterMessage(clearRightMessage, false);
                                    nextMessageType = NextMessageType.none;
                                }
                            }
                        }
                        reportedOverlapRight = false;
                        break;

                    case NextMessageType.stillThere:
                        if (reportedOverlapLeft || reportedOverlapRight)
                        {
                            QueuedMessage holdYourLineMessage = new QueuedMessage(folderStillThere, 0, null);
                            holdYourLineMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                            audioPlayer.removeImmediateMessages(new String[] { folderClearRight, folderClearLeft, folderClearAllRound });
                            audioPlayer.playSpotterMessage(holdYourLineMessage, true);
                            nextMessageType = NextMessageType.stillThere;
                            nextMessageDue  = now.Add(repeatHoldFrequency);
                        }
                        break;

                    case NextMessageType.none:
                        break;
                    }
                }
                else
                {
                    reportedOverlapLeft  = false;
                    reportedOverlapRight = false;
                }
            }
        }
 private void getNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
 {
     if (carsOnLeftCount == 0 && carsOnRightCount == 0 && hasCarLeft && hasCarRight)
     {
         Console.WriteLine("clear all round");
         nextMessageType = NextMessageType.clearAllRound;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount == 0 && hasCarLeft && ((carsOnRightCount == 0 && !hasCarRight) || (carsOnRightCount > 0 && hasCarRight)))
     {
         Console.WriteLine("clear left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the left - might still be a car right
         nextMessageType = NextMessageType.clearLeft;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnRightCount == 0 && hasCarRight && ((carsOnLeftCount == 0 && !hasCarLeft) || (carsOnLeftCount > 0 && hasCarLeft)))
     {
         Console.WriteLine("clear right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the right - might still be a car left
         nextMessageType = NextMessageType.clearRight;
         nextMessageDue  = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount > 0 && (!hasCarLeft || !hasCarRight))
     {
         // new 'in the middle'
         // if there's a 'pending clear' at this point (that is, we would have said "clear" but the delay time isn't up yet), then we're
         // still in overlap-mode so don't want to say this immediately
         if (reportedOverlapLeft && reportedOverlapRight)
         {
             Console.WriteLine("Delayed 3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.threeWide;
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount == 0 && !hasCarLeft && !hasCarRight)
     {
         // if there's a 'pending clear' at this point (that is, we would have said "clear" but the delay time isn't up yet), then we're
         // still in overlap-mode so don't want to say this immediately
         if (reportedOverlapLeft)
         {
             Console.WriteLine("Delayed car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("Car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.carLeft;
     }
     else if (carsOnLeftCount == 0 && carsOnRightCount > 0 && !hasCarLeft && !hasCarRight)
     {
         if (reportedOverlapRight)
         {
             Console.WriteLine("Delayed car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("Car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.carRight;
     }
 }
 public void clearState()
 {
     hasCarLeft = false;
     hasCarRight = false;
     timeWhenChannelShouldBeClosed = DateTime.Now;
     channelLeftOpenTimerStarted = false;
     nextMessageType = NextMessageType.none;
     this.reportedOverlapLeft = false;
     this.reportedOverlapRight = false;
     lastKnownOpponentState.Clear();
     lastKnownOpponentStateUseCounter.Clear();
     audioPlayer.closeChannel();
 }
 private void playNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
 {
     if (nextMessageType != NextMessageType.none && now > nextMessageDue)
     {
         if (messageIsValid(nextMessageType, carsOnLeftCount, carsOnRightCount))
         {
             switch (nextMessageType)
             {
                 case NextMessageType.threeWide:
                     audioPlayer.removeImmediateClip(folderStillThere);
                     audioPlayer.removeImmediateClip(folderCarLeft);
                     audioPlayer.removeImmediateClip(folderCarRight);
                     audioPlayer.removeImmediateClip(folderClearAllRound);
                     audioPlayer.removeImmediateClip(folderClearLeft);
                     audioPlayer.removeImmediateClip(folderClearRight);
                     QueuedMessage inTheMiddleMessage = new QueuedMessage(folderInTheMiddle, 0, null);
                     inTheMiddleMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + inTheMiddleMessageExpiresAfter;
                     audioPlayer.playClipImmediately(inTheMiddleMessage, true, true);
                     nextMessageType = NextMessageType.stillThere;
                     nextMessageDue = now.Add(repeatHoldFrequency);
                     reportedOverlapLeft = true;
                     reportedOverlapRight = true;
                     wasInMiddle = true;
                     break;
                 case NextMessageType.carLeft:
                     audioPlayer.removeImmediateClip(folderStillThere);
                     audioPlayer.removeImmediateClip(folderInTheMiddle);
                     audioPlayer.removeImmediateClip(folderCarRight);
                     audioPlayer.removeImmediateClip(folderClearAllRound);
                     audioPlayer.removeImmediateClip(folderClearLeft);
                     audioPlayer.removeImmediateClip(folderClearRight);
                     QueuedMessage carLeftMessage = new QueuedMessage(folderCarLeft, 0, null);
                     carLeftMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                     audioPlayer.playClipImmediately(carLeftMessage, true, true);
                     nextMessageType = NextMessageType.stillThere;
                     nextMessageDue = now.Add(repeatHoldFrequency);
                     reportedOverlapLeft = true;
                     break;
                 case NextMessageType.carRight:
                     audioPlayer.removeImmediateClip(folderStillThere);
                     audioPlayer.removeImmediateClip(folderCarLeft);
                     audioPlayer.removeImmediateClip(folderInTheMiddle);
                     audioPlayer.removeImmediateClip(folderClearAllRound);
                     audioPlayer.removeImmediateClip(folderClearLeft);
                     audioPlayer.removeImmediateClip(folderClearRight);
                     QueuedMessage carRightMessage = new QueuedMessage(folderCarRight, 0, null);
                     carRightMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                     audioPlayer.playClipImmediately(carRightMessage, true, true);
                     nextMessageType = NextMessageType.stillThere;
                     nextMessageDue = now.Add(repeatHoldFrequency);
                     reportedOverlapRight = true;
                     break;
                 case NextMessageType.clearAllRound:
                     if (reportedOverlapLeft || reportedOverlapRight)
                     {
                         QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                         clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearAllRoundMessageExpiresAfter;
                         audioPlayer.removeImmediateClip(folderCarLeft);
                         audioPlayer.removeImmediateClip(folderStillThere);
                         audioPlayer.removeImmediateClip(folderCarRight);
                         audioPlayer.removeImmediateClip(folderInTheMiddle);
                         audioPlayer.removeImmediateClip(folderClearLeft);
                         audioPlayer.removeImmediateClip(folderClearRight);
                         audioPlayer.playClipImmediately(clearAllRoundMessage, false);
                         nextMessageType = NextMessageType.none;
                     }
                     audioPlayer.closeChannel();
                     reportedOverlapLeft = false;
                     reportedOverlapRight = false;
                     wasInMiddle = false;
                     break;
                 case NextMessageType.clearLeft:
                     if (reportedOverlapLeft)
                     {
                         if (carsOnRightCount == 0 && wasInMiddle)
                         {
                             QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                             clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                             audioPlayer.removeImmediateClip(folderCarLeft);
                             audioPlayer.removeImmediateClip(folderStillThere);
                             audioPlayer.removeImmediateClip(folderCarRight);
                             audioPlayer.removeImmediateClip(folderInTheMiddle);
                             audioPlayer.removeImmediateClip(folderClearRight);
                             audioPlayer.removeImmediateClip(folderClearLeft);
                             audioPlayer.playClipImmediately(clearAllRoundMessage, false);
                             nextMessageType = NextMessageType.none;
                             audioPlayer.closeChannel();
                             reportedOverlapRight = false;
                             wasInMiddle = false;
                         }
                         else
                         {
                             QueuedMessage clearLeftMessage = new QueuedMessage(folderClearLeft, 0, null);
                             clearLeftMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                             audioPlayer.removeImmediateClip(folderCarLeft);
                             audioPlayer.removeImmediateClip(folderStillThere);
                             audioPlayer.removeImmediateClip(folderCarRight);
                             audioPlayer.removeImmediateClip(folderInTheMiddle);
                             audioPlayer.removeImmediateClip(folderClearRight);
                             audioPlayer.removeImmediateClip(folderClearAllRound);
                             audioPlayer.playClipImmediately(clearLeftMessage, false);
                             if (wasInMiddle)
                             {
                                 nextMessageType = NextMessageType.carRight;
                                 nextMessageDue = now.Add(repeatHoldFrequency);
                             }
                             else
                             {
                                 nextMessageType = NextMessageType.none;
                             }
                         }
                     }
                     if (carsOnRightCount == 0)
                     {
                         audioPlayer.closeChannel();
                     }
                     reportedOverlapLeft = false;
                     break;
                 case NextMessageType.clearRight:
                     if (reportedOverlapRight)
                     {
                         if (carsOnLeftCount == 0 && wasInMiddle)
                         {
                             QueuedMessage clearAllRoundMessage = new QueuedMessage(folderClearAllRound, 0, null);
                             clearAllRoundMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                             audioPlayer.removeImmediateClip(folderCarLeft);
                             audioPlayer.removeImmediateClip(folderStillThere);
                             audioPlayer.removeImmediateClip(folderCarRight);
                             audioPlayer.removeImmediateClip(folderInTheMiddle);
                             audioPlayer.removeImmediateClip(folderClearLeft);
                             audioPlayer.removeImmediateClip(folderClearRight);
                             audioPlayer.playClipImmediately(clearAllRoundMessage, false);
                             nextMessageType = NextMessageType.none;
                             audioPlayer.closeChannel();
                             reportedOverlapLeft = false;
                             wasInMiddle = false;
                         }
                         else
                         {
                             QueuedMessage clearRightMessage = new QueuedMessage(folderClearRight, 0, null);
                             clearRightMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + clearMessageExpiresAfter;
                             audioPlayer.removeImmediateClip(folderCarLeft);
                             audioPlayer.removeImmediateClip(folderStillThere);
                             audioPlayer.removeImmediateClip(folderCarRight);
                             audioPlayer.removeImmediateClip(folderInTheMiddle);
                             audioPlayer.removeImmediateClip(folderClearLeft);
                             audioPlayer.removeImmediateClip(folderClearAllRound);
                             audioPlayer.playClipImmediately(clearRightMessage, false);
                             if (wasInMiddle)
                             {
                                 nextMessageType = NextMessageType.carLeft;
                                 nextMessageDue = now.Add(repeatHoldFrequency);
                             }
                             else
                             {
                                 nextMessageType = NextMessageType.none;
                             }
                         }
                     }
                     if (carsOnLeftCount == 0)
                     {
                         audioPlayer.closeChannel();
                     }
                     reportedOverlapRight = false;
                     break;
                 case NextMessageType.stillThere:
                     if (reportedOverlapLeft || reportedOverlapRight)
                     {
                         QueuedMessage holdYourLineMessage = new QueuedMessage(folderStillThere, 0, null);
                         holdYourLineMessage.expiryTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) + holdMessageExpiresAfter;
                         audioPlayer.removeImmediateClip(folderClearRight);
                         audioPlayer.removeImmediateClip(folderClearLeft);
                         audioPlayer.removeImmediateClip(folderClearAllRound);
                         audioPlayer.playClipImmediately(holdYourLineMessage, true, false);
                         nextMessageType = NextMessageType.stillThere;
                         nextMessageDue = now.Add(repeatHoldFrequency);
                     }
                     break;
                 case NextMessageType.none:
                     break;
             }
         }
         else
         {
             audioPlayer.closeChannel();
             reportedOverlapLeft = false;
             reportedOverlapRight = false;
         }
     }
 }
 private Boolean messageIsValid(NextMessageType nextMessageType, int carsOnLeftCount, int carsOnRightCount)
 {
     if (nextMessageType == NextMessageType.carLeft && carsOnLeftCount == 0)
     {
         return false;
     }
     if (nextMessageType == NextMessageType.carRight && carsOnRightCount == 0)
     {
         return false;
     }
     if (nextMessageType == NextMessageType.threeWide && (carsOnRightCount == 0 || carsOnLeftCount == 0))
     {
         return false;
     }
     if (nextMessageType == NextMessageType.stillThere && carsOnRightCount == 0 && carsOnLeftCount == 0)
     {
         return false;
     }
     return true;
 }
 private void getNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
 {
     if (carsOnLeftCount == 0 && carsOnRightCount == 0 && hasCarLeft && hasCarRight)
     {
         Console.WriteLine("clear all round");
         nextMessageType = NextMessageType.clearAllRound;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount == 0 && hasCarLeft && ((carsOnRightCount == 0 && !hasCarRight) || (carsOnRightCount > 0 && hasCarRight)))
     {
         Console.WriteLine("clear left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the left - might still be a car right
         nextMessageType = NextMessageType.clearLeft;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnRightCount == 0 && hasCarRight && ((carsOnLeftCount == 0 && !hasCarLeft) || (carsOnLeftCount > 0 && hasCarLeft)))
     {
         Console.WriteLine("clear right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the right - might still be a car left
         nextMessageType = NextMessageType.clearRight;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount > 0 && (!hasCarLeft || !hasCarRight))
     {
         // new 'in the middle'
         // if there's a 'pending clear' at this point (that is, we would have said "clear" but the delay time isn't up yet), then we're
         // still in overlap-mode so don't want to say this immediately
         if (reportedOverlapLeft && reportedOverlapRight)
         {
             Console.WriteLine("Delayed 3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.threeWide;
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount == 0 && !hasCarLeft && !hasCarRight)
     {
         // if there's a 'pending clear' at this point (that is, we would have said "clear" but the delay time isn't up yet), then we're
         // still in overlap-mode so don't want to say this immediately
         if (reportedOverlapLeft)
         {
             Console.WriteLine("Delayed car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("Car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.carLeft;
     }
     else if (carsOnLeftCount == 0 && carsOnRightCount > 0 && !hasCarLeft && !hasCarRight)
     {
         if (reportedOverlapRight)
         {
             Console.WriteLine("Delayed car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now.Add(repeatHoldFrequency);
         }
         else
         {
             Console.WriteLine("Car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
             nextMessageDue = now;
         }
         nextMessageType = NextMessageType.carRight;
     }
 }
 private void getNextMessage(int carsOnLeftCount, int carsOnRightCount, DateTime now)
 {
     if (carsOnLeftCount == 0 && carsOnRightCount == 0 && hasCarLeft && hasCarRight)
     {
         Console.WriteLine("clear all round");
         nextMessageType = NextMessageType.clearAllRound;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount == 0 && hasCarLeft && ((carsOnRightCount == 0 && !hasCarRight) || (carsOnRightCount > 0 && hasCarRight)))
     {
         Console.WriteLine("clear left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the left - might still be a car right
         nextMessageType = NextMessageType.clearLeft;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnRightCount == 0 && hasCarRight && ((carsOnLeftCount == 0 && !hasCarLeft) || (carsOnLeftCount > 0 && hasCarLeft)))
     {
         Console.WriteLine("clear right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         // just gone clear on the right - might still be a car left
         nextMessageType = NextMessageType.clearRight;
         nextMessageDue = now.Add(clearMessageDelay);
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount > 0 && (!hasCarLeft || !hasCarRight))
     {
         // new 'in the middle'
         Console.WriteLine("3 wide, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.threeWide;
         nextMessageDue = now;
     }
     else if (carsOnLeftCount > 0 && carsOnRightCount == 0 && !hasCarLeft && !hasCarRight)
     {
         Console.WriteLine("car left, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.carLeft;
         nextMessageDue = now;
     }
     else if (carsOnLeftCount == 0 && carsOnRightCount > 0 && !hasCarLeft && !hasCarRight)
     {
         Console.WriteLine("car right, carsOnLeftCount " + carsOnLeftCount + " carsOnRightCount " + carsOnRightCount + " hasCarLeft " + hasCarLeft + " hasCarRight " + hasCarRight);
         nextMessageType = NextMessageType.carRight;
         nextMessageDue = now;
     }
 }