I’m trying to create a diamond shape in a batch script, but I’m only able to generate the right half. The left part does not display as expected. Here’s the code I’m using:
@echo off
cls
setlocal enabledelayedexpansion
set "max=10"
for /L %%i in (1,1,%max%) do (
set "line="
set "spaces="
rem Create spaces
for /L %%j in (1,1,%max% - %%i) do set "spaces=!spaces! "
rem Create stars
for /L %%j in (1,1,%%i * 2 - 1) do set "line=!line!*"
echo !spaces!!line!
)
for /L %%i in (%max%,-1,1) do (
set "line="
set "spaces="
rem Create spaces
for /L %%j in (1,1,%max% - %%i) do set "spaces=!spaces! "
rem Create stars
for /L %%j in (1,1,%%i * 2 - 1) do set "line=!line!*"
if %%i lss %max% echo !spaces!!line!
)
endlocal
pause
Batch doesn’t let you do in-line math like you have in the four for
loops. You’ll have to create a separate variable first and then use that instead.
@echo off
cls
setlocal enabledelayedexpansion
set "max=10"
for /L %%i in (1,1,%max%) do (
set "line="
set "spaces="
rem Create spaces
set /a space_max=max-%%i
for /L %%j in (1,1,!space_max!) do set "spaces=!spaces! "
rem Create stars
set /a star_max=%%i*2-1
for /L %%j in (1,1,!star_max!) do set "line=!line!*"
echo !spaces!!line!
)
for /L %%i in (%max%,-1,1) do (
set "line="
set "spaces="
rem Create spaces
set /a space_max=max-%%i
for /L %%j in (1,1,!space_max!) do set "spaces=!spaces! "
rem Create stars
set /a star_max=%%i*2-1
for /L %%j in (1,1,!star_max!) do set "line=!line!*"
if %%i lss %max% echo !spaces!!line!
)
endlocal
pause
A simpler approach is to prebuild some long strings and take what you need via substring modification when you iterate through the diamonds width:
@echo off
Setlocal EnableDelayedExpansion
Set /a max=10
Set "Spaces= "
Set "Spaces=!spaces: = !"
Set "Spaces=!spaces:~0,%max%! "
Set "Char=!spaces: =*!"
For %%_ in ("!max! -1 1" "2 1 !max!")do For /l %%i in (%%~_)Do (
Echo(!Spaces:~-%%i!!Char:~%%i!!Char:~%%i,-1!
)
Pause
Endlocal & goto:eof
The most efficient approach is to use simple instructions and make good use of every instruction to perform the most possible operations. The simplest way to show variable-length strings is via substring expansion. In this solution a single FOR is used to assemble both the spaces string and the indices used in the second part.
@echo off
setlocal EnableDelayedExpansion
set "max=10"
for /L %%i in (1,1,%max%) do (
set "spaces=!spaces! "
set "indices=%%i !indices! %%i"
)
set "indices=%indices: 1=%"
set "line=%spaces: =*%"
for %%i in (%indices%) do echo !spaces:~-%%i!!line:~%%i!*!line:~%%i!