In [105]:
#Operazioni sulle matrici: Stampa, creazione, controlli vincita, controllo fine partita, inserimento
def init(val): #Creazione
return [[val, val, val],[val, val, val],[val, val, val]]
def ppmatrix(m): #Stampa la matrice
print ("__________________________________________________")
for riga in m:
string = "|\t"
for el in riga:
string = string + str(el) + "\t | \t"
print (string)
print ("__________________________________________________")
def TupleWin(t): #Restituisce Vero se una tupla (riga-colonna-diagonale) contiene una vincita
return (len(set(t)) == 1) and (not(set(t) == set(['']) ))
def control_r(field, p): #Controlla vincita sulle righe
for riga in field:
if (TupleWin(riga) and p in set(riga)) : return True
return False
def traspostaM(field): #Trova la trasposta righe-colonne
i = 0
j = 0
r = init('')
for riga in field:
i = 0
for ele in riga:
r[i][j] = ele
i = i+1
j = j +1
return r
def control_c(field, p): #Controlla vincita sulle colonne
r = traspostaM(field)
return control_r(r, p)
def control_d(field, p): #Controlla vincita sulle diagonali
d = [] #Diagonale 1
d1 = [] #Diagonale 2
i = 0
j = 0
for i in range(3): #Estrae le diagonali
if (field[i][i] != p) or (field[i][2-i] != p) :
return False
else :
d = d + [ field[i][i] ]
d1 = d1 + [ field[i][2-i] ]
if TupleWin(d) or TupleWin(d1) : return True
return False
def win(field, p): #Controlla la vincita globale
return control_r(field, p) + control_c(field, p) + control_d(field, p)
def filled(field): #Controlla se la matrice è piena
for riga in field:
if '' in riga :
return False
return True
def insert(field, x, y, player): #Inserisce nella cella
x = x
y = y
if abs(x) < len(field) and abs(y) < len(field[0]):
field[x][y] = player
#ppmatrix(field)
def insert_controlled(field, x, y, player): #Inserisce nella cella SE è vuota
x = x
y = y
if abs(x) < len(field) and abs(y) < len(field[0]):
if field[x][y] != '':
field[x][y] = player
return True
return False
#ppmatrix(field)
def insert1(field, x, y, player): #Inserisce nella cella
x = x-1
y = y-1
if abs(x) < len(field) and abs(y) < len(field[0]):
field[x][y] = player
#ppmatrix(field)
In [127]:
#Implementaazione IA per il gioco
def check_next(player, field): #Controlla se un determinato Player può vincere con una mossa, ritorna la pos
import copy
for i in range(3):
for j in range(3):
ele = field[i][j]
if ele == '':
r = copy.deepcopy(field) #Crea una nuova variabile uguale all'altra, senza copiare solo il puntatore
r[i][j] = player #prova a mettere player nella cella
if win(r, player) : #se player ha vinto, vuol dire che può vincere con una mossa
return [i,j] # Ritorna la mossa
return False
def balance(player, field, fieldP, peso): #modifica il Peso delle caselle che stanno in una riga/colonna del player
j = 0
i = 0
for riga in field:
i = 0
for ele in riga:
if ele == player:
for c in range(3):
if field[j][c] == '' : fieldP[j][c] = fieldP[j][c] + peso
if field[c][i] == '' : fieldP[c][i] = fieldP[c][i] + peso
i = i + 1
j = j + 1
def onlyFree(field, fieldP): #Asegna il peso minimo alle caselle già occupate
j = 0
i = 0
for riga in field:
i = 0
for ele in riga:
if ele != '' : fieldP[j][i] = -999
i = i + 1
j = j + 1
def choose_best(fieldP): #ritorna la casella con il peso maggiore
i = 0
j = 0
All = []
for j in range(3):
for i in range(3):
All = All + [fieldP[j][i]]
Max = max(All)
for j in range(3):
for i in range(3):
if fieldP[j][i] == Max : return [j,i]
def count_win(player,field): #conta quante mosse vincenti possibili ha un player
import copy
i = 0
j = 0
conta = 0
for riga in field:
i = 0
for ele in riga:
if ele == '':
r = copy.deepcopy(field)
r[j][i] = player
if win(r, player) : conta = conta + 1
i = i+1
j = j+1
return conta
def control_spec(IA, vs, field, fieldP): #Fulcro dell'IA, controlla se ha una mossa vincente fino a 3 livelli avanti
import copy
peso = 10
peso1 = 100
for j in range(3):
for i in range(3):
copia = copy.deepcopy(field) #Crea un primo livello
if (copia[j][i] == ""):
copia[j][i] = IA #Inserisce il giocatore se la casella è vuota
if count_win(IA,copia) > 1 :
fieldP[j][i] = fieldP[j][i] + peso1 #Se ha due vincite possibili, ha vinto metendolo lì
move = check_next(IA, copia)
if move != False : #Se ha una sola possibilità, l'avversario DOVRA' metterlo lì il prossimo turno.
copia[move[0]][move[1]] = vs #Inseerisce la mossa dell'avversario (secondo livello)
for j1 in range(3):
for i1 in range(3):
copia1 = copy.deepcopy(copia) #Crea il terzo livello
if (copia1[j1][i1] == ""): #Prova le caselle vuote
copia1 = copy.deepcopy(copia)
copia1[j1][i1] = IA
vs_move = check_next(vs, copia1) #Vede se l'avversario può vincere in una sola mossa
if not(vs_move) : #Se l'avversario non può vincere
if count_win(IA, copia1) == 2: #Se l'IA ha due caselle vincenti
fieldP[j][i] = fieldP[j][i] + peso #Aggiunge un peso 10 alla casella iniziale livello 1
def IA_move( IA, vs, field):
fieldP = init(0) #Crea una matrice contenente i pesi
balance(vs, field, fieldP, -2) #Diminuisce il peso vicino all'avversario
balance(IA, field, fieldP, 2) #Aumenta il peso vicino a se stessa
fieldP[1][1] = fieldP[1][1] + 3 #Aumenta il peso in centro (casella con più mosse vincenti) (se libera, sarà la prima mossa)
onlyFree(field, fieldP) #Toglie peso alle caselle occupate, in modo da non poter essere scelte
control_spec(IA, vs, field, fieldP) #Esegue un controllo al di vincita al 3o livello di gioco
ppmatrix(fieldP) # Stampa i pesi
return choose_best(fieldP) #Ritorna la mossa con il peso maggiore
def IAPlay(IA, vs, field): #Fa giocare l'IA
move = check_next(IA, field) #Controlla se può vincere con una sola mossa
print(move ,"liv 1")
if not(move): #Se non può vincere in una mossa, controlla se l'avversario potrebbe vincere in una sola mossa
move = check_next(vs, field)
print(move,"liv 2")
if not(move): #Se neanche l'avversario può vincere, pesa la matrice e sceglie la posizione migliore
move = IA_move(IA, vs, field)
insert(field, move[0], move[1], IA) #Muove
In [128]:
#Inizializzazione Gioco
field = init('')
IA1 = "X"
me = "O"
ppmatrix(field)
In [134]:
#Alternare inserimento utente (scegliendo la posizione con i aprametri) e l'istruzione seguente (mossa IA)
insert1(field, 2,1, me)
ppmatrix(field)
In [135]:
#Mossa dell'IA, una volta eseguita si può rieseguire l'istruzione precedente per fare la propria mossa
IAPlay(IA1, me, field)
ppmatrix(field)
In [ ]:
#Far giocare l'IA al posto proprio
IAPlay(me, IA1, field)
ppmatrix(field)
In [7]:
def partita():
field = init("")
p1 = "X"
p2 = "O"
p = ""
vs = ""
while (not(filled(field)) and not(win(field, p))):
#Inverte i giocatori ogni turno
if p == p1 :
p = p2
vs = p1
else :
p = p1
vs = p2
IAPlay(p, vs, field) #fa la mossa
ppmatrix(field) #stampa il campo
if (win(field, p1)): print("Ha vinto " + p1)
elif (win(field, p2)): print("Ha vinto " + p2)
else : print("partita patta")
In [50]:
In [46]:
range(3)
Out[46]:
In [ ]: