CircularQueueDemo

In the circular queue, the successor of an item at the array limit is added at the index value 1 if it is free. This is achieved by the statement

RearIndex := (RearIndex MOD MAX) + 1;.

We store the current length of the queue in order to simplify the code; it makes it easy to test for a full queue.

program CircularQueueDemo;
  {$APPTYPE CONSOLE}
uses
  SysUtils, Windows;  
const
  NOTE_DURATION = 400;
  MAX = 50;
var
  Note : char;
  Notes : array[1..MAX] of char;
  HeadIndex, RearIndex, QueueLength, iChoice, ErrorCode, Count : integer;
  strChoice, Tune : string;

function NewNote : char;
var
  Letter : char;
begin
  repeat
    write('Please type the letter of your note. ');
    readln(Letter);
    Letter := UpCase(Letter);
  until Letter in ['A'..'H'];
  result := Letter;
end;

procedure Enqueue(LastNote: Char);
begin
  if QueueLength < MAX then
    begin
      RearIndex := (RearIndex MOD MAX) + 1;
      Notes[RearIndex] := LastNote;
      inc(QueueLength);
    end
  else
    writeln('Queue full')
end;

function Dequeue : Char;
begin
  if QueueLength = 0 then
    result := '0' //Queue empty
  else
    begin
      result := Notes[HeadIndex];
      HeadIndex := (HeadIndex MOD Max) + 1;
      dec(QueueLength);
    end;
end;

procedure PlayNote(Note : Char);
begin
    write(Note);
    case Note of
      'A' : windows.Beep(440, NOTE_DURATION);
      'B' : windows.Beep(494, NOTE_DURATION);
      'C' : windows.Beep(523, NOTE_DURATION);
      'D' : windows.Beep(587, NOTE_DURATION);
      'E' : windows.Beep(659, NOTE_DURATION);
      'F' : windows.Beep(698, NOTE_DURATION);
      'G' : windows.Beep(784, NOTE_DURATION);
      'H' : windows.Beep(880, NOTE_DURATION);
    end;
end;

procedure Play;
var
  CurrentNote : Char;
begin
  CurrentNote := Dequeue;
  while  CurrentNote <> '0' do
    begin
      PlayNote(CurrentNote);
      CurrentNote := Dequeue;
    end;
end;

procedure Init;
begin
   HeadIndex := 1;
   RearIndex := MAX;
   QueueLength := 0;
end;

begin
  Init;
  repeat
    repeat
      writeln(#13#10'Would you like to ...');
      writeln('1 - Enqueue a note (A to H, where H is A in the next octave.)');
      writeln('2 - Enqueue a string of notes (A to H)');
      writeln('3 - Dequeue a note');
      writeln('4 - Hear queue of notes (tune?)');
      writeln('5 - Quit');
      readln(strChoice);
      val (strChoice, iChoice, ErrorCode);
    until ErrorCode = 0;
    case iChoice of
      1 : Enqueue(NewNote);
      2 : begin
            write('Enter the string of notes (A to H)');
            readln(Tune);
            Tune := Uppercase(Tune);
            for Count := 1 to length(tune) do
              enqueue(tune[Count]);
          end;
      3 : begin
            PlayNote(Notes[HeadIndex]);
            Note := Dequeue;
            if Note <> '0' then
              writeln(' removed')
            else
              writeln('Queue empty');
          end;
      4 : Play;
    end;
  until iChoice = 5;
end.

Programming - a skill for life!

Demonstrations of queues, circular queues, and linked list queues