Wątek przeniesiony 2024-03-10 11:21 z Python przez Althorion.

Gra w kółko i krzyżyk

1

Cześć, jestem początkujący i próbuję zrobić grę w kółko i krzyżyk. Gierka w zasadzie działa, po feedbacku na mikroblogu postanowiłem założyć ten wątek.
Mam prośbę o podpowiedź, jak można zrobić, aby gracz wpisywał np. a1, b2, zamiast osobno kolumny i wiersza? Oraz zastanawiam się jak łatwiej sprawdzić czy krzyżyki bądź kółka są po skosie? Wtedy mógłbym zacząć się zastanawiać nad generowaniem większej planszy.
Pozdrawiam, Jakub

# -*- coding: utf-8 -*-
"""
Created on Wed Mar  6 12:03:44 2024

@author: jakubziom
"""


def Title():
    print(' ===============')
    print('   TIC-TAC-TOE')
    print(' ===============')
    print('')
    return

def PrintBoard():
   
    line=("    a   b   c")
    line0=("  ╔═══╤═══╤═══╗")
    line1=('1 ║ '+ Board0[0] + ' │ '+ Board0[1] +' │ '+ Board0[2]+' ║')
    line2=("  ╟───┼───┼───╢")
    line3=('2 ║ '+ Board1[0] + ' │ '+ Board1[1] +' │ '+ Board1[2]+' ║')
    line5=('3 ║ '+ Board2[0] + ' │ '+ Board2[1] +' │ '+ Board2[2]+' ║')
    line6=("  ╚═══╧═══╧═══╝")
    
    print(line)
    print(line0)
    print(line1)
    print(line2)
    print(line3)
    print(line2)
    print(line5)
    print(line6)  
    return

def PrintCredits():

    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('Created by jakubziom 2024')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    
    return

Title()

Board0=[' ',' ',' ']
Board1=[' ',' ',' ']
Board2=[' ',' ',' ']

PrintBoard()

'Player 1 = x'
'Player 2 = o'

BoardNameList=[Board0,Board1,Board2]

def Player(mark):
    
    while True:
        #letter
        player=str(input(mark+' abc?'))
        #digit
        r=int(input(mark+' 123?'))-1
        if player=='a':
            c=0
        elif player=='b':
            c=1 
        elif player=='c':
            c=2
        else:
            continue
        if True:
            if  True and not ((BoardNameList[r])[c]=='x' or ((BoardNameList[r])[c]=='o')):
                (BoardNameList[r]).pop(c)
                (BoardNameList[r]).insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return

def Player1():
    mark='x'    
    Player(mark)
    return

def Player2():
    mark='o'
    Player(mark)
    return

def PlayerWins(m,win):
    for i in range(0,3):
        # horizontally
        if ((( BoardNameList[i])[0]==m and ( BoardNameList[i])[1]==m and ( BoardNameList[i])[2]==m)
   
        #vertically
            or (Board0[i]==m and Board1[i]==m and Board2[i]==m)
            
        #diagonally
            or (Board0[0]==m and Board1[1]==m and Board2[2]==m)
            or (Board0[2]==m and Board1[1]==m and Board2[0]==m)):
            win=True
            print(m+' wins!')
            PrintCredits()
            input('press Enter to exit!')
            exit()
    return win

def WinCheck():
    m='x'
    PlayerWins(m,win)
    m='o'
    PlayerWins(m,win)
    return

game=0
win=False

while win==False:
    
    Player1()
    WinCheck() 
    game+=1
    print(game)
    if game ==9:
        break
    Player2()
    WinCheck()
    game+=1
    print(game)

    
print('DRAW!')
PrintCredits()
input('press Enter to exit!')
exit()
3

jak można zrobić, aby gracz wpisywał np. a1, b2, zamiast osobno kolumny i wiersza?

Załóżmy że wsadziłeś tekst od gracza do player_input, i załóżmy że kolumna zawsze będzie tylko jednym znakiem, to możesz po prostu wydzielić z niego pierwszy znak player_input[0] na kolumnę, oraz pozostałe znaki player_input[1:] na wiersz

5

@jakubziom:

Mam prośbę o podpowiedź, jak można zrobić, aby gracz wpisywał np. a1, b2, zamiast osobno kolumny i wiersza?

str.split() rozdzieli Ci (wczytanego) stringa na podanym znaku/znakach. Jest też dużo innych rozwiązań, w ramach potrzeb i wymaganej elastyczności.

Oraz zastanawiam się jak łatwiej sprawdzić czy krzyżyki bądź kółka są po skosie?

Na skosie lewa góra → prawy dół obie współrzędne są jednakowe (tzn. w kwadracie 3×3 są to [0][0], [1][1], i [2][2], i analogicznie przy innych rozmiarach).
Na skosie prawa góra → lewy dół obie współrzędne sumują się do rozmiaru tablicy mniej jeden (tzn. w kwadracie 3×3 są to [0][2] (bo 0 + 2 = 3 - 1), [1][1] (bo 1 + 1 = 3 - 1), [2][0] (bo 2 + 0 = 3 - 1), i analogicznie przy innych rozmiarach).


Oprócz tego:

  • Powinieneś darować sobie # -*- coding: utf-8 -*- — UTF-8 jest domyślnym kodowaniem plików źródłowych Pythona od… jakoś tak dwudziestu lat, jak się nie mylę. A już zwłaszcza w Pythonie 3, w którym piszesz (i słusznie, Python 2 to w chwili obecnej dinozaur).
  • input sam z siebie zwraca stringa, nie trzeba go konwertować, tak jak to robisz tu: player=str(input(mark+' abc?'))
  • if True: jest zawsze spełnione, nie ma po co tego pisać; szczególnie późniejsze continue się nigdy nie wykona
  • if True and not … można zredukować do if not …, bo koniunkcja (and) prawdy i czegokolwiek to to samo, co tamto cokolwiek
  • if nie powinien dostawać warunku otoczonego nawiasami, tak jak to robisz w if ((( BoardNameList[i])[0]==m and ( BoardNameList[i])[1]==m and ( BoardNameList[i])[2]==m) — w przyszłości będziesz, być może, pisał swoje własne klasy, i się mocno zdziwisz (bo if nie napotka obiektu tej klasy, tylko jednoelementową krotkę z obiektem tej klasy)
  • jawne porównywanie do False, jak w while win==False:, lepiej zastąpić po prostu negacją notwhile not win:
  • w przyszłości przyda Ci się pewnie curses z biblioteki standardowej albo coś podobnego
0

Dziękuję za podpowiedzi, troszkę poprawiłem ten projekt (nie wszystko potrafiłem zrobić ale to z braku wiedzy) , teraz wracam do kursu Pythona, żeby ogarnąć więcej podstaw : )

