TicTacToe conditional help

Started by
8 comments, last by visitor 15 years, 10 months ago
I am a begginning python programmer and I need some help with a TicTacToe program I am trying to write. My biggest issue is my innability to make a specific winner. I cannot for the life of me make a way to check if either player wins that works. Right now I only have a broken function that is supposed to check if player 1 'X' wins. here is my code. I couldn't figure out how to make it go into a seperate piece that scrolls down like other people.
b = ['_','_','_','_','_','_','_','_','_']
w = 1
check = 0
def printboard():
        print '[',b[0],'][',b[1],'][',b[2],']'  '       [ 1 ][ 2 ][ 3 ]'
        print '[',b[3],'][',b[4],'][',b[5],']'  '       [ 4 ][ 5 ][ 6 ]'
        print '[',b[6],'][',b[7],'][',b[8],']'  '       [ 7 ][ 8 ][ 9 ]'

def plr1():
        s = int(raw_input('player 1 make your move'))
        b = 'X'

def plr2():
        s = <span class="cpp-keyword">int</span>(raw_input('player <span class="cpp-number">2</span> make your move'))
        b = 'O'

def winner1():
        check = b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">2</span>]
        checking1()
        check = b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">5</span>]
        checking1()
        check = b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">7</span>] + b[<span class="cpp-number">8</span>]
        checking1()
        check = b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">6</span>]
        checking1()
        check = b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">7</span>]
        checking1()
        check = b[<span class="cpp-number">2</span>] + b[<span class="cpp-number">5</span>] + b[<span class="cpp-number">8</span>]
        checking1()
        check = b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">8</span>]
        checking1()
        check = b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">2</span>]
        checking1()
    
def checking1():
        <span class="cpp-keyword">if</span> check == 'XXX':
            print 'player <span class="cpp-number">1</span> is the winner'
            w = <span class="cpp-number">2</span>
          
        
<span class="cpp-keyword">while</span> <span class="cpp-keyword">True</span>:
        printboard()
        plr1()
        winner1()
        <span class="cpp-keyword">if</span> w = = <span class="cpp-number">2</span>:
            <span class="cpp-keyword">break</span>
        printboard()
        plr2()
        <span class="cpp-keyword">if</span> w = = <span class="cpp-number">2</span>:
             <span class="cpp-keyword">break</span>



</pre></div><!–ENDSCRIPT–>
If someone can point me to a place that gives ideas &#111;n ways that I can make an efficient working conditional please post.  Any help &#111;n making this work is highly appreciated.

If anyone needs anymore information I'll gladly post it.

<!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - steveworks on June 17, 2008 10:26:07 PM]<!–EDIT–></span><!–/EDIT–>
---------------------------------------------------------------------------------------Exercise, eat right and be the best you can be!Translation: Play video games for finger streangth and eat lots of hot pockets to be at top programming efficiency.
Advertisement
Use the [ source ] [ /source ] tags (without spaces) to format your code, python is very hard to read without the indentation :)
Quote:Original post by BosskIn Soviet Russia, you STFU WITH THOSE LAME JOKES!
Oh god word took away all my indents!

I'll fix it now.


edit: I fixed the code now can someone please help me.
---------------------------------------------------------------------------------------Exercise, eat right and be the best you can be!Translation: Play video games for finger streangth and eat lots of hot pockets to be at top programming efficiency.
I think the problem is that in your functions your not telling python that your using a global variable

At the start of each function that uses check (or any other global variable) you need

global check (or global <variable name> )


Things like printboard probably work because when your reading from a variable python is smart enough to figure out your referring to the global variable. In winner1() however python doesnt know whether something like

check = b[0] + b[1] + b[2]

