jeu – Sam & Max http://sametmax.com Du code, du cul Wed, 30 Oct 2019 15:34:04 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 32490438 La course du bus de l’innovation sur le chemin de la croissance http://sametmax.com/la-course-du-bus-de-linnovation-sur-le-chemin-de-la-croissance/ http://sametmax.com/la-course-du-bus-de-linnovation-sur-le-chemin-de-la-croissance/#comments Sat, 22 Jul 2017 20:10:46 +0000 http://sametmax.com/?p=18765 Ceci est un post invité de 01ivier posté sous licence creative common 3.0 unported.

Bonsjours à toutes et à tous,

Dans un sursaut de patriotisme, je me suis dit qu’il me fallait, moi aussi, participer à l’effort national et promouvoir le savoir-faire technologique français. Partant du constat que, de nos jours, proposer quelque chose de nouveau semble suffisant pour être innovant, j’ai fait comme tout bon startupeur, je ne me suis pas embarrassé à concevoir quelque chose d’utile. À vrai dire, ce n’est même pas nouveau. Mais je suis français et j’ai un compte Twitter, je crois que c’est amplement suffisant pour prétendre au label #CitizenOfTheFrenchTechNation.

 
frenchtech

 

Où le bus l’innovation va tout droit.

Parce que je suis bien conscient de l’influence que cet article va avoir dans le monde du jeu vidéo, je vais détailler les différentes étapes de la réalisation de ce projet bouleversant.

Tout d’abord, j’ai fait en sorte que le bus de l’innovation aille tout droit sur un chemin de la croissance qui est tout droit.

#-*- coding: utf-8 -*-

# On importe de quoi dormir
from time import sleep

# On définit le graphisme en accord avec l'équipe de designers
chemin = " " 
arbre = "A"
bus = "B"

# On définit la qualité de l'image après avoir consulté les experts en GPU du Digital-Agile-Open-Tech-Lab-Responsive.IO
largeur_ecran = 70

# On définit l'état initial conjointement avec la team level design.
# (elle-même ayant sollicité au préalable le narrative designer, bien entendu)
largeur_chemin = 15
position_chemin = 28
position_bus = 35
 
while 1:
 
    # On place la première portion d'arbres dans le paysage
    paysage = arbre * position_chemin
    # On place le chemin
    paysage += chemin * largeur_chemin
    # On remplit le reste du paysage par la deuxième portion d'arbres
    paysage += arbre * (largeur_ecran - len(paysage))
    # On place le bus sur notre paysage
    paysage = paysage[:position_bus] + bus + paysage[position_bus:]

    # On affiche le tout
    print(paysage)

    # On dort un peu
    sleep(0.2)

bus_innovation_droit

Oui. Il est effectivement possible d’arriver plus simplement au même résultat, mais, mes qualifications ne m’offrent pas le loisir d’être incompétent. J’anticipe donc les futurs mouvements du bus de l’innovation ainsi que les inéluctables virages du chemin de la croissance.

Ce doit être un peu déroutant pour vous, j’en conviens, mais c’est l’expérience qui parle.

Faites-moi confiance.

 

Où le bus l’innovation va tout droit mais en bien plus beau.

Parce que l’on n’est jamais assez exigent sur l’apparence d’un produit de luxe, j’ai voulu changer le rendu des arbres en remplaçant le “A” par un “█” bien plus raffiné. Voici le résultat que j’ai obtenu :

bus_innovation_droit_arbre

Diable comme le succès est semé d’embûches !

En effet, un petit…

>>> len("█")
3

… m’a appris que le “█” comptait pour trois caractères, faussant mon ingénieuse gestion des positions.

Mon talent m’avait permis d’anticiper les mouvements et autres virages mais pas ça. Damned. Qu’allais-je faire ?

Un petit replace() bien placé et le tour était joué. Sans compter que je pouvais désormais me permettre de mettre de la couleur.

La classe internationale.

#-*- coding: utf-8 -*-

from time import sleep

chemin = " " 
arbre = "A"
#On définit un arbre classe et vert en utilisant les codes ANSI
arbre_classe_et_vert = "\33[32m█\033[0m"
bus = "B"

