2

I am making a tiktactoe and I have a problem with my player winning like the game even tho I dont get 3 in a row and I just get VIDEO << I didnt event get 3 in a row it just won the game for player 2

my buttons position

                   
white = (250,250,250)
greenbutton2 = button((0,255,0),190,215,100,100, '2')

greenbutton3 = button((0,255,0),335,215,100,100, '3')

greenbutton4 = button((0,255,0),71,215,100,100, '4')

greenbutton5 = button((0,255,0),71,350,100,100, '5')

greenbutton6 = button((0,255,0),190,350,100,100, '6')

greenbutton7 = button((0,255,0),335,350,100,100, '7')


greenbutton8 = button((0,255,0),70,90,100,100, '8')

greenbutton9 = button((0,255,0),190,90,100,100, '9')

greenbutton10 = button((0,255,0),335,90,100,100, '10')

greenbutton4 = button((0,255,0),71,215,100,100, '4')

what I did for example for the first one is 215,215,215 if my partics are over those it should blit the winning image but it blits another image IMAGE but its not blitting the correct image instead its blitting this VIDEO << its the same for all of them it keeps blitting the wrong images and sometimes even though I dont get 3 in a row for the X player or the O enemy it will say I win is there a way I could fix this?

this is for my X player

    # player 2 winning for the rows part
    count = sum([1 if partic.y in [215, 215, 215] else 0 for partic in partics])
    if count == 3:
        lines.append(line(0,0,0,0,white))



    count = sum([1 if partic.y in [90, 90, 90] else 0 for partic in partics])
    if count == 3:
        lines.append(lin(0,0,0,0,white))
   

    count = sum([1 if partic.y in [350, 350, 350] else 0 for partic in partics])
    if count == 3:
        lines.append(liner(0,0,0,0,white))



    count = sum([1 if partic.x in [335, 335, 335] else 0 for partic in partics])
    if count == 3:
        lines.append(low(0,0,0,0,white))


    count = sum([1 if partic.x in [190, 190, 190] else 0 for partic in partics])
    if count == 3:
        lines.append(lowe(0,0,0,0,white))


    count = sum([1 if partic.x in [71, 71, 70] else 0 for partic in partics])
    if count == 3:
        lines.append(lower(0,0,0,0,white))


    count = sum([1 if partic.y in [90, 215, 350] else 0 for partic in partics])
    if count == 3:
        lines.append(win(0,0,0,0,white))

    count = sum([1 if partic.x in [335, 71, 190] else 0 for partic in partics])
    if count == 3:
        lines.append(winner(0,0,0,0,white))




and this is for my O player

    # player 1 winning for the rows part
    count = sum([1 if parti.y in [215, 215, 215] else 0 for parti in parts])
    if count == 3:
        lines.append(line(0,0,0,0,white))



    count = sum([1 if parti.y in [90, 90, 90] else 0 for parti in parts])
    if count == 3:
        lines.append(lin(0,0,0,0,white))
   

    count = sum([1 if parti.y in [350, 350, 350] else 0 for parti in parts])
    if count == 3:
        lines.append(liner(0,0,0,0,white))



    count = sum([1 if parti.x in [335, 335, 335] else 0 for parti in parts])
    if count == 3:
        lines.append(low(0,0,0,0,white))


    count = sum([1 if parti.x in [190, 190, 190] else 0 for parti in parts])
    if count == 3:
        lines.append(lowe(0,0,0,0,white))


    count = sum([1 if parti.x in [71, 71, 70] else 0 for parti in parts])
    if count == 3:
        lines.append(lower(0,0,0,0,white))


    count = sum([1 if parti.y in [90, 215, 350] else 0 for parti in parts])
    if count == 3:
        lines.append(win(0,0,0,0,white))

    count = sum([1 if parti.x in [335, 71, 190] else 0 for parti in parts])
    if count == 3:
        lines.append(winner(0,0,0,0,white))

my full code pastebin

