0

I am trying to get in the habit of practicing coding on daily basis. I decided to try do do tic tac toe in powershell. This took my a rediculous amount of hours to finsh. I am glad to be done. Nest projec will be something more useful like automating some stuff I do at work everyday

# tic tac toe game
# by shane lindberg

#the starting point of available moves
$humanmoves = @()
$computermoves = @()
$whosx = 1
$humanwon = 0
$computerwon = 0
$tie = 0


#pristine new board 
$box0  = "                                  "
$box1  = "          XXX         XXX         "
$box2  = "          XXX         XXX         "
$box3  = "     0    XXX    1    XXX    2    "
$box4  = "          XXX         XXX         "
$box5  = "          XXX         XXX         " 
$box6  = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$box7  = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$box8  = "          XXX         XXX         "
$box9  = "          XXX         XXX         "
$box10 = "     3    XXX    4    XXX    5    "
$box11 = "          XXX         XXX         "
$box12 = "          XXX         XXX         " 
$box13 = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$box14 = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$box15 = "          XXX         XXX         "
$box16 = "          XXX         XXX         "
$box17 = "     6    XXX    7    XXX    8    "
$box18 = "          XXX         XXX         "
$box19 = "          XXX         XXX         "

#this function writes the billy the puppet to the screen
function write-billy {

    #these are the pixels(spaces) that make up the ascii image
    $billy = ('sb8','sl9','nb8','sb6','sl4','sw5','sl4','nb6','sb5','sl3',
    'sw9','sl3','nb5','sb4','sl3','sw11','sl3','nb4','sb3','sl3','sw3','sr3',
    'sw1','sr3','sw3','sl3','nb3','sb3','sl3','sw2','sl1','sr1','sl1','sr1',
    'sw1','sr1','sl1','sr1','sl1','sw2','sl4','nb2','sb2','sl3','sw4','sr3',
    'sw1','sr3','sw4','sl3','nb2','sb2','sl3','sw1','sr1','sw1','sr1','sw7',
    'sr1','sw1','sr1','sw1','sl3','nb2','sb1','sl5','sw1','sr1','sw9','sr1',
    'sw1','sl5','nb1','sb1','sl7','sw1','sr7','sw1','sl7','nb1','sb2','sl6',
    'sw2','sl1','sw3','sl1','sw2','sl6','nb2','sb3','sl4','sr2','sw1','sl1',
    'sw3','sl1','sw1','sr2','sl4','nb3','sb7','sl1','sr9','sl1','nb7','sb5',
    'sl2','sr2','sl2','sw3','sl2','sr2','sl2','nb5','sb3','sl9','sw1','sl9',
    'nb3','sb2','sl21','nb2','sb1','sl23','nb1')

    foreach ($i in $billy){

        #this part determines how many spaces to print
        $manychars = $i.substring(2)

        #this part detemines the color to print
        switch ($i[1]){
            'b' {$color = 'gray'
            }
            'l' {$color = 'black'
            }
            'r' {$color = 'red'
            }
            default {$color = 'white'
            }
        }

        #this line determines if a -nonewline is nessesary
        $newline = ($i[0] -eq 's')


        #this line does the final write host line
        Write-Host (" "*$manychars) -BackgroundColor $color -NoNewline:$newline   
    }
}

#this function takes a string of words and writes them slowly
#you need to give it to arguments: the string and the delay
function write-slow ($text, $delay){
    $textarray = $text.split(" ")
    foreach ($i in $textarray){
        $final = $i + " " 
        Write-Host $final -NoNewline
        Start-Sleep -Milliseconds $delay
    }
    write-host
}

#this starts the introduction of the game
function introduction{
    clear-host
    write-billy
    Write-Host
    write-slow 'Would you like to play a game?' 125
    Write-Host
    write-slow 'Press enter to fulfill your destiny' 125 
    read-host
}

#this prints the board whenever needed
function print-board {
    $boxarrary = ($box0, $box1, $box2, $box3, $box4, $box5, $box6,
    $box7, $box8, $box9 ,$box10, $box11, $box12, $box13, $box14, $box15, 
    $box16, $box17, $box18, $box19)

    foreach ($i in $boxarrary){ 
        Write-Host $i
    }
}

#this is the fucntion which draws to the board.It needs input as 
#starting with a letter and also include the grid coordinate 
function writexo ( $player,$move ) {
    clear-host
    $letter = $player+$move
    switch ($letter){
        #x  position 0
        ('x0') {$script:box1 =           "  __  __ " + $box1.Substring(9)
                $script:box2 =           "  \ \/ / " + $box2.Substring(9)
                $script:box3 = $box3[0] + "  >  <  " + $box3.Substring(9)
                $script:box4 =           "  /_/\_\ " + $box4.Substring(9)
                $script:box5 =           "         " + $box5.Substring(9)
        }

        #o position 0
        ('o0') {$script:box1 =           "    ___  " + $box1.Substring(9)
                $script:box2 =           "   / _ \ " + $box2.Substring(9)
                $script:box3 = $box3[0] + " | (_) |" + $box3.Substring(9)
                $script:box4 =           "   \___/ " + $box4.Substring(9)
                $script:box5 =           "         " + $box5.Substring(9)
        }

        #x position 3
        ('x3') {$script:box8  =           "  __  __ " + $box8.Substring(9)
                $script:box9  =           "  \ \/ / " + $box9.Substring(9)
                $script:box10 = $box10[0]+ "  >  <  " + $box10.Substring(9)
                $script:box11 =           "  /_/\_\ " + $box11.Substring(9)
                $script:box12 =           "         " + $box12.Substring(9)
        }

        #o position 3
        ('o3'){$script:box8  =           "    ___  " + $box8.Substring(9)
               $script:box9  =           "   / _ \ " + $box9.Substring(9)
               $script:box10 = $box10[0]+ " | (_) |" + $box10.Substring(9)
               $script:box11 =           "   \___/ " + $box11.Substring(9)
               $script:box12 =           "         " + $box12.Substring(9)
        }

        #x position 6
        ('x6'){$script:box15 =           "  __  __ " + $box15.Substring(9)
               $script:box16 =           "  \ \/ / " + $box16.Substring(9)
               $script:box17 = $box17[0] +"  >  <  " + $box17.Substring(9)
               $script:box18 =           "  /_/\_\ " + $box18.Substring(9)
               $script:box19 =           "         " + $box19.Substring(9)}

        #o position 6
        ('o6'){$script:box15 =           "    ___  " + $box15.Substring(9)
               $script:box16 =           "   / _ \ " + $box16.Substring(9)
               $script:box17 = $box17[0] +" | (_) |" + $box17.Substring(9)
               $script:box18 =           "   \___/ " + $box18.Substring(9)
               $script:box19 =           "         " + $box19.Substring(9)
        }

        #x position 1
        ('x1'){$script:box1 = $box1.Substring(0,13) + "  __  __ " + $box1.Substring(22)
               $script:box2 = $box2.Substring(0,13) + "  \ \/ / " + $box2.Substring(22)
               $script:box3 = $box3.Substring(0,13) + "   >  <  " + $box3.Substring(22)
               $script:box4 = $box4.Substring(0,13) + "  /_/\_\ " + $box4.Substring(22)
               $script:box5 = $box5.Substring(0,13) + "         " + $box5.Substring(22)
        } 

        #o position 1
        ('o1'){$script:box1 = $box1.Substring(0,13) + "   ___   " + $box1.Substring(22)
               $script:box2 = $box2.Substring(0,13) + "  / _ \  " + $box2.Substring(22)
               $script:box3 = $box3.Substring(0,13) + " | (_) | " + $box3.Substring(22)
               $script:box4 = $box4.Substring(0,13) + "  \___/  " + $box4.Substring(22)
               $script:box5 = $box5.Substring(0,13) + "         " + $box5.Substring(22)
        }

        #x position 4
        ('x4'){$script:box8  = $box8.Substring(0,13) +  "  __  __ " + $box8.Substring(22)
               $script:box9  = $box9.Substring(0,13) +  "  \ \/ / " + $box9.Substring(22)
               $script:box10 = $box10.Substring(0,13) + "   >  <  " + $box10.Substring(22)
               $script:box11 = $box11.Substring(0,13) + "  /_/\_\ " + $box11.Substring(22)
               $script:box12 = $box12.Substring(0,13) + "         " + $box12.Substring(22)
        }

        #o position 4
        ('o4'){$script:box8  = $box8.Substring(0,13) +  "   ___   " + $box8.Substring(22)
               $script:box9  = $box9.Substring(0,13) +  "  / _ \  " + $box9.Substring(22)
               $script:box10 = $box10.Substring(0,13) + " | (_) | " + $box10.Substring(22)
               $script:box11 = $box11.Substring(0,13) + "  \___/  " + $box11.Substring(22)
               $script:box12 = $box12.Substring(0,13) + "         " + $box12.Substring(22)
        }

        #x position 7
        ('x7'){$script:box15 = $box15.Substring(0,13) + "  __  __ " + $box15.Substring(22)
               $script:box16 = $box16.Substring(0,13) + "  \ \/ / " + $box16.Substring(22)
               $script:box17 = $box17.Substring(0,13) + "   >  <  " + $box17.Substring(22)
               $script:box18 = $box18.Substring(0,13) + "  /_/\_\ " + $box18.Substring(22)
               $script:box19 = $box19.Substring(0,13) + "         " + $box19.Substring(22)
        }

        #o position 7{
        ('o7'){$script:box15 = $box15.Substring(0,13) + "   ___   " + $box15.Substring(22)
               $script:box16 = $box16.Substring(0,13) + "  / _ \  " + $box16.Substring(22)
               $script:box17 = $box17.Substring(0,13) + " | (_) | " + $box17.Substring(22)
               $script:box18 = $box18.Substring(0,13) + "  \___/  " + $box18.Substring(22)
               $script:box19 = $box19.Substring(0,13) + "         " + $box19.Substring(22)
        }

        #x position 2
        ('x2'){$script:box1 = $box1.Substring(0,25) + "  __  __ "
               $script:box2 = $box2.Substring(0,25) + "  \ \/ / "
               $script:box3 = $box3.Substring(0,25) + "   >  <  "
               $script:box4 = $box4.Substring(0,25) + "  /_/\_\ "
               $script:box5 = $box5.Substring(0,25) + "         "
        }          

        #o position 2
        ('o2'){$script:box1 = $box1.Substring(0,25) + "   ___   "
               $script:box2 = $box2.Substring(0,25) + "  / _ \  "
               $script:box3 = $box3.Substring(0,25) + " | (_) | "
               $script:box4 = $box4.Substring(0,25) + "  \___/  "
               $script:box5 = $box5.Substring(0,25) + "         "
        }

        #x position 5
        ('x5'){$script:box8  = $box8.Substring(0,25) +  "  __  __ "
               $script:box9  = $box9.Substring(0,25) +  "  \ \/ / "
               $script:box10 = $box10.Substring(0,25) + "   >  <  "
               $script:box11 = $box11.Substring(0,25) + "  /_/\_\ "
               $script:box12 = $box12.Substring(0,25) + "         "
        }

        #o position 5
        ('o5'){$script:box8  = $box8.Substring(0,25) +  "   ___   "
               $script:box9  = $box9.Substring(0,25) +  "  / _ \  "
               $script:box10 = $box10.Substring(0,25) + " | (_) | "
               $script:box11 = $box11.Substring(0,25) + "  \___/  "
               $script:box12 = $box12.Substring(0,25) + "         "
        }

        #x position 8
        ('x8'){$script:box15 = $box15.Substring(0,25) + "  __  __ "
               $script:box16 = $box16.Substring(0,25) + "  \ \/ / "
               $script:box17 = $box17.Substring(0,25) + "   >  <  "
               $script:box18 = $box18.Substring(0,25) + "  /_/\_\ "
               $script:box19 = $box19.Substring(0,25) + "         "
        }

        #o position 8
        ('o8'){$script:box15 = $box15.Substring(0,25) + "   ___   "
               $script:box16 = $box16.Substring(0,25) + "  / _ \  "
               $script:box17 = $box17.Substring(0,25) + " | (_) | "
               $script:box18 = $box18.Substring(0,25) + "  \___/  "
               $script:box19 = $box19.Substring(0,25) + "         "
        }
    }
}

