Symbols get thrown around in batch script - batch-file

I wanted to ask this question for a long time. When I echo for example a box using hashtags, and put inside some text, this happens:
https://i.stack.imgur.com/0VnZq.png
And without the text, it looks normal:
https://i.stack.imgur.com/jyOw7.png
So I made a moving system in batch, and when I opened it it ended up looking like this.
https://i.stack.imgur.com/ZUxf4.png
Here's the code, thank you very much if you find an answer and a fix for this.
#echo off
#title batch rpg
cls
color 0f
:initsetup
set xc=3
set yc=3
:displaysetup
cls
set X1Y1=
set X1Y2=
set X1Y3=
set X1Y4=
set X2Y1=
set X2Y2=
set X2Y3=
set X2Y4=
set X3Y1=
set X3Y2=
set X3Y3=
set X3Y4=
set X4Y1=
set X4Y2=
set X4Y3=
set X4Y4=
:SCREEN
set X%xc%Y%yc%=#
echo ....
echo .%X1Y4%%X2Y4%%X3Y4%%X4Y4%.
echo .%X1Y3%%X2Y3%%X3Y3%%X4Y3%.
echo .%X1Y2%%X2Y2%%X3Y2%%X4Y2%.
echo .%X1Y1%%X2Y1%%X3Y1%%X4Y1%.
echo ....
choice /c wasd /n
set choice=%ERRORLEVEL%
goto choice%choice%
:choice1
set /A yc=%yc%+1
if %yc% GTR 4 (
set /A yc=%yc%-1
goto displaysetup
) ELSE (
goto displaysetup
)
:choice2
set /A xc=%xc%-1
if %xc% LSS 1 (
set /A xc=%xc%+1
goto displaysetup
) ELSE (
goto displaysetup
)
:choice3
set /A yc=%yc%-1
if %yc% LSS 1 (
set /A yc=%yc%+1
goto displaysetup
) ELSE (
goto displaysetup
)
:choice4
set /A xc=%xc%+1
if %xc% GTR 4 (
set /A xc=%xc%-1
goto displaysetup
) ELSE (
goto displaysetup
)

Related

Tic Tac Toe Batch Game

