Tic Tac Toe(v1)

So version 1 of my Tic Tac Toe game is done, with only a few minor things missing.
The main things missing –
– intelligent NPC play
– NPC vs NPC play
– two player play
– better display in cmd
– if possible, graphical display

These are things I want to achieve for the next iteration.
Currently this is what the program looks like…

Currently the program runs with the standard run() function call..
First the program asks you what piece you want to play
Once you’ve chosen, it displays the board format to you and ask who’s going first, ( yes, no, flip).
If you choose this option, the program prompts you to pick Heads or Tails, flips a coin and then compares it to your choice. (for the people who don’t like to make decisions)
In this example the computer won the coin toss and began the game, the rest of the game plays out the same as every other tic tac toe game.
The only other notable pieces of coding are. . .
– if player goes first, the computer shows
[ 1 , 2 , 3 ]
[ 4 , 5 , 6 ]
[ 7 , 8 , 9 ]
to give the player an idea of what the board layout is before they start playing.
– if the gameboard fills up, the game is ended with a print message ” nobody won “

That’s it, now for the coding (this is more documenting for me, than you)…
## This is the first function defined in the code, a simple flip coin function.
## When called it gets either 0 or 1 randomly
## It then matches it up to "Heads" or "Tails" and returns the result

def flip():
    #flipping a coin to decide who goes first
    result = random.randrange(2)
    if result == 0:
        return "Tails"
    else:
        return "Heads"
## The next function is my WinCheck Function.
## This is where it gets a little funky with functioning code.
## This piece of code basically checks each position on the board with ## if statements to see if the given "type" input is in place in any of ## the winning patterns.
## I had to wrench this in late on and couldn't wrap my head around a
## simpler way of performing the same task.

## There is a layer of unused code in here from when i was debugging, 
## it's obviously commented out lines.


def wincheck(type):
    if gb[0][0] == type and gb[0][1] == type and gb[0][2] == type:
        #print (type + " won the game")
        return True
    else:
        if gb[1][0] == type and gb[1][1] == type and gb[1][2] == type:
            #print (type + " won the game")
            return True
        else:
            if gb[2][0] == type and gb[2][1] == type and gb[2][2]==type:
                #print (type + " won the game")
                return True
            else:
                if gb[0][0]==type and gb[1][0]==type and gb[2][0]==type:
                    #print (type + " won the game")
                    return True
                else:
                    if gb[0][1]==type and gb[1][1]==type and gb[2][1]== type:
                        #print (type + " won the game")
                        return True
                    else:
                        if gb[0][2]==type and gb[1][2]==type and gb[2][2]==type:
                            #print (type + " won the game")
                            return True
                        else:
                            #print ("no win")
                            return False
## This is the base building function, it basically prints the rows of ## the current version of the game board.
## Coupled in with this function is how the game checks the board to see ## if anyone has won via the WinCheck function. 
## This seemed like a good way of doing it as when printing the board to ##screen worked out to be a good time to check the board.
## Again, i'm not sure this is the best way of doing it, but it works
## well.

def base():
    global gb
    global running
    for row in gb:
        print (row)
    if wincheck("X") or wincheck("O"):
        print ("\n\nTheres A Winner!")
        running = False
        
## This function when called runs through the function, asking the 
## player who they want to go first in the game.
## It gives three options ( yes, no, flip ). 
## On yes or no, this basically returns true or false for the outer 
## function to use.
## As mentioned the flip coin function is called and resolved now.

def whoGoesFirst():
  
    while True: 
        choice = input("Do you want to go first? : yes, no, flip : ")
        if choice == "yes" or choice == "no" or choice == "flip":
            if choice == "yes":
                return True
            else:
                if choice == "no":       
                    return False
                else:
                    if choice == "flip":
                        flipChoice = input("Heads or Tails? : ")
                        coin = flip()
                        if flipChoice == coin:
                            ##player wins and goes first 
                            print ("you won the coin flip \n")
                            return True
                        else:
                            ##player looses and goes second
                            print ("you lost the coin flip \n")
                            return False
                         
        else:
            print ("invalid choice, please select correctly")
## This is the function that is called for the player to select what 
## piece they want to play as.
## It basically sets the playerPiece and npcPiece depending on the 
## input.


def playerSelect():
    global playerPiece
    global npcPiece
    #asks the player which piece they want, and sets it to global playerPiece
    #also sets the npcPiece to the opposite
    while True:
        playerPiece = input("please select a piece, X/O : ")
        if playerPiece == "X" or playerPiece == "O":
            print ("you have chosen : " + playerPiece)
            if playerPiece == "X":
                npcPiece = "O"
            else: 
                npcPiece = "X"
            break
        print ("invalid selection")
## This is the plot move function, it basically changes the number in 
## game board list that refers to each position. 
## it asks for a position input and the type of piece that is making 
## that move.
## I'm really proud of this little function, it took a lot to think 
## about how i could make it in such a way that both the computer and 
## the player can call it.
## The final thing it does is display the newly update game board.

def plotmove(input,type):
    while True: 
        if input <= 3:
            #row 1
            gb[0][input-1] = type                
        else:
            if input > 3 and input <= 6:
                #row 2
                gb[1][input-4] = type
                
            else:
                if input > 6 and input <= 9:
                    #row 3
                    gb[2][input-7] = type                
        base()
        return
## Surprisingly this was the most annoying function to come up with.
## When called it basically checks through the game board list for the ## input, if the function finds the input in the list, it returns True.
## I found it so hard to get my head around how the for and if 
## statements work together.


def usedbefore(input):
    for number in numcheck:
        if input == number:
            return True 
    return False
    

## Finally this is the run function that you call as a user.
## It in turn calls each function whilst captioned in a infinite True 
## while loop flipping back and forth between npc and player play.

def run():
    
    #main run function and loop that starts the game.
    global numcheck
    global playerPiece
    global npcPiece
    global gb
    global turn
    global running
    running = True
    print ("Welcome to tic tac toe (V1) \n") 
    playerSelect()
    base()
    if whoGoesFirst():
        print ("Player Goes First \n")
        turn = "player"
        print ("[1,2,3]")
        print ("[4,5,6]")
        print ("[7,8,9]")

    else:
        print ("NPC Goes First \n")
        turn = "NPC"

        
    
    while running == True:
        if (len(numcheck)) == 9:
            print("the game is a draw")
            break
        print ("\n")
        if turn == "player":
            #player plays
            while True:
                go = input("Take your turn 1 - 9 : ")
                if not usedbefore(int(go)):
                    numcheck.append(int(go))
                    plotmove(int(go),playerPiece)
                    turn = "npc"
                    break
                print("you've plotted there already")
        else:
            time.sleep(2)
            while True:
                plotter = random.randrange(1,10)
                if not usedbefore(int(plotter)):
                    numcheck.append(plotter)
                    break      
            plotmove(int(plotter),npcPiece)
            print ("NPC went\n")
            turn = "player"
            
            #npc plays
        
    
    
    print ("\n\nCoded by Ash Marshall 31/03/2019")
    #setting everything back to defult
    playerPiece = ""
    npcPiece = ""
    numcheck = []
    gb = [[0,0,0],[0,0,0],[0,0,0]]
    turn = ""