Console based input

I am trying to make a program that will participate in the Learning Machine Game (see: wwww.a-i.com), but am unsure what they mean when they specify that the input will be console based:

"The interface with the judge program is console based.  You receive messages from the judge program on standard input, and you write messages to the judge program on standard output.
TCL isn't involved at all, it just happens that the judge program is written in TCL."

Help ??
bjornborgAsked:
Who is Participating?
 
DMNConnect With a Mentor Commented:
SO! THE PROBLEM WAS REALLY IN OUTPUT FLUSHING!!! HERE BELOW IS WORKING DELPHI RANDOM PLAYER SAMPLE!!!
======================================================
program p1;
{$APPTYPE CONSOLE}
uses
  SysUtils, Classes;

var
  Symbols:TStringList;
  command:string;

procedure out(s:string);
begin
  writeln(s);Flush(Output);
end;

begin
  Symbols := TStringlist.Create;
  Symbols.Duplicates := dupIgnore;
  Symbols.Sorted := True;
  try
    out('@info name p1');
    repeat
      readln(command);
      if pos('@command new',command)=1 then
        Symbols.Clear;
      if pos('@command symbol',command)=1 then
        Symbols.Add(Copy(command,17,length(command)));
      if '@command play'=command then
        out('@output '+Symbols[random(Symbols.Count)]);
    until command='@command exit';
    out('@info exit');
  finally
    Symbols.Free;
  end;
end.
0
 
bjornborgAuthor Commented:
After having written my question I did some searching in the Help files of Delphi, and found that Console is a term that I need to know.

However, my question still stands: How do I receive input and send input to another program using "standard input".

I am expecting to get a message with the following syntax: @command symbol string
0
 
scrapdogCommented:
To send and receive to and from STDIN and STDOUT, simply use readln and writeln.

readln(MyVariable);

or

writeln('Hello world');
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
scrapdogCommented:
btw, thanks for the link to www.a-i.com
I think I'll try it =)
0
 
scrapdogCommented:
A really simple form of a console program:


program Foo;

{$APPTYPE CONSOLE}

var
  Name :string;

begin
   write('Enter your name');
   readln(Name);
   writeln('Hello ', Name);
end.
0
 
bjornborgAuthor Commented:
Do I then make a loop that looks for input until it receives it, or how could that be handled?

Bjorn
0
 
scrapdogCommented:
In this particular problem, I would attack it like this:

repeat
   readln(Command);

   //do something with the command

until Command = '@command exit';


readln "blocks" (i.e. waits) until it the enter key is pressed (more specifically, when a newline character is encountered)

The judge program is going to pipe it's output into your input, so this is all transparent to you.  Just use readln and writeln as if you were interacting with a human user.
0
 
bjornborgAuthor Commented:
Do I then make a loop that looks for input until it receives it, or how could that be handled?

Bjorn
0
 
bjornborgAuthor Commented:
If you do try to make the program which talks to the judge, then please let me know how you manage to communicate.

My little test of what you answered makes it possible to enter and receive data on a DOS window, but the Judge does not seem to get the data.

Bj?rn

0
 
scrapdogCommented:
Did you pipe the output to the judge (using the | operator)?
0
 
scrapdogCommented:
myprogram.exe | judge.exe
0
 
DMNCommented:
Hm. It's really seems to be a problem. For some reason Judge do not work with Delphi app. But when I compile my app with Free Pascal Compiler - all works just fine.
Seems like problem is within delphi Readln procedure realisation... Anybody knows more?
0
 
scrapdogCommented:
Did you include the {$APPTYPE CONSOLE} directive in the Delphi app?
0
 
DMNCommented:
Yes. I thinking about to alternatives:

1. Test why readln does not work.
2. Write my player on Free Pascal.

BTW: If I prepare file command.txt like:
 @command symbol 1
 @command symbol 2
 @command new
 @command play
 @command exit
and run my app from command prompt like

myplayer.exe<command.txt>out.txt

everything work's fine... Seems like Judge uses as linebreak something other than <CR><LF>...