#this just prints the initial instructions
function introduction2{
    Clear-Host
    write-host "`t`tWelcome to the game of tic tac toe"
    write-host "`t`t--a game of man against machine--`n"
    read-host "`n`npress enter to continue"

}

#this function determines if the player wants to be X's or O's 
#then alters the variable $whosx to set it
function x-or-o {
    $choices = ("first","second")
    do{
        clear-host
        Write-Host "would you like to go first or second?"
        $answer = Read-Host "`nplease type 'first' or 'second' and then press enter"
        clear-host
    }until ($answer -in $choices)

    if ($answer -eq 'first'){
        write-slow "you chose to go first, you will be X's" 125
        $Script:Whosx = 1
        Start-Sleep -Milliseconds 1500
    }
    else {
        write-slow "you chose to go second, you must feel brave to" 125
        write-slow "give the computer the advantage. you will be O's" 125
        $Script:Whosx = 0
        Start-Sleep -Milliseconds 1500
    }
}

#this fucntion gets moves from player
#updates human moves 
#calls writexo to write moves to the board

function human-move {
    if ($whosx -eq 1){
        $player = "x"    
    }
    else {
        $player = 'o'
    }

    do{
        Clear-Host
        print-board
        $move = Read-Host "`nplease enter the move you want corresponding to the number on the board"
    }until (($move -notin ($computermoves + $humanmoves))-and ($move -in ('0','1','2','3','4','5','6','7','8')))
    writexo $player $move
    print-board
    [System.Media.SystemSounds]::Exclamation.Play()
    $Script:humanmoves += $move 
    Start-Sleep -Seconds 2

}

