# À gauche n moutons maigres dans leur bergerie. # À droite n moutons gras dans le pâturage. # Il faut rentrer les moutons gras en bergerie et sortir les moutons maigres au pâturage. # Comment faire ? # Les moutons ne peuvent sauter qu'un mouton à la fois et ne peuvent reculer. # # Appel : sm(n=3) # # Touches : # [<-][->] : choix du mouton # [entrer] : avancer ou sauter # [annul] : quitter from ti_graphics import * from ti_system import * y0, sw, sh, fw, fh = 30, 320, 210, 10, 15 mouton_largeur, mouton_hauteur = 30, 22 _codes_touche_quitter = (64, 69, 10, 11, 9) _codes_touche_gauche = (2, 14) _codes_touche_droite = (1, 15) _codes_touche_action = (5, 13) print("À gauche n moutons maigres en bergerie, à droite n moutons gras au pâturage.\nRentre les gras en bergerie et sors les maigres au pâturage.\nLes moutons ne sautent qu'un mouton à la fois ni reculent.\nAppel: sm(n=3)") def sm(n=3): global univers if not isinstance(n, int) or n < 1 : raise ValueError("n must be a strictly positive integer") univers = [[1 for k in range(n)] + [0] + [-1 for k in range(n)]] etat_gagnant = list(univers[0]) etat_gagnant.reverse() univers.extend([-1, sw / len(univers[0]), (0, 158, 0)]) case_ancienne = -1 touche_pressee = -1 coups = 0 mouton_y = _dessine_decor() while not touche_pressee in _codes_touche_quitter and univers[0] != etat_gagnant: touche_pressee = wait_key() rafraichissement_necessaire = False if touche_pressee in _codes_touche_gauche + _codes_touche_droite : case_ancienne = univers[1] _change_case_courante( touche_pressee in _codes_touche_gauche and -1 or 1) rafraichissement_necessaire = True elif univers[1]>=0 and touche_pressee in _codes_touche_action: case_ancienne = univers[1] if _bouge_de(1) or _bouge_de(2): coups += 1 rafraichissement_necessaire = True if rafraichissement_necessaire: _dessine_moi_un_mouton(case_ancienne, univers[2], mouton_y) _dessine_moi_un_mouton(univers[1], univers[2], mouton_y) if univers[0] == etat_gagnant: print("Gagné en " + str(coups) + " coups !") return (univers[0] == etat_gagnant, coups) def _bouge_de(pas): global univers case_courante = univers[1] case_ciblee = case_courante + univers[0][case_courante]*pas if case_ciblee >=0 and case_ciblee < len(univers[0]) and not univers[0][case_ciblee]: _echange_cases(case_courante, case_ciblee) univers[1] = case_ciblee return True return False def _echange_cases(case1, case2): global univers univers[0][case2], univers[0][case1] = univers[0][case1], univers[0][case2] def _change_case_courante(sens): global univers case_courante = univers[1] while not univers[0][univers[1]] or univers[1] == case_courante: univers[1] = (univers[1] + sens) % len(univers[0]) def _dessine_moi_un_mouton(case_numero, case_largeur, y): global univers if univers[0][case_numero]: drawImage(('Mout' + 'BR'[case_numero == univers[1]] + ((univers[0][case_numero] > 0) and 'Pti' or 'Gro')), case_numero*case_largeur + (case_largeur - mouton_largeur)//2, y) else: fillRect(case_numero * case_largeur, y, case_largeur, mouton_hauteur) def _fillRectHorizGradientRGB(x, y, w, h, col1, col2): for k in range(h): setColor([col1[i]+(col2[i] - col1[i])*k//(h-1) for i in range(3)]) drawLine(x, y + k, x + w - 1, y + k) def _dessine_decor(): global univers print("Plantons d'abord le décor !") d, l = int(sh // 3.125), 12 cloture_h, m = d // 8, (sh - 2 * d) // l cloture_w, maison_w, porte_d = cloture_h // 4, d * 3 // 4, d // 4 maison_h, fenetre_w = maison_w // 2, d // 8 maison_x, maison_y, cloture_y = d*7//8, y0 + sh - 2*d - 7*d//64, y0 + sh - d - cloture_h couleur_fond1, couleur_fond2 = univers[3], (0, 255, 255) _fillRectHorizGradientRGB(0, y0, sw, sh - 2*d, couleur_fond2, (255,)*3) setColor((0, 255, 0)) _fillRectHorizGradientRGB(0, y0 + sh - 2*d, sw, d, (0, 255, 0), couleur_fond1) fillRect(0, y0 + sh - d, sw, d) for i in range(m): drawString("*" * (i<3 and i+2 or 5), 0, y0 + l * (m - i - 1)) setColor((255, 255, 0)) fillRect(maison_x, maison_y, maison_w, maison_h) setColor((0,)*3) fillRect(maison_x + maison_w//2 - porte_d//2, maison_y + maison_h - porte_d, porte_d, porte_d) setColor((181, 32, 0)) fillRect(0, y0 + m*l + 2, fw, sh - 5*d//4 - m*l - l) for i in range(0, sw, cloture_h): cloture_x = i + (cloture_h - cloture_w)//2 fillRect(cloture_x, cloture_y, cloture_w, cloture_h) if i//cloture_h % 2: fillPolygon(((cloture_x, cloture_y), (cloture_x - (cloture_h - cloture_w)//2, cloture_y - 3*d//64), (cloture_x, cloture_y - 7*d//64), (cloture_x + cloture_w - 1, cloture_y - 7*d//64), (cloture_x + cloture_w - 1 + (cloture_h - cloture_w)//2, cloture_y - 3*d//64), (cloture_x + cloture_w - 1, cloture_y))) setColor((255, 0, 0)) fillPolygon(((maison_x - 1, maison_y), (maison_x + d//4, maison_y - d//4 - 1), (maison_x + maison_w - d//4 - 1, maison_y - d//4 - 1), (maison_x + maison_w, maison_y))) lst = ((sw // 2, y0 + sh - 2*d), (3 * sw // 4, y0 + sh - 2*d - d//4), (33 * sw // 40, y0 + sh - 2*d - d//8), (31 * sw // 40, y0 + sh - 2*d), (15 * sw // 16, y0 + sh - 2*d - 3*d//8), (sw, y0 + sh - 2*d - d//4), (sw, y0 + sh - 2*d)) setColor((0, 146, 255)) fillPolygon(lst) for i in range(-1, 2, 2): fillRect(maison_x + maison_w//2 +i*porte_d//2 - (i<0 and fenetre_w), maison_y + d*5//64, fenetre_w, d * 3 // 32) setColor((255, 0, 255)) drawPolyLine(lst) setColor(couleur_fond2) mouton_y = y0 + sh - d + (d - mouton_hauteur) // 2 for case_numero in range(len(univers[0])): if univers[0][case_numero]: _dessine_moi_un_mouton(case_numero, univers[2], mouton_y) setColor(couleur_fond1) return mouton_y