largeur_ecran = 70
largeur_chemin = 15
position_chemin = 28
position_bus = 35
 
while 1:
 
    paysage = arbre * position_chemin
    paysage += chemin* largeur_chemin
    paysage += arbre * (largeur_ecran - len(paysage))
    paysage = paysage[:position_bus] + bus + paysage[position_bus:]
    # PAF ! On remplace l'arbre ridicule par un arbre classe et vert après avoir géré la position des différents éléments.
    paysage = paysage.replace(arbre, arbre_classe_et_vert)

    print(paysage)

    sleep(0.5)

BIM !

bus_innovation_droit_arbre_vert

 

Où le bus de l’innovation va tout droit mais sur un chemin de la croissance qui tourne.

Pour faire tourner le chemin de la croissance je fais un petit +2/-2 sur sa position avec un randint(), et zou.

Par contre, pour forcer le chemin de la croissance à rester dans l’écran, j’ai été surpris de ne pas trouver de fonction prête à l’emploi pour contraindre un nombre dans un intervalle donné. Je suis donc passé par une “astuce” pécho sur Stack Overflow que j’ai trouvée élégante. On classe par ordre croissant le nombre donné avec les bornes de l’interval et on récupère le deuxième élément.

position = sorted(position_min, position, position_max)[1]

Si vous avez mieux, ça m’intéresse.

#-*- coding: utf-8 -*-

# On importe de quoi choisir des nombres au hasard
from random import randint

from time import sleep

chemin = " " 
arbre = "A"
arbre_classe_et_vert = "\33[32m█\033[0m"
bus = "B"

largeur_ecran = 70
largeur_chemin = 15
position_chemin = 28
position_bus = 35

# On définit une position maximale pour le chemin de la croissance
position_max_chemin = largeur_ecran - largeur_chemin
 
while 1:

    # On calcule la nouvelle position du chemin de la croissance
    # Un peu plus à droite, un peu plus à gauche ou un peu plus tout droit...
    position_chemin += randint(-2, 2)

    # En s'assurant qu'il ne déborde pas de la largeur de l'écran
    position_chemin = sorted([1, position_chemin, position_max_chemin])[1]
 
    paysage = arbre * position_chemin
    paysage += chemin * largeur_chemin
    paysage += arbre * (largeur_ecran - len(paysage))
    paysage = paysage[:position_bus] + bus + paysage[position_bus:]
    paysage = paysage.replace(arbre, arbre_classe_et_vert)

    print(paysage)

    sleep(0.5)

bus_innovation_chemin_virage

 

Où le bus de l’innovation crache des flammes.

Avant de me pencher sur les mouvements du bus de l’innovation, j’ai pris le temps de le tuner un peu.

Déjà, direct, je l’ai peint en rouge, rapport au fait que le bus de l’innovation, c’est un peu la Ferrari de l’entrepreneuriat.

Et puis, je me suis dit qu’il fallait qu’il n’y ai vraiment absolument aucun doute sur le fait que c’était bel et bien le bus de l’innovation. Je lui ai donc fait écrire “LE BUS DE L’INNOVATION” sur la route. Je m’en remets à vous pour me dire s’il reste une ambiguïté.

Accessoirement, le “A” utilisé pour placer les arbres est devenu un “a“, pour ne pas être confondus avec le “A” présent dans “INNOVATION”. C’est un détail, mais les générations d’ingénieurs qui liront ça dans deux cent ans seront bien contents de trouver cette explication.

#-*- coding: utf-8 -*-

from random import randint
from time import sleep

chemin = " " 
arbre = "a"
arbre_classe_et_vert = "\33[32m█\033[0m"

largeur_ecran = 70
largeur_chemin = 15
position_chemin = 28
position_bus = 35

# On définit le texte écrit par le bus de l'innovation
texte_du_bus = "LE BUS DE L'INNOVATION "
# On récupère le nombre de caractères dans le texte écrit par le bus de l'innovation
nb_caractere = len(texte_du_bus)
# On initialise un compteur pour gérer la succession des caractères
compteur = 0

position_max_chemin = largeur_ecran - largeur_chemin
 
