TI/Kółko i krzyżyk
Z Brain-wiki
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]
#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()