Author Posts

August 5, 2015 at 7:44 pm

This was my first real script I wrote with powershell. thanks for the help I found here!

# 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] + "  >                  < "
               $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')