while 1:

    position_chemin += randint(-2, 2)
    position_chemin = sorted([1, position_chemin, position_max_chemin])[1]
 
    paysage = arbre * position_chemin
    paysage += chemin * largeur_chemin
    paysage += arbre * (largeur_ecran - len(paysage))

    # Dans le texte écrit par le bus de l'innovation, on prend le caractère 
    # indiqué par le compteur modulo le nombre de caractères possibles
    caractere = texte_du_bus[compteur%nb_caractere]
    # On peint le caractère en rouge Ferrari
    bus = "\33[31m{0}\033[0m".format(caractere)
    # On incrémente le compteur pour avoir le caractère suivant au prochain tour
    compteur += 1

    paysage = paysage[:position_bus] + bus + paysage[position_bus:]
    paysage = paysage.replace(arbre, arbre_classe_et_vert)

    print(paysage)

    sleep(0.5)

Magnifique.

bus_innovation_flamme

 

Où l’on cherche à faire tourner le bus de l’innovation.

Je ne vais pas vous mentir, la course du bus de l’innovation sur le chemin de la croissance n’est pas vraiment une nouveauté vidéoludique. Nous, c’est à dire La Labomedia, l’avons déjà présentée à Toulouse lors du THSF 2014 ainsi qu’au PSESHSF 2016 de Choisy-le-Roi dont il existe même une vidéo de la Master Class.

Sur cette photo spectaculaire, vous pouvez découvrir la pertinence de notre ingénieuse interface biologique imputrescible nourrie aux anti-biotiques NF.

busdelinnovationsurlechemindelacroissance

Mais, non seulement j’avais perdu totalement le code initial mais en plus l’installation s’appuyait sur l’excessivement chère MakeyMakey qui, par ailleurs, telle qu’elle est vendue, impose à l’utilisateur d’être relié à une masse.

Pour sa résurrection, je lui ai donc préférée la Capacitive Touch HAT pour RaspberryPi conçue par Adafruit et qui fonctionne direct au simple touché.

(Il va de soit que les natural chicken flavor interfaces n’ont, elles, pas été remises en question.)

Voici le code minimal pour utiliser le Capacitive Touch HAT une fois la librairie d’Adafruit installée :

import Adafruit_MPR121.MPR121
from time import sleep

interface = Adafruit_MPR121.MPR121.MPR121()
interface.begin()

while 1:
 
  # Si la patine numéro 0 est touchée
  if interface.is_touched(0):
      print("GAUCHE !")

  # Si la patine numéro 10 est touchée
  if interface.is_touched(10):
      print("DROITE !")

  sleep(0.1)

Qui devient ceci quand on instaure un seuil de détection pour tenir compte de la conductivité des pattes de poulet.

import Adafruit_MPR121.MPR121
from time import sleep

interface = Adafruit_MPR121.MPR121.MPR121()
interface.begin()

seuil = 100

while 1:
 
  # Si la patte de poulet reliée à la patine numéro 0 est touchée
  if interface.filtered_data(0) < seuil:
      print("GAUCHE !")

  # Si la patte de poulet reliée à la patine numéro 0 est touchée
  if interface.filtered_data(10) < seuil:
      print("DROITE !")

  sleep(0.1)

On ne peut pas dire que ce soit très compliqué. À noter tout de même la nécessité d'activer l'I2C et de lancer le script en root. Une formalité pour celles et ceux qui ont de l'ambition dans la Vie.

Une fois intégré dans notre formidable simulation de sport mécanique extrême, le script ressemble alors à ça :

#-*- coding: utf-8 -*-
 
# On importe la librairie d'Adafruit
import Adafruit_MPR121.MPR121 as MPR121

from random import randint
from time import sleep

# On instancie l'interface...
interface = MPR121.MPR121()
# ... et on la démarre.
interface.begin()

chemin = " " 
arbre = "a"
arbre_classe_et_vert = "\33[32m█\033[0m"
 
largeur_ecran = 70
largeur_chemin = 15
position_chemin = 28
position_bus = 35
 
texte_du_bus = "LE BUS DE L'INNOVATION "
nb_caractere = len(texte_du_bus)
compteur = 0
 
