Fermer

juin 18, 2020

Modernisation des applications: relancer un défi de codage technique


Notre groupe de solutions de développement personnalisées a travaillé pour raviver notre culture de compétition de codage Tech Challenge et a finalement décidé pourquoi réinventer la roue? Une grande partie de notre travail client porte sur la modernisation des applications, alors pourquoi ne modernisons-nous pas une ancienne application Tech Challenge?

Contexte

En 2008, Bryan Dougherty, maintenant notre général Manager, a créé l'original Tech Challenge . Le déroulement du jeu est vaguement basé sur un jeu de société de style bataille préféré des enfants; couler tous les navires de vos adversaires pour gagner la partie. Quelques améliorations ont été ajoutées pour rendre le gameplay plus excitant. Tout comme le plateau de jeu, le champ de bataille est une grille. Cependant, contrairement au jeu classique, jusqu'à 16 joueurs peuvent s'affronter dans le même jeu. La flotte de chaque équipe est affectée à une région du champ de bataille.

Ci-dessous, vous pouvez voir un exemple de capture d'écran d'un jeu avec trois équipes. Les blocs en rouge indiquent des dommages. Le bas de l'écran affiche des informations telles que des messages, des résultats de commande ou des navires coulés.

 Image001

Gameplay

Les règles simples du jeu sont: [19659010] Chaque joueur doit définir sa flotte. Pour qu'une flotte soit valide, elle doit contenir un de chaque type de navire.

  • Le jeu nécessite qu'une flotte soit définie dans une région 20 x 20. Si un joueur positionne un vaisseau en dehors de la région, le joueur sera expulsé du jeu.
  • L'empilement de vaisseaux est interdit. Le joueur ne doit pas placer un vaisseau de manière à ce qu'il chevauche un vaisseau qu'il a précédemment placé. Si cela se produit, le joueur sera expulsé du jeu.
  • Chaque tour consiste en un ordre tiré par joueur.
  • Les ordres doivent être de trois types: attaque, reconnaissance ou diffusion d'un message. [19659011] Les joueurs peuvent exécuter n'importe quel ordre s'il reste au moins un navire dans la flotte, une fois que tous leurs navires sont coulés, ils ne peuvent plus émettre d'ordres.
  • Le jeu ne vous protégera pas des ordres mal placés. Si vous attaquez vos propres positions de vaisseau, elles seront enregistrées comme coups sûrs. Si vous envoyez des coordonnées d'ordre en dehors de la taille maximale du champ de bataille, cela comptera comme un tour et un échec.
  • Une fois qu'un ordre est reçu d'un joueur et traité, l'ordre et les résultats de l'ordre suivants seront envoyés en réponse à chaque joueur.
  • Les flottes des joueurs seront enregistrées au départ. Lorsque toutes les flottes sont enregistrées, le jeu renverra une liste des joueurs du jeu et leurs coordonnées de début et de fin. Cela devrait fournir les informations nécessaires pour qu'un joueur détermine quelles régions du plateau attaquer. Le jeu commencera et des coordonnées absolues seront définies pour chaque navire. Les coordonnées absolues sont les coordonnées qui correspondent au tableau partagé qui contient toutes les flottes. Le jeu parcourt chaque joueur pour son prochain coup (attaque, diffusion ou reconnaissance), calcule le résultat, l'affiche sur l'interface utilisateur, puis renvoie le résultat du coup à tous les joueurs. Deux améliorations ont été ajoutées au jeu pour augmenter le plaisir et la complexité: la diffusion et la reconnaissance. Chaque joueur soumet un coup par tour. Seul le commandement d'attaque inflige des dégâts à un adversaire. Des mises à jour et des améliorations minimales ont été apportées à la logique de jeu globale lors de la modernisation de l'application.

    La commande de diffusion permet à un joueur de diffuser un message à toutes les autres flottes. Le message s'affiche sur l'interface utilisateur, puis le message de diffusion est renvoyé à chaque lecteur.

    La commande de reconnaissance permet à un joueur de balayer une zone 3 × 3 spécifiée en commençant par une coordonnée spécifique. Le balayage commencera aux coordonnées spécifiées et se déplacera de haut en bas, de gauche à droite. Si un navire ou des navires sont trouvés dans la zone 3 × 3, le jeu renverra les coordonnées du premier espace où un navire se trouve uniquement au joueur qui a soumis la commande de reconnaissance . Tous les autres joueurs ne seront informés que d'une reconnaissance sans informations de coordonnées. Un exemple de recon potentiel est présenté ci-dessous. Ici, une reconnaissance a été ordonnée à (1, 1). La reconnaissance commence là et se déplace de haut en bas, puis dans la colonne suivante. Une fois le balayage effectué (3, 1), il a trouvé un navire et arrête tout autre balayage dans la zone de reconnaissance, qu'il y ait ou non d'autres navires dans la zone.

     Image002

    Disposition des plateaux / joueurs:

    2 joueurs: largeur du champ de bataille – 40 × 20

     Image004

    2-4 joueurs: champ de bataille largeur – 40 × 40

     Image005

    5-9 joueurs: largeur du champ de bataille – 60 × 60

     Image006 [19659002] 10 – 16 joueurs: largeur du champ de bataille – 80 × 80

     Image007

     Covid 19

    Modernisation de l'application

    Architecture originale

    Le jeu original a été construit en 2008 en utilisant WPF et WCF. La demande était divisée en trois parties. Le projet Composants était un assemblage partagé qui contenait les classes qui géraient la communication et la logique du jeu ainsi que les définitions de classe pour tous les navires (c'est-à-dire AircraftCarrier, Destroyer, etc.). Le plateau de jeu a utilisé WPF pour afficher l'action sur le champ de bataille. Enfin, des applications de console ont été construites par chaque équipe souhaitant participer.

     Image015

    Approche de modernisation des applications

    Nous avons essayé d'examiner la modernisation des applications du Tech Challenge dans de nombreux comme nous le ferions pour un projet client. Nous devions d'abord comprendre le problème et déterminer les objectifs commerciaux du projet. Le jeu original avait 12 ans, n'utilisait pas beaucoup de technologie moderne et ne se prêtait pas bien à une approche de joueur agnostique. Nous voulions lancer le Tech Challenge (le plus tôt sera le mieux) où un joueur pourrait être construit en utilisant une technologie agnostique, moderne et pertinente pour notre espace commercial actuel. La mise à jour de l'apparence était moins importante car nous avons aimé l'ambiance rétro de l'interface utilisateur du jeu. Nous avons créé une approche progressive pour réaliser le changement et la valeur dès que possible tout en améliorant le cadre pour prendre en charge les futures mises à jour.

    Décisions majeures

    Nous avons décidé de limiter les modifications majeures apportées à la logique de jeu et à l'interface utilisateur de l'application WPF Desktop. L'interface utilisateur WPF devait uniquement être mise à jour pour recevoir les commandes du lecteur d'une méthode différente de celle des écouteurs / rappels WCF. Les modifications de l'interface utilisateur WPF ont été limitées pour mettre à jour la façon dont le système a reçu une commande de lecteur d'un appel API par rapport à une série d'écouteurs / rappels WCF. La logique de jeu a été déplacée dans un WebJob et les appels de commande des joueurs respectifs ont été mis à jour. La logique de jeu elle-même est restée la même, mais la méthode de connexion à chaque joueur et la communication aller-retour ont été mises à jour. Le WebJob mis à jour utilisait des URL de lecteur dans le fichier de configuration pour initier les connexions client HTTP et les méthodes d'écoute / rappel ont été remplacées par des appels GET / POST vers des points de terminaison définis.

    Nous voulions pouvoir stocker les jeux pour les réexécuter ou les traiter ultérieurement. Le WebJob a stocké chaque commande de jeu dans un fichier json enregistré dans le stockage d'objets blob. Le fichier json était dans le même format et dans l'ordre nécessaire à l'interface utilisateur pour traiter le jeu. Cela a permis l'audit des jeux joués ainsi que la possibilité de réexécuter des jeux précédemment traités via l'interface utilisateur et de contourner le WebJob si vous le souhaitez.

    Nous voulions que les joueurs soient agnostiques à la technologie. Nous voulions que les gens expérimentent différentes technologies et plongent leurs pieds dans quelque chose qu'ils ne connaissaient pas nécessairement. L'ensemble du gameplay est contenu dans deux appels GET et deux appels POST. Tant qu'un joueur peut exposer un point de terminaison http: // baseurl / {methodName} pour les quatre appels et adhère aux modèles de données corrects, n'importe quelle technologie peut être utilisée.

    Nous voulions également que la barrière à l'entrée soit faible pour encourager la participation. Nous avons fourni des exemples de joueurs de base et exploitables dans quatre technologies différentes: Azure API App, Google Cloud Endpoint, AWS API Gateway et Python hébergés sur PythonAnywhere.

    Résultat

    Comme illustré dans le diagramme ci-dessous, le WebJob a été créé pour exécuter la logique du jeu et se connecter à chaque joueur via une connexion HttpClient pour les commandes du jeu. Le WebJob envoie chaque commande traitée à la file d'attente Service Bus et enregistre une copie dans le fichier blob du jeu. L'interface utilisateur WPF a été mise à jour pour extraire la commande de jeu suivante d'une API. Chaque appel de l'API GET extrait la commande de jeu suivante de la file d'attente Service Bus jusqu'à ce qu'un état de fin de jeu soit reçu. L'affichage de l'interface utilisateur n'a pas été modifié dans la phase initiale.

     Image018

    Défis liés à la modernisation de l'application

    Découplage du jeu et de la logique du joueur de l'interface utilisateur. Notre équipe a suivi un cours intensif sur WPF, travaillant à comprendre l'interface utilisateur et à s'assurer qu'elle serait découplée correctement. Il a fallu un travail initial pour déterminer où nous voulions découpler la connexion et combien vivraient dans le WebJob vs rester dans l'application de bureau UI. L'un de nos objectifs d'extensibilité était de remplacer facilement les interfaces utilisateur dans une phase future. Nous avons donc déplacé toute la logique du jeu dans le WebJob. Cela a permis au jeu complet d'être exécuté et traité sans interface utilisateur. Nous avons limité la fonctionnalité de l'interface utilisateur à l'affichage strict des mouvements des joueurs à l'écran tels qu'ils ont été reçus d'une source API.

    Contraintes autour de la testabilité du système. Afin de tester le jeu complet de bout en bout, nous avions besoin de deux joueurs suffisamment intelligents pour terminer le jeu. Comme la modernisation de l'application était axée sur la mise à jour et le déplacement de la logique de jeu vers le cloud et sur son test, les versions initiales des joueurs utilisaient soit des attaques aléatoires, soit une traversée basique de gauche à droite de haut en bas de la grille (ce qui pouvait entraîner 400 tours dans un jeu à deux joueurs seul). Les premiers jeux prendraient entre 5 et 15 minutes pour être entièrement traités dans le WebJob, puis 5 à 15 minutes pour regarder l'interface utilisateur. Si nous voulions apporter une petite modification à l'interface utilisateur et redéployer, nous devrions recommencer tout le processus à partir du WebJob. Un cycle de test peut prendre 30 minutes ou pire, expirer. Lors du test de jeux à 3-4 joueurs, ce temps pourrait facilement doubler ou tripler. Pour atténuer cette contrainte, nous avons mis à jour l'interface utilisateur et institué un paramètre de configuration qui nous a permis de traiter une partie de fichier enregistrée soit via la file d'attente Service Bus, soit via un fichier json local. Nous devions également prendre en charge les tests des utilisateurs finaux une fois le Tech Challenge lancé. Nous voulions faciliter le test individuel des interfaces utilisateur des joueurs et nous ne voulions pas que les gens aient à dérouler la base de code, à la reconstruire et à l'exécuter, ni à mettre à jour le code du jeu de base. Nous avons créé un exécutable d'application autonome comme faisceau de test pour les tests de logique des joueurs. Un téléchargement du fichier .exe et une simple mise à jour de la configuration pour pointer vers l'URL appropriée constituaient la configuration requise pour tester un lecteur local ou déployé.

    Logiciels originaux et intégration de technologies modernes. Nous avons rencontré quelques problèmes en plaçant la technologie moderne au-dessus d'une interface utilisateur construite en 2008. Le jeu d'origine n'était pas conçu pour gérer les appels d'API asynchrones car il était construit sur .NET 3.0 et async n'était inclus dans .NET que jusqu'à 4.5. Pendant la modernisation de l'application, les itérations initiales de async / wait n'ont pas été complètement implémentées et les exceptions async / wait se perdaient sur la pile. L'interface utilisateur échouerait en arrière-plan lors d'un appel à l'API et elle se bloquerait simplement sans trace de ce qui s'est produit. Il y avait également quelques problèmes de thread avec un contexte non asynchrone appelant incorrectement du code asynchrone. Si l'exécution s'est terminée dans l'appelant, il peut ne pas obtenir les résultats de ce qu'il a appelé et il peut arrêter l'exécution tous ensemble.

    Considérations relatives à l'API du joueur

    Stockage . Le gameplay est exposé via des API, donc un élément d'état doit être ajouté pour gérer le jeu. Comment suivez-vous les statistiques des jeux? Répondez-vous aux coups des autres joueurs? Suivez-vous chaque adversaire au niveau du vaisseau ou juste un nombre total de coups? Combien vaut l'effort initial? Réflexions sur l'approche progressive: avez-vous besoin de suivre chaque match et chaque joueur affronté? Probablement pas pour un tournoi unique. Si c'était une saison et que vous avez joué plusieurs fois avec les mêmes joueurs, il peut être judicieux de suivre la position de leurs navires, etc.

    Logique de jeu . Est-il préférable de concentrer votre temps sur des combats en tête-à-tête ou multi-joueurs? La reconnaissance vaut-elle le tour de non-attaque? Basez-vous votre prochaine attaque sur les coups précédents des autres joueurs, c'est-à-dire que le joueur 4 frappe le joueur 3 à (3,3), comme le joueur 2 attaquez-vous (3,4) ou certaines coordonnées environnantes comme votre prochain mouvement d'attaque? Ceci est évidemment plus utile dans les scénarios multi-joueurs car un match en tête-à-tête ne serait que votre dernier appel.

    Tech Challenge Tournament 2020

    16 API de joueurs ont été soumises. Deux styles de tournois ont été configurés, un tournoi en mode tête à tête et un tournoi Battle Royale multi-joueurs.

    Tournoi en tête-à-tête

    Le tournoi en tête-à-tête était semé au hasard et joué dans un style de support typique. L'un des matchs du premier tour s'est terminé dans une impasse car aucun joueur n'a attaqué avec précision l'autre joueur, ce qui a entraîné un temps mort. Les deux joueurs n'ayant pas réussi à attaquer l'adversaire, ils ont été disqualifiés du tournoi. Pour remplir cette place au tour 2, un tour de rachat a été mis en place, composé des 4 meilleures équipes qui ont perdu au tour 1. Le vainqueur du tour de rachat est rentré dans le tournoi pour le tour 2. Le vainqueur du tournoi était C & C Torpedos commandé par Bryan Dougherty.

     Image012

    Tournoi Battle Royale

    Le tournoi battle royale était divisé en deux mini-tournois. Le premier mini-tournoi était une bataille à cinq joueurs. Deux matchs à cinq joueurs ont eu lieu au premier tour, puis les cinq meilleurs joueurs finissants de ces matchs disputés dans la finale à cinq joueurs. Le deuxième mini-tournoi était une bataille à un joueur et à dix joueurs. Le vainqueur des deux mini-tournois était l'escadron 42 commandé par Evan Glanz.

     Image013

    La première phase de la modernisation de l'application Tech Challenge a réussi à remplir trois objectifs principaux: un défi technologique engageant et à faible barrière à l'entrée au cours du premier semestre de 2020, prend en charge les joueurs agnostiques et offre une solution extensible où l'interface utilisateur peut être facilement remplacée dans une phase future.

    À propos de l'auteur

    Judah est un directeur de l'unité commerciale Custom Development Solutions de Perficient, basée à Chicago.

    More from this Author




    Source link