0

So i want to create typing text for a Turn Based RPG (in batch), where you have a person controlling almost everything that interacts with the players. I want it so when everyone's turn is over, it will display what everyone did, but in a dramatic way. Now some of us know

for %%i in (h e l l o) do (set /p a=%%i<nul & ping 0.0.0.0 -n 2.5>nul 2>&1)

but I want to have a variable do this using set /p Write=<Write.txt so i can have something like for %%i in (%write%) do (set /p a=%%i<nul & ping 0.0.0.0 -n 2.5>nul 2>&1) to make it write one letter at a time.

Thanks!

face5054
  • 25
  • 6
  • 2
    On a totally unrelated note, you can only use integers for the `-n` option of ping, because it's a count of how many times to run ping, not how many seconds to pause. – SomethingDark Oct 16 '15 at 04:20
  • @SomethingDark Yeah, I guess i knew that already, but it was just from another post, and it seemed delayed enough, so i thought it was legit. – face5054 Oct 17 '15 at 05:00

4 Answers4

1

The Batch file below use an interesting trick I borrowed from this post that convert the Ascii (1-byte) characters into Unicode 2-bytes characters via /U switch of cmd.exe (inserting a zero-byte between characters), and then split the zero-bytes in individual lines via find command:

@echo off
setlocal

echo Hello, World!> Write.txt

for /F %%a in ('echo prompt $H^| cmd') do set "BS=%%a"

for /F "delims=" %%i in ('cmd /D /U /C type Write.txt ^| find /V ""') do (
   set /P "=X%BS%%%i" < NUL
   ping localhost -n 2 > NUL
)

EDIT: New version added

I modified previous code to show several lines in the right way; it also use JScript's sleep method in order to use variable delay intervals between each character, this point results in an output appearing in a more dramatic way.

@if (@CodeSection == @Batch) @then


@echo off

(
echo Hello, World!
echo The World is ending!
) > Write.txt

for /F %%a in ('echo prompt $H^| cmd') do set "BS=%%a"

for /F "delims=" %%a in (Write.txt) do (
   for /F "delims=" %%i in ('cmd /D /U /C set /P "=%%a"^<NUL ^| find /V ""') do (
      set /P "=X%BS%%%i" < NUL
      REM ping localhost -n 3 > NUL
      cscript //nologo //E:JScript "%~F0"
   )
   echo/
)
goto :EOF


@end


// JScript section: wait a random number of milliseconds between 0 and 300
WScript.Sleep(300*Math.random());
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Can your code be changed so that if the text file has multiple lines it will output onto multiple lines on the screen. When I put two lines into a file it output as one. Hello, World!The World is ending! – Squashman Oct 16 '15 at 20:19
  • I'm a newbie at this corner of coding, but why, if you put code above `@if (@CodeSection == @Batch) @then` is results in `(1, 6) Microsoft JScript compilation error: Expected ';'`? – face5054 Oct 18 '15 at 05:03
  • 1
    @face5054: This is a script that contain both Batch and JScript code (hybrid script). The first line is used to omit the Batch section so the JScript compiler does not mark errors on it. Further details at http://stackoverflow.com/questions/15167742/execute-wshshell-command-from-a-batch-script/15176096#15176096 – Aacini Oct 18 '15 at 15:17
1

This is a version of Ghost typer that uses a variable, to display text on a screen in a way that a person might type it.

@echo off
:: Ghost typer - variable version

:: shows text in a variable on the screen in a way that a person might type it.
:: Do not use " in the text to be printed, replace them with '

:: Adjust speed variable - higher numbers increase typing speed - default=3
set speed=6

:: backspace variable is used in the printing routine
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"

set "line=Your dog was eaten by a red winged dragon!"
call :begin
set "line=Two sloths ate all your chocolate!"
call :begin
set "line=A genie appears, and grants you 4 wishes...."
call :begin
set "line=How many woodchucks does it take?"
call :begin


pause>nul
goto :EOF

:begin
set num=0
:type
call set "letter=%%line:~%num%,1%%"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul

for /L %%b in (1,%speed%,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type
foxidrive
  • 40,353
  • 10
  • 53
  • 68
0

To print the characters one by one of an arbitrary string, you could use the following:

@echo off

rem define string to print:
set "WRITE=Hello world!"

setlocal EnableDelayedExpansion

for /L %%I in (0,1,8191) do (
    set "CHAR=!WRITE:~%%I,1!"
    rem if "!WRITE:~%%I,2!"=="!CHAR! " set "CHAR=!CHAR! "
    if "!CHAR!"=="" goto :SKIP
    < nul set /P "DUMMY=!CHAR!"
    > nul 2>&1 ping 127.0.0.1 -n 2
)
:SKIP

endlocal

As you will notice, the SPACE within the string in WRITE is not printed, because set /P does not print any (leading) spaces in the prompt string. To work around this, remove the rem in front of the if inside of the for loop. Actually this previews the next character and appends it to the current one in case it is a space, as set /P prints trailing spaces.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
0
@echo off
setlocal enabledelayedexpansion

for /f %%A in ('"prompt $H &echo on &for %%B in (1) do rem"') do set BS=%%A

set /P string=<write.txt
call :StrLen "%string%" _len1

for /L %%A in (0,1,%_len1%) do (
   set "substring=!string:~%%A,1!"
   set /p "=.%BS%!substring!" <nul
   > nul 2>&1 ping 127.0.0.1 -n 1
)
echo.
pause
GOTO :EOF

REM Subroutine to return the length of a string variable
:StrLen [string] [len-var]
  set "_str=A%~1" & set "_len=0"
  for /L %%A in (12,-1,0) do (set /a "_len|=1<<%%A" & for %%B in (!_len!) do if "!_str:~%%B,1!"=="" set /a "_len&=~1<<%%A")
  set /a %~2=%_len%
  exit /b
Squashman
  • 13,649
  • 5
  • 27
  • 36