position_max_chemin = largeur_ecran - largeur_chemin

seuil = 100
 
while 1:

    # En fonction des patines touchées,
    # on déplace le bus de l'innovation vers la droite...
    if interface.filtered_data(0) < seuil:
        position_bus += 1

    # ... ou vers la gauche.
    if interface.filtered_data(10) < seuil:
        position_bus -= 1
 
    position_chemin += randint(-2, 2)
    position_chemin = sorted([1, position_chemin, position_max_chemin])[1]

    paysage = arbre * position_chemin
    paysage += chemin * largeur_chemin
    paysage += arbre * (largeur_ecran - len(paysage))

    caractere = texte_du_bus[compteur%nb_caractere]
    bus = "\33[31m{0}\033[0m".format(caractere)
    compteur += 1
 
    paysage = paysage[:position_bus] + bus + paysage[position_bus:]
    paysage = paysage.replace(arbre, arbre_classe_et_vert)
 
    print(paysage)
 
    sleep(0.5)

bus_innovation_tourne

 

Où le bus de l'innovation est tenu de rester sur le chemin de la croissance.

Écoutez, que les choses soient bien claires, moi aussi je trouve cet article beaucoup trop long, mais c'est du rayonnement de la France dont il est question. Dois-je vous le rappeler ?

Voici donc comment j'ai tenu compte des sorties du chemin de la croissance par notre bus de l'innovation :

#-*- coding: utf-8 -*-
 
import Adafruit_MPR121.MPR121 as MPR121
 
from random import randint
from time import sleep

interface = MPR121.MPR121()
interface.begin()
 
chemin = " " 
arbre = "a"
arbre_classe_et_vert = "\33[32m█\033[0m"
 
largeur_ecran = 70
largeur_chemin = 15
position_chemin = 28
position_bus = 35
 
texte_du_bus = "LE BUS DE L'INNOVATION "
nb_caractere = len(texte_du_bus)
compteur = 0
 
position_max_chemin = largeur_ecran - largeur_chemin

# On définit un booléen qui rendra compte de l'état du bus de l'innovation
le_bus_roule = True

seuil = 100
 
while 1:

    if interface.filtered_data(0) < seuil:
        position_bus += 1
 
    if interface.filtered_data(10) < seuil:
        position_bus -= 1

    # Si le bus roule...
    if le_bus_roule:
 
        position_chemin += randint(-2, 2)
        position_chemin = sorted([1, position_chemin, position_max_chemin])[1]
     
        paysage = arbre * position_chemin
        paysage += chemin * largeur_chemin
        paysage += arbre * (largeur_ecran - len(paysage))     

        # Si le bus sort de la route, à gauche ou à droite...
        if position_bus <= position_chemin or position_bus >= position_chemin + largeur_chemin:

            # On change l'apparence du bus (qui devient une croix verte)
            bus = "\33[32mX\033[0m"
            # On change l'état du bus de l'innovation
            le_bus_roule = False

        # Sinon, on affiche le bus comme précédement défini
        else:
            caractere = texte_du_bus[compteur%nb_caractere]
            bus = "\33[31m{0}\033[0m".format(caractere)
            compteur += 1
     
        paysage = paysage[:position_bus] + bus + paysage[position_bus:]
        paysage = paysage.replace(arbre, arbre_classe_et_vert)
     
        print(paysage)

        # Si, entre temps, le bus de l'innovation s'est arrêté de rouler
        if not le_bus_roule:
 
            # On affiche un message sympathique après avoir sauté une ligne
            print("\nIl n'est pas exclu que le bus de l'innovation se soit pris un arbre...")
     
        sleep(0.5)

bus_innovation_crash

 

Où la course du bus de l'innovation sur le chemin de la croissance va pouvoir enfin commencer.

Afin que le public intègre bien le défi collectif que représente la relance de l'économie par le financement et le développement d'innovants nouveaux projets novateurs avec de la technologie à la pointe de la technologie, j'ai fait en sorte d'afficher la croissance totale que l'ensemble des joueurs auront fait parcourir au bus de l'innovation.

Ainsi, n'y a-t-il jamais un individu qui perd, mais toujours un collectif qui gagne.