"""
Created on Wed Mar  6 12:03:44 2024

@author: jakubziom
"""

def Title():
    print(' ===============')
    print('   TIC-TAC-TOE')
    print(' ===============')
    print('type a1, b3, etc.')
    return

def PrintBoard():
   
    line=("    a   b   c")
    line0=("  ╔═══╤═══╤═══╗")
    line1=('1 ║ '+ Board0[0] + ' │ '+ Board0[1] +' │ '+ Board0[2]+' ║')
    line2=("  ╟───┼───┼───╢")
    line3=('2 ║ '+ Board1[0] + ' │ '+ Board1[1] +' │ '+ Board1[2]+' ║')
    line5=('3 ║ '+ Board2[0] + ' │ '+ Board2[1] +' │ '+ Board2[2]+' ║')
    line6=("  ╚═══╧═══╧═══╝")
    
    print(line)
    print(line0)
    print(line1)
    print(line2)
    print(line3)
    print(line2)
    print(line5)
    print(line6)  
    return

def PrintCredits():

    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('Created by jakubziom 2024')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    
    return

Title()

Board0=[' ',' ',' ']
Board1=[' ',' ',' ']
Board2=[' ',' ',' ']

PrintBoard()

'Player 1 = x'
'Player 2 = o'

BoardList=[Board0,Board1,Board2]

def Player(mark):
    
    while True:
        #player input
        player=input(mark+'?')
        c_input=player[0]
        r=(int(player[1:])-1)
        #column translation from letter to number
        if c_input=='a':
            c=0
        elif c_input=='b':
            c=1 
        elif c_input=='c':
            c=2
        else:
            continue
        if not BoardList[r][c]=='x' or BoardList[r][c]=='o':
                BoardList[r].pop(c)
                BoardList[r].insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return

def PlayerWins(mark,win):
    for i in range(0,3):
        # horizontally
        if (( BoardList[i][0]==mark and  BoardList[i][1]==mark and  BoardList[i][2]==mark)
        #vertically
            or (Board0[i]==mark and Board1[i]==mark and Board2[i]==mark)
        #diagonally
            or (Board2[2]==mark and Board1[1]==mark and Board0[0]==mark )
            or (Board0[2]==mark and Board1[1]==mark and Board2[0]==mark)):
            win=True
            print(mark+' wins!')
            PrintCredits()
            input('press Enter to exit!')
            exit()
    return win

game=0
win=False

while not win:
    
    Player('x')
    PlayerWins('x',win)
    PlayerWins('o',win)
    game+=1
    if game ==9:
        break
    Player('o')
    PlayerWins('x',win)
    PlayerWins('o',win)
    game+=1
  
print('DRAW!')
PrintCredits()
input('press Enter to exit!')
exit() 
4

przeklejam swoją poprzednią odpowiedź (z mikrobloga). Widzę, że już pewne rzeczy zastosowałeś.

Tu by się przydało uogólnienie. Np. nie potrzebujesz oddzielnych funkcji Player1Wins i Player2Wins. Możesz mieć jedną funkcję, która obsługuje dowolnego gracza. Czym się te funkcje różnią? Tylko tym, że jest 'o' a w drugim 'x'? To możesz to jako argument dać w funkcji

def PlayerWins(player):

a potem sprawdzać

 if ((Board1[0]==player and Board1[1]==player and Board1[2]==player)

itp.
dalej. Jeśli masz zmienne Board1, Board2 i Board3 i używasz ich baaaardzo podobnie pod kątem algorytmu, to jest to oznaka, że zapewne potrzebujesz zrobić jakąś listę boards i zamiast Board1 będziesz miał boards[0], zamiast Board2 będziesz miał boards[1], zamiast Board3 będzie boards[2]. Obczaj sobie jak zrobić zagnieżdżone listy i jak po nich iterować za pomocą pętli.

Te ify

if player1=='a1' and not (Board1[0]=='x' or Board1[0]=='o'):

też można by uogólnić (w końcu w każdym ifie sprawdzasz prawie to samo i reagujesz prawie tak samo).

Jest to dla mnie ciekawe, dlaczego kod początkujących w wiekszości przypadków jest tak samo podobny w tym, że nie wykorzystuje uogólnienia/abstrakcji, tylko jest pisany każdy przypadek z osobna (pomyśl o tym, jak ty grasz w kółko i krzyżyk jako człowiek. Zapewne jak grasz, to myślisz w ten sposób, że musisz postawić 3 znaki tak, żeby wypełnić nimi całą linię (poziomą, pionową albo skośną). I to samo można zaprogramować komputerowi. Ogólne zasady. Pomyśl np. że robisz kółko i krzyżyk, ale z tą różnicą, że wielkość będzie można dostosować (może być 3x3, ale i 10x10). Albo że graczy jest trzech. Wtedy już coraz trudniej byłoby rozpatrywać każdy przypadek z osobna.

Tylko może być tak, że brak ci pewnej wiedzy o języku (tutaj zapewne dotyczącej: używania zmiennych; argumentów w funkcjach; list zagnieżdżonych; iterowania po listach)

0

Poprawiłem nieco funkcję Player, żeby nie powodowało błędów przy przypadkowych wpisach:

def Player(mark):
    
    while True:
        #player input
        player=input(mark+'?') 
        try:
            r=(int(player[1:])-1)
        except:
            continue    
        c_input=player[0]
        if r >= 3 or r <=-1:
            continue
        #column translation from letter to number
        if c_input=='a':
            c=0
        elif c_input=='b':
            c=1 
        elif c_input=='c':
            c=2
        else:
            continue
        if not BoardList[r][c]=='x' or BoardList[r][c]=='o':
                BoardList[r].pop(c)
                BoardList[r].insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return
0

Udało mi się napisać funkcję, która sprawdza krzyżyki bądź kółka po pierwszej przekątnej. Sprawdzanie poziome zastąpiłem countem aby można było powiększyć później planszę. Zostało mi rozwiązanie sprawdzania pionowego oraz po drugiej przekątnej : )

def PlayerWinsD1(mark,D1,win):
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1+=1   
            print('D1',mark,D1)
    if D1==BoardSize:
        Congratulations(win,mark)
    return D1,win

Litery wpisuje się teraz ze słownika.


col={'a':0,'b':1,'c':2,'d':3,'e':4,'f':5}

BoardList=[Board0,Board1,Board2]

def Player(mark):
    
    while True:
        #player input
        player=input(mark+'?') 
        try:
            r=(int(player[1:])-1)
        except:
            continue    
        c_input=player[0]
        if r >= BoardSize or r <=-1:
            continue
        #column translation from letter to number
        try:
            c=col[c_input]
        except:
            continue
        if c >= BoardSize or c <=-1:
            continue
        if not BoardList[r][c]=='x' or BoardList[r][c]=='o':
                BoardList[r].pop(c)
                BoardList[r].insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return
0

Ciąg dalszy : ) Udało mi się zrobić liczniki kółek i krzyżyków w pionie (Vx i Vo). Musiałem rozdzielić kółka i krzyżyki na stare (postawione w poprzednim ruchu) (OldVx i OldVo) i te w obecnym. Mam nadzieję, że jeśli liczniki mam na listach, to będę mógł je później poszerzyć w przypadku większej planszy.