is assigning to a global variable or creating a local variable within the function and assign to that. By default it will create the local variable which is destroyed at the end of the function when it goes out of scope, leaving your global variable unchanged.
Quote:Original post by BosskIn Soviet Russia, you STFU WITH THOSE LAME JOKES!
Not too long ago while I was watching tv I thought that may be the problem. I'll see if I can get it to work now.
---------------------------------------------------------------------------------------Exercise, eat right and be the best you can be!Translation: Play video games for finger streangth and eat lots of hot pockets to be at top programming efficiency.
In programming, the normal way we pass information between functions is to pass it in via the parameters, and out via the return value. This is why they're called functions: they calculate some function of the input, and return the output. Just as in mathematics.

When we write code, one of the major goals is to keep things organized. One aspect of this is making sure that functions do all the work that they're supposed to, and only that work. Usually, we can figure out what work is appropriate from the function name.

Let's analyze the existing code. In checking1(), we want to receive the "check" value, and we determine as a result whether or not player 1 is the winner. Right now, we store that result by setting the 'w' global variable. Instead, we'll return a value. The key phrase "whether or not" tells us that we want to return a boolean: True meaning player 1 won, False meaning he didn't.

To receive the 'check' value, we'll use a parameter to the function. To call checking1(), we'll pass the appropriate value from winner1() each time. Notice how each time checking1() is called, 'check' (which is now a parameter, or 'argument' to checking1) takes on a different value - the one that was passed.

In winner1(), we want to check if any of the checking1() calls returned True. Fortunately for us, Python (assuming you have version 2.5 installed) provides a built-in function for this purpose, called 'any'. It takes a sequence of values, and returns if any of them are true (technically, if any of them evaluate as True when converted to bool). We can make a tuple out of all the checking1() results, call any(), and return that result. Then, the main loop makes use of that value.

