def copyMat(grille): """ list(list(int)) -> list(list(int)) Renvoie la copie de grille """ nouvGrille = nvl.genere_grille_vide() for i in range(len(grille)): for j in range(len(grille[0])): nouvGrille[i][j] = grille[i][j] return nouvGrille
def approx_nbGrille1(listNum): """ Renvoie une approximation du nombre de grilles différentes possibles contenant la liste de bateaux passée en paramètre. Une manière un peu bourrine consiste à multiplier les résultats respectifs de la fonction 'pos_un_bateau(...) appliquée aux différents bateaux de 'listNum. """ res = 1 for i in listNum: res *= pos_un_bateau(nvl.genere_grille_vide(), i) return res
def approx_nbGrille2(listNum): """ Renvoie une approximation du nombre de grilles différentes possibles contenant la liste de bateaux passée en paramètre. Une manière consiste à calculer le nombre de grilles possibles en plaçant le premier bateau, puis placer ce bateau dans une nouvelle grille, puis calculer le nombre de grilles possibles en plaçant le second bateau dans cette nouvelle grille et ainsi de suite. """ res = 1 grilleCour = nvl.genere_grille_vide() for i in listNum: res *= pos_un_bateau(grilleCour, i) nvl.place_alea(grilleCour, i) return res
def __init__(self): self.nom = "IA Probabiliste simplifiée" # self.restants : list((int, int)), tient à jour les bateaux restants # /!\ Notez que la stratégie n'exploitera pas la connaissance du nombre # de cases restantes pour chaque bateau (ce serait de la triche) bien # qu'on la stocke ici par soucis d'implémentation self.restants = [ (5, config.reference[5][1]), (4, config.reference[4][1]), (3, config.reference[3][1]), (2, config.reference[2][1]), (1, config.reference[1][1]), ] # self.probas : list(list(int)), une grille initialisée à 0, contiendra # les probabilités cumulées de la position possible des bateaux self.probas = nvl.genere_grille_vide()
def pos_des_bateaux(liste): """ list(int) -> int Rend le nombre de possibilité de placer des bateaux dans une grille vide """ return pos_des_bateauxrec(nvl.genere_grille_vide(), liste)
def main(): print(pos_un_bateau(nvl.genere_grille_vide(), 5)) print() colNames = ["", "2", "3", "4", "5"] li1 = [ "pos_un_bateau", pos_un_bateau(nvl.genere_grille_vide(), 1), pos_un_bateau(nvl.genere_grille_vide(), 2), pos_un_bateau(nvl.genere_grille_vide(), 3), pos_un_bateau(nvl.genere_grille_vide(), 5) ] dply.affiche_tabl([colNames, li1]) print() colNames = ["Fonction\\Nombre de bateaux", "1", "2", "3", "4", "5"] li1 = [ "pos_des_bateaux", pos_des_bateaux([5]), pos_des_bateaux([5, 4]), "pos_des_bateaux([5,4,3])", "pos_des_bateaux([5,4,3,2])", "pos_des_bateaux([5,4,3,2,1])" ] dply.affiche_tabl([colNames, li1]) print() # colNames = ["test_grilleAleaEgale pour 15s\\Nombre de bateaux", "1", "2", "3", "4", "5"] # li1 = [ # "(Nb d'itérations, nb de grilles)", # test_grilleAleaEgale(15, [5]), # test_grilleAleaEgale(15, [5, 4]), # test_grilleAleaEgale(15, [5, 4, 3]), # "test_grilleAleaEgale(60, [5, 4, 3, 2])", # "test_grilleAleaEgale(60, [5, 4, 3, 2, 1])" # ] # # dply.affiche_tabl([ colNames, # li1]) print() colNames = [ "Valeurs à tester", "pos_des_bateaux", "approx_nbGrille1", "approx_nbGrille2" ] li1 = [ "[5]", pos_des_bateaux([5]), approx_nbGrille1([5]), approx_nbGrille2([5]) ] li2 = [ "[5, 4]", pos_des_bateaux([5, 4]), approx_nbGrille1([5, 4]), approx_nbGrille2([5, 4]) ] li3 = [ "[5, 4, 3]", "/", # pos_des_bateaux([5, 4, 3]), approx_nbGrille1([5, 4, 3]), approx_nbGrille2([5, 4, 3]) ] li4 = [ "[5, 4, 3, 2]", "/", # pos_des_bateaux([5, 4, 3, 2]), approx_nbGrille1([5, 4, 3, 2]), approx_nbGrille2([5, 4, 3, 2]) ] li5 = [ "[5, 4, 3, 2, 1]", "/", # "pos_des_bateaux([5, 4, 3, 2, 1])", approx_nbGrille1([5, 4, 3, 2, 1]), approx_nbGrille2([5, 4, 3, 2, 1]) ] dply.affiche_tabl([colNames, li1, li2, li3, li4, li5]) print() colNames = [ "Valeurs à tester", "pos_des_bateaux", "approx_nbGrille1", "approx_nbGrille2" ] li1 = [ "[5, 4]", pos_des_bateaux([5, 4]), approx_nbGrille1([5, 4]), approx_nbGrille2([5, 4]) ] li2 = [ "[3, 4]", pos_des_bateaux([3, 4]), approx_nbGrille1([3, 4]), approx_nbGrille2([3, 4]) ] li3 = [ "[2, 4]", pos_des_bateaux([2, 4]), approx_nbGrille1([2, 4]), approx_nbGrille2([2, 4]) ] li4 = [ "[5, 3]", pos_des_bateaux([5, 3]), approx_nbGrille1([5, 3]), approx_nbGrille2([5, 3]) ] dply.affiche_tabl([colNames, li1, li2, li3, li4])
def joue(self, bataille): # self.probas : list(list(int)), est ré-initialisée à chaque tour self.probas = nvl.genere_grille_vide() # t : int, décalage (voir plus loin) t = 0 # bonus : int bonus = 0 # peut_poser : boolean peut_poser = False effect = -1 # effect est <= -1 quand la case visée a déjà été jouée while (effect <= -1): """ Calculer la probabilité pour chaque case de contenir ce bateau sans tenir compte de la position des autres bateaux. """ # Pour chaque bateau restant : for b in self.restants: # Si le bateau est coulé (taille à 0) : if b[1] == 0: # On ne calcule plus sa probabilité continue # Pour chaque case de 0 à 99 : for i in range(10): for j in range(10): # Si la case à été jouée et n'était pas un bateau : if bataille.get((i, j)) == -1: # Pas de bateau ici self.probas[i][j] = 0 else: t = 0 bonus = 0 # Si la case était un bateau et a été jouée if bataille.get((i, j)) == -2: # Les probabilités seront "boostées" bonus = 1 # En revanche, impossible de toucher un bateau # ici (case déjà jouée) self.probas[i][j] = 0 # La case aura toujours une probabilité égale à # 0 si elle a déjà été jouée, donc lors de # l'attribution des probabilités aux cases que # le bateau pourrait couvrir, on ignore la case # d'origine t = 1 """Peut-on poser 'b' verticalement ?""" peut_poser = True # Parcours des cases direction sud : for u in range(1, config.reference[b[0]][1]): # Si la case explorée est hors-limite ou # qu'elle a été jouée et n'a pas touché de # bateau : if not bataille.checkBound( (i + u, j)) or bataille.get( (i + u, j)) == -1: peut_poser = False break # Si la case explorée est un bateau touché, les # chances qu'une autre case bateau se trouve # proche sont plus grandes : if bataille.get((i + u, j)) == -2: # On booste les probabilités des cases # explorées bonus += 1 """ Attribution des probabilités """ if peut_poser: # on peut attribuer leurs probabilités aux # cases que le bateau pourrait couvrir sur sa # longueur (avec un bonus significatif) : for u in range(t, config.reference[b[0]][1]): if bataille.get((i + u, j)) != -2: self.probas[i + u][j] += 1 + bonus * 2 """Peut-on poser 'b' horizontalement ?""" peut_poser = True for v in range(1, config.reference[b[0]][1]): # Si la case explorée est hors-limite ou # qu'elle a été jouée et n'a pas touché de # bateau : if not bataille.checkBound( (i, j + v)) or bataille.get( (i, j + v)) == -1: peut_poser = False break # Si la case explorée est un bateau touché, les # chances qu'une autre case bateau se trouve # proche sont plus grandes : if bataille.get((i, j + v)) == -2: bonus += 1 """ Attribution des probabilités """ if peut_poser: # on peut attribuer leurs probabilités aux # cases que le bateau pourrait couvrir sur sa # longueur (avec un bonus significatif) : for v in range(t, config.reference[b[0]][1]): if bataille.get((i, j + v)) != -2: self.probas[i][j + v] += 1 + bonus * 2 """Choisir une position dans probas""" # C'est le moment où après avoir calculé une grille de # probabilités on choisit la case ayant la plus forte probabilité # de contenir un bateau flatProbas = [item for sublist in self.probas for item in sublist] maxiProba = max(flatProbas) x = flatProbas.index(maxiProba) // 10 y = (flatProbas.index(maxiProba) + 10) % 10 effect = bataille.joue((x, y)) # Sortie de boucle while effect <= -1 """ A décommenter pour pouvoir observer l'évolution de la grille de probabilité pendant la démo : """ # print([h[0] for h in self.restants if h[1] != 0]) # nvl.affiche_tabl([[i for i in range(10)]] + self.probas, replace=("0", " ")) # time.sleep(4) """Fin décommenter""" """Màj des bateaux restants en cas de tir réussi""" if effect != 0: for i in range(len(self.restants)): if self.restants[i][0] == effect: self.restants[i] = (self.restants[i][0], self.restants[i][1] - 1) return effect