-- _ _______ _________ _______ _______ _______ _______ ______ _______ _ _ _______ _______ _______ _______ _______ -- ( \ ( ____ \ \__ __/( ____ )( ____ \( ___ )( ____ ) ( __ \ ( ____ \ | \ /\( ( /|( ___ )( ____ \( ____ \( ___ )( ____ \ -- | ( | ( \/ ) ( | ( )|| ( \/| ( ) || ( )| | ( \ )| ( \/ | \ / /| \ ( || ( ) || ( \/| ( \/| ( ) || ( \/ -- | | | (__ | | | (____)|| (_____ | | | || (____)| | | ) || (__ | (_/ / | \ | || | | || (_____ | (_____ | | | || (_____ -- | | | __) | | | __)(_____ )| | | || __) | | | || __) | _ ( | (\ \) || | | |(_____ )(_____ )| | | |(_____ ) -- | | | ( | | | (\ ( ) || | | || (\ ( | | ) || ( | ( \ \ | | \ || | | | ) | ) || | | | ) | -- | (____/\| (____/\ | | | ) \ \__/\____) || (___) || ) \ \__ | (__/ )| (____/\ | / \ \| ) \ || (___) |/\____) |/\____) || (___) |/\____) | -- (_______/(_______/ )_( |/ \__/\_______)(_______)|/ \__/ (______/ (_______/ |_/ \/|/ )_)(_______)\_______)\_______)(_______)\_______) --[[ Note : il est conseillé d'afficher le code avec la police "courier" pour afficher correctement les grands titres. Les polices d'écriture des titres ont été trouvées sur http://www.kammerl.de/ascii/AsciiSignature.php Ce programme a été réalisé par le membre de pseudo mdr1 dans le cadre du concours "Le trésor de Knossos" organisé sur le site http://tiplanet.org (Octobre 2013) Il s'agit d'un programme codé en Lua pour TI-Nspire qui permet à un aventurier d'avoir le plus de chances possibles d'aller chercher le trésor puis le ramener sans tomber dans le trou d'une salle ou se faire dévorer par le Wumpus. Le code est découpé comme suit : * Une petite fonction pour copier une table. * Ens : table de fonctions pour manipuler les ensembles. * HypTrous : table de fonctions pour manipuler les hypothèses quand à la position des trous. * HypWumpus : table de fonctions pour manipuler les hypothèses quand à la position éventuelle du Wumpus. * HypTresor : table de fonctions pour manipuler les hypothèses quand à la position du trésor. * HypVoisins : table de fonctions pour manipuler les hypothèses quand à la façon dont les salles sont reliées. * Info : table de fonctions permettant des connaître les salles visitées et de calculer des trajectoires. * init : fonction qui initialise la mémoire de l'intelligence artificielle, appelée avant chaque partie. * think : fonction qui analyse les informations données par la salle courante pour faire le maximum de déductions. * action : fonction qui choisit une direction à prendre en fonction des données courantes. * Le code qui gère le déroulement de la partie et qui fait appel à l'intelligence artificielle ; il est fourni par le concours. ]]-- -- Version v4 sans la possibilité d'avoir mdr1 = 1/0. -------------------------------------- -- partie ci-dessous modifiable - il est permis d'appeler des programmes TI-Basic ou Ndless externes -- interdiction d'utiliser les variables ou fonctions definies plus bas, a l'exception bien sur des seules variables passees en parametres -------------------------------------- Outil = {} function Outil.copieTable(t) local k, l, r r = {} for k, l in pairs(t) do r[k] = l end return r end -- ############################ -- # ___ # -- # ( _`\ # ############################## -- # | (_(_) ___ ___ # # Fonctions relatives # -- # | _)_ /' _ `\/',__) # # à la gestion d'ensembles # -- # | (_( )| ( ) |\__, \ # # mathématiques. # -- # (____/'(_) (_)(____/ # ############################## -- # # -- ############################ Ens = {} -- Ensemble vrai = true -- Designe ce qui est vrai faux = false -- Designe ce qui est faux peutEtre = nil -- Designe ce qui peut-etre vrai ou faux, par manque d'information function Ens.nouv(t) local ens = {} local l for _, l in ipairs(t) do ens[l] = true end return ens end function Ens.union(a,b) local res = Ens.nouv{} local k for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end function Ens.intersection(a,b) local res = Ens.nouv{} local k for k in pairs(a) do res[k] = b[k] end return res end function Ens.copie(a) local res = Ens.nouv{} local k for k in pairs(a) do res[k] = true end return res end function Ens.moins(a,b) -- Renvoie a privé de b local res = Ens.copie(a) local k for k in pairs(b) do res[k] = nil end return res end function Ens.estEgalA(a,b) local k for k in pairs(a) do if not(b[k]) then return false end end -- Verifie si les éléments de a sont dans b. for k in pairs(b) do if not(a[k]) then return false end end -- Verifie si les éléments de b sont dans a. return true end function Ens.contient(a,b) -- renvoie true si a contient b (cad b inclus dans a) local k for k in pairs(b) do if not(a[k]) then return false end end return true end function Ens.estUnSingleton(a) -- Renvoie false si a n'est pas un singleton, l'élément qu'il contient sinon local n, k, e n=0 for k in pairs(a) do if a[k] then n = n+1 e = k end end if n==1 then return e else return false end end function Ens.cardinal(a) -- Renvoie le cardinal de l'ensemble a. local cardinal = 0 for _ in pairs(a) do cardinal = cardinal + 1 end return cardinal end -- ###################################################### -- # _ _ _____ # -- # ( ) ( ) (_ _) # ######################### -- # | |_| | _ _ _ _ | | _ __ _ _ _ ___ # # Fonctions relatives # -- # | _ |( ) ( )( '_`\ | |( '__)/'_`\ ( ) ( )/',__) # # aux hypothèses sur # -- # | | | || (_) || (_) )| || | ( (_) )| (_) |\__, \ # # l'emplacement des # -- # (_) (_)`\__, || ,__/'(_)(_) `\___/'`\___/'(____/ # # trous. # -- # ( )_| || | # ######################### -- # `\___/'(_) # -- # # -- ###################################################### HypTrous= {} function HypTrous.init(n) HypTrous.sallesSansTrou = Ens.nouv{} -- Salles dont on est certains qu'il n'y a pas de trou HypTrous.groupesDeSallesAvecTrou = Ens.nouv{} -- Liste qui contient des ensembles de salles telle que pour chaque ensemble de salles, il y ait au moins un trou dans l'un d'entre elles end function HypTrous.consequences() -- a chaque endroit on on est certains qu'il y a un trou, il n'y a pas de Wumpus ni de tresor. local k for k in pairs(HypTrous.groupesDeSallesAvecTrou) do local s = Ens.estUnSingleton(HypTrous.groupesDeSallesAvecTrou[k]) if s then HypWumpus.pasDeWumpusDans(Ens.nouv{s}) HypTresor.pasDeTresorDans(Ens.nouv{s}) end end end function HypTrous.pasDeTrouDans(ens) -- ens= ensemble de salles HypTrous.sallesSansTrou = Ens.union(HypTrous.sallesSansTrou, ens) HypTrous.rafraichir() HypTrous.consequences() end function HypTrous.rafraichir() -- Usage interne a HypTrous uniquement. print(" Rafraichir trous") -- Permet de retirer les salles sans trou (pour HypTrous.groupesDeSallesAvecTrou). local k for k in pairs(HypTrous.groupesDeSallesAvecTrou) do HypTrous.groupesDeSallesAvecTrou[k] = Ens.moins(HypTrous.groupesDeSallesAvecTrou[k], HypTrous.sallesSansTrou) end print(" Liste = "..serialize(HypTrous.groupesDeSallesAvecTrou).."\n") -- Enlever les groupes inutiles (qui contiennent un autre groupe). k=1 print(" Taille grpes = "..tostring(#HypTrous.groupesDeSallesAvecTrou).."\n") while k <= #HypTrous.groupesDeSallesAvecTrou do print(" k = "..tostring(k)..", grpes = "..serialize(HypTrous.groupesDeSallesAvecTrou).."\n") local j=1 while k+j <= #HypTrous.groupesDeSallesAvecTrou do print(" j = "..tostring(k)..", grpes = "..serialize(HypTrous.groupesDeSallesAvecTrou).."\n") if Ens.contient(HypTrous.groupesDeSallesAvecTrou[k], HypTrous.groupesDeSallesAvecTrou[k+j]) then print(" Le groupe "..serialize(HypTrous.groupesDeSallesAvecTrou[k+j]).." est déjà dans "..serialize(HypTrous.groupesDeSallesAvecTrou[k]).."\n") table.remove(HypTrous.groupesDeSallesAvecTrou, k+j) else j=j+1 end end k=k+1 end end function HypTrous.unTrouEstDansUneDes(ens) -- Ajoute dans les donnees un ensemble de salles dont au moins l'une d'entre elles a un trou. table.insert(HypTrous.groupesDeSallesAvecTrou, ens) HypTrous.rafraichir() HypTrous.consequences() end function HypTrous.savoirSiTrouDans(ens) local l if Ens.estEgalA(Ens.intersection(HypTrous.sallesSansTrou, ens), ens) then -- Si aucune salle de "ens" n'est piege, renvoyer faux. return faux end for _, l in ipairs(HypTrous.groupesDeSallesAvecTrou) do -- Pour chaque ensemble de salles qui en contient une piege if s and Ens.estEgalA(Ens.intersection(l, ens), l) then -- Si l'ensemble "l" est inclus dans "ens" return vrai -- Renvoyer vrai (une des salles est piege) end end return peutEtre -- Sinon, on ne sait pas. end -- ############################################################################ -- # _ _ _ _ # -- # ( ) ( ) ( ) _ ( ) # ######################### -- # | |_| | _ _ _ _ | | ( ) | | _ _ ___ ___ _ _ _ _ ___ # # Fonctions relatives # -- # | _ |( ) ( )( '_`\ | | | | | |( ) ( )/' _ ` _ `\( '_`\ ( ) ( )/',__) # # aux hypothèses sur # -- # | | | || (_) || (_) )| (_/ \_) || (_) || ( ) ( ) || (_) )| (_) |\__, \ # # l'emplacement du # -- # (_) (_)`\__, || ,__/'`\___x___/'`\___/'(_) (_) (_)| ,__/'`\___/'(____/ # # Wumpus. # -- # ( )_| || | | | # ######################### -- # `\___/'(_) (_) # -- # # -- ############################################################################ HypWumpus = {} function HypWumpus.init(n) local i HypWumpus.sallesPossibles = Ens.nouv{} -- Les salles ou le Wumpus peut se trouver for i=2, n do HypWumpus.sallesPossibles[i] = true end HypWumpus.salleDeterminee = false -- Si l'on sait precisement ou est le Wumpus HypWumpus.vivant = true -- Permet de savoir si le Wumpus est toujours vivant end function HypWumpus.consequences() -- Si le Wumpus est dans une salle, celle-ci n'est pas piegee et ne contient pas le tresor. Usage interne. local s = Ens.estUnSingleton(HypWumpus.sallesPossibles) if s and not(HypWumpus.salleDeterminee) then -- Si l'on sait precisement ou est le Wumpus mais que ce n'etait pas le cas avant (afin d'eviter une recursivite infinie). HypWumpus.salleDeterminee = true HypTrous.pasDeTrouDans(Ens.nouv{s}) HypTresor.pasDeTresorDans(Ens.nouv{s}) end end function HypWumpus.pasDeWumpusDans(ens) -- ens = Ensemble de salles if HypWumpus.vivant then -- En fait, l'information n'est valable que si le Wumpus est vivant : sinon, il est toujours dans la salle, mais il ne pue plus donc ne semble pas etre la. HypWumpus.sallesPossibles = Ens.moins(HypWumpus.sallesPossibles, ens) HypWumpus.consequences() end end function HypWumpus.leWumpusEstDansUneDes(ens) HypWumpus.sallesPossibles = Ens.intersection(HypWumpus.sallesPossibles, ens) HypWumpus.consequences() end function HypWumpus.savoirSiWumpusDans(ens) if not(HypWumpus.vivant) then return faux end -- On dit pour l'utilisation extérieure que lorsque le Wumpus est mort, il n'est nulle part. local e = Ens.intersection(HypWumpus.sallesPossibles, ens) if Ens.estEgalA(e, HypWumpus.sallesPossibles) then -- Si les salles possibles pour le Wumpus sont dans "ens", c'est vrai. return vrai end for _, l in pairs(e) do if l then return peutEtre end -- On renvoie "peut-etre" si un terme est dans l'intersection. end return faux end function HypWumpus.plusDeWumpus(salle) -- Le Wumpus a ete tue dans la salle "salle". HypWumpus.vivant = false HypWumpus.sallesPossibles = Ens.nouv{--salle } HypWumpus.consequences() end function HypWumpus.lieuWumpus() -- Renvoie les endroits possibles pour le Wumpus return Ens.copie(HypWumpus.sallesPossibles) end -- ############################################################# -- # _ _ _____ # -- # ( ) ( ) (_ _) # ######################### -- # | |_| | _ _ _ _ | | _ __ __ ___ _ _ __ # # Fonctions relatives # -- # | _ |( ) ( )( '_`\ | |( '__)/'__`\/',__) /'_`\ ( '__) # # aux hypothèses sur # -- # | | | || (_) || (_) )| || | ( ___/\__, \( (_) )| | # # l'emplacement du # -- # (_) (_)`\__, || ,__/'(_)(_) `\____)(____/`\___/'(_) # # Trésor. # -- # ( )_| || | # ######################### -- # `\___/'(_) # -- # # -- ############################################################# HypTresor = {} function HypTresor.init(n) local i HypTresor.sallesPossibles = Ens.nouv{} -- Les salles ou le tresor peut se trouver for i=2, n do HypTresor.sallesPossibles[i] = true end HypTresor.salleDeterminee = false end function HypTresor.consequences() local s = Ens.estUnSingleton(HypTresor.sallesPossibles) if s and not(HypTresor.salleDeterminee) then -- Si l'on sait précisément où est le Tresor mais que ce n'était pas le cas avant (afin d'éviter une récursivité infinie). HypTresor.salleDeterminee = true HypTrous.pasDeTrouDans(Ens.nouv{s}) HypWumpus.pasDeWumpusDans(Ens.nouv{s}) end end function HypTresor.pasDeTresorDans(ens) -- ens = Ensemble de salles HypTresor.sallesPossibles = Ens.moins(HypTresor.sallesPossibles, ens) HypTresor.consequences() end function HypTresor.leTresorEstDansUneDes(ens) HypTresor.sallesPossibles = Ens.intersection(HypTresor.sallesPossibles, ens) HypTresor.consequences() end function HypTresor.savoirSiTresorDans(ens) local e = Ens.intersection(HypTresor.sallesPossibles, ens) local l if Ens.estEgalA(e, HypTresor.sallesPossibles) then -- Si les salles possibles pour le tresor sont dans "ens", c'est vrai. return vrai end for _, l in pairs(e) do if l then return peutEtre end -- On renvoie "peut-etre" si un terme est dans l'intersection. end return faux end function HypTresor.plusDeTresor(salle) HypTresor.sallesPossibles = Ens.nouv{salle} HypTresor.consequences() -- On tire les consequences du fait que le tresor était dans telle salle. HypTresor.sallesPossibles = Ens.nouv{} -- Mais ensuite, le trésor n'y est plus. end function HypTresor.lieuTresor() return Ens.copie(HypTresor.sallesPossibles) end -- ################################################################## -- # _ _ _ _ # -- # ( ) ( ) ( ) ( ) _ _ # ######################### -- # | |_| | _ _ _ _ | | | | _ (_) ___ (_) ___ ___ # # Fonctions relatives # -- # | _ |( ) ( )( '_`\ | | | | /'_`\ | |/',__)| |/' _ `\/',__) # # aux hypothèses sur # -- # | | | || (_) || (_) )| \_/ |( (_) )| |\__, \| || ( ) |\__, \ # # la façon dont les # -- # (_) (_)`\__, || ,__/'`\___/'`\___/'(_)(____/(_)(_) (_)(____/ # # salles sont reliées. # -- # ( )_| || | # ######################### -- # `\___/'(_) # -- # # -- ################################################################## HypVoisins = {} function HypVoisins.init(n) local i, j HypVoisins.voisinsMin = {} -- Pour chaque élément d'indice i, contient un ensemble de salles inclus dans celui des voisins de la salle i HypVoisins.voisinsMax = {} -- Pour chaque élément d'indice i, contient un ensemble de salles contenant celui des voisins de la salle i for i=1,n do HypVoisins.voisinsMin[i] = Ens.nouv{} HypVoisins.voisinsMax[i] = Ens.nouv{} for j=1,n do if j~=i then HypVoisins.voisinsMax[i][j] = true end end end end function HypVoisins.aPourVoisins(salle, ens) -- ens : toujours un ensemble de salles HypVoisins.voisinsMin[salle] = Ens.copie(ens) HypVoisins.voisinsMax[salle] = Ens.copie(ens) -- Il faut également ajouter la salle en tant que voisine de ses voisines. local k for k in pairs(ens) do HypVoisins.voisinsMin[k][salle] = true end -- Et ajouter la salle en tant que non voisine de ses non voisines. for k=1, Info.nombreDeSalles do if #(Ens.intersection(ens, Ens.nouv{k})) == 0 then -- Si la salle k n'est pas voisine de "salle" HypVoisins.voisinsMax[k][salle] = nil -- La salle "salle" n'est pas voisine de la salle k. end end end function HypVoisins.aAuMoinsPourVoisins(salle, ens) HypVoisins.voisinsMin[salle] = Ens.union(HypVoisins.voisinsMin[salle], ens) local k for k in pairs(ens) do HypVoisins.voisinsMin[k][salle] = true end end function HypVoisins.aAuPlusPourVoisins(salle, ens) HypVoisins.voisinsMax[salle] = Ens.copie(ens) end function HypVoisins.voisinsPossiblesDe(salle) -- Les voisins eventuels d'une salle return HypVoisins.voisinsMax[salle] end function HypVoisins.voisinsSursDe(salle) -- Renvoie un ensemble de salles dont on est certains qu'elles sont voisines de cette derniere return HypVoisins.voisinsMin[salle] end -- ############################## -- # _ ___ # ############################## -- # (_) /'___) # # Fonctions sur si les # -- # | | ___ | (__ _ # # salles ont été visitées, # -- # | |/' _ `\| ,__)/'_`\ # # calcul de trajectoires, # -- # | || ( ) || | ( (_) ) # # fonction sur le danger # -- # (_)(_) (_)(_) `\___/' # # d'une salle. # -- # # ############################## -- ############################## Info = {} function Info.init(n) Info.sallesVisitees = Ens.nouv{} Info.nombreDeSalles = n end function Info.ajSalleVisitee(salle) Info.sallesVisitees[salle] = true end function Info.savoirSiSalleVisitee(salle) return Info.sallesVisitees[salle] end function Info.recevoirSallesVisitees() return Info.sallesVisitees end function Info.tauxDEmbuche(salle) if debug_versLeTresor then print("-->Info.tauxDEmbuche("..tostring(salle)) end -- Associe +infini à un éventuel trou, 1 à un éventuel Wumpus, 0 sinon. if HypTrous.savoirSiTrouDans(Ens.nouv{salle}) ~= faux then if debug_versLeTresor then print("<-- infini") end return 1/0 elseif HypWumpus.savoirSiWumpusDans(Ens.nouv{salle}) ~= faux then if debug_versLeTresor then print("<-- 1") end return 1 else if debug_versLeTresor then print("<-- 0") end return 0 end end function Info.meilleurTrajetAuBoutDUnChemin(chemin, arrivee, fnScore, tauxMaxEmbuches) -- chemin = chemin déjà parcouru, pour ne pas revenir sur ses pas. -- arrivee = salle d'arrivee -- fnScore = fonction qui à un chemin associe un nombre de points indiquant à quel point il est bien -- (plus de points = meilleur chemin) -- tauxMaxEmbuches = le taux d'embûche maximal que l'on s'accorde pour un chemin. -- 0 => trajet sûr ; 1 => au maximum 1 endroit où il peut y avoir le Wumpus. -- Renvoie le meilleur chemin acceptable possible (nil s'il n'y a pas de chemin acceptable) et le score associé. local posActuelle = chemin[#chemin] -- posActuelle = Position actuelle qui se trouve au bout du chemin actuellement parcouru. local v = HypVoisins.voisinsSursDe(posActuelle) -- v = Ensemble de salles dont on est certains qu'elles sont voisines de la position actuelle. local meilleurChemin = nil -- Le résultat. local meilleurScore = -1/0 -- La borne supérieure de l'image directe de l'ensemble des chemins proposés par la fonction -- qui à un chemin associe la somme des images des salles par "fnScore" (cet ensemble est ici vide). local degreDEmbucheDuMeilleurChemin = 1/0 local tailleDuMeilleurChemin = 1/0 if debug_versLeTresor then print("\n--> Info.meilleurTrajetAuBoutDUnChemin("..serialize(chemin)..","..tostring(arrivee)..","..tostring(fnScore)..","..tostring(tauxMaxEmbuches)..")") print("posActuelle = "..tostring(posActuelle)) print("v = "..serialize(v)) end local k if debug_versLeTresor then print("==> Entrée for k in pairs(v)") end for k in pairs(v) do if debug_versLeTresor then print("** Dans for : k = "..tostring(k)) end local reboucle = false -- À true si l'on retourne sur nos pas. local i for _, i in ipairs(chemin) do if i==k then reboucle=true end end if debug_versLeTresor then print("** reboucle = "..tostring(reboucle)) print("** Info.tauxDEmbuche(k) = "..tostring(Info.tauxDEmbuche(k))) end -- Si l'on ne reboucle pas et que la salle proposée est acceptable. if not(reboucle) and Info.tauxDEmbuche(k) <= tauxMaxEmbuches then if debug_versLeTresor then print("** Condition sur reboucle et taux d'embûche ok") end local scoreSalle = fnScore(k) local cheminProposePartiel = Outil.copieTable(chemin) table.insert(cheminProposePartiel, k) -- cheminProposePartiel = chemin proposé arrivant à la salle k. local cheminPropose -- Chemin proposé final. local score -- Le score du chemin proposé final, commençant en la salle actuelle -- (il est inutile d'y inclure le chemin déjà parcouru puisqu'il est identique pour tous les chemins qui y prennent source). local degreDEmbuche = Info.tauxDEmbuche(k) -- Degré d'embûche du chemin à partir de k (compris). if debug_versLeTresor then print("** scoreSalle = "..tostring(scoreSalle)) print("** cheminProposePartiel = "..serialize(cheminProposePartiel)) print("** degreDEmbuche (temporaire) = "..tostring(degreDEmbuche)) end if k==arrivee then cheminPropose = cheminProposePartiel score = scoreSalle degreDEmbuche = 0 if debug_versLeTresor then tostring("*** k=arrivee="..tostring(k)) end if debug_versLeTresor then print("*** cheminPropose = "..serialize(cheminPropose)) print("*** score = "..tostring(score)) print("*** degreDEmbuche = "..tostring(degreDEmbuche)) end else if debug_versLeTresor then print("** k="..tostring(k).." <> arrivee="..tostring(arrivee)) end local degreDEmbuchePartiel cheminPropose, score, degreDEmbuchePartiel = Info.meilleurTrajetAuBoutDUnChemin(cheminProposePartiel, arrivee, fnScore, tauxMaxEmbuches - Info.tauxDEmbuche(k)) score = score + scoreSalle degreDEmbuche = degreDEmbuche + degreDEmbuchePartiel if debug_versLeTresor then print("*** cheminPropose = "..serialize(cheminPropose)) print("*** score = "..tostring(score)) print("*** degreDEmbuche = "..tostring(degreDEmbuche)) end end if cheminPropose then if debug_versLeTresor then print("*** cheminPropose <> nil") end if score > meilleurScore or (score == meilleurScore and #cheminPropose < tailleDuMeilleurChemin) then -- Si ce chemin est meilleur que les précédents meilleurChemin = cheminPropose -- On le prend. meilleurScore = score degreDEmbucheDuMeilleurChemin = degreDEmbuche tailleDuMeilleurChemin = #meilleurChemin if debug_versLeTresor then print("**** score > meilleurScore or [...]") print("-------------------------------------------") print(" meilleurChemin = "..serialize(cheminPropose)) print(" meilleurScore = "..serialize(meilleurScore)) print("degreDEmbucheDuMeilleurChemin = "..tostring(degreDEmbuche)) print("tailleDuMeilleurChemin = "..tostring(#meilleurChemin)) end else if debug_versLeTresor then print("*** cheminPropose = nil") end end end end end if debug_versLeTresor then print("<-- "..serialize(meilleurChemin)..","..tostring(meilleurScore)..","..tostring(degreDEmbucheDuMeilleurChemin).."\n") end return meilleurChemin, meilleurScore, degreDEmbucheDuMeilleurChemin end function Info.meilleurTrajet(depart, arrivee, fnScore, tauxMaxEmbuches) -- depart = salle de départ, arrivee = salle d'arrivée -- fnScore = fonction qui à un chemin associe un nombre de points indiquant à quel point il est bien -- (plus de points = meilleur chemin) -- Renvoie le meilleur chemin acceptable possible (nil s'il n'y a pas de chemin acceptable). -- (Un chemin acceptable est un chemin de taux d'embûches inférieur ou égal à tauxMaxEmbuches). if debug_versLeTresor then print("\n\n*****\nInfo.meilleurTrajet("..tostring(depart)..","..tostring(arrivee)..","..tostring(fnScore)..","..tostring(tauxMaxEmbuches)) local k for k = 1, Info.nombreDeSalles do print("Voisins de "..tostring(k).." : "..serialize(HypVoisins.voisinsSursDe(k))) end print("Lieu Wumpus = "..serialize(HypWumpus.sallesPossibles)) print("Salles sans trou = "..serialize(HypTrous.sallesSansTrou)) print("Groupes de salles avec trou = "..serialize(HypTrous.groupesDeSallesAvecTrou)) print("Wumpus vivant ? "..tostring(HypWumpus.vivant)) end local res = Info.meilleurTrajetAuBoutDUnChemin({depart}, arrivee, fnScore, tauxMaxEmbuches) return res end function Info.fnScoreTrajetLePlusCourt(salle) -- Fonction à utiliser en #3 dans Info.meilleurTrajet. -- Permet de selectionner le trajet acceptable le plus court. if Info.recevoirDanger(salle) == faux then return -1 -- Score négatif, proportionnel à la taille du trajet. elseif HypTrous.savoirSiTrouDans(Ens.nouv{salle}) == faux then -- Il y a peut-être du Wumpus, mais pas de trou. return -2 -- Lorsque l'on accepte le Wumpus, il faudra toutefois 1 tour pour le tuer. else -- Il y a peut-être des trous. return -1/0 -- On ne veut pas d'une salle dangereuse. -- Remarque : cette valeur n'est en fait jamais utilisée car on remarque le statut de non-acceptabilité d'une salle -- grâce à la fonction Info.tauxDEmbuche. On peut donc modifier ceci est renvoyant une probabilité de tomber sur un danger. end end function Info.fnScoreTrajetLeMoinsDangereux(salle) -- Fonction à utiliser en #3 dans Info.meilleurTrajet. -- Permet de sélectionner le trajet acceptable avec le moins d'embûche. local danger = Info.recevoirDanger(salle) if danger == faux then return 0 elseif danger == vrai then return -1/0 end return -1 end function Info.recevoirDangerProba(salle) local proba = 0 local danger = Info.recevoirDanger(salle) if danger == faux then return 0 elseif danger == vrai then return 1 end if HypWumpus.savoirSiWumpusDans(Ens.nouv{salle}) ~= faux then proba = 1/Ens.cardinal(HypWumpus.lieuWumpus()) end if HypTrous.savoirSiTrouDans(Ens.nouv{salle}) ~= faux then local groupe for groupe in pairs(Ens.nouv(HypTrous.groupesDeSallesAvecTrou)) do proba = proba+(1-proba)/Ens.cardinal(groupe) end end return proba end function Info.recevoirDangerProbaDuTrajet(chemin) local danger = 0 local salle for _, salle in ipairs(chemin) do danger = danger+(1-danger)*Info.recevoirDangerProba(salle) end return danger end function Info.recevoirDanger(salle) -- Permet de savoir si une salle est avec ou sans danger, ou si l'on en sait rien. local w = HypWumpus.savoirSiWumpusDans(Ens.nouv{salle}) local t = HypTrous.savoirSiTrouDans(Ens.nouv{salle}) if w==vrai or t==vrai then return vrai elseif w==peutEtre or t==peutEtre then return peutEtre else return faux end end --function Info.tenterUnTrajet( -- ########################## -- # _ # -- # _ _ ( )_ # ####################### -- # (_) ___ (_)| ,_) # # Initialisation de # -- # | |/' _ `\| || | # # la mémoire, entre # -- # | || ( ) || || |_ # # chaque circuit. # -- # (_)(_) (_)(_)`\__) # ####################### -- # # -- ########################## function init(n) -- n : nombre de salles du labyrinthe, numerotees de 1 a n -- 1 : salle de depart -- Role de la fonction: creer une liste mem globale -- qui va coder la representation memoire qu'a l'IA du labyrinthe: print("\n******** Initialisation **************\n") mem = {} mem.actionPrec = false -- Désigne le type d'action précédente. -- false : rien, 1 : déplacement, {salle} : tir d'une flèche dans la salle précisée mem.provisionFleche = true -- À false si on n'a plus de flèche. HypTrous.init(n) HypWumpus.init(n) HypTresor.init(n) HypVoisins.init(n) Info.init(n) mem.versLaSortie = false mem.trajetPrevu = false dbg_n = 0 dbg_var = "" debug_versLeTresor = false end -- ##################################### -- # _ _ _ # -- # ( )_ ( ) _ ( ) # ########################### -- # | ,_)| |__ (_) ___ | |/') # # Fonction qui exploite # -- # | | | _ `\| |/' _ `\| , < # # les informations # -- # | |_ | | | || || ( ) || |\`\ # # acquises. # -- # `\__)(_) (_)(_)(_) (_)(_) (_) # ########################### -- # # -- ##################################### function think(n,ip,lv,lc) -- n: nombre de salles du labyrinthe, numerotees de 1 a n -- ip: numero de la salle courante -- lv: liste des numeros des salles voisines -- lc: liste ordonnee des 4 sensations suivantes - une valeur de 1 indique la sensation comme percue -- - "ca pue " -> attention, le monstre est dans une salle voisine -- - "ca souffle " -> attention, il y a un trou dans une salle voisine -- - "ca brille " -> le tresor est dans une salle voisine -- - "c'est lourd" -> le tresor a ete ramasse -- Role de la fonction: mettre a jour la variable globale mem avec les nouvelles informations/deductions print("***** think(n="..tostring(n)..",ip="..tostring(ip)..",lv="..serialize(lv)..",lc="..serialize(lc)..") *****|n") local singleton = Ens.nouv{ip} HypWumpus.pasDeWumpusDans(singleton) HypTrous.pasDeTrouDans(singleton) HypTresor.pasDeTresorDans(singleton) local voisins = Ens.nouv(lv) -- Ensemble des voisins HypVoisins.aPourVoisins(ip, voisins) Info.ajSalleVisitee(ip) if lc[1] == 1 then -- ça pue HypWumpus.leWumpusEstDansUneDes(voisins) else HypWumpus.pasDeWumpusDans(voisins) end if lc[2] == 1 then -- ça souffle HypTrous.unTrouEstDansUneDes(voisins) else HypTrous.pasDeTrouDans(voisins) end if lc[3] == 1 then -- ça brille HypTresor.leTresorEstDansUneDes(voisins) else HypTresor.pasDeTresorDans(voisins) end if type(mem.actionPrec) == "table" then -- Si l'on a tiré une flèche la dernière fois mem.provisionFleche = false -- On n'a plus de flèche. if lc[1] ~= 1 then -- S'il n'y a pas de Wumpus, on l'a tué. HypWumpus.plusDeWumpus(mem.actionPrec[1]) -- Il n'y a plus de Wumpus. HypTrous.pasDeTrouDans(Ens.nouv{mem.actionPrec[1]}) HypTresor.pasDeTresorDans(Ens.nouv{mem.actionPrec[1]}) else -- Sinon, on sait quand même que là où on a tiré, il n'y a pas le Wumpus HypWumpus.pasDeWumpusDans(Ens.nouv{mem.actionPrec[1]}) end end if lc[4] == 1 then -- Nous sommes en route vers la sortie (le depart, en fait). if not(mem.versLaSortie) then -- On vient de prendre le tresor HypTresor.plusDeTresor(ip) mem.versLaSortie = true end debug_versLeTresor = true local temp = Info.meilleurTrajet(ip, 1, Info.fnScoreTrajetLePlusCourt, 0) -- Calcul d'un trajet sûr, le plus court possible. mem.prochaineSalle = temp[2] -- On prend la prochaine salle prévue par le meilleur chemin. -- Remarque : on recalcule le chemin à chaque fois car il est possible que nous gagnions en informations et trouvions donc par la suite un meilleur chemin. end print('Lieu trésor : '..serialize(HypTresor.lieuTresor()) ..'\nLieu Wumpus : '..serialize(HypWumpus.lieuWumpus()) ..'\nGroupes trous : '..serialize(HypTrous.groupesDeSallesAvecTrou) ..'\nSalles sans trous : '..serialize(HypTrous.sallesSansTrou)) end -- ############################################ -- # _ # -- # ( )_ _ # ############################ -- # _ _ ___ | ,_)(_) _ ___ # # Fonction qui choisit # -- # /'_` ) /'___)| | | | /'_`\ /' _ `\ # # une action en fonction # -- # ( (_| |( (___ | |_ | |( (_) )| ( ) | # # des données. # -- # `\__,_)`\____)`\__)(_)`\___/'(_) (_) # ############################ -- # # -- ############################################ function action(n,ip,lv) -- n: nombre de salles du labyrinthe, numerotees de 1 a n -- ip: numero de la salle courante dans laquelle se situe le joueur -- lv: liste des salles voisines -- Role de la fonction: decide: -- - soit d'aller dans l'une des salles voisines et retourne son numero -- - soit de tirer dans l'une des salles voisines (droit a 1 seul coup) pour y tuer le Wumpus et retourne l'oppose de son numero -- code par defaut librement modifiable: le joueur avance au hasard --i=1 --if #lv>0 then -- i = math.random(1,#lv) --end --return lv[i] print("****** action (...) *******") mem.actionPrec = 1 -- Par défaut, l'action que l'on va mener est un déplacement (modifié sinon) local sallesVoisines = Ens.nouv(lv) local salles = Ens.nouv{} -- Ensemble des salles. local k for k=1, n do salles[k] = true end --------------------------------------------------------------------------- -- Si l'on se dirige vers la sortie, on prend la prochaine salle prévue. -- --------------------------------------------------------------------------- if mem.versLaSortie then print("Vers sortie, salle "..tostring(mem.prochaineSalle).."\n") return mem.prochaineSalle end ------------------------------------------------------------------------------------ -- Si l'on sait où se trouve le trésor et qu'il y a un trajet sûr, on s'y dirige. -- ------------------------------------------------------------------------------------ local posTresor = Ens.estUnSingleton(HypTresor.lieuTresor()) if posTresor then -- Si l'on connaît la position du trésor avec certitude. local trajet = Info.meilleurTrajet(ip, posTresor, Info.fnScoreTrajetLePlusCourt, 0) if trajet then print("Vers trésor, salle "..tostring(trajet[2]).."\n") return trajet[2] end end -------------------------------------------------------------------------------------------------------- -- Si l'on sait où se trouve le Wumpus et que l'on a une flèche, on se rapproche de lui si besoin est -- -- (et si l'on peut emprunter un chemin sûr), et on lui tire une flèche. -- -------------------------------------------------------------------------------------------------------- local posWumpus = Ens.estUnSingleton(HypWumpus.lieuWumpus()) if posWumpus and mem.provisionFleche then if sallesVoisines[posWumpus] then -- Si le Wumpus est à côté print("On tire une flèche salle "..tostring(posWumpus).."\n") mem.actionPrec = {posWumpus} return -posWumpus else local t = Info.meilleurTrajet(ip, posWumpus, Info.fnScoreTrajetLePlusCourt, 0) -- En pratique, nous n'irons pas jusqu'au Wumpus. if t then -- Si l'on a trouvé un trajet sûr print("Vers le Wumpus en allant salle "..tostring(t[2]).."\n") return t[2] end end end local t --------------------------------------------------------------------------------------------------------------------- -- S'il y a une salle à laquelle on peut accéder sans danger et dans laquelle il peut y avoir le trésor, on y va : -- --------------------------------------------------------------------------------------------------------------------- for k in pairs(Ens.intersection(salles, HypTresor.lieuTresor())) do local trajet = Info.meilleurTrajet(ip, k, Info.fnScoreTrajetLePlusCourt, 0) if trajet then print("Option 4, salle "..tostring(trajet[2]).."\n") return trajet[2] end end -------------------------------------------------------------------------------------------------------------- -- S'il y a une autre salle non visitée à laquelle on peut accéder sans danger, on va vers la plus proche : -- -------------------------------------------------------------------------------------------------------------- local meilleureTaille = 1/0 local salleLaPlusProche for k in pairs(Ens.moins(salles, Ens.union(HypTresor.lieuTresor(), Info.recevoirSallesVisitees()))) do -- On examine toutes les salles non visitées accessibles sans danger. local trajet = Info.meilleurTrajet(ip, k, Info.fnScoreTrajetLePlusCourt, 0) if trajet and #trajet < meilleureTaille then -- On prend la salle la plus proche. meilleureTaille = #trajet salleLaPlusProche = trajet[2] end end if salleLaPlusProche then print("Vers salle non visitée, salle "..tostring(salleLaPlusProche).."\n") return salleLaPlusProche end ------------------------------------------------------------------------------------------------------------------------- -- S'il est possible d'accéder à un emplacement possible du trésor avec au plus un emplacement où le Wumpus peut être -- -- là sur le chemin, on effectue le trajet et on tirera une flèche sur cet emplacement (si on a encore une flèche). -- ------------------------------------------------------------------------------------------------------------------------- meilleureTaille = 1/0 salleLaPlusProche = nil if mem.provisionFleche then for k in pairs(HypTresor.lieuTresor()) do local trajet = Info.meilleurTrajet(ip, k, Info.fnScoreTrajetLePlusCourt, 1) if trajet and #trajet < meilleureTaille then meilleureTaille = #trajet salleLaPlusProche = trajet[2] end end if salleLaPlusProche then if HypWumpus.savoirSiWumpusDans(Ens.nouv{salleLaPlusProche}) ~= faux then mem.actionPrec = {salleLaPlusProche} print("Vers trésor malgré Wumpus, salle "..tostring(-salleLaPlusProche).."\n") return -salleLaPlusProche else print("Vers trésor malgré Wumpus, salle "..tostring(salleLaPlusProche).."\n") return salleLaPlusProche end end end ------------------------------------------------------------------------------------------------------------------------------ -- S'il est possible d'accéder à un emplacement non visité et sans danger certain, avec au plus un emplacement -- -- possible du Wumpus sur le trajet, on l'effectue et on tirera une flèche sur cet emplacement (si on a encore une flèche). -- ------------------------------------------------------------------------------------------------------------------------------ if mem.provisionFleche then print("Tentons d'avancer avec une flèche même si Wumpus.") print("Salles à essayer : "..serialize(Ens.moins(salles, Info.recevoirSallesVisitees()))) local mdr1 for mdr1=1, n do -- On commence par le plus faible nombre d'endroits où il peut y avoir le Wumpus sur le trajet. print(" mdr1 = "..tostring(mdr1)) for k in pairs(Ens.moins(salles, Info.recevoirSallesVisitees())) do local trajet = Info.meilleurTrajet(ip, k, Info.fnScoreTrajetLePlusCourt, mdr1) if trajet and #trajet < meilleureTaille then meilleureTaille = #trajet salleLaPlusProche = trajet[2] end end if salleLaPlusProche then if HypWumpus.savoirSiWumpusDans(Ens.nouv{salleLaPlusProche}) ~= faux then mem.actionPrec = {salleLaPlusProche} print("Option 7, salle "..tostring(-salleLaPlusProche)) mem.actionPrec = {salleLaPlusProche} return -salleLaPlusProche else print("Option 7, salle "..tostring(salleLaPlusProche)) return salleLaPlusProche end end end print("Tant pis finalement.\n") end ----------------------------------------------------------------------------------------------------------------- -- Nous sommes désespérés et tentons donc d'aller dans une salle qui peut contenir le trésor malgré le danger. -- ----------------------------------------------------------------------------------------------------------------- local salleTresor local salleLaPlusSureDAcces local probabiliteDeLaMeilleureSalle = 1 dbg_msg("Désespérés") dbg_msg("Nous sommes salle "..tostring(ip)) for salleTresor in pairs(HypTresor.lieuTresor()) do dbg_msg("Test salle "..tostring(salleTresor)) local chemin = Info.meilleurTrajet(ip, salleTresor, Info.fnScoreTrajetLeMoinsDangereux, 1/0) if chemin then local probabiliteDeCetteSalle = Info.recevoirDangerProbaDuTrajet(chemin) dbg_msg("Proba : "..tostring(probabiliteDeCetteSalle)) if probabiliteDeCetteSalle < probabiliteDeLaMeilleureSalle then salleLaPlusSureDAcces = chemin[2] probabiliteDeLaMeilleureSalle = probabiliteDeCetteSalle dbg_msg("Salle "..tostring(salleLaPlusSureDAcces).." bien.") end end end if salleLaPlusSureDAcces then return salleLaPlusSureDAcces end ----------------------------------------------------------------------------------------------------------------------------------- -- Nous ne connaissons aucun chemin menant à une salle, même de manière dangereuse. Nous allons donc dans une salle non visitée. -- ----------------------------------------------------------------------------------------------------------------------------------- local salleInconnue probabiliteDeLaMeilleureSalle = 1 tailleDuMeilleurTrajet = 1/0 dbg_msg("Désespérés désespérés") dbg_msg("Nous sommes salle "..tostring(ip)) for salleInconnue in pairs(Ens.moins(salles, Info.recevoirSallesVisitees())) do dbg_msg("Test salle "..tostring(salleInconnue)) local chemin = Info.meilleurTrajet(ip, salleInconnue, Info.fnScoreTrajetLeMoinsDangereux, 1/0) if chemin then local probabiliteDeCetteSalle = Info.recevoirDangerProbaDuTrajet(chemin) dbg_msg("Proba : "..tostring(probabiliteDeCetteSalle)) dbg_msg("Proba meilleure salle : "..tostring(probabiliteDeLaMeilleureSalle)) if probabiliteDeCetteSalle < probabiliteDeLaMeilleureSalle or (probabiliteDeCetteSalle == probabiliteDeLaMeilleureSalle and ((not salleLaPlusSureDAcces) or #chemin < tailleDuMeilleurTrajet)) then -- La deuxième ligne dans la condition permet de choisir le trajet le plus court à danger égal. salleLaPlusSureDAcces = chemin[2] probabiliteDeLaMeilleureSalle = probabiliteDeCetteSalle tailleDuMeilleurTrajet = #chemin dbg_msg("Salle "..tostring(salleLaPlusSureDAcces).." bien.") end end end return salleLaPlusSureDAcces --[[ Problème à corriger (=> version 3) : il arrive que l'IA fasse une boucle infinie entre deux salles. En fait, c'est qu'elle change sans cesse d'avis sur quel trajet emprunter. => Enregistrer le trajet. ]]-- end dbg_n = nil function dbg_msg(texte) --if string.len(dbg_var) > 1500 then -- dbg_n = dbg_n + 1 -- dbg_var = "" --end --dbg_var = dbg_var..texte.."\n" --math.eval('console'..tostring(dbg_n)..':="'..dbg_var..'"') --math.eval("n_console := "..tostring(dbg_n)) print(texte.." ") end function serialize(t) if type(t) == "table" then local sRet = "[" local i, j for i, j in pairs(t) do sRet = sRet..serialize(i)..":"..serialize(j).."," end sRet = sRet.."]" return sRet elseif type(t) == "string" then return '"'..t..'"' else return tostring(t) end end ---------------------------------------------------------------------------------- -- INTERDICTION DE MODIFIER OU D'UTILISER CE QUI SUIT DANS LE CADRE DU CONCOURS -- ---------------------------------------------------------------------------------- imgwumpus = image.new("*\000\000\000.\000\000\000\000\000\000\000T\000\000\000\016\000\001\000\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\161\185\161\185\161\185\161\185\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\206\222\183\255\254\255\254\255\183\255\206\222\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\183\255\183\255\254\255\254\255\254\255\254\255\183\255\183\255\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\206\222\183\255\183\255\254\255\254\255\254\255\254\255\183\255\183\255\206\222\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\206\222\183\255\183\255\183\255\254\255\254\255\183\255\183\255\183\255\206\222\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\206\222\206\222\206\222\206\222\183\255\183\255\183\255\183\255\206\222\206\222\206\222\206\222\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\206\222\206\222\183\255\183\255\227\156\227\156\227\156\227\156\183\255\183\255\206\222\206\222\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\227\156\206\222\183\255\227\156\227\156\247\235 \132 \132\247\235\227\156\227\156\183\255\206\222\227\156\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\161\185\161\185\161\185\031|\031|\128\145\128\145\031|\031|\031|\227\156\206\222\227\156\247\235 \132\174\202 \132 \132\174\202 \132\247\235\227\156\206\222\227\156\031|\031|\031|\128\145\128\145\031|\031|\161\185\161\185\161\185\031|\031|\031|\031|\031|\031|\031|\227\156\206\222\183\255\183\255\161\185\161\185G\150\232\202\128\145\224\144\031|\227\156\227\156 \132\174\202 \132 \132 \132 \132 \132 \132\174\202 \132\227\156\227\156\031|\224\144\128\145\232\202G\150\161\185\161\185\183\255\183\255\206\222\227\156\031|\031|\031|\031|\031|\227\156\206\222\183\255\254\255\254\255\254\255\183\255\161\185\128\145G\150B\165\224\144\227\156\161\185\227\156 \132 \132 \132 \132 \132 \132 \132 \132\227\156\161\185\227\156\224\144B\165G\150\128\145\161\185\183\255\254\255\254\255\254\255\183\255\206\222\227\156\031|\031|\031|\227\156\206\222\206\222\254\255\254\255\254\255\254\255\254\255\183\255\161\185\232\202\232\202B\165\227\156\206\222\227\156\174\202 \132\192\177\224\136\224\136\192\177 \132\174\202\227\156\206\222\227\156B\165\232\202\232\202\161\185\183\255\254\255\254\255\254\255\254\255\254\255\206\222\206\222\227\156\031|\031|\227\156\206\222\183\255\254\255\254\255\254\255\254\255\254\255\183\255\161\185G\150B\165B\165\227\156\206\222\227\156\247\235 \132!\227\192\177\192\177!\227 \132\247\235\227\156\206\222\227\156B\165B\165G\150\161\185\183\255\254\255\254\255\254\255\254\255\254\255\183\255\206\222\227\156\031|\227\156\206\222\206\222\183\255\183\255\254\255\254\255\254\255\183\255\183\255\161\185\128\145G\150\160\140\224\177\227\156\206\222\227\156\174\202\192\177!\227!\227\192\177\174\202\227\156\206\222\227\156\224\177\160\140G\150\128\145\161\185\183\255\183\255\254\255\254\255\254\255\183\255\183\255\206\222\206\222\227\156\227\156\206\222\206\222\183\255\183\255\183\255\183\255\183\255\183\255\161\185\254\255\227\156\128\145\160\140\224\177\227\156\183\255\227\156\247\235 \132\224\136\224\136 \132\247\235\227\156\183\255\227\156\224\177\160\140\128\145\227\156\254\255\161\185\183\255\183\255\183\255\183\255\183\255\183\255\206\222\206\222\227\156\227\156\206\222\206\222\227\156\227\156\183\255\183\255\183\255\161\185\254\255\183\255\227\156\160\140\224\177\224\177\224\144\227\156\183\255\227\156\227\156\247\235\247\235\227\156\227\156\183\255\227\156\224\144\224\177\224\177\160\140\227\156\183\255\254\255\161\185\183\255\183\255\183\255\227\156\227\156\206\222\206\222\227\156\227\156\206\222\227\156 \132\247\235 \132\247\235 \132\227\156\183\255\206\222\227\156\224\177\005\227\224\144\031|\031|\227\156\183\255\183\255\227\156\227\156\183\255\183\255\227\156\031|\031|\224\144\005\227\224\177\227\156\206\222\183\255\227\156 \132\247\235 \132\247\235 \132\227\156\206\222\227\156\031|\227\156\174\202 \132 \132\192\177\192\177\227\156\183\255\206\222\161\185\224\144\005\227\224\177\224\144\031|\031|\031|\227\156\227\156\183\255\183\255\227\156\227\156\031|\031|\031|\224\144\224\177\005\227\224\144\161\185\206\222\183\255\227\156\192\177\192\177 \132 \132\174\202\227\156\031|\031|\031|\227\156 \132\192\177\247\235\227\156\183\255\206\222\206\222\227\156B\165\005\227\224\144\031|\031|\031|\031|\031|\031|\227\156\227\156\224\144\031|\031|\031|\031|\031|\224\144\005\227B\165\227\156\206\222\206\222\183\255\227\156\247\235\192\177 \132\227\156\031|\031|\031|\031|\227\156\174\202\227\156\227\156\183\255\206\222\206\222\227\156\031|B\165\005\227\224\144\160\140\160\140\160\140\160\140\031|\031|\224\144B\165\224\144\031|\160\140\160\140\160\140\160\140\224\144\005\227B\165\031|\227\156\206\222\206\222\183\255\227\156\227\156\174\202\227\156\031|\031|\031|\031|\031|\227\156\183\255\183\255\206\222\161\185\227\156\031|\031|\224\144\005\227\224\177\224\144G\150\160\140\128\145\160\140\224\144\224\177\224\177\224\144\160\140\128\145\160\140G\150\224\144\224\177\005\227\224\144\031|\031|\227\156\161\185\206\222\183\255\183\255\227\156\031|\031|\031|\031|\031|\031|\031|\161\185\161\185\227\156\031|\031|\031|\160\140\128\145\224\144\005\227\224\144\128\145\128\145\160\140\128\145\224\144\005\227\224\144\160\140\128\145\160\140\128\145\128\145\224\144\005\227\224\144\128\145\160\140\031|\031|\031|\227\156\161\185\161\185\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\160\140\224\144B\165\224\177\224\144\224\144\128\145\160\140\224\144\005\227\224\144\128\145\160\140\128\145\224\144\224\144\224\177B\165\224\144\160\140\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\160\140\128\145\128\145\128\145\224\144B\165\224\177B\165\224\144\224\144\224\144\224\177\224\177\224\144\224\144\224\144B\165\224\177B\165\224\144\128\145\128\145\128\145\160\140\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\160\140\128\145\128\145\160\140\160\140\160\140\128\145\224\144\224\144B\165B\165B\165\224\144\224\144B\165\224\144B\165B\165B\165\224\144\224\144\128\145\160\140\160\140\160\140\128\145\128\145\160\140\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\128\145G\150\160\140\160\140\128\145\128\145\160\140\160\140\128\145\128\145\224\144\160\140\160\140\128\145\160\140\160\140\128\145\160\140\160\140\224\144\128\145\128\145\160\140\160\140\128\145\128\145\160\140\160\140G\150\128\145\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\128\145G\150\160\140\128\145\128\145\128\145\160\140\128\145G\150\128\145\160\140\160\140\128\145\128\145\232\202G\150\128\145\232\202\128\145\128\145\160\140\160\140\128\145G\150\128\145\160\140\128\145\128\145\128\145\160\140G\150\128\145\160\140\031|\031|\031|\031|\031|\031|\031|\031|\160\140\128\145\128\145G\150G\150\128\145\160\140G\150G\150\128\145\128\145\128\145\128\145\232\202G\150G\150\128\145\128\145G\150G\150\232\202\128\145\128\145\128\145\128\145G\150G\150\160\140\128\145G\150G\150\128\145\128\145\160\140\031|\031|\031|\031|\031|\031|\031|\160\140\128\145G\150G\150\160\140\160\140\160\140G\150\128\145\206\243\232\202\128\145\128\145G\150\232\202\206\243\232\202G\150\232\202\206\243\206\243G\150\232\202\128\145\128\145\232\202\206\243\128\145G\150\160\140\160\140\160\140G\150G\150\128\145\160\140\031|\031|\031|\031|\031|\031|\160\140G\150\160\140\160\140\031|\160\140G\150\128\145\206\243G\150G\150\128\145\128\145\206\243\206\243G\150G\150G\150G\150G\150\232\202\206\243\206\243\128\145\128\145G\150G\150\206\243\128\145G\150\160\140\031|\160\140\160\140G\150\160\140\031|\031|\031|\031|\031|\031|\031|\160\140\031|\031|\160\140\128\145\128\145\206\243\206\243\232\202\128\145\128\145\128\145\206\243G\150\206\243\232\202G\150\232\202\206\243G\150\232\202\206\243\128\145\128\145\128\145\232\202\206\243\206\243\128\145\128\145\160\140\031|\031|\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\128\145G\150\232\202G\150\128\145G\150\128\145\128\145\232\202\206\243\232\202G\150G\150G\150G\150\232\202\206\243\232\202\128\145\128\145G\150\128\145G\150\232\202G\150\128\145\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\160\140\128\145\128\145\232\202\232\202\232\202G\150\160\140\160\140\160\140G\150\232\202G\150\232\202G\150\232\202\232\202G\150\232\202G\150\160\140\160\140\160\140G\150\232\202\232\202\232\202\128\145\128\145\160\140\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\193\160\160\140\128\145\232\202\160\140\160\140\160\140\160\140 \181\193\160 \181\160\140\232\202\206\243\232\202G\150G\150\232\202\206\243\232\202\160\140 \181\193\160 \181\160\140\160\140\160\140\160\140\232\202\128\145\160\140\193\160\031|\031|\031|\031|\031|\031|\031|\031|\193\160\193\160 \181\160\140G\150\160\140\031|\031|\193\160\193\160\193\160 \181 \181\160\140G\150\232\202\232\202G\150\232\202G\150\232\202G\150\160\140 \181 \181\193\160\193\160\193\160\031|\031|\160\140G\150\160\140 \181\193\160\193\160\031|\031|\031|\031|\031|\193\160 \181 \181 \181\160\140\160\140\031|\193\160\193\160 \181\128\205 \181 \181\193\160\031|\160\140G\150\232\202G\150G\150\232\202G\150\160\140\031|\193\160 \181 \181\128\205 \181\193\160\193\160\031|\160\140\160\140 \181 \181 \181\193\160\031|\031|\031|\193\160\128\205\128\205\193\160\193\160\031|\031|\193\160\128\205 \238\128\205\193\160\193\160\193\160\031|\193\160 \181\160\140G\150\232\202\128\145\232\202\160\140 \181\193\160\031|\193\160\193\160\193\160\128\205 \238\128\205\193\160\031|\031|\193\160\193\160\128\205\128\205\193\160\031|\031|\193\160 \238\193\160\031|\031|\031|\193\160\128\205\134\246\193\160\193\160 \181\193\160\031|\193\160\128\205 \181\193\160\160\140G\150\128\145G\150\160\140 \181\128\205\193\160\031|\193\160 \181\193\160\193\160\134\246\128\205\193\160\031|\031|\031|\193\160 \238\193\160\031|\031|\193\160 \238\193\160\031|\031|\031| \181N\255\193\160\031|\193\160 \181\193\160\031| \181N\255\193\160\031|\031|\160\140G\150\160\140\031|\193\160N\255 \181\031|\193\160 \181\193\160\031|\193\160N\255 \181\031|\031|\031|\193\160 \238\193\160\031|\031|\193\160\128\205\128\205\193\160\031| \181N\255\128\205\193\160\031|\031|\193\160\031| \181N\255 \238\193\160\031|\031|\031|\160\140\031|\031|\193\160 \238N\255 \181\031|\193\160\031|\031|\193\160\128\205N\255 \181\031|\193\160\128\205\128\205\193\160\031|\031|\031|\193\160\128\205\193\160\031| \181\134\246\193\160\031|\031|\031|\031|\031| \181N\255\193\160\031|\031|\031|\031|\031|\031|\031|\031|\193\160N\255 \181\031|\031|\031|\031|\031|\193\160\134\246 \181\031|\193\160\128\205\193\160\031|\031|\031|\031|\031|\193\160\031|\031|\193\160 \238\193\160\031|\031|\031|\031|\031| \181N\255\193\160\031|\031|\031|\031|\031|\031|\031|\031|\193\160N\255 \181\031|\031|\031|\031|\031|\193\160 \238\193\160\031|\031|\193\160\031|\031|\031|\031|\031|\031|\031|\031|\031|\193\160\128\205\128\205\193\160\031|\031|\031|\031|\193\160\134\246\193\160\031|\031|\031|\031|\031|\031|\031|\031|\193\160\134\246\193\160\031|\031|\031|\031|\193\160\128\205\128\205\193\160\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\193\160\128\205\193\160\031|\031|\031|\031|\193\160\128\205\128\205\193\160\031|\031|\031|\031|\031|\031|\193\160\128\205\128\205\193\160\031|\031|\031|\031|\193\160\128\205\193\160\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\193\160\031|\031|\031|\031|\031|\031|\193\160\128\205\193\160\031|\031|\031|\031|\031|\031|\193\160\128\205\193\160\031|\031|\031|\031|\031|\031|\193\160\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\193\160\031|\031|\031|\031|\031|\031|\031|\031|\193\160\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|\031|") imgwumpus_width = image.width(imgwumpus) imgwumpus_height = image.height(imgwumpus) imgchest = image.new("\025\000\000\000\022\000\000\000\000\000\000\0002\000\000\000\016\000\001\000\255\127\255\127\255\127\222\127U\243\207\238\240\2385\243\221\255\255\127\255\127\255\127\255\127\255\127\255\127\222\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\222\127\255\127\153\251\237\242\202\246\208\222\246\210\214\206\211\210\212\222\243\2265\2395\2435\243\153\251\222\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\155\251P\2470\247\023\223\127\223~\223\127\215\127\215^\211\242\222\169\242k\234\146\214\145\206\178\214\243\2304\235x\247\153\251y\247\221\255\255\127\255\127\255\127\255\1271\243s\247\022\235\191\239\190\235\158\235\158\235~\2272\239N\255\209\230]\219\127\215_\211^\211_\207\246\210i\234\228\233\195\225\229\229k\234\155\251\255\127y\247\182\251\244\234\158\231\158\235\159\235\190\235\191\239V\239\146\255\241\234\159\235\159\235\158\235\158\235\158\227\023\227\012\251%\238\010\210u\186u\186M\210i\234x\247\019\243\153\251\180\218\127\215}\223~\223~\227\092\227s\2473\243[\235\190\235\190\235\190\239\191\239[\235q\251h\238\011\206\153\174\186\178\187\178\150\186i\238\240\238\242\238\250\255T\243\019\235\024\219^\211\027\2155\239\214\255\017\239]\219~\227~\227\158\227\158\231V\239P\247\231\221\152\178\186\182\186\182\187\182\150\190\138\238\240\238\018\243\182\251\019\231T\243\178\251\212\214V\239\144\246\240\242\245\255\019\231_\207;\215<\215\027\215U\243\171\242.\206\187\178\187\182\187\186\187\186\150\194\169\238\018\2433\243Q\251\248\210\027\207T\243\016\243\144\246\229\216\000\180k\234\178\251\210\222u\247u\247\019\235\185\251\139\234R\198\188\182\187\186\187\186\187\186\149\198\169\2383\2433\243.\251\247\218\127\215\240\234\145\255\175\250\022\243\000\192\004\209\210\255q\2512\239\243\226\017\239\216\255\138\238q\198\220\182\187\186\187\186\188\182\149\198\169\2423\2434\243\012\251\247\222\159\223\239\234\145\255\162\241\160\220@\212$\221\178\251\145\255\245\218_\207\027\207s\247\138\238q\198\220\182\187\186\187\186\188\182q\202\200\2465\2434\243\010\255\204\246\240\234\012\247\011\247\195\249\000\237\160\228\006\246\143\255N\255\023\223\127\215;\215Q\247\137\238q\198\220\182\187\182\150\194k\222\135\242\137\238x\247\188\251\169\238\169\242\200\246\169\242\138\238\202\250\161\253\195\249\012\255\201\246\011\247\240\234\127\223]\2190\247\135\242q\198\151\190l\222f\242i\226\007\226\207\238\255\127\255\127\016\243\014\247\246\218}\223\243\230\201\246\234\250\234\250\201\246\169\238\135\242\010\251\240\238\020\231-\247\137\238'\226F\238H\230r\194\153\174K\222\240\238\255\127\255\127\016\239\143\255\014\247:\219]\219\139\234\167\250\167\250\167\250f\242\243\226\207\234\201\246\201\250\234\250F\238(\226q\198\153\178\186\182\186\182j\230\241\242\255\127\255\127\016\239\237\242\208\222\016\239>\203\247\214h\238\140\226h\234\139\230]\219\127\223]\219\023\223\235\246\228\233s\190\188\178\187\182\187\186\186\182i\234\018\243\255\127\255\127\240\242\011\247\146\214\170\234\140\226\028\199\210\222\171\234\139\230\025\211_\211\027\2153\2390\243n\251F\238u\198\220\182\188\182\150\190k\222f\242\018\243\255\127\255\127\207\242\234\250\201\250\234\250\010\251\240\234\243\218\211\210\249\202\248\206\178\214\016\243.\251\208\226O\251f\242\150\194\186\182n\214F\238\138\238\240\234\188\251\255\127\255\127\188\251V\247\188\251x\247\241\242\204\246\201\246\234\250\012\247\237\242\234\250\201\246\145\210\249\202-\247\135\242L\214h\234G\238V\247\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\221\255x\2474\243\238\242\202\246\234\250\234\250\235\246+\251\135\242F\238\207\238\221\255\255\127\255\127\255\127\255\127\255\127\255\127\222{\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\222\127\154\2514\243\238\242\234\250%\2385\243\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127\189\247\255\127\255\127\255\127\255\127\255\127\255\127\255\127\222\127\018\243\018\239\255\127\255\127\255\127\255\127\255\127\255\127\255\127\255\127") imgchest_width = image.width(imgchest) imgchest_height = image.height(imgchest) imgtrap = image.new(" \000\000\000\019\000\000\000\000\000\000\000@\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153+\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153\242\169U\178\242\169+\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153+\153+\153\000\000\000\000+\153\242\169U\178U\178U\178\242\169\142\153+\153\000\000+\153+\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153\142\153U\178U\178+\153\233\140\233\140\242\169\242\169\242\169\242\169\242\169\142\153+\153+\153\142\153\142\153\142\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153+\153\142\153\242\169\242\169+\153\142\153+\153+\153\233\140\233\140+\153+\153+\153\167\140\233\140\142\153\242\169\242\169\242\169+\153+\153\142\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153\142\153\233\140+\153+\153\142\153+\153\233\140+\153\233\140\167\140\233\140\233\140\233\140e\132e\132\233\140+\153+\153\233\140\142\153\142\153\142\153\242\169\142\153+\153\000\000\000\000\000\000\000\000\000\000+\153\142\153+\153\233\140+\153+\153+\153\167\140\167\140\233\140\167\140\167\140\233\140\233\140\167\140\000\128\167\140\167\140\233\140e\132\167\140\233\140\233\140+\153\242\169\242\169+\153\000\000\000\000\000\000\000\000\000\000+\153+\153\142\153\233\140\233\140\233\140\167\140e\132e\132\167\140e\132\167\140\233\140\167\140\000\128\000\128\167\140\167\140\000\128e\132e\132e\132\000\128\167\140\142\153\242\169\142\153+\153\000\000\000\000\000\000+\153\242\169\242\169U\178\142\153\000\128e\132e\132e\132\000\128e\132\000\128\000\128e\132\167\140\000\128\000\128e\132e\132\000\128\000\128\000\128e\132e\132\000\128e\132+\153\142\153\242\169+\153\000\000+\153\142\153\242\169U\178U\178\142\153e\132\000\128e\132e\132\000\128e\132\000\128\000\128e\132\167\140\000\128\000\128\000\128e\132\000\128\000\128\000\128e\132\000\128\000\128\233\140\142\153\242\169U\178\142\153+\153+\153\142\153\142\153U\178\242\169\142\153\167\140e\132\000\128e\132\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128e\132\000\128e\132\233\140\242\169U\178U\178\242\169+\153+\153+\153\142\153\233\140\233\140\233\140\167\140e\132\233\140+\153\167\140\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128\000\128+\153\242\169U\178U\178\142\153\167\140\142\153\242\169\142\153\142\153\233\140+\153\142\153\242\169\142\153+\153\233\140+\153+\153+\153U\178\242\169+\153\000\128\000\128\000\128\167\140\000\128\000\128\000\128\000\128\233\140\142\153U\178\242\169\242\169\242\169+\153\142\153+\153\142\153+\153\000\000+\153\142\153\242\169U\178\142\153\167\140+\153\142\153U\178U\178U\178\242\169e\132e\132+\153\242\169+\153\233\140\000\128\000\128+\153\142\153U\178\242\169\242\169\242\169+\153+\153+\153+\153\000\000\000\000\000\000+\153\242\169U\178\142\153\233\140\142\153\242\169\242\169\242\169U\178\142\153+\153+\153\242\169U\178\242\169+\153\233\140e\132+\153\142\153\142\153\242\169\242\169\142\153\142\153+\153\233\140\000\000\000\000\000\000\000\000+\153\142\153\142\153+\153\233\140+\153\242\169\242\169\242\169U\178\142\153+\153\142\153\142\153\242\169\142\153+\153+\153\142\153\242\169U\178\242\169+\153\242\169U\178+\153+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153\233\140\233\140+\153\142\153\242\169\242\169\242\169\142\153+\153\142\153\142\153\142\153\142\153+\153\233\140+\153\242\169\142\153+\153\233\140+\153+\153\000\000\000\000\142\153\142\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153\142\153\242\169+\153+\153\233\140+\153\142\153\142\153+\153\233\140\233\140+\153+\153+\153\000\000\000\000\000\000\000\000\000\000\142\153\242\169\242\169+\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153+\153\233\140\000\000\000\000\000\000+\153+\153\233\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000+\153+\153\000\000\000\000") imgtrap_width = image.width(imgtrap) imgtrap_height = image.height(imgtrap) imgplayer = image.new("!\000\000\0000\000\000\000\000\000\000\000B\000\000\000\016\000\001\000\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130;\130;\130;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\255\255;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\191\142\255\255\255\255;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\191\142\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130;\130\191\142\255\255\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130@\237@\237\251\128\255\255\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\249\001\249\001\249\001\249\001\249\001\249\001@\237@\237\230\253\230\253@\237\191\142;\130\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\249\001\249\001\249\001\249\001\249\001@\2375\255\230\2535\255\230\253\230\253@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130;\130\249\001\249\001@\237@\2375\255\230\2535\255\230\253\230\2535\255\230\253@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\127\207;\130@\2375\255\230\253@\237\230\253\230\253@\237@\237\230\2535\255\230\253@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001;\130\127\207;\130@\237@\237\003\255@\237@\237\003\255\003\255@\237\230\2535\255@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128;\130\127\207;\130@\237\003\255@\237\183\255\000\128\000\128\160\242@\2375\255@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128\191\157\000\128;\130\127\207\000\128\003\255\146\255\183\255\000\128\183\255\160\242@\237\230\253@\237\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128\191\157\223\206\000\128;\130\000\128\003\255\146\255\183\255\146\255\146\255\160\242\160\242@\237\000\128\251\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128\255\169\223\206\255\169\000\128;\130\000\128\003\255\146\255\146\255\160\242\160\242@\237\000\128\003\255\251\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\180\128\000\128\223\206\191\157\000\128\000\128\000\128\251\128\000\128\000\128\000\128\000\128\000\128\000\128\003\255\251\128\000\128\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\255\166\255\255\025\130\000\128\000\128\000\128\000\128\180\128\180\128\000\128\000\128\000\128\246\137\246\137\246\137\000\128\000\128\000\128\000\128\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\255\255\255\166\025\130\180\128\000\128\031\174\180\128\246\137\156\154\156\154\159\231\159\231\156\154\246\137\000\128\156\154\159\231\159\2319\142\000\128\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\255\166\025\130\025\130\180\128\000\128\180\128\001\255\146\255\156\154\146\255\146\255\001\255\001\255\000\1289\142\159\231\156\154\156\1549\142\000\128\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\191\157\180\128\180\128\180\128\127\215\000\128\180\128\246\137\001\255\001\255\001\255\001\255\156\154\246\137\000\1289\142\159\231\156\1549\1429\142\000\128\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\191\157\191\157\127\215\127\215\000\128\180\128\246\137\159\231\001\255\159\231\156\154\156\154\246\137\000\1289\142\159\2319\1429\1429\142\000\128\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\180\128\180\128\000\128\000\128\000\128\180\128\246\137\156\154\180\128\156\154\246\137\246\137\180\128\191\142\000\128\000\128\000\128\000\128\000\128\000\128\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224\180\128\180\128\003\255\180\128\180\128\180\128\159\223\159\223\191\142\000\128\255\255\255\255\127\215\000\128\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224c\224\003\255\146\255\003\255\160\242\180\128\159\223\191\142\191\142\000\128\255\255\191\231\127\215\000\128\031\175\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224c\224\180\128\180\128\003\255\180\128\180\128\246\137\180\128\180\128\180\128\000\128\191\231\127\215\180\128\180\128\180\128\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224\180\128\001\255\159\231\180\128\159\231\156\154\001\255\246\137\180\128\246\137\246\137\000\128\180\128\191\157\223\206\180\128\031\175\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224c\224\180\128\180\128\001\255\159\231\001\255\001\255\156\154\180\128\180\128\246\137\246\137\000\128\191\157\255\169\223\206\180\128\000\128\031\175\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128c\224c\224c\224\180\128\003\255\180\128\001\255\159\231\156\154\180\128\159\223\180\128\003\255\000\128\180\128\180\128\180\128\180\128\180\128\000\128\031\175\031\175\031\175\192\250\000\128\000\128\249\001\249\001\249\001\249\001\000\128\000\128c\224c\224c\224c\224\180\128\003\255\000\128\180\128\156\154\180\128\191\142\159\223\180\128\003\255\000\128\191\157\255\169\223\206\191\157\000\128c\224\000\128\031\175\192\250\192\250\192\250\031\175\000\128\000\128\000\128\000\128c\224c\224c\224c\224c\224c\224\180\128\003\255\000\128\159\223\180\128\191\142\000\128\159\223\159\223\180\128\000\128\255\169\255\169\223\206\191\157\000\128c\224\000\128\192\250\192\250\192\250\031\175\031\175\000\128\000\128c\224c\224c\224c\224c\224c\224c\224c\224\180\128\253\174\000\128\159\223\159\223\191\142\000\128\159\223\159\223\180\128\003\255\000\128\223\206\191\157\000\128c\224c\224c\224\000\128\192\250\031\175\031\175\031\175\000\128\249\001\000\128c\224c\224c\224c\224c\224c\224c\224c\224\180\128\000\128\159\223\159\223\191\142\000\128\191\142\159\223\159\223\180\128\253\174\000\128\000\128c\224c\224c\224c\224\000\128\031\175\031\175\031\175\000\128\249\001\249\001\249\001\000\128\000\128c\224c\224c\224c\224c\224c\224c\224\000\128\159\223\159\223\191\142\000\128\000\128\191\142\159\223\246\137\180\128\000\128c\224c\224c\224c\224\000\128\249\001\000\128\031\175\031\175\000\128\249\001\249\001\249\001\249\001\249\001\000\128\000\128\000\128c\224c\224c\224c\224m\128m\128m\128m\128m\128c\224\000\128\159\223\191\142\246\137\000\128c\224c\224c\224\000\128\249\001\249\001\249\001\000\128\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\000\128\000\128\000\128\000\128m\128\251\128\191\157\251\128m\128c\224m\128m\128m\128m\128m\128c\224\000\128\000\128\249\001\249\001\249\001\249\001\249\001\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128\146\255\146\255\224\254m\128\000\128m\128\251\128\191\157\251\128m\128\000\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128\251\128\255\214\191\157\251\128m\128\249\001m\128\224\254\146\255\146\255\224\254m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128\224\254\224\254\255\214\191\157\251\128m\128\249\001\249\001m\128\191\157\255\214\251\128m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128\251\128\255\214\251\128\224\254\191\157\251\128m\128\249\001\249\001m\128\191\157\255\214\224\254\224\254m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128\251\128\255\214\255\214\251\128\224\254\224\254m\128\249\001\249\001m\128\224\254\224\254\251\128\255\214\251\128m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128m\128m\128m\128m\128m\128m\128\249\001\249\001\249\001m\128\251\128\251\128\255\214\255\214\251\128m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001m\128m\128m\128m\128m\128m\128m\128\249\001\249\001\249\001\249\001\249\001\249\001\249\001\249\001") imgplayer_width = image.width(imgplayer) imgplayer_height = image.height(imgplayer) imgdoor = image.new("\028\000\000\0004\000\000\000\000\000\000\0008\000\000\000\016\000\001\000@\136\130\144\130\144a\140\130\140\164\148\130\144\130\144\130\140\163\148\163\144\131\144\163\144\131\144\163\144\163\148\130\144\130\144a\140a\140b\140\163\148\130\140a\140\163\148\130\140\163\148a\140\163\148\196\152'\161\006\161'\165\006\161'\161\229\156\006\157\230\156\230\156\006\161\006\161\007\161'\165\006\161\006\161\006\161'\161(\165'\165'\161\007\161'\165\007\161\006\161\196\152a\140a\136\230\156H\169H\169i\173i\173i\173i\169i\173i\169i\169i\169i\169i\169i\169i\169'\165(\165H\169H\169H\165'\165H\169H\165H\169i\173H\169\196\148@\136'\161\130\144\130\140a\140b\140\130\144\196\148\196\152\196\148a\140\130\144\130\144\130\140\131\144\130\144\130\140\163\144\130\140\130\140a\140a\140b\140\130\144\130\140\130\144'\161a\140@\136I\169\130\140a\140\130\144\130\144\163\144\163\148\164\148\196\148\197\152\229\152\196\152\230\156\196\152\196\152\196\152\229\152\163\148\196\152\229\152\163\148\006\157\196\148\196\148\163\148H\165\163\148\000\128\205\185\237\189/\1980\198P\1980\198Q\202P\202P\202P\202P\202P\202/\1940\198/\198P\198/\194P\202P\202/\198P\198\014\194/\198/\198/\198i\173\130\144@\136\237\185\014\190\014\190\204\185\237\189/\194\237\185\171\181\205\185/\194\237\189\014\194\237\189\015\194\014\194\014\190\238\189\204\181\014\194\015\194\237\189\204\185\237\185\237\185\014\194\171\181a\140@\132/\198\196\152\131\144\163\148\163\144\196\148\163\148\196\152\163\148\163\144\163\148\196\148\164\148\163\148\196\148\196\148\164\148\130\144\196\148\229\156\164\148\196\148\196\152\196\148'\165\138\177\163\144@\136P\202\230\156\204\181\170\177\163\148\014\194p\202/\198\014\194G\169\228\156\014\194h\169&\161\228\152A\136\005\157\203\181\013\190\013\190\237\189\228\152\137\177\237\189j\173i\173\230\156a\136Q\202\230\156\171\181\006\161\196\152H\169P\198O\198p\202h\169\228\156\014\194G\165&\161\228\152a\136G\165\204\185/\194p\202\170\177\195\152\137\173\013\190\138\177\138\173\006\157 \132P\202\229\152\171\177G\165\005\157h\173\237\189\236\189\236\185h\169\196\152\013\190\203\181G\169\006\161a\136G\169h\173\170\177\137\177\203\181\005\161h\169\013\194i\173\138\173\229\156a\140q\206'\161\171\177G\169\195\148\137\177\171\181\203\181\013\190\137\173\162\148\171\177\236\185&\165\228\152a\140\196\152H\169\237\185\170\177\138\177\195\152\236\189.\194\138\173\138\173\229\152@\132P\198\229\156\170\177\170\181\195\148G\169G\165H\169\228\156\228\152\228\152\229\156\137\173G\169\227\152a\140\130\144\163\148\005\157\004\157\004\157\228\152\137\177\014\194i\173i\173\229\156@\132P\202(\165\137\173h\173\005\161\229\156\196\152\228\152G\165\171\181&\161\130\144H\169F\165\162\144\162\144G\169\228\152\162\144\195\148\229\156&\161\169\177\013\190i\169\138\173\229\152\130\144q\202'\165\006\161\203\181\204\185\005\157\137\177g\169h\169\138\177\137\177\196\152\162\144\195\148\163\144\195\148%\161G\169\170\177\005\161\228\152\170\177p\202i\173H\165\138\177\164\148\130\140\146\206\006\161\229\156\236\185\236\189H\169'\165&\165G\169\137\177\228\156\162\144\228\152\196\152\130\144\195\152G\169g\169\136\173\006\161G\169.\198\204\185\195\148\007\161\138\177\196\148\163\148\146\206\006\161b\140i\169O\198\013\190\196\152h\173\005\161\228\156g\169\236\185\236\189\013\194\235\185F\165\005\157G\169h\173\228\152\171\181\171\181\005\157\138\177H\165\138\173\163\144\131\144/\198\196\152\195\152\130\140\170\177\012\190\228\156\196\152\228\152\236\189p\202O\198\012\190\013\190/\198/\198\236\189\005\157\196\152\005\157\137\177\228\152\203\181/\198H\169i\173\163\144\163\148q\202\163\148\228\156G\169\229\156\170\177\005\161\195\148\203\181p\202\235\181\202\181.\194\013\190\236\189\013\194O\198\202\181\006\161\228\156\228\152h\173\236\185g\169'\165\138\177\164\148\196\148/\194\163\148h\173\203\181\236\185\013\190\136\173&\161/\198\202\181\170\181\203\181\170\181.\194q\206/\198\236\185\236\189\169\177\195\152\013\194O\198\013\194\169\177(\165\138\177\130\140\229\152/\198\229\152a\140\005\157.\198-\194\005\157\170\177\013\194\169\177\203\181I\1691\194\016\190H\165\237\189\236\189\013\190\203\181&\161&\165\170\177h\169\196\152\006\161\171\177a\140\196\152\015\194\196\152\130\144a\140\162\144&\161G\165\202\181\170\177\169\181\138\173T\1904\162\019\162\148\198'\165\237\189\203\181\203\185G\165\196\152\195\148\228\152\204\181\230\156\139\177\130\144\163\148/\198\163\144\195\152G\169\006\161\195\148\162\144\162\148\195\148\228\152\015\190T\166\222\247\217\178T\178\205\185\195\152\163\148\163\148\162\144\195\148\196\152\236\189\236\185\006\161\138\177\163\148\130\144P\198\163\148\005\157G\165\013\190'\165/\198\171\181h\173\228\156j\169\017\174\152\166\153\166T\182I\169G\169\137\173h\173\137\173\005\157h\169\013\194\136\173\229\156\171\181\130\144\163\144P\198\163\148F\165%\161.\194\005\157\137\177\203\185\202\181&\165\006\157J\169\017\1862\186\140\173H\169\236\185\202\181\013\190\170\181\006\161\236\189\236\189N\198\229\152\171\177\163\148@\132q\206\163\148\170\177\236\185O\198\196\152\228\152\228\152\195\152\195\148\195\148\197\148\198\152\230\156\229\152\229\156\228\156\228\156\228\152\228\152\228\152\204\185O\198\168\181\130\144\237\189\131\144 \132P\198\229\152\170\181\136\177.\198\005\157\236\189\236\185\005\157\005\157G\165\005\157\005\161\171\181G\169G\169G\169\171\181\170\181G\165\006\161\236\185.\194\168\181a\140\205\185b\140@\132q\206\196\152\136\173\136\173.\194\005\157/\194\013\190\202\181\236\185\137\177\137\173\203\185\202\181\202\181\202\181g\173\169\177\013\190\236\189\228\156\170\177O\198\170\181\131\144\238\189\130\144@\136\146\206\163\144&\161\170\177\137\173\195\148&\161\196\152\228\152\196\152\163\148\162\144\130\144\163\144\130\144\130\144\163\148\005\161&\161i\173\228\156\130\144\170\177\137\177\163\148\014\194\130\144@\1360\198\163\148\195\148\005\157\130\144A\136 \132@\132@\136@\136\130\144\131\144\130\144\130\144\163\148a\140A\136@\132@\132 \132@\136@\136\006\157G\165\163\144\014\190\163\148@\132/\198\130\140\130\140\130\140\130\144b\140\130\140\130\140\130\144\196\152\164\148\196\148\163\148\196\152\196\152\196\152\196\152\196\148\196\148\196\148\196\148\196\148\163\148\196\152\164\148\237\189a\140@\136/\194\163\148\146\210q\202Q\202\014\194\014\190\138\173\138\177\138\177\014\194\015\194q\206P\202\146\206P\202q\206P\202q\202P\2020\198/\194P\202q\206q\202\014\190\130\140\000\128\014\194\130\144\014\190\204\185\204\185\204\181\237\185\237\185\172\181\237\189/\194/\194\014\190\237\185\237\189\237\185\014\190\237\189\204\181\237\189\014\194\171\181\014\190\237\189\204\185\014\194\163\148 \132\014\190\130\144\006\161\006\157\006\157\006\157\229\156\196\152\229\156\007\161H\165\006\161\229\152\164\148\196\152\229\156\229\152'\161'\161\229\156\229\156\229\156\006\157\196\152\230\156\238\189\130\140a\136\205\185\130\140'\165'\161H\165'\165I\169(\165H\169i\169i\169i\169H\169(\165'\165'\165'\165H\165'\165'\165(\165'\165'\165\006\157\006\161\237\189\131\144A\136\014\190\130\144\006\161\006\157\006\157'\161\006\161\006\161\007\161\006\161'\161\006\157\006\161\229\156'\165'\165\006\161'\165H\169'\165\006\161\006\161\007\161\006\161\229\156\237\185a\140a\140\014\194\163\148\163\144\163\148\006\157\196\152\130\140\163\148\196\148\163\148\196\152\196\148\164\148\163\144\163\144\164\148\163\148\196\152\230\156\196\148\197\152\229\156\196\152\229\156\229\156\204\185\130\140@\136\204\181a\136a\136a\136\130\144\130\144\130\140a\140\130\140A\136a\140a\140a\140a\136\130\144a\136\163\148a\140\130\144\163\148\130\144\163\148\130\144a\140\130\140\171\181\130\140a\140\014\194!\132!\136B\136B\136B\136B\136B\136B\136B\136B\140B\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140\171\181\163\148@\132\014\190B\136B\136B\136B\136B\136B\136B\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140\238\189\163\148A\136\205\185B\136B\136B\136c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140c\140\237\189\163\148@\136\014\190B\136c\140c\140c\140c\140c\140c\140c\140c\140c\144c\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\237\185\163\144@\136\014\194c\140c\140c\140c\140c\140c\144c\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\204\185\131\144a\140\204\181c\140c\140\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\144\171\181\131\144\130\144\139\177\132\144\132\144\132\144\132\144\132\144\132\144\132\144\132\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\171\181\130\140\196\148\138\177\132\144\132\144\132\144\132\148\132\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\138\173\130\144\196\148i\169\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\165\148\138\177\163\144\196\148H\169\165\148\165\148\165\148\165\148\165\148\165\148\165\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152i\173\130\144\196\148H\169\165\148\165\152\165\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152i\169b\140\163\144H\169\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152i\169b\140@\136H\169\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152\198\152H\169\131\144@\136a\136\198\152\198\152\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156\198\156a\140\130\140") imgdoor_width = image.width(imgdoor) imgdoor_height = image.height(imgdoor) fontsize = 6 strHeight = 0 inited = false derr = false err = "" n = 0 d = 0 p = 0 maze = {} traps= {} width = 0 height = 0 xc = 0 xy = 0 r = 0 pi = 0 border = math.max(imgwumpus_width,imgwumpus_height)/2 it = 0 iw = 0 ip = 0 lv = {} coups = 0 maxcoups = 0 lip = {} vict = 0 total = 0 tc = 0 mode = 0 period=0.01 lc = {0,0,0,0} canshoot=true function cango(s1,s2,safe) lvo1 = getvoisof(s1,safe) lvi1 = {} lvo2 = getvoisof(s2,safe) lvi2 = {} inter = false while not inter and #lvo1~=0 and #lvo2~=0 do for i=1,#lvo1 do for j=1,#lvo2 do if lvo1[i]==lvo2[j] then inter = true break end end end insertinto(lvo1,lvi1) lvo1 = getvoisofl(lvo1,safe) removefrom(lvi1,lvo1) insertinto(lvo2,lvi2) lvo2 = getvoisofl(lvo2,safe) removefrom(lvi2,lvo2) end return inter end function insertinto(l1,l2) for i=1,#l1 do found = false for j=1,#l2 do if l2[j]==l1[i] then found = true break end end if not found then table.insert(l2,#l2+1,l1[i]) end end return l2 end function removefrom(l1,l2) for i=1,#l1 do for j=1,#l2 do if l2[j]==l1[i] then table.remove(l2,j) j=j-1 break end end end return l2 end function getvoisofl(l,safe) lv = {} for j=1,#l do for i=1,n do if maze[l[j]][i]==1 then found = false for k=1,#lv do if lv[k]==i then found = true break end end if not found and (not safe or traps[i]==0) then table.insert(lv,#lv+1,i) end end end end return lv end function getvoisof(s,safe) return getvoisofl({s},safe) end function getvois(safe) return getvoisof(ip,safe) end function reposimg(w,h,i) i=i-1 x=xc+r*math.cos(i*2*pi/n) y=yc+r*math.sin(i*2*pi/n) x=x-w/2 y=y-h/2 return {x,y} end function repostxt(w,h,i) i=i-1 rc = math.sqrt(w*w+h*h)+r h=h x=xc+rc*math.cos(i*2*pi/n) y=yc+rc*math.sin(i*2*pi/n) x=x-w/2 y=y+h/2 return {x,y} end function fullinitMaze() total=0 vict=0 tc=0 maxcoups = n*d -- to kill stucked IA which can't resolve themselves to commit suicide initMaze() end function initMaze() canshoot=true lc[4]=0 if mode==1 then mode=0 end ok = false while not ok do maze = {} traps = {} ip = 1 lip = {1} coups = 0 for j=1,n do maze[j]={} traps[j]=0 for i=1,n do maze[j][i]=0 end end for j=1,n-1 do for i=j+1,n do maze[j][i]=math.floor(d/100+math.random()) maze[i][j]=maze[j][i] end end iw = math.random(2,n) it=iw while it==iw do it = math.random(2,n) end for i=2,n do if i~=iw and i~=it then traps[i]=math.floor(p/100+math.random()) end end _,err = init(n) -- code du participant if err then err = "Error(init): "..err derr = true end if cango(1,iw,false) and cango(1,it,true) then ok =true end end feel() end function on.varChange() nn = var.recall("n") if nn ~= n then if nn<3 or math.floor(nn)~=nn then return 1 -- disallow modifications end n=nn fullinitMaze() return 0 -- allow modifications end nd = var.recall("d") if nd ~= d then if nd<=0 or nd>100 then return 1 -- disallow modifications end d=nd fullinitMaze() return 0 -- allow modifications end np = var.recall("p") if np ~= p then if np<=0 or np>=100 then return 1 -- disallow modifications end p=np fullinitMaze() return 0 -- allow modifications end return 0 -- allow modifications of other monitored variables if any end offset=215 function on.paint(gc) if not inited then width = platform.window:width() height = platform.window:height() if width>0 then pi = math.pi xc = width/2 yc = height/2 r = math.min(width,height)/2-border n = var.recall("n") d = var.recall("d") p = var.recall("p") fullinitMaze() var.monitor("n") var.monitor("d") var.monitor("p") gc:setFont("sansserif", "r", fontsize) strHeight = gc:getStringHeight("H") timer.start(period) inited = true end end gc:setFont("sansserif", "r", fontsize) gc:drawString("m: move",offset,1*strHeight) gc:drawString("p: play",offset,2*strHeight) gc:drawString("a: auto",offset,3*strHeight) gc:drawString("s: stop",offset,4*strHeight) gc:drawString("f: forfeit",offset,5*strHeight) gc:setColorRGB(255,0,0) for i=1,n do if traps[i]==1 then l = reposimg(imgtrap_width,imgtrap_height,i) gc:drawImage(imgtrap,l[1],l[2]) end end l = reposimg(imgdoor_width,imgdoor_height,1) gc:drawImage(imgdoor,l[1],l[2]) if(iw>0) then l = reposimg(imgwumpus_width,imgwumpus_height,iw) gc:drawImage(imgwumpus,l[1],l[2]) end if(it>0) then l = reposimg(imgchest_width,imgchest_height,it) gc:drawImage(imgchest,l[1],l[2]) end l = reposimg(imgplayer_width,imgplayer_height,ip) gc:drawImage(imgplayer,l[1],l[2]) for i=1,n do l = repostxt(gc:getStringWidth(i),strHeight,i) gc:drawString(i,l[1],l[2]) gc:setColorRGB(255,0,0) gc:setFont("sansserif", "r", fontsize) end for j=1,n-1 do for i=j+1,n do if maze[j][i]==1 then gc:drawLine(xc+r*math.cos((i-1)*2*pi/n),yc+r*math.sin((i-1)*2*pi/n),xc+r*math.cos((j-1)*2*pi/n),yc+r*math.sin((j-1)*2*pi/n)) end end end gc:setColorRGB(0,0,255) for i=1,#lip-1 do gc:drawLine(xc+r*math.cos((lip[i]-1)*2*pi/n),yc+r*math.sin((lip[i]-1)*2*pi/n),xc+r*math.cos((lip[i+1]-1)*2*pi/n),yc+r*math.sin((lip[i+1]-1)*2*pi/n)) l = repostxt(gc:getStringWidth(lip[i]),strHeight,lip[i]) gc:drawString(lip[i],l[1],l[2]) end gc:setColorRGB(0,0,0) if derr then gc:drawString(err,0,4*strHeight) end if it==0 and ip==1 then gc:drawString("Gagne!",offset,height) end if ip==iw or traps[ip]==1 then gc:drawString("Perdu...",offset,height) end if total>0 then gc:drawString("Succes: "..vict.." ("..(math.floor((vict*1000)/total)/10).."%)",0,1*strHeight) end if vict>0 then gc:drawString("Coups moyens: "..(math.floor(tc*10/vict)/10),0,2*strHeight) end gc:drawString("Parties: "..total,0,3*strHeight) gc:drawString("Coups: "..coups,0,4*strHeight) if lc[1]==1 then gc:drawString("Ca pue...",0,height-2*strHeight) end if lc[2]==1 then gc:drawString("Ca souffle...",0,height-1*strHeight) end if lc[3]==1 then gc:drawString("Ca brille...",0,height-0*strHeight) end end function list2str(l) str = "{" for i=1,#l do if i>1 then str=str.."," end str=str..l[i] end str=str.."}" return str end function on.timer() if mode>0 then nextstep() end end forfeit = false function on.charIn(str) if str=="m" then mode=0 nextstep() elseif str=="p" then mode=1 elseif str=="a" then mode=2 elseif str=="s" then mode=0 elseif str=="f" then forfeit=true end end function on.mouseDown() mode=0 nextstep() end function feel() lv = getvois(false) lc[1]=0 lc[2]=0 lc[3]=0 if ip==iw then lc[1]=1 end -- ca pue for i=1,#lv do if lv[i]==iw then lc[1]=1 -- ca pue end if lv[i]==it then lc[3]=1 -- ca brille end if lc[2]~=1 then for j=1,#traps do if traps[j]==1 and (ip==j or lv[i]==j) then lc[2]=1 -- ca souffle break end end end end end function nextstep() if derr or forfeit or coups>maxcoups or (it==0 and ip==1) or ip==iw or traps[ip]==1 then derr = false forfeit = false total = total +1 if it==0 and ip==1 then vict=vict+1 tc=tc+coups end initMaze() else _,err = think(n,ip,lv,lc) -- code du participant if not err then ni,err = action(n,ip,lv) -- code du participant if not err then shooting = false ok = false if ni<0 then shooting = true ni = -ni end for i=1,#lv do if lv[i]==ni then ok=true break end end if shooting and not canshoot then ok = false end if ok then if shooting then if ni==iw then iw=0 end canshoot = false else ip = ni table.insert(lip,#lip+1,ni) coups=coups+1 if(ip==it) then it = 0 lc[4]=1 end end feel() else if shooting then err="Error(action): can't shoot anymore" else err="Error(action): invalid move" end derr = true end else err = "Error(action): "..err end else err = "Error(think): "..err end if err then derr = true end end platform.window:invalidate() end