TI/Kółko i krzyżyk

Z Brain-wiki

Media:tablica.jpg

import numpy as np
import random

n=3
a=np.zeros((3,3))

def znak(liczba):
    if liczba==1: return 'O'
    if liczba==2: return 'X'
    return ' '

def rysuj(tablica):
    for i in range(tablica.shape[0]):
        linijka=''
        for j in range(tablica.shape[1]):
            linijka+=znak(tablica[i,j])+'|'
        print(linijka[:-1])
        if i<tablica.shape[0]-1: 
            print(('-+'*tablica.shape[1])[:-1])

def czyKoniec(tablica):
    n=tablica.shape[0]
    if tablica.shape[1]!=n: return None  
    
    for numerGracza in [1,2]: #dla kazdego gracza
        a=(tablica==numerGracza)
        for i in range(n):
           if ((a[i,:]).sum()==n)  or  ((a[:,i]).sum()==n): 
               return 'wygral gracz numer '+str(numerGracza) #sprawdzamy wiersze i kolumny
        if (sum([a[i,i] for i in range(n)])==n) or (sum([a[i,n-1-i] for i in range(n)])==n):
            return 'wygral gracz numer '+str(numerGracza) #sprawdzamy przekatne
    if ((tablica>0).sum()==n*n): return 'remis' 
    return False
        


def wczytajRuch(numerGracza, tablica):
    while True:    
        while True:
            x=input('podaj wsp.x miejsca w ktorym chcesz wstawic znak '+znak(numerGracza)+': ')
            x=int(x)
            if (x<tablica.shape[0]) and (x>=0): break
            print('podales zle dane')
        while True:
            y=input('podaj wsp.y miejsca w ktorym chcesz wstawic znak '+znak(numerGracza)+': ')
            y=int(y)
            if (y<tablica.shape[1]) and (y>=0): break
            print('podales zle dane')
        if not tablica[x,y]:
            tablica[x,y]=numerGracza
            break
        print('pole zajete')

def gdzieZera(tablica):
    return np.transpose(np.nonzero(tablica<1)).tolist()
#print(gdzieZera(np.array([[1,2,1,0],[0,1,2,1],[1,1,1,2],[2,2,2,0]])))

def gra2P():
    zmieniacz=[0,2,1]
    numerGracza=1
    while True:                    
        rysuj(a)
        wczytajRuch(numerGracza,a)
        koniec=czyKoniec(a)
        if koniec:
            rysuj(a)
            print(koniec)
            break
        numerGracza=zmieniacz[numerGracza]

def gra1P():
    while True:                    
        rysuj(a)
        wczytajRuch(1,a)
        koniec=czyKoniec(a)
        if koniec:
            rysuj(a)
            print(koniec)
            break
        ruchKomputera(2,a)
        koniec=czyKoniec(a)
        if koniec:
            rysuj(a)
            print(koniec)
            break
        
def losowyRuchKomputera(numerGracza,tablica):
    print('robie losowy ruch')
    mozliweRuchy=gdzieZera(tablica)
    if mozliweRuchy:
        x,y=random.choice(mozliweRuchy)
        tablica[x,y]=numerGracza

#sprawdza czy w linijce jest raz 0 i dwa razy numerGracza
def sprawdzLinijke(numerGracza,linia):
    n=len(linia)
    linia=np.array(linia)    
    return (np.count_nonzero(linia==numerGracza)==n-1) and (np.count_nonzero(linia==0)==1)
    
def offense(numerGracza,tablica):
    for i in range(n):
           if sprawdzLinijke(numerGracza,a[i,:]): 
               return (i,np.nonzero(a[i,:]==0)[0][0])
           if sprawdzLinijke(numerGracza,a[:,i]): 
               return (np.nonzero(a[:,i]==0)[0][0],i)
    linijka=np.array([a[i,i] for i in range(n)])
    if sprawdzLinijke(numerGracza,linijka): 
        i=np.nonzero(linijka==0)[0][0]
        return (i,i)
    linijka=np.array([a[i,n-1-i] for i in range(n)])
    if sprawdzLinijke(numerGracza,linijka): 
        i=np.nonzero(linijka==0)[0][0]
        return (i,n-1-i)