Habib Ismail
  • 69
  • 5
  • 16
  • Sorry, but I think you got something fundamentally wrong. A condition like `partic.y in [215, 215, 215] ` makes no sense. Either `partic.y` is 215 or it is not. It is the same as `partic.y == 215`. – Rabbid76 Nov 22 '20 at 21:34
  • I recommend investigating the answer to your one of your previous questions: [Pygame Tic Tak Toe Logic? How Would I Do It](https://stackoverflow.com/questions/64825967/pygame-tic-tak-toe-logic-how-would-i-do-it) – Rabbid76 Nov 22 '20 at 21:38
  • What's the different between `parts` and `partics`? Can you please explain why the algorithm is checking the `score` in the `turns()` function. I don't understand it. – Kingsley Nov 22 '20 at 21:42
  • its checking if my score is 2 and I am hover any of my buttons then Player X should go and if my score is 3 and my O is over any button then player 2 Should go I got everything working expect the part to check if the player wins or not the parts list is for player 2 and the partics list is for player 1 I have 2 defferent classes to display different images for X and O thats why I used to defferent list there to – Habib Ismail Nov 22 '20 at 22:02
  • I see the method you did but I am trying to think of a different way I could do this I tried to check for collisions like `if [partic.rect.colliderect(greenbutton2.rect) and partic.rect.colliderect(greenbutton3.rect) and partic.rect.colliderect(greenbutton4.rect) for partic in partics]: lines.append(liner(0,0,0,0,white))` but this method is not working well it only checks if I click either one of them then is clicked then I win – Habib Ismail Nov 22 '20 at 22:11
  • I am going to add the sprites that I am using to see what is going on if you like – Habib Ismail Nov 22 '20 at 22:12

1 Answers1

2

My suggestion is to simply use the status of a .result in your button() class.

class button():
    def __init__(self, color, x,y,width,height, text=''):
        # ...
        self.result = ''    # empty

    def getResult( self ):
        return self.result

    def setResult( self, value ):
        self.result = value

    def reset( self ):
        self.result = ''   # back to empty state

Then when you create a Parti or Partic, tell the button to remember the result:

if score == 2:
    if greenbutton4.isOver(pos):
        greenbutton4.setResult( 'x' )
        partics.append(Partic(71,215,100,100,white))

#  ... 

if score == 3:
    if greenbutton4.isOver(pos):
        greenbutton4.setResult( 'o' )
        parts.append(Parti(71,215,100,100,white))

There are only 8 ways to win at tic-tac-toe / noughts-and-crosses: 3x horizontal, 3x vertical, and 2x diagonals. This is a fairly simple check:

def winner( b1, b2, b3, b4, b5, b6, b7, b8, b8 ):
    """ Given the buttons 1-9 in order from top-left to bottom right
        return whether 'x' or 'o' has won the game, or None and which
        line/row/vertical the win was made on """
    winner = ( None, None )
    # make a grid of the board-state for iteration
    board = [ [ b1.getResult(), b2.getResult(), b3.getResult() ],
              [ b4.getResult(), b5.getResult(), b6.getResult() ],
              [ b7.getResult(), b8.getResult(), b9.getResult() ] ]

    # EDIT: some debug code
    print( "BOARD IS: ")
    print( " %3s | %3s | %3s " % ( b1.getResult(), b2.getResult(), b3.getResult() ) )
    print( "-----+-----+-----" )
    print( " %3s | %3s | %3s " % ( b4.getResult(), b5.getResult(), b6.getResult() ) )
    print( "-----+-----+-----" )
    print( " %3s | %3s | %3s " % ( b7.getResult(), b8.getResult(), b9.getResult() ) )
    print( "" )


    # check the horizontals
    for row in range( 3 ):
        if ( board[row][0] != '' and
             board[row][0] == board[row][1] and board[row][0] == board[row][2] ):
            winner = ( board[row][0], 'h'+str( row ) )
            break
    # check the verticals
    for col in range( 3 ):
        if ( board[0][col] != '' and
             board[0][col] == board[1][col] and board[0][col] == board[2][col] ):
            winner = ( board[col][0], 'v'+str( col ) )
            break
    # diagonals
    if ( board[1][1] != '' ):
        if ( board[0][0] == board[1][1] and board[2][2] == board[1][1] ):
            winner = ( board[1][1], 'd1' )
        elif ( board[0][2] == board[1][1] and board[2][0] == board[1][1] ):
            winner = ( board[1][1], 'd2' )
    return winner

The code seems to create the buttons with button2 at the centre (based on the video), so the call to this function would be something like:

player_wins, row = winner( greenbutton8,  greenbutton9,  greenbutton10,   
                           greenbutton4,  greenbutton2,  greenbutton3,  
                           greenbutton5,  greenbutton6,  greenbutton7 )
if ( player_wins != None ):
    print( "Player "+ player_wins + " has won on " + row )
Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • I am getting this error `player_wins, row = winner( greenbutton8, greenbutton9, greenbutton10, TypeError: __init__() takes 6 positional arguments but 10 were given` >>> – Habib Ismail Nov 23 '20 at 01:42
  • also does the code you provided works for both because when is player X turn its going to be PLayer O turn does it check for player O to? – Habib Ismail Nov 23 '20 at 01:51
  • Did you paste something incorrectly? The error refers to `__init__()` not `winner()`. Something is wrong here. The function doesn't care who the winner is, it returns which ever symbol fills the cells in the winning pattern. It could be `o` and `x` (or carrot & banana). – Kingsley Nov 23 '20 at 02:09
  • yes I pasted in correctly but its still giving me the error [image](https://gyazo.com/7b80f92c60c215569b6ddc7df2ed216a) – Habib Ismail Nov 23 '20 at 02:33
  • Update your pastebin, I'll take a quick look – Kingsley Nov 23 '20 at 02:43
  • You have a class named `winner`, so you'll need to rename the class or the function. – Kingsley Nov 23 '20 at 02:47
  • ok I fixed that but when I do 3 in a row of any of the buttons nothing gettings returned [image](https://gyazo.com/d41ee4987750af9d4efadfbc0f66762f) – Habib Ismail Nov 23 '20 at 02:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/224948/discussion-between-kingsley-and-habib-ismail). – Kingsley Nov 23 '20 at 03:05