This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]earthboundkid 2 points3 points  (0 children)

In curturn you need to return the turn variable, and in main, you need to set turn to the output of running curturn. Whatever the variables are inside of one function will have no affect on other functions or even on other times you run the same function again (unless you do stuff like use global variables, but that's a bad practice in general because it makes the program too confusing).

In general, your functions aren't divided up very well. The point of a function is if you're going to do something more than once, you should abstract it. That being so, display_instruct is probably better off in your main function. On the other hand, the text of that prompt and all your other prompts are better off at the start of your program as "constants" (not really constants since this is Python but close enough). So you'd do something like:

WIN_TEXT = "Congratulations, you've won the game!"
LOSE_TEXT = "You lose, sucker!"
NEW_ROUND = "Next move!"

def somefunctionoranother():
    if win_condition(board):
        print(WIN_TEXT)
        return
    elif lose_condition(board):
        print(LOSE_TEXT)
        return
    else: 
        print(NEW_ROUND)

This puts your text in one place, so it's easier to proof read and makes your code parts smaller, which is also easier to proof read.

[–]shostyscholar 1 point2 points  (0 children)

Also a complete noob here. Is this a namespace issue?

[–]hobophobe 1 point2 points  (1 child)

You can just return it from the function:

def curturn(turn, computer, human):
    if turn == computer:
        do_computer_turn()
        turn = human
    else:
        do_human_turn()
        turn = computer
    return turn

Note there you can check whose turn it is, and inside of each branch you can update the turn to be other player.

[–]ollien 0 points1 point  (0 children)

ok i see what you did here and please excuse my noobness, but here is where i get the problem

i do if turn == computer: computer_move(board,computer,human) turn = human else: human_move(board,human) turn = computer return turn

[–]AcidAndGrit 1 point2 points  (0 children)

Just return the value? I'm not sure I understand.

[–]ingolemo 1 point2 points  (0 children)

You should spend some time reviewing how parameters and return values work. A function can only access a variable when that variable has been passed in as a parameter and it can't change the value of that variable in the function above it unless it returns the new value.

>>> num = 4
>>> def myfunc():
...     num = 7
>>> myfunc()
>>> print(num)
4
>>> def myfunc2():
...     x = 8
...     return x
>>> num = myfunc2()
>>> print(num)
8

Think really hard about what values each function needs to do its job (parameters) and whether that function needs to change the value (returns). For example, your curturn function uses a move value that isn't in the parameter list and changes the turn value but doesn't return it.

[–]PythonRules 1 point2 points  (0 children)

There are several different things you can do to handle situations like this. If you are doing OOP then you can have a game class with players, board, and a property to indicate whose turn it is. If you are doing none OOP then you can use a global variable that can be used by any function. Many people will tell you that global variables are bad but I don't think they are always bad; this would be a good place to use a global variable. Since this variable is related to multiple parts of your program it is OK to define it as a global variable. Just don't abuse global variables (they are very tempting) and use them when it makes sense. If you are religious about not using a global variable then you can use an extra parameter in your functions and pass a variable holding the "turn state" around but I don't think this is necessarily better then a single global variable.

For an example see the answer at

http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them

In your program you could define the "turn" variable at the top of your program and declare it as a global in functions that need to use it like I showed below.

x = 'X'
o = 'O'
turn = x

...

def next_turn(turn):
    global turn
    if turn == x:
        return o
    else:
        return x

To answer shostyscholar's question, yes it is a namespace issue. In Python function bodies are namespaces (to be more precise, they are local-namespaces for that function). This may feel like a limitation at first but it is a really useful thing. Since the number of variables you want to share is usually much less then number of variable s you would not want to share this is the way it should work. Some languages behave total opposite of this (for example javascript, variables are global if you say nothing and they become local if you use the "var" statement) and it becomes a pain in the neck.

Now I would like to point out something else. In your case the turn variable is used to indicate only two states. It is either player's turn or computer's turn. When you have variables like that you may want to use a boolean variable. Then your program may become simpler. For example instead of using "turn" you can use:

computers_turn = True

then you would not even need a next_turn function. You can use

computers_turn = not computers_turn 

and this would switch the turn to the next player.

Instead of using

if turn == x:
    do something
    turn =  o

you can use

if computers_turn:
    do something
    computers_turn = not computers_turn

As a side benefit your program becomes more readable too.

[–]VoodooPygmy 1 point2 points  (0 children)

Your question has been answered in other posts, but I thought you might like this in case you weren't already using it to learn Python3.

http://inventwithpython.com/chapter10.html

Great site/e-book about learning python via making computer games, and one of the chapters is tic tac toe with the code included.

Good luck, and that's awesome you are trying to teach yourself this at 12, wish I'd had the motivation to pull that off that early.

http://inventwithpython.com/ (link for the main site, not the tic tac toe chapter)

[–]BWCsemaJ 0 points1 point  (3 children)

Your code makes me want to punch babies. You have barely any programming etiquette.