Solved

Console based input

Posted on 2001-08-15
22
424 Views
Last Modified: 2010-04-06
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 ??
0
Comment
Question by:bjornborg
  • 9
  • 8
  • 5
22 Comments
 

Author Comment

by:bjornborg
ID: 6389306
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
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389350
To send and receive to and from STDIN and STDOUT, simply use readln and writeln.

readln(MyVariable);

or

writeln('Hello world');
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389361
btw, thanks for the link to www.a-i.com
I think I'll try it =)
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389371
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
 

Author Comment

by:bjornborg
ID: 6389586
Do I then make a loop that looks for input until it receives it, or how could that be handled?

Bjorn
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389620
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
 

Author Comment

by:bjornborg
ID: 6389638
Do I then make a loop that looks for input until it receives it, or how could that be handled?

Bjorn
0
 

Author Comment

by:bjornborg
ID: 6389740
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
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389963
Did you pipe the output to the judge (using the | operator)?
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6389966
myprogram.exe | judge.exe
0
 
LVL 4

Expert Comment

by:DMN
ID: 6393513
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 5

Expert Comment

by:scrapdog
ID: 6393550
Did you include the {$APPTYPE CONSOLE} directive in the Delphi app?
0
 
LVL 4

Expert Comment

by:DMN
ID: 6393644
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
 
LVL 5

Expert Comment

by:scrapdog
ID: 6393653
In that case you can just use "read" and manually search for newlines
0
 
LVL 4

Expert Comment

by:DMN
ID: 6393698
Yep. But for some reason then I try to read something - nothing happens :)
0
 
LVL 4

Expert Comment

by:DMN
ID: 6393701
I mean then I try to read input char by char - I can't do it...
0
 
LVL 5

Expert Comment

by:scrapdog
ID: 6393750
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
 

Author Comment

by:bjornborg
ID: 6394200
I have sent a question to the organisers of the challenge with the last messages to see what they say.
0
 

Author Comment

by:bjornborg
ID: 6403056
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
 

Author Comment

by:bjornborg
ID: 6403300
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
 
LVL 4

Accepted Solution

by:
DMN earned 100 total points
ID: 6403322
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
 

Author Comment

by:bjornborg
ID: 6403351
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

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now