I'm trying to code a tictactoe game in batch.
But I ran into several problems I can't solve.
After the third move of player 1, the game has to check if player 1 has won.
I tried to do that by making 8 variables of all possible 8 winlines. And then the game checks if any of the winlines equals to XXX or OOO.
The Problem is that the field variables (_f1, _f2, etc.) don't change to X or O. I set them at the beginning of the script by their numbers, but I dont understand why they dont change once a player put a X or O in that field/variable.
The code is very ugly and unnecessarily long. I'm aware of the for command and i can do basic loops, but I cant wrap my head around the syntax if the command gets too complicated. How can I put all the repititions in for loops?
#echo off
setlocal enabledelayedexpansion
title .:TIC TAC TOE:.
mode con: cols=40 lines=20
color 02
cls
goto :main
:check
if !_win1!==XXX (
echo END OF GAME
pause
)
if !_win2!==XXX (
echo END OF GAME
pause
)
if !_win3!==XXX (
echo END OF GAME
pause
)
if !_win4!==XXX (
echo END OF GAME
pause
)
if !_win5!==XXX (
echo END OF GAME
pause
)
if !_win6!==XXX (
echo END OF GAME
pause
)
if !_win7!==XXX (
echo END OF GAME
pause
)
if !_win8!==XXX (
echo END OF GAME
pause
)
goto :eof
:player2turn
choice /c 123456789 /n /m "!_player2!, it's your turn!"
if !errorlevel!==1 (
if !_f1!==1 (
set _f1=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==2 (
if !_f2!==2 (
set _f2=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==3 (
if !_f3!==3 (
set _f3=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==4 (
if !_f4!==4 (
set _f4=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==5 (
if !_f5!==5 (
set _f5=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==6 (
if !_f6!==6 (
set _f6=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==7 (
if !_f7!==7 (
set _f7=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==8 (
if !_f8!==8 (
set _f8=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==9 (
if !_f9!==9 (
set _f9=!_player2symbol!
goto :eof
) else (
goto :player1turn
)
)
goto :eof
:player1turn
choice /c 123456789 /n /m "!_player1!, it's your turn!"
if !errorlevel!==1 (
if !_f1!==1 (
set _f1=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==2 (
if !_f2!==2 (
set _f2=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==3 (
if !_f3!==3 (
set _f3=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==4 (
if !_f4!==4 (
set _f4=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==5 (
if !_f5!==5 (
set _f5=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==6 (
if !_f6!==6 (
set _f6=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==7 (
if !_f7!==7 (
set _f7=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==8 (
if !_f8!==8 (
set _f8=!_player1symbol!
goto :eof
) else (
goto :player1turn
)
)
if !errorlevel!==9 (
if !_f9!==9 (
set _f9=!_player1symbol!
echo !_win1!
echo !_player1symbol!
pause
goto :eof
) else (
goto :player1turn
)
)
goto :eof
::displaying the map
:map
echo.
echo.
echo.
echo !_f7! ^| !_f8! ^| !_f9!
echo ---------
echo !_f4! ^| !_f5! ^| !_f6!
echo ---------
echo !_f1! ^| !_f2! ^| !_f3!
echo.
echo.
echo.
goto :eof
::setting variables
:setvar
set _f1=1
set _f2=2
set _f3=3
set _f4=4
set _f5=5
set _f6=6
set _f7=7
set _f8=8
set _f9=9
set _win1=!_f7!!_f8!!_f9!
set /a _win2=!_f4!+!_f5!+!_f6!
set /a _win3=!_f1!+!_f2!+!_f3!
set /a _win4=!_f7!+!_f4!+!_f1!
set /a _win5=!_f8!+!_f5!+!_f2!
set /a _win6=!_f9!+!_f6!+!_f3!
set /a _win7=!_f7!+!_f5!+!_f3!
set /a _win8=!_f9!+!_f5!+!_f1!
goto :eof
::player settings
:setup
echo.
set /p _player1=Enter name for Player 1:
echo.
choice /c xo /n /m "!_player1! do you want to play as X or O?"
if !errorlevel!==1 (
set _player1symbol=X
set _player2symbol=O
) else (
set _player1symbol=O
set _player2symbol=X
)
echo.
echo.
set /p _player2=Enter name for Player 2:
echo.
cls
echo.
echo.
echo.
echo !_player1!(!_player1symbol!) vs. !_player2!(!_player2symbol!)
pause>nul
goto :eof
:main
setlocal
call :setup
cls
call :setvar
call :map
call :player1turn
cls
call :map
call :player2turn
cls
call :map
call :player1turn
cls
call :map
call :player2turn
cls
call :map
call :player1turn
call :check
endlocal
goto :eof
You should research and define your coding approach before write a single line of program. Also, you should learn the language features in order to make good use of its facilities. This applies to any programming language.
This is the way I would do it:
#echo off
setlocal EnableDelayedExpansion
rem Test for win: Horizontal rows
set "win[1]=%%pos[1]%%%%pos[2]%%%%pos[3]%%"
set "win[2]=%%pos[4]%%%%pos[5]%%%%pos[6]%%"
set "win[3]=%%pos[7]%%%%pos[8]%%%%pos[9]%%"
rem Test for win: Vertical cols
set "win[4]=%%pos[1]%%%%pos[4]%%%%pos[7]%%"
set "win[5]=%%pos[2]%%%%pos[5]%%%%pos[8]%%"
set "win[6]=%%pos[3]%%%%pos[6]%%%%pos[9]%%"
rem Test for win: Diagonals
set "win[7]=%%pos[1]%%%%pos[5]%%%%pos[9]%%"
set "win[8]=%%pos[7]%%%%pos[5]%%%%pos[3]%%"
for /L %%i in (1,1,9) do set "pos[%%i]=%%i"
set "taken=_"
cls
set /P "player[X]=Enter player 1 (X) name: "
set /P "player[O]=Enter player 2 (O) name: "
call :showBoard
set "players=XO"
for /L %%n in (1,1,9) do (
call :playerTurn !players:~0,1!
if !result! equ 1 echo You win^^^! & goto :EOF
set "players=!players:~1,1!!players:~0,1!"
)
echo Game was a draw...
goto :EOF
:playerTurn wichOne
choice /C 123456789 /N /M "!player[%1]!, it's your turn: "
set "choice=%errorlevel%"
if "!taken:%choice%=!" neq "%taken%" echo Bad position & goto playerTurn
set "taken=%taken%%choice%"
set "pos[%choice%]=%1"
call :showBoard
rem Test if win
set "result=0"
for /L %%i in (1,1,8) do if !result! equ 0 (
call set "line=!win[%%i]!
if "!line!" equ "%1%1%1" set "result=1"
)
exit /B
:showBoard
echo/
echo/
echo %pos[1]% ^| %pos[2]% ^| %pos[3]%
echo ---------
echo %pos[4]% ^| %pos[5]% ^| %pos[6]%
echo ---------
echo %pos[7]% ^| %pos[8]% ^| %pos[9]%
echo/
echo/
exit /B
EDIT 2021/12/08: New version added
The original version of this program was simple enough to be understand by the OP. The next version below was written with the purpose of be as efficient and short as possible:
#echo off
setlocal EnableDelayedExpansion
set "win=" & set "out="
for %%a in (1:2:3 4:5:6 7:8:9 1:4:7 2:5:8 3:6:9 1:5:9 3:5:7) do (
for /F "tokens=1-3 delims=:" %%x in ("%%a") do (
set "win=!win! ^!pos[%%x]^!^!pos[%%y]^!^!pos[%%z]^!"
if "!out:~-3,1!" neq "9" set "out=!out!$^!pos[%%x]^! ^^| ^!pos[%%y]^! ^^| ^!pos[%%z]^!"
)
)
set "out=!out:~1!"
:menu
cls
set /P "player[X]=Enter player 1 (X) name: "
set /P "player[O]=Enter player 2 (O) name: "
for /L %%i in (1,1,9) do set "pos[%%i]=%%i"
set "options=123456789" & set "filler=asdfghjkl"
for %%n in (X O X O X O X O X) do (
cls
echo/& echo/& echo %out:$=& echo --+---+--& echo %& echo/& echo/
choice /C !options! /N /M "!player[%%n]!, it's your turn: "
for /F "tokens=1,2" %%e in ("!errorlevel! !filler:~0,1!") do (
set "options=!options:%%e=%%f!" & set "filler=!filler:~1!" & set "pos[%%e]=%%n"
)
set "line=%win%"
if "!line:%%n%%n%%n=!" neq "!line!" echo You win^^^! & goto nextGame
)
echo Game was a draw...
:nextGame
echo/
pause
goto :menu
#Aacini posted a great answer, so I decided to post my own as well. As they say, there are many ways to skin a cat.
#echo off & Title Tic-Tac-Toe
setlocal enabledelayedexpansion & mode con: cols=40 lines=20 & color 02
for /F %%i in ('echo prompt $E ^| cmd') do set "n=%%iE"
:menu
cls & set gone=. & for %%p in (player[X] player[O]) do set /p "%%~p=enter name %%p: "
for /l %%i in (1,1,9) do set a%%i=%%i
for /L %%i in (1,1,4) do for %%a in (X O) do (
for %%x in (!a1!!a2!!a3! !a4!!a5!!a6! !a7!!a8!!a9! !a1!!a4!!a7! !a2!!a5!!a8! !a3!!a6!!a9! !a1!!a5!!a9! !a3!!a5!!a7!) do (
if "%%x" == "!_h!!_h!!_h!" echo !pl! wins & timeout /t 4 /NOBREAK >nul & goto :menu
)
set "pl=!player[%%a]!" & set _h=%%a
call :play
set "a!ch!=%%a"
if %%i geq 4 echo No winners & timeout /t 4 /NOBREAK >nul & goto :menu
)
:play
cls & echo(
echo !a1! ^| !a2! ^| !a3!%n% ----------%n% !a4! ^| !a5! ^| !a6!%n% ----------%n% !a7! ^| !a8! ^| !a9!%n%
choice /c 123456789 /m "!pl!'s turn"
set ch=!errorlevel!
if !ch! equ 0 exit /b
if "!gone:%ch%=!" neq "%gone%" echo That spot has been taken, try again & timeout /t 3 /NOBREAK >nul & goto :play
set "gone=%gone%!ch!"
goto :eof
And a version for older windows that does not support VT100:
#echo off & Title Tic-Tac-Toe
setlocal enabledelayedexpansion & mode con: cols=40 lines=20 & color 02
:menu
cls & set gone=. & for %%p in (player[X] player[O]) do set /p "%%~p=enter name %%p: "
for /l %%i in (1,1,9) do set a%%i=%%i
for /L %%i in (1,1,4) do for %%a in (X O) do (
for %%x in (!a1!!a2!!a3! !a4!!a5!!a6! !a7!!a8!!a9! !a1!!a4!!a7! !a2!!a5!!a8! !a3!!a6!!a9! !a1!!a5!!a9! !a3!!a5!!a7!) do (
if "%%x" == "!_h!!_h!!_h!" echo !pl! wins & timeout /t 4 /NOBREAK >nul & goto :menu
)
set "pl=!player[%%a]!" & set _h=%%a
call :play
set "a!ch!=%%a"
if %%i geq 4 echo No winners & timeout /t 4 /NOBREAK >nul & goto :menu
)
:play
cls & echo(
echo !a1! ^| !a2! ^| !a3!&echo ----------&echo !a4! ^| !a5! ^| !a6!&echo ----------&echo !a7! ^| !a8! ^| !a9!&echo(
choice /c 123456789 /m "!pl!'s turn"
set ch=!errorlevel!
if !ch! equ 0 exit /b
if "!gone:%ch%=!" neq "%gone%" echo That spot has been taken, try again & timeout /t 3 /NOBREAK >nul & goto :play
set "gone=%gone%!ch!"
goto :eof
I got the solution
All i had to do was to set the win variables later, when checking the winlines.
For the task of testing, string substitution can be used with variables to test a list of winning cell combinations concisely.
#Echo off & CHCP 65001 > nul
Set LF=^
%= Above empty line required =%
For /l %%i in (1 1 9)Do Set c%%i=_
Set Screen=Player: !Player!!LF!!LF! [!c7!][!c8!][!c9!]!LF! [!c4!][!c5!][!c6!]!LF! [!c1!][!c2!][!c3!]!LF!
Set state=!c1!!c2!!c3!,!c1!!c4!!c7!,!c1!!c5!!c9!,!c4!!c5!!c6!,!c7!!c8!!c9!,!c7!!c5!!c3!,!c3!!c6!!c9!,!c2!!c5!!c8!
Set "p1=X" & Set "p2=O"
Set /A "choices=123456789","Move=0","p%p1%%p1%%p1%=1","p%p2%%p2%%p2%=2"
Setlocal EnableDelayedExpansion & For /l %%m in (1 1 9)Do (
Set /A "player=((%%m-1) %% 2)+1"
cls & Echo(%Screen%
For /f "Delims=" %%e in ('Choice /n /c:!choices!')Do (
Set "choices=!choices:%%e=!"
For %%i in (!player!)Do Set "c%%e=!p%%i!"
)
cls & Echo(%Screen%
If %%m GTR 4 (
Set "test=%State%"
For %%i in (!p1!!p1!!p1! !p2!!p2!!p2!)Do if not "!test:%%i=!"=="!test!" (
Echo(player !p%%i! won
Goto:Eof
) ) )
Echo(draw & Endlocal

Why doesn't this Batch Program give an Output?

I recently had an issue with one of my batch programs, it is basically an incompleted platformer: My code is work in progress and i got stuck with my attemp of collision detection. I have a matrix M, that i can access within an EnableDelayedExpansion block like this !M[%%a][%%d]!
The first time it works, but the second usage does not work anymore:
echo A!M[%xx%,%yy%]!B yields AB.
I would appreciate any hint.
Thanks in advance!
#echo off
::creating a new line variable for multi line strings
set NLM=^
:: Two empty lines are required here
::set up initial grid
set height=9
set width=14
for /l %%a in (0,1,9) do (
for /l %%d in (0,1,14) do (
set M[%%a][%%d]=.
)
)
::create some vars at an initial value
set falling=0
set row=5
set turns=0
set x=8
set face=empty
:turn
set M[%row%][%x%]=^P
::set wall position
set x2=4
set y2=6
set M[%y2%][%x2%]=^#
::display current grid
setlocal EnableDelayedExpansion
set "grid="
for /l %%a in (0,1,9) do (
set line=!M[%%a][0]!
for /l %%d in (1,1,14) do (
set line=!line!!M[%%a][%%d]!
)
set grid=!grid! !NLM! !line!
)
cls
echo !grid!
endlocal
::prompt and make move
:: 4 = d
choice /c:wasd /n /m "" /t 1 /d s
set move=0
set /a xx=x
set /a yy=row
:move clearing Player
set M[%row%][%x%]=.
:: ^ this clears the characters trail so that there is no trail left behind after
:: moves, even when blocked. But at the start of grid Player is drawn again.
if %errorlevel%==4 ( if %x% LSS %width% ( set face=right
set /a xx=x+1) else ( set face=empty))
::if %errorlevel%==3 ( if %row% LSS %height% ( set face=down
::set /a move=0) else ( set face=empty))
if %errorlevel%==2 ( if %x% GTR 0 ( set face=left
set /a xx=x-1) else ( set face=empty))
if %errorlevel%==1 ( if %row% GTR 0 ( set face=up
set /a move=1) else ( set face=empty))
::falling!
set /a yy=yy-move
if %move%==0 (
set /a falling+=1
set face=down
) else (
set falling=0
)
set /a yy=yy+falling
::collision tests
setlocal enableDelayedExpansion
::echo !M[%xx%,%yy%]! > tmp.var
echo A!M[%xx%,%yy%]!B
endlocal
::set /P var1="" < tmp.var
::if %var1%==# (
:: set face=empty
::)
::now the actual movements
::if %face%==right set /a x+=1
::if %face%==left set /a x-=1
::if %face%==up set /a row=yy
::if %face%==down set /a row=yy
set /a x=xx
set /a row=yy
::increment turns, return to top
set /a turns+=1
goto :turn

Set /a not working as 2 / 2

I couldn't get %difference_two% to work It can find %difference_one% as 2 but when I make it divide 2 by 2 it doesn't display as anything.
Use the numbers 2,5,10,17,26
To get what I need.
#echo off
color 0a
title Solver
:numbers
cls
set /p first=First:
set /p second=Second:
set /p third=Third:
set /p fourth=Fourth:
set /p fifth=Fifth:
goto solve
:solve
cls
set /a second_minus_first= %second% - %first%
set /a third_minus_second= %third% - %second%
if %third_minus_second%==%second_minus_first% (
goto s
) else (
goto d
)
:d
cls
set /a fourth_minus_third= %fourth% - %third%
set /a difference= %third_minus_second% - %second_minus_first%
set /a difference_one= %fourth_minus_third% - %third_minus_second%
if %difference%==%difference_one% (
set /a difference_two= %difference_one% / 2
set /a thing= %first% - %difference_two%
cls
echo %difference_two%n Squared + %thing%
pause >nul
goto numbers
) else (
goto wrong
)
Try this:
#echo off
setlocal EnableDelayedExpansion
color 0a
title Solver
:numbers
cls
set /p first=First:
set /p second=Second:
set /p third=Third:
set /p fourth=Fourth:
set /p fifth=Fifth:
goto solve
:solve
cls
set /a second_minus_first= %second% - %first%
set /a third_minus_second= %third% - %second%
if %third_minus_second%==%second_minus_first% (
goto s
) else (
goto d
)
:d
cls
set /a fourth_minus_third= %fourth% - %third%
set /a difference= %third_minus_second% - %second_minus_first%
set /a difference_one= %fourth_minus_third% - %third_minus_second%
if %difference%==%difference_one% (
set /a difference_two= !difference_one! / 2
set /a thing= !first! - !difference_two!
cls
echo !difference_two!n Squared + !thing!
pause >nul
goto numbers
) else (
goto wrong
)
In batch, commands in a code block (between ( )) are interpreted as on the same line, so you need to use setlocal EnableDelayedExpansion and use ! instead of % inside them.

How can I deal with this error in my Batch script?

I'm not sure what is happening as batch script closes almost immediately when I try to run it. It's pretty simple it should test whether a number(num) is a prime Number. If not it continues until num1 is bigger than num.
echo off
title Prime Numbers
cls
set /a prime=7
set /a num1=2
set /a num2=2
:do1
if %prime% == %num1% * %num2% goto do_if_1
if else %prime% LSS %num1% * %num2% set /a num2=%num2%+1
if else %prime% GTR %num1% * %num2% goto do_if_2
if else %prime% LSS %num1% * 1 goto do_if_3
goto do1
:do_if_1
set /a prime=%prime%+1
set /a num1=2
set /a num2=2
goto do1
:do_if_2
set /a num1=%num1%+1
set /a num2=2
goto do2
:do_if_3
echo %prime%
goto do_if_1
Edit: 6n±1 method
In case it's useful to anyone, here's a much more efficient method for testing whether a number is prime or composite. It's a Batch language adaptation of the 6n±1 algorithm mentioned by several people on this post.
#echo off & setlocal enabledelayedexpansion
if "%~1"=="" goto usage
for /f "delims=0123456789" %%I in ("%~1") do goto usage
if %~1 LEQ 1 (
echo %~1 is neither prime nor composite.
exit /b 1
) else if %~1 LEQ 3 (
echo %~1 is prime.
exit /b 0
)
set /a "mod2or3 = ^!(%~1 %% 2) | ^!(%~1 %% 3), half = %~1 / 2"
if %mod2or3% EQU 1 (
echo %~1 is composite.
exit /b 1
)
for /L %%I in (5,6,%half%) do (
set /a "n6pm1 = ^!(%~1 %% %%I) | ^!(%~1 %% (%%I + 2))"
if !n6pm1! EQU 1 (
echo %~1 is composite.
exit /b 1
)
)
echo %~1 is prime.
goto :EOF
:usage
echo Usage: %~nx0 integer
goto :EOF
Original answer:
Thought I might accept the challenge.
#echo off
setlocal enabledelayedexpansion
if "%~1"=="" goto usage
for /f "delims=0123456789" %%I in ("%~1") do goto usage
set /a limit = %~1 - 1
for /L %%I in (2,1,%limit%) do (
set /a modulo = %~1 %% %%I
if !modulo! equ 0 (
echo %~1 is composite ^(divisible by %%I^).
goto :EOF
)
)
echo %~1 is prime.
goto :EOF
:usage
echo Usage: %~nx0 integer
You had commented under Dominique's answer, "So how do I fix this?" Take the first part of your script:
set /a prime=7
set /a num1=2
set /a num2=2
:do1
if %prime% == %num1% * %num2% goto do_if_1
Since you've been informed by both Squashman and myself that if %prime% == %num1% * %num2% is not going to work as you intend, you should now know that you need to insert an additional set /a above your if statement to perform %num1% * %num2%.
set /a prime=7
set /a num1=2
set /a num2=2
:do1
set /a product = num1 * num2
if %prime% == %product% goto do_if_1
Let's continue...
...
if %prime% == %product% goto do_if_1
if else %prime% LSS %num1% * %num2% set /a num2=%num2%+1
There are two immediate problems here. #1, I think you probably meant else if, not if else. #2, in batch scripting, else needs to be included as a part of the if command you're else-ing. This means else either needs to be appended to the end of the previous line, or you should use some parentheses. Rewrite it like this:
if %prime% == %product% (
goto do_it_1
) else if %prime% LSS %product% (
set /a num2 += 1
) else etc...
The first thing I advise you, is to get rid of the echo off, like this you can follow what your script is doing:
D:\>set /a prime=7
D:\>set /a num1=2
D:\>set /a num2=2
D:\>if 7 == 2 * 2 goto do_if_1
7 was unexpected at this time. => this is causing your problem!
D:\>if else 7 LSS 2 * 2 set /a num2=2+1
D:\>

Rubik's cube scrambler [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I made this awesome (horrible) Rubik's cube scrambler a while ago, but when I look at the code, it's just too much, I know there is a very simpler way of doing this. If there is anyone who can modify certain bits to make the code more compact, I would really appreciate it.
This is purely for my understanding in batch, and hopefully others can learn from anything you answer.
Here is the code:
#echo off
mode con: cols=62 lines=10
title Cube Scrambler
color 0a
Setlocal EnableDelayedExpansion
set ct = 0
:strt
set scram=BDEFLMRSUbdflru
set /a ct = ct +1
set /a a=%random%%%14
set /a b=%random%%%14
set /a c=%random%%%14
set /a d=%random%%%14
set /a e=%random%%%14
set /a f=%random%%%14
set /a g=%random%%%14
set /a h=%random%%%14
set /a i=%random%%%14
set /a j=%random%%%14
set /a k=%random%%%14
set /a l=%random%%%14
set /a m=%random%%%14
set /a n=%random%%%14
set /a o=%random%%%14
set a=!scram:~%a%,1!
set b=!scram:~%b%,1!
set c=!scram:~%c%,1!
set d=!scram:~%d%,1!
set e=!scram:~%e%,1!
set f=!scram:~%f%,1!
set g=!scram:~%g%,1!
set h=!scram:~%h%,1!
set i=!scram:~%i%,1!
set j=!scram:~%j%,1!
set k=!scram:~%k%,1!
set l=!scram:~%l%,1!
set m=!scram:~%m%,1!
set n=!scram:~%n%,1!
set o=!scram:~%o%,1!
set /a z1=%random%%%2 +1
set /a z2=%random%%%2 +1
set /a z3=%random%%%2 +1
set /a z4=%random%%%2 +1
set /a z5=%random%%%2 +1
set /a z6=%random%%%2 +1
set /a z7=%random%%%2 +1
set /a z8=%random%%%2 +1
set /a z9=%random%%%2 +1
set /a z10=%random%%%2 +1
set /a z11=%random%%%2 +1
set /a z12=%random%%%2 +1
set /a z13=%random%%%2 +1
set /a z14=%random%%%2 +1
set /a z15=%random%%%2 +1
if %z1% == 2 goto 2x2
set x1='
:2x2
if %z2% == 2 goto 3x3
set x2='
:3x3
if %z3% == 2 goto 4x4
set x3='
:4x4
if %z4% == 2 goto 5x5
set x4='
:5x5
if %z5% == 2 goto 6x6
set x5='
:6x6
if %z6% == 2 goto 7x7
set x6='
:7x7
if %z7% == 2 goto 8x8
set x7='
:8x8
if %z8% == 2 goto 9x9
set x8='
:9x9
if %z9% == 2 goto 10x10
set x9='
:10x10
if %z10% == 2 goto 11x11
set x10='
:11x11
if %z11% == 2 goto 12x12
set x11='
:12x12
if %z12% == 2 goto 13x13
set x12='
:13x13
if %z13% == 2 goto 14x14
set x13='
:14x14
if %z14% == 2 goto 15x15
set x14='
:15x15
if %z15% == 2 goto ans
set x15='
:ans
echo.
echo Scramble: %ct%
echo.
echo.
echo %a%%x1% %b%%x2% %c%%x3% %d%%x4% %e%%x5% %f%%x6% %g%%x7% %h%%x8% %i%%x9% %j%%x10% %k%%x11% %l%%x12% %m%%x13% %n%%x14% %o%%x15%
echo.
echo.
echo { Enter } = New scramble
echo Made by: Ruan Swanepoel
pause>nul
cls
set x1=
set x2=
set x3=
set x4=
set x5=
set x6=
set x7=
set x8=
set x9=
set x10=
set x11=
set x12=
set x13=
set x14=
set x15=
goto strt
Maybe something like this approach using FOR loops?
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
mode con: cols=62 lines=10
title Cube Scrambler
color 0a
set "ct=0"
set "discontinue="
:strt
set "scram=BDEFLMRSUbdflru"
set /a "ct+=1"
for %%x in (a b c d e f g h i j k l m n o) do (
set /a "xx=!random!%%15"
call set "%%x=%%scram:~!xx!,1%%"
)
for /L %%y in (1, 1, 15) do (
set /a "yy=!random!%%2"
if !yy! EQU 1 (
set "x%%y= "
) else (
set "x%%y='"
)
)
:ans
echo(
echo Scramble: %ct%
echo(
echo(
echo %a%%x1% %b%%x2% %c%%x3% %d%%x4% %e%%x5% %f%%x6% %g%%x7% %h%%x8% %i%%x9% %j%%x10% %k%%x11% %l%%x12% %m%%x13% %n%%x14% %o%%x15%
echo(
echo(
echo { Enter } = New scramble
echo Made by: Ruan Swanepoel
set /P "discontinue="
if defined discontinue goto :endlocal
cls
goto strt
:endlocal
color
title %CD%
rem mode con: cols=80 lines=25
ENDLOCAL
goto :eof
It could probably be trimmed down a bit more (especially if I wanted to tweak the spacing), but I got it down to 29% of what it was, so there's that.
#echo off
setlocal enabledelayedexpansion
mode con cols=62 lines=10
title Cube Scrambler
color 0A
set ct=0
:begin
set scram=BDEFLMRSUbdflru
set /a ct+=1
for /l %%A in (1,1,15) do (
set /a mod_15=!random!%%15
for /F "delims=" %%B in ("!mod_15!") do (
set mov[%%A]=!scram:~%%B,1!
)
set /a inv[%%A]=!random!%%2
if !inv[%%A]! equ 0 (
set "inv[%%A]= "
) else (
set "inv[%%A]=' "
)
)
echo.
echo Scramble: !ct!
echo.
for /l %%A in (1,1,15) do (
set /p"=!mov[%%A]!!inv[%%A]!"<nul
)
echo.
echo.
echo { Enter } = New scramble
echo Made by: Ruan Swanepoel
pause>nul
cls
goto begin
This version is even smaller (just above 18% of the original) at the expense of some readability:
#echo off
setlocal enabledelayedexpansion
mode con cols=45 lines=10
set c=0
set s=BDEFLMRSUbdflru
:a
set /a c+=1
title Cube Scramble !c!
for /l %%A in (1,1,15) do (
set /a r=!random!%%15,i%%A=!random!%%2
for /F %%B in ("!r!") do set m%%A=!s:~%%B,1!
if !i%%A! equ 0 (set i%%A= ) else (set i%%A=' )
)
echo.
for /l %%A in (1,1,15) do set /p=!m%%A!!i%%A!<nul
echo.
echo Enter: Rescramble
pause>nul
cls
goto a

Resources