5

Im making a .bat game, and currently when putting in a command the code is

set /p command=

What i want to know is if you can somehow have a time limit for inputting the commands. For example if your fighting a guard, and you haven't put a command in for say 5 seconds, the guard attacks.

This is not something of dire need, I am just wondering more about the limitations im bound to, and i think i know the anawer anyway (the answer being that you cant)

Thanks

Gareth Jones
  • 1,241
  • 4
  • 17
  • 38
  • Not if you are only using batch script. The way to get around this is to have the batch script call a timer program not written in MS batch script. – Mikhail Oct 09 '11 at 04:59
  • See http://stackoverflow.com/questions/299392/how-do-i-create-a-batch-file-timer-to-execute-call-another-batch-throughout-the – Mikhail Oct 09 '11 at 05:01
  • 1
    Seriously? In 2011, you're making a batch file game? – Greg Hewgill Oct 09 '11 at 05:03
  • @Misha How would this work, because its the set /p itself, which stops the program until an input is made, thats the problem, and I lack the skill to make a timer program that would pass the command vir itself as null (which is what the program wants the user to imput) – Gareth Jones Oct 09 '11 at 05:04
  • 1
    @Greg yes i am, and its going well. http://db.tt/WYR7Ok0z feel free to make suggestions. Oh and it will crash after you kill the guard cause its not done – Gareth Jones Oct 09 '11 at 05:05
  • 2
    I give you props for effort. But still, there are likely better programming languages... – Greg Hewgill Oct 09 '11 at 05:06
  • @Greg that there is, but i wanted to make a Zork like game, and since i know bat and its a nice challange – Gareth Jones Oct 09 '11 at 05:07
  • Man, +1 because of the attempt. – Camilo Martin Sep 11 '12 at 00:10
  • @GarethJones I remember my first "programs" were in batch, and it was more or less what got me started into programming, a few years ago. Now I hate batch when I have to deal with it (even simple things are hard, compared to bash for example), but back then I even made some neat graphs and progress bars with ASCII characters and it was so nice when it ran. Even if I wouldn't give it a spin at the moment, did you finish the game? You could link to it maybe, if it's finished. – Camilo Martin Sep 11 '12 at 03:39

4 Answers4

3

It is possible to mix a batch file with something else, for example c#. As .net is installed on almost all windows pc nowadays, that should not be a big problem.

In the example below there is a 3 second delay where the user can enter some input. If nothing is entered, the program continues, but %result% will be empty.

/* 2>NUL
@echo off 
REM cls
set WinDirNet=%WinDir%\Microsoft.NET\Framework
IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
%csc% /nologo /out:"%~0.exe" %0



echo enter some text:

set result=
for /F "tokens=*" %%a in ('"%~0.exe"') do set result=%%a

echo you have entered:%result%




del "%~0.exe"
goto :eof
*/
using System;
using System.Text;
using System.IO;
using System.Threading;

class Program
{
    static void Main (string[] args)
    {
        byte[] buffer=new byte[80];

        using (Stream s = Console.OpenStandardInput ()) {
            ManualResetEvent e=new ManualResetEvent(false);
            s.BeginRead (buffer, 0, buffer.Length, x => e.Set(), null);

            e.WaitOne (3000);
        }

        Console.WriteLine (Encoding.UTF8.GetString (buffer));
    }
}

This way you can program your batch file, and use c# for everything what is not possible in batch files. Note there are several improvements possible to this code.

See How to add a Timeout to Console.ReadLine()? for improvements of the c# code.

(Source of embedded c# code)

Community
  • 1
  • 1
wimh
  • 15,072
  • 6
  • 47
  • 98
3

It can also be done with batch only.

You can create a second thread (in the same window) with start /b.
If this thread wait with set /p for user input, the main thread is not affected.
This sample will wait for 5 seconds for userinput, if the user inputs text it is moved into a file, so the first thread can access it.

@echo off
setlocal EnableDelayedExpansion
if "%1" NEQ "" goto %1

del enter.tmp 2>nul >nul
start /b cmd /c %0 :secondThread

:FirstThread
set n=0
echo Enter Text (5 seconds timeout):

:loop
set /a n+=1
ping -n 2 localhost > nul
if !n! LSS 5 (
    if not exist entER.tmp goto :loop
    < Enter.tmp (
        set /p input=
    )
    echo !input!
) ELSE (
    echo Timeout for input
)

exit /b

:secondThread
set /p var=
> enter.tmp echo !var!
exit /b
jeb
  • 78,592
  • 17
  • 171
  • 225
  • 1
    The problem with this method is that the second thread receives input focus, so to end it MUST read an input. If the first thread continue after 5 seconds and execute another START /B, a third thread will be created, that will receive the input focus (making impossible to terminate the second thread) and so on. – Aacini Oct 16 '11 at 01:15
2

If commands have a unique starting letter, maybe you can consider using the CHOICE command? (Available again in Windows 7)

mousio
  • 10,079
  • 4
  • 34
  • 43
1

Batch file capabilities may be increased with the aid of auxiliary programs, some of wich may be very simple if they are written in assembly language:

@ECHO OFF
(
ECHO A100
ECHO MOV AH,B
ECHO INT 21
ECHO MOV AH,4C
ECHO INT 21
ECHO/
ECHO RCX
ECHO 8
ECHO W
ECHO Q
) | DEBUG CHKKEY.COM

Previous Batch file creates the 8-bytes long CHKKEY.COM auxiliary program that check if a key was pressed and return an ERRORLEVEL of 255 if so, or zero if not. For example:

:waitforkey
echo Waiting for a key to be pressed...
chkkey
if not errorlevel 1 goto waitforkey
echo A key was pressed!

If you have not the DEBUG.COM program, you may get it in the web. This way, to wait for a key for 5 seconds:

for /F "tokens=3 delims=:." %%a in ("%time%") do set /A second=%%c+5
if %second% geq 60 set /A second-=60
:waitforkey
for /F "tokens=3 delims=:." %%a in ("%time%") do if %%c == %second% goto timeexceeded
chkkey
if not errorlevel 1 goto waitforkey
set /P command=

If you change the B value by 1 in MOV AH,B instruction, a key is read and its ASCII code is returned in ERRORLEVEL; this feature allows to read a single keystroke and process it immediately. If the value is 8, the key read is not displayed in the screen; this allows to process any key of the keyboard even function and special keys that return two values: the first one is zero (that identify a special key) and the second one identify the key pressed. For example, F1 key returns 0 and 59.

Aacini
  • 65,180
  • 12
  • 72
  • 108