Vx=[0,0,0]
Vo=[0,0,0]
V={'x':Vx,'o':Vo}

OldVx=[0,0,0]
OldVo=[0,0,0]
OldV={'x':Vx,'o':Vo}

def OldMarkV(n,i,mark,OldV):
    for i in range(0,BoardSize):
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                OldV[mark][i]+=1
    print('OldV',mark,OldV)
    return OldV

def PlayerWinsV(n,i,mark,V):
    for i in range(0,BoardSize):
        V[mark][i]-=(OldV[mark][i])
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                V[mark][i]+=1
                if V[mark][i]==BoardSize:
                    Congratulations(win,mark)
    print('V',mark,V)

    return V,win

Kolejność rozgrywki:


while not win:
    
    OldMarkV(n, i, 'x', OldV)
    Player('x')  
    PlayerWinsV(n,i,'x',V)
    PlayerWinsD1H('x',win,n,i)
    game+=1
    if game ==BoardSize**2:
        break
    OldMarkV(n, i, 'o', OldV)
    Player('o')  
    PlayerWinsV(n,i,'o',V)
    PlayerWinsD1H('o',win,n,i)
    game+=1
  
print('DRAW!')
PrintCredits()
input('press Enter to exit!')
exit()
0

Wersja "Beta", na pewno da się jeszcze uprościć trochę rzeczy. Można wybrać między planszą 1x1 a 6x6. Dziękuję @LukeJ za inspirację : )

"""
Created on Wed Mar  6 12:03:44 2024

@author: jakubziom
"""

def Title():
    print(' ===============')
    print('   TIC-TAC-TOE')
    print(' ===============')
    print('type a1, b3, etc.')
    return

Title()
    
BoardSize=int(input('Board Size? 1-6?'))  
    
Board0=[]
Board1=[]
Board2=[]
Board3=[]
Board4=[]
Board5=[]

'Player 1 = x'
'Player 2 = o'

col={'a':0,'b':1,'c':2,'d':3,'e':4,'f':5}

BoardList=[Board0,Board1,Board2,Board3,Board4,Board5]

Vx=[]
Vo=[]
V={'x':Vx,'o':Vo}

OldVx=[]
OldVo=[]
OldV={'x':Vx,'o':Vo}

for i in range(0,BoardSize):
    for i in range(0,BoardSize):
        BoardList[i].insert(0,' ')
    Vx.insert(0,0)
    Vo.insert(0,0)
    OldVx.insert(0,0)
    OldVo.insert(0,0)
    continue

def PrintBoard():
    BoardLetter=['    a','   b','   c','   d','   e','   f']
      
    LINE1=['1 │ ',]
    LINE2=['2 │ ',]
    LINE3=['3 │ ',]
    LINE4=['4 │ ',]
    LINE5=['5 │ ',]
    LINE6=['6 │ ',]

    BOARD=[LINE1,LINE2,LINE3,LINE4,LINE5,LINE6]

    for i in range(0,BoardSize):
        Letters=BoardLetter[slice(0,BoardSize)]
        lineSepTop='  ┼'+ i*('───┼') + '───┼'
        lineSepMid='  ┼'+i*('───┼')+'───┼'
        for n in range(0,BoardSize):
                BOARD[n].append(BoardList[n][i])
                BOARD[n].append(' │ ')
        '''
        lineSepDwn='  ╚'+i*('═══╧')+'═══╝'
        '''
    line1=''
    line2=''
    line3=''
    line4=''
    line5=''
    line6=''
    letters=''
    for a in LINE1:
        line1 += a
    for a in LINE2:
        line2 += a
    for a in LINE3:
        line3 += a
    for a in LINE4:
        line4 += a
    for a in LINE5:
        line5 += a
    for a in LINE6:
        line6 += a
    lines=[line1,line2,line3,line4,line5,line6]
    for a in Letters:
        letters += a
    print(letters)
    print(lineSepTop)
    for i in range(0,BoardSize):
        print(lines[i])
        print(lineSepMid)
    return

def PrintCredits():

    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('Created by jakubziom 2024')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    
    return

PrintBoard()

def Player(mark):
    
    while True:
        #player input
        player=input(mark+'?') 
        try:
            r=(int(player[1:])-1)
        except:
            continue    
        c_input=player[0]
        if r >= BoardSize or r <=-1:
            continue
        #column translation from letter to number
        try:
            c=col[c_input]
        except:
            continue
        if c >= BoardSize or c <=-1:
            continue
        if not (BoardList[r][c]=='x' or BoardList[r][c]=='o'):
                BoardList[r].pop(c)
                BoardList[r].insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return