Quelque chose entre la victoire éternelle et le succès permanent.

Une véritable leçon de Vie.

#-*- coding: utf-8 -*-
 
import Adafruit_MPR121.MPR121 as MPR121
 
from random import randint
from time import sleep

interface = MPR121.MPR121()
interface.begin()
 
chemin = " " 
arbre = "a"
arbre_classe_et_vert = "\33[32m█\033[0m"
 
largeur_ecran = 70
largeur_chemin = 15

# On met en place un système d'initialisation des positions
# du chemin de l'innovation et du bus de la croissance
init_position_chemin = 28
init_position_bus = 35
position_chemin = init_position_chemin
position_bus = init_position_bus
 
texte_du_bus = "LE BUS DE L'INNOVATION "
nb_caractere = len(texte_du_bus)
compteur = 0
 
position_max_chemin = largeur_ecran - largeur_chemin

seuil = 100

le_bus_roule = True

# On déclare des variables qui vont nous permettre de rendre compte
# des quantités de croissance parcourue par le bus de l'innovation
croissance_parcourue_totale = 0
croissance_parcourue = 0

# On définit un petit texte à formater pour présenter les quantités en question
texte_crash ='''
Bravo !
Tu t'es pris un arbre mais tu as parcouru {0} mètres de croissance !
 
Pour ton information, le Bus de l'Innovation a parcouru {1} mètres
de croissance depuis son départ.
 
Pour le faire redémarrer, appuie sur la cuisse de poulet du milieu.
La France compte sur toi !
'''
 
while 1:

    if interface.filtered_data(0) < seuil:
        position_bus += 1
 
    if interface.filtered_data(10) < seuil:
        position_bus -= 1

    # On met en place un moyen de reprendre le chemin de la croissance
    # si le bus de l'innovation s'est pris un arbre
    if if interface.filtered_data(5) < seuil and not le_bus_roule:
        le_bus_roule = True
        croissance_parcourue = 0
        position_chemin = init_position_chemin
        position_bus = init_position_bus
        compteur = 0

    if le_bus_roule:
 
        position_chemin += randint(-2, 2)
        position_chemin = sorted([1, position_chemin, position_max_chemin])[1]
     
        paysage = arbre * position_chemin
        paysage += chemin * largeur_chemin
        paysage += arbre * (largeur_ecran - len(paysage))     

        if position_bus <= position_chemin or position_bus >= position_chemin + largeur_chemin:

            bus = "\33[32mX\033[0m"
            le_bus_roule = False

        else:
            caractere = texte_du_bus[compteur%nb_caractere]
            bus = "\33[31m{0}\033[0m".format(caractere)
            compteur += 1
            # On incrémente la croissance parcourue à chaque tour
            croissance_parcourue += 5
     
        paysage = paysage[:position_bus] + bus + paysage[position_bus:]
        paysage = paysage.replace(arbre, arbre_classe_et_vert)
     
        print(paysage)

        if not le_bus_roule:
 
            # On calcule la croissance totale parcourue
            croissance_parcourue_totale += croissance_parcourue
            # On formate notre petit texte pour informer le joueur de sa 
            # performance individuelle et collective.
            print(texte_crash.format(croissance_parcourue, croissance_parcourue_totale))
     
        sleep(0.5)

bus_innovation_arcade

]]>
http://sametmax.com/la-course-du-bus-de-linnovation-sur-le-chemin-de-la-croissance/feed/ 6 18765
Not invented here http://sametmax.com/not-invented-here/ http://sametmax.com/not-invented-here/#comments Thu, 24 Apr 2014 07:18:30 +0000 http://sametmax.com/?p=10065 Il va sur redtube Il réinvente la roue, bien sûr ! ]]> À la maison on joue beaucoup. Aux jeux vidéo, bien entendu, mais aussi à tout un tas d’autres trucs, incluant des jeux de rôles, de société, de carte… Ça joue même de la musique. Il y a un carton qui déborde de cartes magic, l’indispensable pot plein de dés 6/10/20, et des dizaines de boîtes en tout genre, parfois des titres dont moi-même je n’ai jamais entendu parlé, un piano à queue, divers lots de baffles et même des contentions psychiatriques. Pour d’autres jeux.