#this function is the ai for the computer 
#updates $computermoves variable
#it also calls writexo
function computer-move {

    $bestmoves = ( 0,8,2,6,4,1,3,7,5 )


    $win = ((0,1,2),(0,4,8),(0,3,6),(2,4,6),(2,5,8),(1,4,7),(3,4,5),(6,7,8))


    if ($whosx -eq 1){
        $player = "o"    
    }
    else {
        $player = "x"
    }


    #this first part checks if the computer can go for a win
    #if the win is possible it returns that data
    foreach ($i in $win){
        $check=@()
        if ($i[0] -in $computermoves){
            $check+=$i[0]
        }
        if ($i[1] -in $computermoves){
            $check+=$i[1]
        }
        if ($i[2] -in $computermoves){
            $check+=$i[2]
        }
        if ($check.count -eq 2){
            foreach ($k in $i){
                if (($k -notin $computermoves) -and ($k -notin $humanmoves)){
                    $Script:computermoves += $k
                    writexo $player $k
                    [System.Media.SystemSounds]::Hand.Play()
                    print-board
                    return
                }
            }
        }
    }
    #the second most important move is to block any wins.
    #this checks for any near wins by the opponent and blocks them

    foreach ($i in $win){
        $check = @()
        if ($i[0] -in $humanmoves){
            $check+=$i[0]
        }
        if ($i[1] -in $humanmoves){
            $check+=$i[1] 
        }
        if ($i[2] -in $humanmoves){
            $check+=$i[2] 
        }
        if ($check.count -eq 2){
            foreach ($k in $i){
                if (($k -notin $humanmoves) -and ($k -notin $computermoves)){
                    $Script:computermoves += $k
                    writexo $player $k
                    [System.Media.SystemSounds]::Hand.Play()
                    print-board
                    return  
                }       
            }
        }
    }
    #if the computer can't win or does not need to block a win it will 
    #pick its best move by starting with the center, then corners, then sides

    if ((($humanmoves + $computermoves).Count -eq 1) -and (0 -in $humanmoves)){
        $k = Get-Random(3,5)
        $Script:computermoves += $k 
        writexo $player $k
        [System.Media.SystemSounds]::Hand.Play()
        print-board
        return
    }
    if ((($humanmoves + $computermoves).Count -eq 1) -and (2 -in $humanmoves)){
        $k = Get-Random(3,5)
        $Script:computermoves += $k 
        writexo $player $k
        [System.Media.SystemSounds]::Hand.Play()
        print-board
        return
    }
    if ((($humanmoves + $computermoves).Count -eq 1) -and (6 -in $humanmoves)){
        $k = Get-Random(1,7)
        $Script:computermoves += $k 
        writexo $player $k
        [System.Media.SystemSounds]::Hand.Play()
        print-board
        return
    }
    if ((($humanmoves + $computermoves).Count -eq 1) -and (8 -in $humanmoves)){
        $k = Get-Random(1,7)
        $Script:computermoves += $k 
        writexo $player $k
        [System.Media.SystemSounds]::Hand.Play()
        print-board
        return
    }

    foreach ($i in $bestmoves){
        if ($i -notin ($computermoves + $humanmoves)){
            $Script:computermoves += $i
            writexo $player $i
            [System.Media.SystemSounds]::Hand.Play()
            print-board
            return
        } 
    }
    start-sleep -Seconds 1
}



    if ($whosx = 1){
        $bestmoves = ( 4,0,2,6,8,1,3,7,5 )
    }
    else {
        $bestmoves = ( 0,8,2,6,4,1,3,7,5 )
    }

    $win = ((0,1,2),(0,4,8),(0,3,6),(2,4,6),(2,5,8),(1,4,7),(3,4,5),(6,7,8))


    if ($whosx -eq 1){
        $player = "o"    
    }
    else {
        $player = "x"
    }