0
 
scrapdogCommented:
In that case you can just use "read" and manually search for newlines
0
 
DMNCommented:
Yep. But for some reason then I try to read something - nothing happens :)
0
 
DMNCommented:
I mean then I try to read input char by char - I can't do it...
0
 
scrapdogCommented:
I don't know exactly how they are going to set up the judge to communicate (through pipes, or some other IPC method), but write, read, writeln, and readln are the simplest ways to read/write to the standard channels.

You could also use BlockRead and BlockWrite or related procedures, but I don't think that they would be necessary.
0
 
bjornborgAuthor Commented:
I have sent a question to the organisers of the challenge with the last messages to see what they say.
0
 
bjornborgAuthor Commented:
Here is the temporary reply that I got:

"I have forwarded these details on to the programmer of the judge program in the hope that he'll be able to help you out.  In the meantime, you might try flushing your output buffer every time you write any output to the judge program.  Let me know if that helps."

I have tried sending an empty string to the output using both

write('@info name BBKM'+#13#10);

writeln('@info name BBKM');

or

  FhStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
  WriteConsole(FhStdOut,PChar(s),Length(s),ulLength,NIL);

0
 
bjornborgAuthor Commented:
Dear Scrapdog, I will give you the points - but I keep this discussion going until we have found the working answer:


Here is my program that hangs until i terminate the application.

//Program listing---------------------//

program BBKLM;

{$APPTYPE CONSOLE}

uses
  SysUtils;


var
 Command : string;
 i : integer;

Function EvaluateInput(Inputcommand : string) : integer;
Begin

  Result := 1;

  writeln('#info ' + Command+' received at NameOfTheGame application');

  if Inputcommand = '@command new' then
  Begin
     writeln('#Ready for new game');
     writeln('@info name NameOfTheGame');
  End;

  if Inputcommand = '@command symbol 5' then
  Begin
     writeln('#OK have got Symbol 5');
  End;

  if Inputcommand = '@command exit' then
  Begin
   writeln('@info exit');
   Result := 0;
  End;

  if Inputcommand = '@command play' then
  Begin
    writeln('@output 1');
  End;
End;


//MAIN PROCEDURE
begin
  i := 1; //Initialize variable
  repeat
    readln(Command);

    If Command <> '' then
    Begin

    End;
  Until i = 0;
  writeln('Finished: i = 0');

end.

//END OF PROGRAM LISTING ----------------//

The program hangs until it it terminated (CTRL+ALT+DELETE)
When it does terminate the Judge program displays the following text:

@command symbol 1
@command symbol 2
@command symbol 3
@command symbol 4
@command symbol 5
@command symbol 1 received
#info @command symbol 1 received at NameOfTheGame application
@command symbol 2 received
#info @command symbol 2 received at NameOfTheGame application
@command symbol 3 received
#info @command symbol 3 received at NameOfTheGame application
@command symbol 4 received
#info @command symbol 4 received at NameOfTheGame application
@command symbol 5 re



//NEW ATTEMPT//
This time I modify the code to be:


      writeln(Command + ' received');
      i := EvaluateInput(Command);
      i := 0; //Just to get out of the hold...

//AND THE RESULT...
is that the application does not keep the control since it terminates by itself, and the Judge immediately displays the message:

@command symbol 1
@command symbol 2
@command symbol 3
@command symbol 4
@command symbol 5
@command symbol 1 received
#info @command symbol 1 received at NameOfTheGame application
Finished: i = 0

-------------------

The question is then:
How do I keep my program in a loop so that it waits for the next command without hanging??




0
 
bjornborgAuthor Commented:
You were right DMN!

I found the Flush command, but the help file was not very useful!

It said:
procedure Flush(var t: Text);

Description
F is a text file variable.

I had no idea that "output" was the variable it was looking for.

Thanks, this answer helped.

(even though I mentioned in the comment above that Scrapdog would get the points, I will give them to DMN.

0
All Courses

From novice to tech pro — start learning today.