zmieniacz=[0,2,1]
def defense(numerGracza,tablica): 
    return offense(zmieniacz[numerGracza],tablica)

def czySrodek(i,j):
    if (i==1) and (j==1): return True
    return False
    
def czyBok(i,j):
    if (i==1)^(j==1): return True
    return False
    
def czyNaroznik(i,j):
    if (i!=1) and (j!=1): return True
    return False

#funkcja analizuje tablice na której są dwa kółka i jeden krzyzyk
#funkcja znajduje ich wspołrzędne
def trzyZnaki(tablica):
    o=np.transpose(np.nonzero(tablica==1)).tolist()
    x=np.transpose(np.nonzero(tablica==2)).tolist()
    if (len(x)!=1) or (len(o)!=2): return False
    return (tuple(x[0]),[tuple(oo) for oo in o])

#test funkcji trzy znaki
#print(trzyZnaki(np.array([[0,1,1],[0,2,0],[0,0,0]])))

def trudnaCzescLogikiKomputera(tablica):
    #punkt 3) jezeli mozna wstaw w srodek
    if tablica[1,1]==0: return (1,1)
    
    #jezeli to twoj pierwszy ruch i wsrodku jest kolko
    #wstawiaj w naroznik
    if np.sum(tablica)==1 and tablica[1,1]==1: return (0,0)

    #sprawdzamy czy na planszy sa o,o,x
    if trzyZnaki(tablica):
        (x,o)=trzyZnaki(tablica)
        
        #4a) jeżeli sa na przekatnej i x jest w rogu (a na pewno to 0,0) => wstaw w rogu
        if (x==(0,0)) and (o[0][0]==o[0][1]) and (o[1][0]==o[1][1]):
            return (0,2)
                
        
        #4b) jeżeli sa na przekatnej i x jest w sroku => wstaw na boku
        if czySrodek(*x) and czyNaroznik(*o[0]) and czyNaroznik(*o[1]):
            #wystarczy sprawdzic czy kolka sa w naroznikach
            #na pewno nie sa na sasiadujacych bo zadzialalby defense
            return (0,1)
        
        #w tym miejscu na pewno jedno z kółek jest na boku
        #usawiamy liste o w takiej kolejnoscy czy kołko bedące na boku było pierwsze
        if czyBok(*o[1]): o=o[::-1]
        
        #wyrzucamy przypadek gdy sa na jednej linii
        if (o[0][0]==o[1][0]) or (o[0][1]==o[1][1]): return False
        
        #5) jeżeli x w srosku i kółka na bokach => wstaw w naroznik miedzy kółkami
        #6) jeżeli x w sorku, jedno kołko na boku i jedno na rogu => wstaw w naroznik miedzy kółkami
        #UWAGA jeżeli doszlismy do tego miejsca to na pewno mamy doczynienia
        # z sytuacją opisana w punkcie 5) lub 6)
        if o[0][0]==1: 
            return (o[1][0],o[0][1])
        else:
            return (o[0][0],o[1][1])
          
                


def ruchKomputera(numerGracza,tablica):
    offe=offense(numerGracza,tablica)
    if offe:
        print('offe',offe)
        tablica[offe[0],offe[1]]=numerGracza
        return None
    defe=defense(numerGracza,tablica)
    if defe:
        print('defe',defe)
        tablica[defe[0],defe[1]]=numerGracza
        return None
    trudna=trudnaCzescLogikiKomputera(tablica)
    if trudna:
        print('trudna',trudna)
        tablica[trudna[0],trudna[1]]=numerGracza
        return None
    losowyRuchKomputera(numerGracza,tablica)    

gra1P()