Hello à Toutes et Tous,
Merci critor pour le "Divin SlyVTT"
, je me sens pousser des ailes
Comme tout le monde, je tiens à tous vous remercier pour ce superbe challenge. Une nouvelle marche a été franchie quand à l'utilisation de Python sur nos belles machines. Imaginez : faire tourner un DoomEngine en Python sur une Casio G35+E II, vous n'en rêviez même pas il y a encore quelques semaines, mais Critor et Lephe l'ont fait !!! Chapeau bas les mecs !!!
J'ai quelques remerciements tout particuliers à émettre avant de commencer mon roman photos
:
- tout d'abord bien entendu à Critor et Lephe pour l'organisation du jeu concours et leur énergie mise au service de TI-Planet et Planète Casio,
- notre Bosse de Team préférée, Hackcell/Hackcel4TI/Alice (rayer la mention inutile selon d'où vous venez
) qui a permis de créer la super "Team v601" avec de loin le plus beau des logos, même si les plus médisants disent que ça fait très 1er ou 3ème Reich ...
- Afyu et TIny_Hacker de la Team v601 pour les super échanges et la franche rigolade à échafauder des théories parfois des plus fumeuses,
- cent20 sans qui définitivement un tel concours serait moins marrant, merci pour la bonne humeur et les vannes bon enfant dans le tchat,
- Max et la Team QATW pour la collaboration et les échanges de codeur à codeur, qui m'ont permis notamment de découvrir Tk/Tkinter et pygfx. Et bien sûr pour la co-création d'un superbe outil, mais nous y reviendrons plus avant,
- Bien entendu tous ceux que j'oublie et qui ont rendu ce concours passionnant et challenging ...
Pour moi cette année, le concours, c'était un peu en "semi-dilettante", étant pas mal occupé par ailleurs entre le taf et les travaux de réfection de ma maison. Mon but premier était donc clairement de m'amuser sans forcément chercher un excellent ranking. Même si je dois avouer qu'on se prend vite au jeu, et que le compétiteur qui sommeille en chacun de nous reprend vite le dessus.
Je pense que comme tout le monde j'ai largement tâtonné au début en essayant de chopper juste des souris jaunes en passant et en évitant les rouges pour pas me prendre des châtaignes électriques, mais on se rend très vite compte que cette technique ne mène pas très loin au niveau du score, car il faut chopper des souris au maximum à son propre niveau, mais pas trop basses non plus en niveau car sinon ça ne rapporte vraiment rien. Mon tout premier score plafonnant alors à 1392 points.
Hélas, visuellement il n'y a pas de distinction entre les souris de son niveau exact (valant 100 points) et les souris de niveau plus bas (et valant donc moins). Très vite alors je suis rentré dans le code python du jeu pour créer un petit mod et obtenir un visuel de la map et des niveaux exacts des souris via un code couleur pour les souris.
J'ai donc réalisé le mod v1 que j'ai releasé à la communauté :
Ce mod représentait en plus de la vue du raycaster, une minimap du labyrinthe et la représentation des souris par couleur en fonction du nombre de points et de leur altitude. Ce mod a visiblement permis à pas mal de monde d'avancer sur son score. Je trouvais que c'était sympa de releaser, pour ouvrir la voie à d'autres mods par la suite. Cette version était nommée ModV1 en interne.
Ce qui est marrant est que cent20 montrait quelques minutes/après la release, son mod interne à lui avec les souris affichées dans le labyrinthe 3D avec un code couleur. Les grands esprits se rencontrant, ce que je n'ai pas annoncé à l'époque était que ma version perso du mod (codename ModV2) contenait aussi cette feature. Les souris dessinées en sprites dans le labyrinthe étaient aussi dessinées avec le même code couleur de la minimap, pour faciliter la lecture du jeu et facilement les reconnaître dans le labyrinthe quand la situation est confuse.
Sans trop améliorer la stratégie et en collectant juste un peu mieux les souris sans chercher trop à les faire évoluer en niveau, j'ai pu rapidement grapiller quelques centaines de points par ci par là et monter progressivement dans le ranking avec des envois vers 1400, 1470, 1580 puis ...
Cela m'a permis assez facilement de passer la barrière imposée par Hackcell pour rejoindre la team v601 (à savoir 1674,6 points) en proposant un 1764,8 points (oui je sais effort minimum). A l'époque seul TIny_Hacker avait rempli les objectifs. Ceci fait, j'ai donc intégré assez rapidement la v601 et nous avons commencé à raisonner en tant qu'équipe dès le début, cherchant à bien comprendre les subtilités du jeu ainsi que comment envoyer les scores dans l'ordre adéquat pour maximiser le score de groupe.
En interne, les développements du mod ont bien entendu continué. Notamment afin de résoudre un "gros problème" permettant de mieux jouer et de maximiser le score : la randomisation. En effet vous avez tous du remarquer l'aspect "aléatoire" des déplacements, il s'agit d'un paramètre important dans le jeu et chaque action (avancer, reculer, sauter, ...) a un impact direct sur la graine de randomisation. Savoir ou prévoir où vont les souris un coup en avance est donc un point très important, mais il est impossible de prévoir ce qui va se passer à l'étape suivante en l'état.
Lors d'une discussion avec TIny_Hacker, il me faisait la remarque suivante : on pourrait tout précalculer pour savoir quelle sera la valeur de la graine pour le coup suivant, ce qui est une très bonne remarque, mais finallement, ce qui compte, c'est juste le coup suivant (N+1) pour déclencher la meilleure action pour le coup N.
Je me suis donc mis à travailler sur une version avec affichage des vecteurs de déplacement de chacune des sourisprévu par rapport aux données actuelles du plateau. Pour cela, j'ai rajouté quelques paramètres dans le noyau du jeu pour chaque souris en chopant les résultats de la fonction get_avance_position(player, l, angle) du module pyka3dlb.py et en traçant le vecteur (X0,Y0)=(player[PREV_X],player[PREV_Y])-->(X1,Y1)=(player[NEXT_X],player[NEXT_Y]) le point P0 étant la position courante de la souris et P1 celle où elle sera le coup suivant. Cela permet de voir l'effet de chacun des mouvements du joueur sur les souris environnantes ou des souris les unes sur les autres. Bien entendu il fallait faire attention de ne pas modifier quoi que ce soit qui puisse rendre les scripts incompatibles avec la version de Critor pour l'évaluation finale et l’enregistrement des scores.
- Code: Select all
def get_avance_position(player, l, angle):
l = bound_min_max(l, -1, 1) * player_step(player)
x, y = player[:P_Z]
#all the next variables are added by SlyVTT for vector visualization
#Be carefull : not to be used on Critor's initial script
player[PREV_X]=x
player[PREV_Y]=y
player[NEXT_X]=x
player[NEXT_Y]=y
dx, dy = cos_sin(angle)
nx = x + l*dx
ny = y + l*dy
if (nx != x or ny != y) and cango(player, nx, ny):
pr = player_radius(player)
if cango(player, nx + pr*sign(dx), y):
x = nx
player[NEXT_X]=nx
if cango(player, x, ny + pr*sign(dy)):
y = ny
player[NEXT_Y]=ny
return x, y, dx, dy
Cela permet d'avoir une approche plus fine de l'effet des déplacements, comme le montre la photo. J'ai aussi rajouté une police de caractères miniature dans cette version (codename ModV3) du mod partagée avec la Team v601 et surtout fait quelques accélérations du moteur de Raycasting en élargissant la taille en largeur d'un rayon. Certes le rendu devient moins beau mais nettement plus rapide. Bien sûr in-game, on pouvait faire varier ce paramètre avec les touches qui vont bien (F7/F8 pour les curieux). Les minimaps à différent niveaux de zoom permettent quant à elles de mieux voir ce qui entoure le joueur ou avoir une vue d'ensemble de la population.
Pour l'accélération du rendu, j'ai aussi tenu à donner l'astuce en publiant la technique dans le fil ad-hoc du forum afin que tout le monde en profite. Je considérais que c’était un peu du SAV de mon premier mod.
Voici ci-après quelques illustrations à ce stade du développement :
La version "accélérée" avec rendu vraiment très très (mais alors très très très
) vilain mais rapide (notez la tronche de la souris verte, il faut être imaginatif pour y voir encore une souris
) :
La version "normale" avec rendu vraiment très propre mais hyper lent (du genre moins de 0.3FPS sur un PC de course
):
Je précise qu'assez tôt aussi j'ai eu des discussions en "OFF" avec Afyu que je pensais (à raison) être le fameux Inconnu01 en haut du classement, se battant avec LaTaupe. Ayant bataillé avec/contre lui l'année dernière sur le concours La Geste d'Alrys, je pensais reconnaître son approche. Il m'a donc avoué être le "Scoreur masqué". Mais on voulait taire le secret pour garder un peu de suspens et pour faire mariner un peu les collègues de la compétition (qui se reconnaîtront)
Bon an mal an, mes participations se sont améliorées en étant un peu plus malin et stratège et surtout en essayant de ne pas manger n'importe quelles souris (pas bon pour l'estomac les mauvaises souris ...) mais seulement des souris à 100pts et au pire 50points. Cela m'a permis d'envoyer quand nécessaire des participations vers 1780, 1880, 2010 puis 2102 points.
Puis quelques discussions ont commencé avec Max et un de ses screenshots envoyé sur le tchat et le forum de TIP m’a fait penser que finalement le rendu 3D/Raycasting était peu utile, par contre, j'étais vraiment intéressé par la partie "annexe" de la fenêtre "TK". Max m'ayant donné l'accès au code source de son outil (codename CtrlV1), j'ai pu me plonger dedans et voir avec gros intérêt sa méthode pour gérer les Undo. C'était pour moi l'étape suivante sur la liste de développements à faire pour mon mod et m'évitait donc une grosse tartine de développement.
Comme il a expliqué, la gestion de l'Undo lui était rendu possible par un gros boulot de sa part sur l’isolement du code du moteur de jeu de Critor/Lephe, son encapsulation dans des classes et en son instanciation pour faire tourner le jeu et faire des "savestates"/"restorestates" de l'ensemble des variables. Pouvoir annuler les actions était vraiment un gros gros plus. Par contre, nos améliorations graphiques et de prévisions de mouvements étaient vraiment au top et nous manquait vraiment beaucoup.
J'ai donc repris le code de Max pour y intégrer tous nos ajouts (minimaps et vecteurs) et ainsi fusionner les deux outils en un seul. Bien entendu tout cela en développant encore plus l'interface pour ajouter de nouvelles features utiles. Les canvas de TK ayant une bien meilleure résolution graphique que le raycaster avec polycal_SDL2, il devenait même possible de mettre les vecteurs sur la minimap globale sans la rendre illisible, de rajouter les rayons d'interaction des souris les unes avec les autres, ... bref un gros ajout au niveau des infos disponibles à chaque instant pour l'utilisateur.
Et voici ce que ça donne dans la première mouture de l'outil fusionné et appelée CtrlV2:
Afyu a alors commencé à vraiment utiliser l'outil pour poncer le jeu et j'en ai profité pour ajouter au fil de l'eau divers trucs sympas comme le suivi de la population de souris par niveau, la liste des fusions, plus deux trois truc à calculer qui lui servait, le tout dans la fenêtre de l'outil plutôt que dans la console python qui lui était difficile d'accès (bein oui monsieur n’a qu'un seul écran
, vraiment pas un programmeur). La galère a été de gérer la liste à jour des fusions en cas de Undo, j'y ai passé quelques heures à transpirer à cause d'un bug bien pourri dans mon code (oui, en maths moins fois moins, ça fait plus, mais pas toujours dans mon code
).
Pour les bigleux (dont je fais partie je précise), toute fusion lance le mode alerte (gros warning rouge) et positionne un cercle blanc sur la minimap pour localiser la zone où se produit la fusion en question.
In fine, on disposait d'un outil avec rendu 3D et des fonctions vraiment cool comme le Undo et la prévision des mouvements pour résoudre le jeu. Avec un dernier coup de main de Max pour charger une partie au lieu de tripatouiller dans le code directement. Bref de la balle.
Voici la toute dernière version appelée Ctrlv8:
Je vous joins cette version ici
https://tiplanet.org/forum/archives_voir.php?id=3119411 :
Elle est calibrée pour un écran 1920*1080 (en fait deux écrans serait nettement mieux). Les touches sont les suivantes pour ceux qui voudrait tester :
- flèches et 4/5/6 comme la version originale de PyKaster3D
- U pour faire un undo de la dernière action
L'outil a bien entendu largement circulé entre les deux équipes de l'époque (QATW et v601) afin de faire profiter du travail de code commun. Une bonne collaboration.
Pour être totalement exhaustif et transparent, je tiens aussi à revenir sur un dernier point. Vous avez certainement remarqué un gros changement dans les scores des groupes quelques jours avant la fin du concours. Lors de notre travail d'optimisation de la stratégie de groupe avec Afyu, nous avons remarqué que le score de l'équipe nsi42 était "anormalement bas" par rapport à ceux des 3 autres équipes (y compris pour notre Team v601). Nous avons donc décortiqué la moulinette de calcul des scores de groupe et avons constaté un bug. D'un commun accord avec l'ensemble de l'équipe, nous avons donc proposé à Critor de la corriger afin de mettre les 4 équipes sur un pied d'égalité. Clairement la Team v601 aurait tiré un trop net avantage de ce bug (notre score final aurait frolé les 4800 voir 4900points), écrasant complètement la compétition avec l'impossibilité de nous battre (pour gagner, il aurait fallu que certains joueurs fassent des scores >3500points individuellement, ce qui est impossible. Dans un soucis de Fair Play, nous avons donc voulu corriger ce "bug" et ramener un calcul égalitaire permettant à toutes les équipes de se battre avec les mêmes armes.
Nous avons donc proposé une petite routine python de calcul du score a priori correcte pour nous aider (et vérifier notre hypothèse), que Critor a par la suite très gentiment reconvertie vers l'équivalent en PHP pour le site :
Show/Hide spoilerAfficher/Masquer le spoiler
- Code: Select all
def score(L):
mini=10000
maxi=0
n=len(L)
print('n = ', n)
for elt in L:
if elt>maxi:
maxi=elt
if elt<mini:
mini=elt
bonus=n**(1/2)
s3=0
n3=0
for elt in L:
n3+=1
s3+=elt
s2=0
n2=0
k2=1
for elt in L:
n2+=k2
s2+=k2*elt
k2+=1
s1=0
n1=0
k1=1
liste_bonus=[1 for i in range(n)]
for elt in L:
if n > 4 and elt == mini:
#print('mini avec bonus')
liste_bonus[L.index(elt)]=bonus
if n > 8 and elt == maxi:
#print('maxi avec bonus')
liste_bonus[L.index(elt)]=bonus
if k1 == 1 :
#print('plus recent avec bonus')
liste_bonus[L.index(elt)]=bonus
if k1 == n :
#print('plus vieux avec bonus')
liste_bonus[L.index(elt)]=bonus
print('rang = ',k1,' score = ', elt, ' coeff = ', k1, ' bonus =', liste_bonus[k1-1], ' valeur = ', k1*elt*liste_bonus[k1-1])
if (elt == mini or elt == maxi or k1 == 1 or k1 == n) :
print('valeur = ',elt,'vrai')
elt*=liste_bonus[k1-1] #bonus
n1+=k1
s1+=k1*elt
k1+=1
print('\n')
print("n1",n1,"s1",s1,"mini",mini,"maxi",maxi)
return (s1/n1,s2/n2,s3/n3,bonus,liste_bonus)
#liste des score a prendre en compte par ordre décroissant chronologique
L1=[2058.3,2178.8,2335.4,2655.2]
L2=[2308.0,2211.6,2120.5,2189.9]
L3=[2376.0,2376.05,2376.1]
L3bis=[2376.0,2376.05,2376.1,2376.075]
L4=[1608.4,1770.4,1448.0,1721.3,1453.7,1560.4,1811.0,1494.1,1442.9,1397.5,1320.6,1385.8,1380.6,1376.0,1375.0,1368.2,1337.8,1388.7]
L5=[2178.8, 2335.5, 2376, 2376.2, 2376.3, 2058.3, 2655.2]
print('Team V601')
print(score(L1)[0])
print('\n')
Mon rôle dans l'équipe vous l'aurez compris était donc plutôt de coder l'outil, j'ai finalement relativement peu joué en tant que tel (pas la patience de poncer le truc), par contre la partie dev était vraiment sympa. Mais sur la fin, il me fallait aussi monter dans le score afin de mettre la V601 à l'abri des remontées de la team de cent20 (tu nous auras fait transpirer mon coquin
et on avait vraiment peur que LaTaupe nous sorte un pur score de derrière les fagots
).
Alors ma technique a évolué, ne manger que des souris à 100points en limitant les fusions non voulues pour garder un max de petites souris et pouvoir faire monter un maximum de souris vers les hauts niveaux pour la fin du jeu, en gros essayer de faire comme Afyu, mais en nettement moins réussi, facile à dire, mais pas si facile à faire. A ce jeu d'autres sont (bien) meilleurs que moi, alors chapeau à eux.
Néanmoins, j'ai pu progressivement gravir les dernières marches pour envoyer des scores au-delà de 2200 points, et même pendant un court moment ranker 1er (bon il faut être honnête, avec la bienveillance de Afyu qui aurait pu défoncer mon score
). Ces derniers jours, j'affichais donc un fier 2316 avec en stock mon 2335 final pour permettre à la toute fin que l'équipe fasse un envoi groupé dans le bon ordre (et oui l'ordre d'envoi comptait tout autant que le score envoyé). On a donc aussi poncé la stratégie de groupe pour mettre toutes les chances de notre côté.
Je me dois aussi de dire pour être complet que la moulinette Python de Afyu permettant d'affiner les sauts et les déplacements et de grappiller quelques points sur un parcours terminé m'a aussi bien servi. Donc merci à lui.
Voilà pour les explications qui vont bien sur mon parcours dans le concours 2022.
Concernant le lot, ce qui me ferait plaisir consiste en un lot CX2CAS, mais subtilité, avec une
TI-nSpire CX CAS Ndlessable (oui vous lisez bien c'est moi le masochiste qui a demandé à Critor une CX version 1). Le but étant d'avoir une machine pour tester mes progs sur CX II et sur CX et ainsi pouvoir vérifier que ça ne rame pas trop sur cette dernière
. Cela permettra aussi aux jeunes qui ont besoin de profiter des CX-II
...
Ainsi si cela est possible voici ce qui me ferait plaisir dans le détail et si disponible bien entendu :
1 lot CX2CAS : 1
calculatrice TI-Nspire CX II-T CAS (ou autre TI-Nspire Ndlessable) au choix + 1
licence logiciel TI-Nspire élève + 1
kit de géométrie Calcuso + 1
pack de goodies TI + 1
pack de goodies Xcas + 1
pack de goodies TI-Planète CasioAvec si possible, concernant la calculatrice et comme annoncé avant, une
TI-Nspire CX version 1. Donc une de celles-ci (tant qu'elle est Ndlessable, cela me conviendra parfaitement) :
- TI-Nspire CX CAS révision matérielle AA, en boîte, avec OS 4.4.0.532 préinstallé, Ndlessable
- TI-Nspire CX CAS révision matérielle Y, en boîte, avec OS 4.4.0.532 préinstallé, Ndlessable
- TI-Nspire CX CAS sous blister scellé 2015, Ndlessable
- TI-Nspire CX CAS sous blister scellé 2012, Ndlessable
Concernant les goodies :
pack de goodies TI- 1 adaptateur pour périphériques USB (clavier, clé USB, souris, etc.)
- 1 clavier USB dédié au choix --> pour TI-83 Premium CE
- 1 porte-clésTI au choix --> celui de gauche (avec la calculatrice qui serre le signe Pi)
- 1 autocollant TI au choix --> celui intitulé "Spread Math Love"
- 1 coffret de 3 casse-têtes TI
- 1 stylo TI au choix --> peu importe
- 1 paire de chaussettes TI-84 Plus CE --> faut donner sa pointure ?
- 1 cahier TI (200 pages)
- 1 sac en toile TI
- 1 clé USB TI au choix --> la petite clef nSpire Noire est trop cute, si encore disponible
- 1 goodie TI au choix --> boîte cubique TI-83 Premium CE
- 1 cahier d'activités TI au choix --> Les raccourcis Python Texas Instruments
pack de goodies Xcas- 1 autocollant Xcas
- 1 goodie Xcas au choix --> si dispo l'aimantin Xcas
pack de goodies TI-Planète Casio- 1 aimantin TI-Planet au choix --> Le noir en bas avec plein de ballons serait super
- 1 autocollant TI-Planet au choix --> sans le "VIP"
- 1 autocollant Planète Casio
Etant déjà premium je cède bien volontiers le compte premium au prochain de la liste qui n'est pas déjà. C'est Noël avant l'heure, encore une fois merci pour tout et bravo pour ce superbe concours
.
Je suis personnellement vraiment fan de la partie concours en équipe, cela rajoute clairement une nouvelle dimension à cette sympathique compétition.
Sly
PS : j'attends de voir ce que vous allez nous concocter pour l'année prochaine. Il y a du challenge pour faire encore mieux (mais vous aurez peut être un GetKey non bloquant sur Casio à ce moment là
)