The print statement to indicate the winner belongs in the main loop, not buried inside checking1(). Why? Well, first off, the organization point that I mentioned earlier (one guiding principle is that a function doesn't talk about the same value it calculates: that way, the calling function loses the flexibility to shut it up :) ), and second, because a player could simultaneously "win" in multiple ways at once, and we don't want to print the message multiple times if that happens.

b = ['_','_','_','_','_','_','_','_','_']def printboard():        print '[',b[0],'][',b[1],'][',b[2],']'  '       [ 1 ][ 2 ][ 3 ]'        print '[',b[3],'][',b[4],'][',b[5],']'  '       [ 4 ][ 5 ][ 6 ]'        print '[',b[6],'][',b[7],'][',b[8],']'  '       [ 7 ][ 8 ][ 9 ]'def plr1():        s = int(raw_input('player 1 make your move'))        b = 'X'<br><br>def plr2():<br>        s = <span class="cpp-keyword">int</span>(raw_input('player <span class="cpp-number">2</span> make your move'))<br>        b = 'O'<br><br>def winner1():<br>        # There are two sets of parentheses enclosing the<br>        # checking1 calls here: the outer set is to make the function call,<br>        # and the inner set is to create the tuple that is passed to any().<br>        <span class="cpp-keyword">return</span> any((<br>                checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">2</span>]),<br>                checking1(b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">5</span>]),<br>                checking1(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">7</span>] + b[<span class="cpp-number">8</span>]),<br>                checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">6</span>]),<br>                checking1(b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">7</span>]),<br>                checking1(b[<span class="cpp-number">2</span>] + b[<span class="cpp-number">5</span>] + b[<span class="cpp-number">8</span>]),<br>                checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">8</span>]),<br>                checking1(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">2</span>])<br>        ))<br>    <br>def checking1(check):<br>        <span class="cpp-keyword">return</span> check == 'XXX'<br>          <br>        <br><span class="cpp-keyword">while</span> <span class="cpp-keyword">True</span>:<br>        printboard()<br>        plr1()<br>        <span class="cpp-keyword">if</span> winner1():<br>                print 'Player <span class="cpp-number">1</span> is the winner'<br>                <span class="cpp-keyword">break</span><br>        # etc.<br><br></pre></div><!–ENDSCRIPT–><br><br>As an exercise, write the corresponding code to handle player 2. Then I can show you how to handle both players with the same set of functions, and also start explaining about how to give functions better names. :)
Zahlman, you REALLY need to write a book and publish it. You'd get stinkingly rich by all the newbies and medium level programmers buying your book.
I finished the code like you asked and I managed to get it to run well. My only problem is that I am able to overwrite other players choices. here is the source.

b = ['_','_','_','_','_','_','_','_','_']def printboard():    print '[',b[0],'][',b[1],'][',b[2],']'  '       [ 1 ][ 2 ][ 3 ]'    print '[',b[3],'][',b[4],'][',b[5],']'  '       [ 4 ][ 5 ][ 6 ]'    print '[',b[6],'][',b[7],'][',b[8],']'  '       [ 7 ][ 8 ][ 9 ]'def plr1():    s = int(raw_input('player 1 make your move'))    b = 'X'<br><br>def plr2():<br>    s = <span class="cpp-keyword">int</span>(raw_input('player <span class="cpp-number">2</span> make your move'))<br>    b = 'O'<br><br>def winner1():<br>    <span class="cpp-keyword">return</span> any((<br>        checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">2</span>]),<br>        checking1(b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">5</span>]),<br>        checking1(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">7</span>] + b[<span class="cpp-number">8</span>]),<br>        checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">6</span>]),<br>        checking1(b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">7</span>]),<br>        checking1(b[<span class="cpp-number">2</span>] + b[<span class="cpp-number">5</span>] + b[<span class="cpp-number">8</span>]),<br>        checking1(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">8</span>]),<br>        checking1(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">2</span>])<br>    ))<br><br>def winner2():<br>    <span class="cpp-keyword">return</span> any((<br>        checking2(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">2</span>]),<br>        checking2(b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">5</span>]),<br>        checking2(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">7</span>] + b[<span class="cpp-number">8</span>]),<br>        checking2(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">3</span>] + b[<span class="cpp-number">6</span>]),<br>        checking2(b[<span class="cpp-number">1</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">7</span>]),<br>        checking2(b[<span class="cpp-number">2</span>] + b[<span class="cpp-number">5</span>] + b[<span class="cpp-number">8</span>]),<br>        checking2(b[<span class="cpp-number">0</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">8</span>]),<br>        checking2(b[<span class="cpp-number">6</span>] + b[<span class="cpp-number">4</span>] + b[<span class="cpp-number">2</span>])<br>))<br>def checking1(check):<br>    <span class="cpp-keyword">return</span> check == 'XXX'<br><br>def checking2 (check):<br>    <span class="cpp-keyword">return</span> check == 'OOO'<br><br><span class="cpp-keyword">while</span> <span class="cpp-keyword">True</span>:<br>    printboard()<br>    plr1()<br>    <span class="cpp-keyword">if</span> winner1():<br>        printboard()<br>        print 'player <span class="cpp-number">1</span> is the winner'<br>        <span class="cpp-keyword">break</span><br>    printboard()<br>    plr2()<br>    <span class="cpp-keyword">if</span> winner2():<br>        printboard()<br>        print 'player <span class="cpp-number">2</span> is the winner'<br>        <span class="cpp-keyword">break</span><br><br>[\source]<br></pre></div><!–ENDSCRIPT–> 
---------------------------------------------------------------------------------------Exercise, eat right and be the best you can be!Translation: Play video games for finger streangth and eat lots of hot pockets to be at top programming efficiency.
I don't know python at all, but you just need to add some checking on your input.

You can check the array location (the input from the player) is still '_', if it is, then process the input, otherwise, loop back until the player gives you a valid input. That will fix your overwrite issue.

The other thing you will want to check is if the board is full then there is a draw.

Great job so far!

-------------------------------------All i know is i don't know anything
Ok, now you are using return values.

The second thing is to look at what you pass into the functions. Look at winner1 and winner2 (together with checking1 and checking2). Aren't they very-very similar? Now if only we could remove one of them by passing the only thing that makes them different as a function argument...

Now, plr1 and plr2 are also very similar. And if you are planning to add some checks to them, wouldn't it also be nice if it was one and the same function?

This topic is closed to new replies.

Advertisement