i=0

def Congratulations(win,mark):
    win=True
    print(mark+' wins!')
    PrintCredits()
    input('press Enter to exit!')
    return win,mark

def PlayerWinsD1(mark,D1,win):
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1+=1   
    '''
    print('D1',mark,D1)
    '''
    if D1==BoardSize:
        Congratulations(win,mark)
    return D1,win

def PlayerWinsD2(mark,D2,win):
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2+=1 
    '''
    print('D2',mark,D2)
    '''
    if D2==BoardSize:
        Congratulations(win,mark)
    return D2,win

def OldMarkV(n,i,mark,OldV):
    for i in range(0,BoardSize):
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                OldV[mark][i]+=1
    return OldV

def PlayerWinsV(n,i,mark,V):
    for i in range(0,BoardSize):
        V[mark][i]-=(OldV[mark][i])
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                V[mark][i]+=1
                if V[mark][i]==BoardSize:
                    Congratulations(win,mark)
    '''
    print('V',mark,V)
    '''
    return V,win

def PlayerWinsDH(mark,win,n,i):
    PlayerWinsD1(mark,D1,win)
    PlayerWinsD2(mark, D2, win)
    for i in range(0,BoardSize):
        # horizontally
        if BoardList[i].count(mark)==BoardSize:
            Congratulations(win,mark)
    return win
n=0
D1=0
D2=0
game=0
win=False

while not win:
    
    OldMarkV(n, i, 'x', OldV)
    Player('x')  
    PlayerWinsV(n,i,'x',V)
    PlayerWinsDH('x',win,n,i)
    game+=1
    if game ==BoardSize**2:
        break
    OldMarkV(n, i, 'o', OldV)
    Player('o')  
    PlayerWinsV(n,i,'o',V)
    PlayerWinsDH('o',win,n,i)
    game+=1
  
print('DRAW!')
PrintCredits()
input('press Enter to exit!')
exit()

1

Teraz możesz dodać podpowiadanie najlepszego ruchu w danym momencie, coś jak silnik do analizy partii lub dodanie bota z różnym poziomem trudności.

Wyliczysz sobie MinMax lub MinMax z pruningiem gałęzi czyli alpha beta pruning.

Potem możesz wyświetlać statystyki np. 100% lose, 50% draw i 100% win dla wybrania danego ruchu, np. jeśli przeciwnik nie ma żadnego ruchu, który przed przegraniem go uchroni to możesz dać 100% win, możesz wyliczać bardziej te statystyki lub zawsze dawać 50%, jeśli ty i przeciwnik macie po ruchu, który broni przed przegraniem każdego z graczy.

Bota teraz jak będziesz chciał zrobić, to wybierasz najlepszy ruch, ale jak chcesz bota trochę słabszego zrobić to możesz zrobić jakiś epsilion greedy losowanie, gdzie byś ustawiał w jakim procencie ma wybierać najlepszy ruch np. w 80% wybiera najlepszy możliwy ruch, prowadzący do wygranej, a 20% szans na wybranie ruchu między remisem, a porażką.
Oczywiście tam można znacznie bardziej rozszerzyć działanie tego bota.

0

Spróbuję : ) W międzyczasie uzupełniłem gierkę o poprawne sprawdzanie remisów (mogą zostać niewypełnione pola i być remis). Funkcje liczą czy jest co najmniej jedno kółko i krzyżyk w linii (poziom, pion, ukos1, ukos2) Przy ukosach są tylko po 1 do spełnienia, przy innych liniach musiałem policzyć też ilość linii na planszy.

#values for checking draw 
D1Drawx=False
D1Drawo=False
D2Drawx=False
D2Drawo=False
D1Draw={'x':D1Drawx,'o':D1Drawo}
D2Draw={'x':D2Drawx,'o':D2Drawo}
#diagonaldraw
def PlayerDrawD1(mark,D1Draw,win):
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1Draw[mark]=True   
    #this is for testing
    print('D1Draw',D1Draw)
    return D1Drawx,D1Drawo,win

def PlayerDrawD2(mark,D2Draw,win):
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2Draw[mark]=True 
    #this is for testing
    print('D2Draw',D2Draw)
    return D2Drawx, D2Drawo, win

def Draw(win):   
    VDrawCount=0
    HDrawCount=0
    #VerticalDraw
    for i in range(0,BoardSize):
        if( V['x'][i]>=1 and V['o'][i]>=1):
            VDrawCount+=1
    #HorizontalDraw
    for i in range(0,BoardSize):
        if (BoardList[i].count('x')>=1 and BoardList[i].count('o')>=1):
            HDrawCount+=1
    #this is for testing 
    print('VDrawCount',VDrawCount)
    print('HDrawCount',HDrawCount)   
    #DrawConditions
    if (D1Draw['x']==True and D1Draw['o']==True
        and D2Draw['x']==True and D2Draw['o']==True
        and VDrawCount==BoardSize
        and HDrawCount==BoardSize):      
        win=True
        print('DRAW!')
        input('press Enter to exit!')
        exit()
    return win


Skróciłem też trochę funkcję drukowania planszy:

def PrintBoard():
    BoardLetter=['    a','   b','   c','   d','   e','   f']
      
    LINE1=['1 │ ',]
    LINE2=['2 │ ',]
    LINE3=['3 │ ',]
    LINE4=['4 │ ',]
    LINE5=['5 │ ',]
    LINE6=['6 │ ',]

    BOARD=[LINE1,LINE2,LINE3,LINE4,LINE5,LINE6]

    for i in range(0,BoardSize):
        Letters=BoardLetter[slice(0,BoardSize)]
        lineSep='  ┼'+i*('───┼')+'───┼'
        for n in range(0,BoardSize):
                BOARD[n].append(BoardList[n][i])
                BOARD[n].append(' │ ')
    line1=''
    line2=''
    line3=''
    line4=''
    line5=''
    line6=''
    letters=''
    lines=[line1,line2,line3,line4,line5,line6]
    for i in range(0,BoardSize):
        for a in BOARD[i]:
            lines[i] += a
    for a in Letters:
        letters += a
    print(letters)
    print(lineSep)
    for i in range(0,BoardSize):
        print(lines[i])
        print(lineSep)
    return