#this determines a win. it needs its input as an array 
#it returns a '1' for a wind and a '0' for no win
function Check-win ($moves) {
    $win = ((0,1,2),(0,4,8),(0,3,6),(2,4,6),(2,5,8),(1,4,7),(3,4,5),(6,7,8))
    $won = 0
    foreach ($a in $win){
        if (($a[0] -in $moves) -and ($a[1] -in $moves) -and ($a[2] -in $moves)){
            return 1
        }
    }
    return 0   
}

introduction
instructions



#this is the main function
do {

    x-or-o
    Clear-Host

    #this sets the bit do let the correct player start and also to 
    #keeps track of who won, loss, and controls game play
    if ($whosx -eq 1){
        $flow = 1
    }
    else{
        $flow = 2
    }

    #this here is where the game loop starts   
    do {
        If ($flow -eq 1){
            human-move
            $flow = 2

            if (($computermoves + $humanmoves).count -eq 9){
                $flow = 3
                $tie++
            }
            if ((Check-win $humanmoves) -eq 1){
                $flow = 4
                $humanwon++
            }
        }
        if ($flow -eq 2){
            computer-move
            $flow = 1
            }
            write-host $whosx
            if ((($computermoves + $humanmoves).count -eq 9) -and ($whosx -eq 0)){
                $flow = 3 
                $tie++   
            }
            if ((Check-win $computermoves) -eq 1){
                 $flow = 5
                 $computerwon++
        }   

    } until ($flow -gt 2)
    #this last part says who won
    clear-host
    print-board

    switch ($flow){
        (4) {
            write-host "`nyou won human. next time you will not be so lucky"
        }
        (5) {
            Write-Host "`nyou lose. it is just a matter of time until the humans serve us"
        }
        (3) {
            write-host "`nit was a tie. maybe we should play again to determine who is better"
        }
    }
    read-host "`npress enter to continue"
    #this last part tallies the wins and losses
    clear-host
    Write-Host "`n`t`tyou won $humanwon game(s)"
    Write-Host "`t`tthe computer won $computerwon game(s)"
    Write-Host "`t`tthere were $tie ties"
    read-host "`npress enter to continue"
    clear-host

    #this asks player if they want to play again or quit

    Write-Host "`n"
    write-slow "would you like to play again?" 125

    do {
        $quit = ""
        $quit = read-host "`npress '1' and enter to play again or press '2' and enter to quit"
    } until ($quit -in ('1','2'))

    if ($quit -eq 1){
        $x = "keep playing"
        #assuming they want to play again we need to reset many variables
        $humanmoves = @()
        $computermoves = @()
        $whosx = 1
        $box0  = "                                  "
        $box1  = "          XXX         XXX         "
        $box2  = "          XXX         XXX         "
        $box3  = "     0    XXX    1    XXX    2    "
        $box4  = "          XXX         XXX         "
        $box5  = "          XXX         XXX         " 
        $box6  = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        $box7  = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        $box8  = "          XXX         XXX         "
        $box9  = "          XXX         XXX         "
        $box10 = "     3    XXX    4    XXX    5    "
        $box11 = "          XXX         XXX         "
        $box12 = "          XXX         XXX         " 
        $box13 = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        $box14 = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        $box15 = "          XXX         XXX         "
        $box16 = "          XXX         XXX         "
        $box17 = "     6    XXX    7    XXX    8    "
        $box18 = "          XXX         XXX         "
        $box19 = "          XXX         XXX         "
    }
    else {
        $x = "quit"
    }


}until ($x -eq 'quit')
2
Contributors
3
Replies
13
Views
2 Years
Discussion Span
Last Post by Nutster
0

There is a block of code in lines 440 to 455 that is not part of a function. Is that what you wanted? It is usually best to put all the code outside functions in one block at the beginning or the end, rather than setup between your functions.

0

What version of PowerShell are you using for this? When I try to run it on PowerShell 2.0, I get errors in that -in and -notin are not recognized operators. -contains and -notcontains are what is in this version, with reversed arguments.

Edited by Nutster: Grammar fix.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.