Je me tâte à faire une rubrique “jeu” d’ailleurs, pour introduire un jeu de plateau de temps en temps.

Évidement, à force de parties, on commence à en avoir plein le cul d’attendre le tour de l’autre, donc on joue au chrono. On a tenté le sablier, la montre, le portable, l’app, et rien n’est vraiment satisfaisant.

Que fait un programmeur dans ce cas ? Il réinvente la roue, bien sûr !

Voici donc All That Counts, une Web app qui contient :

  • Des timers.
  • Des chronos.
  • Des compteurs de points.

C’est du HTML5 + Javascript, il n’y a pas de backend. Est inclus un mode offline, donc il suffit de visiter l’app une fois pour pouvoir toujours l’utiliser sauf vidange du cache. Magie de Bootstrap, ça marche sur mobile, tablette et destop. Comprendre : design responsive générique.

Sur les navs supportant l’élément audio, ça gong à la fin des timers.

La page “Count Down” est pratique pour faire sa gym, cuire ses œufs et organiser une partie avec des tours limités dans le temps pour 3 joueurs ou plus. Les widgets incluent le temps de dépassement si on a besoin de mettre des pénalités aux escargots et aux stallers.

La partie “Chrono”, c’est gadget pour moi, mais ça pourra peut être servir à certains. J’y ai collé la possibilité de cumuler des temps de tours, pour les sportifs. Je ne sais pas si c’est utile, les coureurs me diront. A la limite pour les concours d’apnée…

L’onglet “Counter” c’est pour compter les points quand on a pas de papier ou de jeton, c’est du dépannage. Ça peut servir aussi pour les gens dont le métier implique de compter des têtes de pipe comme les videurs, les hôtesses de l’air, etc.

Ce qu’on utilise le plus est le mode “Versus”, qui sert aux duels. C’est une sorte de pendule d’échecs, avec plusieurs comportements réglables. Par défaut, le passage d’un décompte à l’autre se fait automatiquement et manuellement, chaque changement de joueur impliquant une remise à zéro.

Comme il n’y a pas de backend, vous pouvez avoir le code source en faisant Ctrl + S, donc je vais pas vraiment me faire chier à le mettre sur github. Déjà, j’ai du codé en pur JS. Moi. Heureusement qu’il y a AngularJS, sinon je changeais de métier. Le déploiement, pareil, c’est Ctrl + C, Ctrl + V, donc je vais pas écrire de doc. L’utilisation, bon, c’est des clics sur des boutons labellisés…

Le code source est dispo sur github.

La seule astuce, c’est qu’en mode versus, CTRL permet de faire un switch, et SPACE permet de faire pause et resume. Je pense que vous vous en sortirez. C’est un compteur, pas une navette spatiale.

Si l’envie incroyable de rajouter des features vous prend, mettez un comment, et je me bougerais le cul pour githuber tout ça.

]]>
http://sametmax.com/not-invented-here/feed/ 19 10065
Game of thrones, le jeu de plateau http://sametmax.com/game-of-thrones-le-jeu-de-plateau/ http://sametmax.com/game-of-thrones-le-jeu-de-plateau/#comments Sun, 02 Jun 2013 22:02:09 +0000 http://sametmax.com/?p=6321 J’avais le choix entre écrire un article et rejoindre une bande de geeks pour tester GOT en jeu de plateau. J’adore les jeux de société (labyrinthe, muchkin, risk, loup garou, times up, boggle, etc), et je connaissais pas celui là.

Mon hôte possède un nombre impressionant de boîtes, j’ai rencontré un mec qui avait dans sa collec magic un lotus noir, les pizzas sont sorties, Tenacious D est en fond. Bref, une bonne soirée d’ados.

Conclusion : pas de gros article aujourd’hui, mais GOT en jeu est super cool (mais tellement compliqué qu’il faut pas imaginer apprendre le truc en lisant les règles par soi-même).

C’est dimanche, bon dimanche, sous vos applaudissements.

]]>
http://sametmax.com/game-of-thrones-le-jeu-de-plateau/feed/ 8 6321