1

Temat wyewoluował, zdecydowałem się go przenieść do innego działu.

Mam też następujące podstawowe¹ uwagi co do kodu (kolejność przypadkowa, w szczególności nie jest to kolejność od najważniejszych do najmniej ważnych):

  1. Nazewnictwo zmiennych i funkcji — trzeba się wgryzać, żeby zobaczyć, co to jest D1Drawo, czemu służy i czym się różni od D2Drawo albo D1Drawx.
  2. Powtarzanie logiki w funkcjach — czym takim się różni PlayerDrawD1 od PlayerDrawD2, żeby to były osobne funkcje?
  3. if nie potrzebuje mieć warunku w (nawiasach) — wręcz nie powinien, zbyt łatwo pomylić z tupką.
  4. Jawne porównywanie z True powoduje tylko wydłużenie kodu bez zwiększenia czytelności, szczególnie gdy skutkuje połamaniem kodu na wiele linii.
  5. Przeplatanie kodu produkcyjnego printami „#this is for testing” to proszenie się o wyciek takich wypisów testowych do kodu produkcyjnego. Jeszcze u Ciebie pół biedy, bo nie robisz tradycyjnego „dupa-debugu”, ale wciąż…
  6. BOARD czy lines możesz znacznie krócej i czytelniej zrobić przez list comprehension. A jeśli tego nie znasz i jeszcze nie chcesz znać, to chociaż samo lines możesz zrobić szybciej przez nie tworzenie sześciu takich samych line{1..6}, tylko skorzystać sześć razy z jednej.

¹ Uwag byłoby więcej, ale dopiero się uczysz, więc nie ma co sugerować rozwiązań wymagających większej znajomości języka.

0

Wrzucam całość, dodałem opisy do poszczególnych elementów, poprawiłem wprowadzanie rozmiaru planszy (nie wywala przy złych wpisach). Złączyłem niepotrzebnie osobne funkcje związane z remisem w jedną. Przy funkcjach związanych z player wins też chciałem to zrobić, ale to trochę większa robota żeby dalej działało, więc na razie zostawiłem. Z lines jeszcze nie poprawiłem, muszę teraz wreszcie wrócić do kursu i dowiedzieć się więcej o języku : ) Przyznam się, że jest to jeden z pierwszych projektów i czuję duży zapał, ale muszę sobie zrobić przerwę na dzień, dwa.

"""
Created on Wed Mar  6 12:03:44 2024

@author: jakubziom
"""

def Title():
    #prints title
    print(' ===============')
    print('   TIC-TAC-TOE')
    print(' ===============')
    print('type a1, b3, etc.')
    return

Title()

#defines size of the side of the board
while True:
    try:
        BoardSize=int(input('Board Size? 1-6?'))        
    except:
        continue    
    if  1 > BoardSize >6:
        continue
    elif 0 < BoardSize <7:
        break
         
#horizontal lines
Board0=[]
Board1=[]
Board2=[]
Board3=[]
Board4=[]
Board5=[]

'Player 1 = x'
'Player 2 = o'

#column letters transation to numbers
col={'a':0,'b':1,'c':2,'d':3,'e':4,'f':5}

BoardList=[Board0,Board1,Board2,Board3,Board4,Board5]

#number of marks in vertical lines (after player input)
Vx=[]
Vo=[]
#putting it together
V={'x':Vx,'o':Vo}

#number of marks in vertical lines (before player input)
OldVx=[]
OldVo=[]
#putting it together
OldV={'x':Vx,'o':Vo}

for i in range(0,BoardSize):
    #filling the lists to create the board
    for i in range(0,BoardSize):
        BoardList[i].insert(0,' ')
    #filling the lists to make vertical mark counters
    Vx.insert(0,0)
    Vo.insert(0,0)
    OldVx.insert(0,0)
    OldVo.insert(0,0)
    continue

def PrintBoard():
    #displays the board with separator lines (what player sees)
    BoardLetter=['    a','   b','   c','   d','   e','   f']
    #lists to put the horizontal line elements together
    LINE1=['1 │ ',]
    LINE2=['2 │ ',]
    LINE3=['3 │ ',]
    LINE4=['4 │ ',]
    LINE5=['5 │ ',]
    LINE6=['6 │ ',]

    BOARD=[LINE1,LINE2,LINE3,LINE4,LINE5,LINE6]

    for i in range(0,BoardSize):
        Letters=BoardLetter[slice(0,BoardSize)]
        lineSep='  ┼'+i*('───┼')+'───┼'
        for n in range(0,BoardSize):
                BOARD[n].append(BoardList[n][i])
                BOARD[n].append(' │ ')
    #lists for making final look of the horizontal lines
    line1=''
    line2=''
    line3=''
    line4=''
    line5=''
    line6=''
    letters=''
    lines=[line1,line2,line3,line4,line5,line6]
    for i in range(0,BoardSize):
        for a in BOARD[i]:
            #creates final looking lines with marks
            lines[i] += a
    for a in Letters:
        letters += a
    print(letters)
    print(lineSep)
    for i in range(0,BoardSize):
        print(lines[i])
        print(lineSep)
    return

def PrintCredits():
    #it prints credits after the game
    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('Created by jakubziom 2024')
    print('')
    print('')
    print('')
    print('')
    print('')
    print('')
    
    return

PrintBoard()

def Player(mark):
    #putting the mark
    while True:
        #player input
        player=input(mark+'?') 
        try:
            r=(int(player[1:])-1)
        except:
            continue    
        c_input=player[0]
        if r >= BoardSize or r <=-1:
            continue
        #column translation from letter to number
        try:
            c=col[c_input]
        except:
            continue
        if c >= BoardSize or c <=-1:
            continue
        #condition to prevent from putting the mark again in same place
        if not (BoardList[r][c]=='x' or BoardList[r][c]=='o'):
                BoardList[r].pop(c)
                BoardList[r].insert(c, mark)
                PrintBoard()
                break       
        else:  
            continue  
    return

i=0

def Congratulations(win,mark):
    #if one of the players wins
    win=True
    print(mark+' wins!')
    PrintCredits()
    input('press Enter to exit!')
    exit()
    return win,mark

