Home > database >  Tic Tac Toe Batch Game
Tic Tac Toe Batch Game

Time:12-09

I'm trying to code a tictactoe game in batch. But I ran into several problems I can't solve.

  1. 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.

  2. 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
    

CodePudding user response:

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

CodePudding user response:

@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 /p "playerX=enter name Player 1 (X): " & set /p "playerO=enter name Player 2 (O): "
set gone=.
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 /p "playerX=enter name Player 1 (X): " & set /p "playerO=enter name Player 2 (O): "
set gone=.
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
  • Related