import itertools #piece = [centre, nw, ne, se, sw] #1 = trou ; 0 = plein PIECES = [("p1", [1, 1, 0, 0, 0]),\ ("p2", [0, 1, 0, 0, 0]),\ ("p3", [0, 1, 0, 1, 0]),\ ("p4", [0, 1, 1, 0, 0])] # probleme est une liste contenant successivement : # le nombre de barques devant apparaitre # le nombre de bateaux blancs devant apparaitre # le nombre de bateaux rouges devant apparaitre # le nombre de montagnes devant apparaitre # le nombre d'iles devant apparaitre PR1 = [0,5,0,0,0] PR2 = [0,0,3,2,0] PR3 = [3,0,0,0,2] PR4 = [0,0,0,2,2] PR5 = [0,0,3,1,0] PR6 = [2,0,3,2,0] PR7 = [0,1,0,2,0] PR8 = [2,5,0,0,0] PR9 = [0,1,3,0,0] PR10 = [0,0,0,2,3] PR11 = [2,0,3,0,0] PR12 = [0,0,1,2,0] PR13 = [0,5,1,0,0] PR14 = [0,2,3,2,0] PR15 = [0,0,2,2,3] PR16 = [0,3,3,0,0] PR17 = [0,3,0,0,0] PR18 = [2,0,3,0,1] PR19 = [1,0,1,2,3] PR20 = [1,5,0,0,1] PR21 = [0,1,3,1,2] PR22 = [0,1,2,1,3] PR23 = [0,1,1,0,1] PR24 = [0,1,3,2,1] PR25 = [0,3,3,0,1] PR26 = [0,1,1,0,2] PR27 = [0,1,2,0,0] PR28 = [0,0,2,1,2] PR29 = [0,4,0,0,2] PR30 = [0,4,2,0,1] PR31 = [0,1,2,2,2] PR32 = [0,0,1,1,1] PR33 = [1,0,0,2,3] PR34 = [1,0,3,1,2] PR35 = [0,0,3,1,1] PR36 = [0,0,2,1,0] PR37 = [3,1,1,1,0] PR38 = [2,0,1,1,0] PR39 = [0,4,0,1,2] PR40 = [2,1,0,2,0] PR41 = [2,0,3,1,1] PR42 = [0,0,2,2,2] PR43 = [2,0,1,2,0] PR44 = [0,2,2,1,2] PR45 = [0,1,2,0,2] PR46 = [0,4,1,0,2] PR47 = [1,1,2,0,3] PR48 = [0,0,1,1,2] RIEN = 0 BARQUE = 1 BATEAU_BLANC = 2 BATEAU_ROUGE = 3 MONTAGNE = 4 ILE = 5 PLATEAU = [[RIEN, BARQUE, BARQUE, MONTAGNE, BATEAU_BLANC],\ [BATEAU_ROUGE, RIEN, MONTAGNE, BATEAU_BLANC, ILE],\ [ILE, BATEAU_ROUGE, BATEAU_BLANC, BATEAU_BLANC, RIEN],\ [BATEAU_BLANC, BARQUE, BATEAU_ROUGE, ILE, RIEN]] def generer_rotations(piece): """ Fonction générant toutes les rotations d'une pièce. Le centre (à l'indice 0) ne bouge pas """ tete = piece[0] peripherie = piece[1:] retour = [] for i in range(1,5): tour = peripherie[i:] + peripherie[:i] tour.insert(0, tete) retour.append(tour) return retour def creer_table_rotations(pieces): """ Création d'un ictionnaire associant à chaque pièce ses 4 rotations possibles. """ retour = {} for couple in pieces: rotations = generer_rotations(couple[1]) retour[couple[0]] = rotations return retour def generer_config_rotations(): """ Création d'un tableau spéciant toutes les possibilités de rotation des pièces à chaque position. """ retour = [] for i1 in range(4): for i2 in range(4): for i3 in range(4): for i4 in range(4): retour.append([i1, i2, i3, i4]) return retour def resoudre(pieces, probleme): noms_pieces = ["p1", "p2", "p3", "p4"] table_rotations = creer_table_rotations(pieces) config_rotations = generer_config_rotations() for permutation in itertools.permutations(noms_pieces): for config in config_rotations: try: position = generer_position(table_rotations, permutation, config) if verifier_correction(probleme, position): return position except Exception: pass def generer_position(table_rotations, permutation, config): position = [] erreur = False for indice_piece in range(4): piece = permutation[indice_piece] numero_rotation = config[indice_piece] if piece == "p3" and numero_rotation > 1: # la pièce p3 possède une symétrie centrale ; # On considère donc ses positions 2 et 3 comme illégales raise Exception() else: position.append(table_rotations[piece][numero_rotation]) return position def verifier_correction(probleme, position): visu = [] for i in range(4): visu.append([0] * 5) for case in range(4): for place in range(5): # Un trou étant représenté par un "1", multiplier par un trou # préserve l'objet. # Un plein étant représenté par un "0", multipier par un plein # masque l'objet visu[case][place] = PLATEAU[case][place] * position[case][place] visu_globale = [objet for case in visu for objet in case] visu_resumee = [visu_globale.count(BARQUE),\ visu_globale.count(BATEAU_BLANC),\ visu_globale.count(BATEAU_ROUGE),\ visu_globale.count(MONTAGNE),\ visu_globale.count(ILE)] return visu_resumee == probleme def jeu(probleme): solution = resoudre(PIECES, probleme) chaines = list(map(representer, solution)) print("---------") print("|"+ chaines[0][0] + "|" + chaines[1][0] + "|") print("|"+ chaines[0][1] + "|" + chaines[1][1] + "|") print("|"+ chaines[0][2] + "|" + chaines[1][2] + "|") print("---------") print("|"+ chaines[2][0] + "|" + chaines[3][0] + "|") print("|"+ chaines[2][1] + "|" + chaines[3][1] + "|") print("|"+ chaines[2][2] + "|" + chaines[3][2] + "|") print("---------") def representer(piece): ligne1 = car(piece[1]) + "*" + car(piece[2]) ligne2 = "*" + car(piece[0]) + "*" ligne3 = car(piece[4]) + "*" + car(piece[3]) return [ligne1, ligne2, ligne3] def car(x): return " " if x == 1 else "*"