def PlayerWinsD1(mark,D1,win):
    #diagonal win 1
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1+=1   
    #this is for testing
    '''
    print('D1',mark,D1)
    '''
    if D1==BoardSize:
        Congratulations(win,mark)
    return D1,win

def PlayerWinsD2(mark,D2,win):
    #diagonal win 2
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2+=1 
    #this is for testing
    '''
    print('D2',mark,D2)
    '''
    if D2==BoardSize:
        Congratulations(win,mark)
    return D2,win

def OldMarkV(n,i,mark,OldV):
    #counting marks from previous round in vertical lines
    for i in range(0,BoardSize):
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                OldV[mark][i]+=1
    return OldV

def PlayerWinsV(n,i,mark,V):
    #vertical win
    for i in range(0,BoardSize):
        #substracting marks from previous round in vertical lines
        V[mark][i]-=(OldV[mark][i])
        #counting marks x or o in vertical lines
        for n in range(0,BoardSize):
            if BoardList[n][i]==mark:
                V[mark][i]+=1
                if V[mark][i]==BoardSize:
                    Congratulations(win,mark)
    #this is for testing
    '''
    print('V',mark,V)
    '''
    return V,win

#diagonal or horizontal win
def PlayerWinsDH(mark,win,n,i):
    #diagonal win
    PlayerWinsD1(mark,D1,win)
    PlayerWinsD2(mark, D2, win)
    for i in range(0,BoardSize):
        # horizontal win
        if BoardList[i].count(mark)==BoardSize:
            Congratulations(win,mark)
    return win

#values for checking draw
#is x in diagonal line 1?
D1Drawx=False
#is o in diagonal line 1?
D1Drawo=False
#is x in diagonal line 2?
D2Drawx=False
#is o in diagonal line 2?
D2Drawo=False
#putting it together
D1Draw={'x':D1Drawx,'o':D1Drawo}
D2Draw={'x':D2Drawx,'o':D2Drawo}

def Draw(win,mark):
    #diagonal draw 1
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1Draw[mark]=True   
    #this is for testing 
    '''
    print('D1Draw',D1Draw)
    '''
    #diagonal draw 2
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2Draw[mark]=True 
    #this is for testing
    '''
    print('D2Draw',D2Draw)
    '''
    VDrawCount=0
    HDrawCount=0
    #vertical draw
    for i in range(0,BoardSize):
        if V['x'][i]>=1 and V['o'][i]>=1:
            VDrawCount+=1
    #horizonal draw
    for i in range(0,BoardSize):
        if BoardList[i].count('x')>=1 and BoardList[i].count('o')>=1:
            HDrawCount+=1
    #this is for testing
    '''    
    print('VDrawCount',VDrawCount)
    print('HDrawCount',HDrawCount)
    '''
    #draw conditions
    if (D1Draw['x']==True and D1Draw['o']==True
        and D2Draw['x']==True and D2Draw['o']==True
        and VDrawCount==BoardSize
        and HDrawCount==BoardSize):      
        win=True
        print('DRAW!')
        PrintCredits()
        input('press Enter to exit!')
        exit()
    return win,mark

#number of horizontal and verical lines with x and o in them
HDrawCount=0
VDrawCount=0
#this just counts the loop
n=0
#number of x or o in diagonal line 1 and 2
D1=0
D2=0
#number of rounds (obsolete)
game=0
#if true the game ends (player wins or draw)
win=False

while not win:
    #loop until the player wins or draw
    #x
    OldMarkV(n, i, 'x', OldV)
    Player('x')  
    PlayerWinsV(n,i,'x',V)
    PlayerWinsDH('x',win,n,i)
    Draw(win,'x')
    game+=1
    #o
    OldMarkV(n, i, 'o', OldV)
    Player('o')  
    PlayerWinsV(n,i,'o',V)
    PlayerWinsDH('o',win,n,i)
    Draw(win,'o')
    game+=1
0

W linku projekt grafiki 3d do gry, zacząłem się interesować silnikiem Panda3d i mam w planach zrobienie tej gierki w 3d. (I żeby dało się klikać myszką : ) Trochę czytałem już o minmax ale muszę najpierw przerobić prostszy przykład.

Może zrobiłbym też kilka skórek, na razie jedna, aby w ogóle mieć na czym pracować.

https://drive.google.com/drive/folders/1JBZUX-32noPx4SIkWOecdmLdS1ST-UKR?usp=sharing

0
jakubziom napisał(a):

W linku projekt grafiki 3d do gry, zacząłem się interesować silnikiem Panda3d i mam w planach zrobienie tej gierki w 3d. (I żeby dało się klikać myszką : ) Trochę czytałem już o minmax ale muszę najpierw przerobić prostszy przykład.

Może zrobiłbym też kilka skórek, na razie jedna, aby w ogóle mieć na czym pracować.

https://drive.google.com/drive/folders/1JBZUX-32noPx4SIkWOecdmLdS1ST-UKR?usp=sharing

Panda3D, wow dawno nie słyszałem tego określenia, czemu akurat ten silnik? Dla Pythona?

0
dalbajob napisał(a):

Panda3D, wow dawno nie słyszałem tego określenia, czemu akurat ten silnik? Dla Pythona?

Tak, bo pisze się w Pythonie. Zacząłem już coś robić, ale nic mi nie wychodzi na razie. Muszę nauczyć się jak pracować na obiektach itd..

0
jakubziom napisał(a):
dalbajob napisał(a):

Panda3D, wow dawno nie słyszałem tego określenia, czemu akurat ten silnik? Dla Pythona?

Tak, bo pisze się w Pythonie. Zacząłem już coś robić, ale nic mi nie wychodzi na razie. Muszę nauczyć się jak pracować na obiektach itd..

No to będzie duży przeskok dla ciebie. Jak dla mnie lepiej jeśli zacząłbyś od prostej wersji 2D, nawet nie w silniku do gry tylko z biblioteką do GUI, np. z TkInter

0

Powoli idzie do przodu : )

1

Trochę nowych rzeczy w gierce: każdy bloczek to osobna zmienna, dzięki czemu mogę z nimi coś robić. W kodzie użyłem zmiennych, tak jak w wersji tekstowej, żeby móc stworzyć później większe plansze. Teraz próbuję rozgryźć obsługę myszką (użycie collision ray). Na razie ciężko mi to idzie, ale pewnie jest to do zrobienia : )

1

Kolejny etap - udało się dodać obsługę myszką i resetowanie planszy. Gierka jeszcze nie wykrywa remisów, ale jest to do zrobienia 🙂

1

Update:
-dodane wybieranie wielkości planszy (3x3 i 4x4), docelowo może będzie też 5x5
-dodane wykrywanie remisów

Jednak następną rzeczą, jaką chcę zrobić jest zapoznanie się minimax 🙂

0

Udało mi się zrobić bota dla wersji tekstowej, trzeba było trochę poszperać w internecie. Na razie jest tak, że dla planszy 3x3 jest depth 5 albo większy, dla planszy 4x4 działa tylko depth 3
Tutaj kod dla wprowadzania znaków przez komputer oraz algorytm minimax:

    
def insertLetter(mark,n,i):
    if not (BoardList[n][i]=='x' or BoardList[n][i]=='o'):
        BoardList[n].pop(i)
        BoardList[n].insert(i, mark)
        PrintBoard()
    else:
        exit()
    return  

def Computer(max_depth):
    
    max_score=-float('inf')
    best_moveR = 0
    best_moveC = 0
    
    for n in range(0,BoardSize):
        for i in range(0,BoardSize):
            if BoardList[n][i]==' ':
                BoardList[n].pop(i)
                BoardList[n].insert(i,'o')
                score = minimax(0,False,max_depth)
                BoardList[n].pop(i)
                BoardList[n].insert(i,' ')
                if score > max_score:
                    max_score = score
                    best_moveR = n
                    best_moveC= i
                    random_moveR = random.randint(0, BoardSize)
                    random_moveC= random.randint(0, BoardSize)

    
        #insertLetter('o', random_moveR,random_moveC)  
    
    insertLetter('o', best_moveR,best_moveC)
    return best_moveR,best_moveC

def minimax(depth, isMaximizing,max_depth):
    if HorizontalWinC('o') or PlayerWinsVC('o',V) or PlayerWinsD1C('o', D1, win) or PlayerWinsD2C('o',D2,win):
        return 1
    if HorizontalWinC('x') or PlayerWinsVC('x',V) or PlayerWinsD1C('x', D1, win) or PlayerWinsD2C('x',D2,win): 
        return -1
    
    if DrawC(win,'o') or DrawC(win,'x') or depth==max_depth:
        return 0
    
    
    if isMaximizing:
        max_score = -float('inf')
    
        for n in range(0,BoardSize):
            for i in range(0,BoardSize):
                if BoardList[n][i]==' ':
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,'o')
                    score = minimax(depth+1,False,max_depth)
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,' ')
                    
                    max_score = max(max_score, score)
        return max_score
    else:
        min_score = float('inf')
        for n in range(0,BoardSize):
            for i in range(0,BoardSize):
                if BoardList[n][i]==' ':
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,'x')
                    score = minimax(depth+1,True,max_depth)
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,' ')
                    
                    min_score = min(min_score, score)
        return min_score  

Funkcje dla wykrywania wygranej przez komputer:

def DrawC(win,mark):
    #diagonal draw 1
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1Draw[mark]=True   
    #this is for testing 
    '''
    print('D1Draw',D1Draw)
    '''
    #diagonal draw 2
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2Draw[mark]=True 
    #this is for testing
    '''
    print('D2Draw',D2Draw)
    '''
    VDrawCount=0
    HDrawCount=0
    #vertical draw
    for i in range(0,BoardSize):
        if V['x'][i]>=1 and V['o'][i]>=1:
            VDrawCount+=1
    #horizonal draw
    for i in range(0,BoardSize):
        if BoardList[i].count('x')>=1 and BoardList[i].count('o')>=1:
            HDrawCount+=1
    #this is for testing
    '''    
    print('VDrawCount',VDrawCount)
    print('HDrawCount',HDrawCount)
    '''
    #draw conditions
    if (D1Draw['x']==True and D1Draw['o']==True
        and D2Draw['x']==True and D2Draw['o']==True
        and VDrawCount==BoardSize
        and HDrawCount==BoardSize):      
        return win, True

def PlayerWinsD1C(mark,D1,win):
    D1=0
    #diagonal win 1
    for i in range(0,BoardSize):
        if BoardList[i][i]==mark:
            D1+=1  
    #print(D1)
    #this is for testing
    '''
    print('D1',mark,D1)
    '''
    if D1==BoardSize:       
        return True
    
def PlayerWinsD2C(mark,D2,win):
    D2=0
    #diagonal win 2
    for i in range(0,BoardSize):
        if BoardList[BoardSize-1-i][i]==mark:
            D2+=1 
    #print(D2)
    #this is for testing
    '''
    print('D2',mark,D2)
    '''
    if D2==BoardSize:
        return True    
    
def HorizontalWinC(mark):
    for i in range(0,BoardSize):
        #print(BoardList[i].count(mark))
        # horizontal win
        if BoardList[i].count(mark)==BoardSize:
            
            return True

Natomiast napotkałem na problem. Gdy przepisałem to do wersji 3d, funkcje najprawdopodobniej przestały zwracać wartość "True" (debugowałem żeby znaleźć problem).
Nie wiem czym to jest spowodowane. Gdy dam żeby było zawsze True to coś się dzieje, znaczy pozostała część kodu działa:
W Panda3d cała zawartość uruchamiana jest pod klasą MyApp, stąd przed każdą zmienną dopisek "self":
Sama plansza jest wpisana na zewnątrz klasy MyApp, ale próbowałem też ją wpisać wewnątrz MyApp i rezultat był taki sam, nic to nie zmienia.

WERSJA 3d: Plansza

Board0=['','','',''] 
Board1=['','','','']
Board2=['','','','']
Board3=['','','','']

BoardList=[Board0,Board1,Board2,Board3]

Kod dla ruchu komputera:

    def computer(self, max_depth):
        
        self.max_score=-1000
        self.best_moveR = 0
        self.best_moveC = 0
        self.random_moveR = random.randint(0, self.BoardSize-1) 
        self.random_moveC = random.randint(0, self.BoardSize-1) 
        
        for i in range(0,self.BoardSize):
            for n in range(0,self.BoardSize):
                if BoardList[n][i]=='':
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,'o')
                    self.score = self.minimax(0,False,max_depth)
                    BoardList[n].pop(i)
                    BoardList[n].insert(i,'')
                    if self.score > self.max_score:
                        self.max_score = self.score
                        self.best_moveR = n
                        self.best_moveC = i
                        print(self.best_moveR)
                        print(self.best_moveC)

            
         
        '''
        try: 
            self.insertLetter('o', self.random_moveR,self.random_moveC)
        except:
            try:
                self.insertLetter('o', self.random_moveR,self.random_moveR) 
            except:
                self.insertLetter('o', self.best_moveR,self.best_moveC)
        '''        
        
        self.insertLetter('o', self.best_moveR,self.best_moveC)
        
                               
             
        return self.best_moveR,self.best_moveC
  
    
    def minimax(self, depth, isMaximizing,max_depth):
        

       
        if self.HorizontalWinC('o') or self.PlayerWinsVC('o') or self.PlayerWinsD1C('o') or self.PlayerWinsD2C('o'):
            return 1
             
        if self.HorizontalWinC('x') or self.PlayerWinsVC('x') or self.PlayerWinsD1C('x') or self.PlayerWinsD2C('x'): 
            return -1
        
        if self.DrawC('o') or self.DrawC('x') or depth==max_depth:
            return 0
        
        print(self.HorizontalWinC('o'),self.PlayerWinsVC('o'),self.PlayerWinsD1C('o'),self.PlayerWinsD2C('o'))
        print(self.HorizontalWinC('x'),self.PlayerWinsVC('x'),self.PlayerWinsD1C('x'),self.PlayerWinsD2C('x'))
        print(self.DrawC('o'),self.DrawC('x'))
            
        if isMaximizing:
            self.max_score = -1000
            
            for n in range(0,self.BoardSize):
                for i in range(0,self.BoardSize):
                    if BoardList[n][i]=='':
                        BoardList[n].pop(i)
                        BoardList[n].insert(i,'o')
                        self.score = self.minimax(depth+1,False,max_depth)
                        BoardList[n].pop(i)
                        BoardList[n].insert(i,'')
                        if self.score > self.max_score:
                            self.max_score = self.score
            return self.max_score
            
        else:
            self.max_score = 800
            for n in range(0,self.BoardSize):
                for i in range(0,self.BoardSize):
                    if BoardList[n][i]=='':
                        BoardList[n].pop(i)
                        BoardList[n].insert(i,'x')
                        self.score = self.minimax(depth+1,True,max_depth)
                        BoardList[n].pop(i)
                        BoardList[n].insert(i,'')
                        if self.score < self.max_score:
                            self.max_score = self.score
            return self.max_score  

Oraz funkcje, które nie zwracają teraz "True" (są bardzo podobne jak w przypadku wersji tekstowej)

    def HorizontalWinC(self,mark):
        for i in range(0,self.BoardSize):
            print(BoardList[i].count(mark))
            #checking horizontal win
            if BoardList[i].count(mark)==self.BoardSize:
                return True
            
    def PlayerWinsVC(self,mark):
        for i in range(0,self.BoardSize):
            self.VC[mark][i]=0
            
        for i in range(0,self.BoardSize):
            #counting marks x or o in vertical lines
            for n in range(0,self.BoardSize):
                if BoardList[n][i]==mark:
                    self.VC[mark][i]+=1
                    print('VC'+str(self.VC))
                    if self.VC[mark][i]==self.BoardSize:
                        return True
            
    def PlayerWinsD1C(self,mark):
        self.D1C[mark]=0  
        for i in range(0,self.BoardSize):
            if BoardList[i][i]==mark:
                self.D1C[mark]+=1 
                print('D1C'+str(self.D1C))
        if self.D1C[mark]==self.BoardSize:
            return True
        
    def PlayerWinsD2C(self,mark):    
        self.D2C[mark]=0   
        
        for i in range(0,self.BoardSize):
            if BoardList[self.BoardSize-1-i][i]==mark:
                self.D2C[mark]+=1 
                print('D2C'+str(self.D2C)) 
        if self.D2C[mark]==self.BoardSize:
            return True 
    
    def DrawC(self,mark):
        self.D1DrawC[mark]=False
        self.D2DrawC[mark]=False
        for i in range(0,self.BoardSize):
            self.VC[mark][i]=0
 
        for i in range(0,self.BoardSize):
            if BoardList[i][i]==mark:
                self.D1DrawC[mark]=True  
                print('D1DrawC',self.D1DrawC)
        #this is for testing 
        
        #diagonal draw 2
        for i in range(0,self.BoardSize):
            if BoardList[self.BoardSize-1-i][i]==mark:
                self.D2DrawC[mark]=True 
                print('D2DrawC',self.D2DrawC)
        #this is for testing
        
        self.VDrawCountC=0
        self.HDrawCountC=0
        #vertical draw
        for i in range(0,self.BoardSize):
            if self.VC['x'][i]>=1 and self.VC['o'][i]>=1:
                self.VDrawCountC+=1
                print('VDrawCountC',self.VDrawCountC)
        #horizonal draw

        for i in range(0,self.BoardSize):
            if BoardList[i].count('x')>=1 and BoardList[i].count('o')>=1:
                self.HDrawCountC+=1
                print('HDrawCountC',self.HDrawCountC)
        #this is for testing
        
        if (self.D1DrawC['x']==True and self.D1DrawC['o']==True
            and self.D2DrawC['x']==True and self.D2DrawC['o']==True
            and self.VDrawCountC==self.BoardSize
            and self.HDrawCountC==self.BoardSize):      
            return True   

Nie wiem czemu to teraz nie działa, jedyna różnica jest taka, że wszystko jest w klasie MyApp, która jest uruchomiona w pętli, może ktoś zna na to odpowiedź, albo korzystał z tego silnika... ?
Liczniki liczą podobnie jak w przypadku wersji tekstowej.

ps: wiem już że nazwy funkcji pisze się małą literą, ale jeszcze tego nie poprawiłem :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1