[JAVA] L'histoire de la création d'un jeu d'Othello de type communication avec Scala.

introduction

Cela fait environ un mois que j'ai appris Scala par moi-même, j'ai donc créé un jeu Othello en utilisant la communication par socket comme pratique. Voici un résumé de ce que j'ai appris. La période de mise en œuvre est d'environ 2 semaines. (Hors apprentissage de Scala seul)

スクリーンショット 2018-12-10 16.17.29.png

[Code source] https://github.com/yuto226/Oselo

What is Scala Scala est reconnu comme un parent de Java. Ce que vous pouvez faire avec Scala peut être fait essentiellement avec Java.

Ce que je ressentais le plus différemment de Java, c'était qu'il contenait une petite quantité de code et qu'il était possible de faire de la programmation fonctionnelle au lieu d'une programmation robuste orientée objet.

La fonction appelée trait semble être utile, mais je ne pouvais pas l'utiliser pour la capacité pendant cette période, donc je voudrais l'améliorer à l'avenir.

environnement

Mac OS X Sierra 10.12.6 InteliJ IDEA Scala 2.12.7 jdk-9

Ce que j'ai fait

Récemment, j'étais paresseux dans la technologie, alors j'ai créé Othello avec l'intention de faire un jeu avec le sens de bouger mes mains de toute façon. À propos, la communication par socket est également implémentée en tant que revue du traitement du réseau. J'ai utilisé Scala parce qu'il y avait de fortes chances que j'utilise Java pour travailler à l'avenir, donc quand je cherchais quelque chose de similaire, j'ai trouvé quelque chose de proche, alors j'ai commencé avec intérêt. Depuis que je l'ai fait avec une telle motivation, je pense que je n'ai pas atteint l'implémentation qui utilise pleinement les bienfaits de Scala. (J'avais l'intention de bouger de toute façon) Cependant, Scala en lui-même était assez utilisable et facile à écrire, donc je pense que je vais étudier dur à l'avenir.

Conception simple (flux)

Puisqu'il s'agit d'une communication socket, il s'agit d'un format client-serveur. Le côté serveur est en charge du noir d'Othello, et le client se connecte et il est blanc. Grâce à la douille, nous échangerons les coordonnées de l'endroit où la pièce a été placée avec un message et procéderons au jeu. Au stade de la conception, je pensais que le processus de dessin de l'interface graphique serait gênant, mais il l'a été plus tard (rires).

la mise en oeuvre

Cela faisait un moment que je n'avais pas programmé la communication par socket, donc le premier obstacle était de connecter des sockets et d'échanger des messages. De plus, puisqu'il s'agit d'un jeu, le traitement du dessin d'écran pour l'interface graphique sera inclus. J'ai introduit le multi-threading car la limite est inévitablement atteinte lors de l'exécution d'un programme avec un thread. Dans le sous-fil, la réception du message est faite pour attendre dans une boucle infinie, et le jugement de victoire et le dessin d'écran sont effectués dans ce fil. Le multi-threading est indispensable lorsque vous attendez indéfiniment un tel traitement d'E / S dont vous ne savez pas quand il arrivera. (Au début, je devais attendre indéfiniment dans ce fil, mais bien sûr, le processus a cessé de fonctionner du tout.)

 override def run(): Unit ={
     createServer
     receiveMsg
   }

La fonction receiveMsg attend indéfiniment. La fonction createServer initialise BufferedReader etc. par défaut. Héritez de la classe Java Thread et appelez-la à partir de ce thread avec la méthode start. Fondamentalement, si vous laissez le client et le serveur attendre de la même manière et alterner le contrôle de l'ordre, le jugement de victoire, la transmission de messages, etc., ce sera un jeu.

Le dessin d'écran lui-même a été réalisé avec scalafx (javafx), mais scalafx vous permet de concevoir une interface graphique avec une interface graphique à l'aide d'un outil appelé Scene Builder. (Comme lors de la création d'un écran d'application iPhone avec X Code)

Il n'y a rien de tel dans le swing, et il semble que l'implémentation sera un mélange de code d'interface utilisateur et de code de traitement de données, donc je pense que c'est un avantage de scalafx (javafx).

Blocage / non-blocage

En fin de compte, si vous le rendez multi-thread pendant la mise en œuvre, vous pouvez résoudre la réception des messages et le dessin d'écran! J'ai découvert, mais pendant que je me promenais, le mot blocage / non-blocage est apparu et j'étais assez perdu. (Je me souviens avoir entendu les mots lors d'une conférence universitaire)

En conclusion, l'idée de blocage / non-blocage est d'utiliser le non-blocage lorsqu'il existe un risque que plusieurs clients accèdent au serveur. ... Apparemment ... (Veuillez me dire si c'est différent ...) Du point de vue des ressources informatiques, il est évident que si vous attribuez des processus de thread à plusieurs clients, il sera épuisé, alors mettez dans un processus pour "surveiller" et connectez-vous s'il s'agit d'une nouvelle connexion. Il semble idéal de l'implémenter en traitant lorsqu'un message vole. Je pense que je vais étudier à nouveau quand je serai calme ici.

Apprendre et résumer

Il est résumé dans les bulletins suivants. -Utilisez le multithreading pour un traitement d'E / S en attente infinie. -En multi-thread, soyez prudent lorsque vous effectuez un traitement de dessin d'écran dans un sous-thread. -Pour une communication un à un comme celle-ci, le blocage du traitement est correct. Lorsque plusieurs clients arrivent, insérez un processus de surveillance non bloquant. ・ L'algorithme d'inversion d'Othello est très difficile. (Plus de 500 lignes de code pour cette classe.) ・ J'aimerais pouvoir utiliser plus de Scala.

Je vais laisser le code pour dessiner l'écran en multi-thread car cela semble déroutant. Il a été résolu en passant la fonction cible à Platform # runLater.

Platform.runLater(() -> hogehoge())

Je voulais étudier Scala à l'avenir, donc si vous lisez le code, c'est ici qu'il faut aller! Si vous pouvez commenter cela, ce sera une source d'étude. Vous remerciant à l'avance.

Recommended Posts

L'histoire de la création d'un jeu d'Othello de type communication avec Scala.
L'histoire de la fabrication d'un Othello ordinaire à Java
L'histoire de la création d'un lanceur de jeu avec une fonction de chargement automatique [Java]
L'histoire de la création d'un proxy inverse avec ProxyServlet
Comment faire fonctionner IGV en utilisant la communication par socket, et l'histoire de la création d'un Ruby Gem en utilisant cette méthode
L'histoire de la création de Dr.Orchid avec LINE BOT
Une histoire sur la compatibilité d'un Dockerfile existant avec le GPU
L'histoire de l'introduction de la communication Ajax à Ruby
Une histoire sur la création d'un Builder qui hérite du Builder
[Jackson] Une histoire sur la conversion de la valeur de retour du type BigDecimal avec un sérialiseur personnalisé.
L'histoire de la création de DTO, semblable à Dao avec Java, SQLite
Une histoire de rendre catkin_make de rosjava compatible hors ligne
[Ruby] Prenez l'habitude d'utiliser la méthode dup lors de la copie d'une variable chaîne
Histoire de créer une application de gestion de tâches avec Swing, Java
Une histoire remplie des bases de Spring Boot (résolu)
L'histoire de la transmission de Java à Heroku à l'aide du pipeline BitBucket
[Apache Tomcat] L'histoire de l'utilisation d'Apache OpenWebBeans pour activer CDI
L'histoire du refactoring avec un assistant personnel pour la première fois dans une application Rails
Une histoire sur l'utilisation de l'API League Of Legends avec JAVA
Une histoire sur la fabrication d'une calculatrice pour calculer le taux de monticule d'obus
Une histoire qui a eu du mal avec l'introduction de Web Apple Pay
[Édition Java] Histoire de la sérialisation
L'histoire de @ViewScoped dévore la mémoire
Un mémorandum du problème FizzBuzz
Ecrire une casse nulle en utilisant le type facultatif sans utiliser l'instruction if
Une histoire à laquelle j'étais accro lors du test de l'API à l'aide de MockMVC
[Java] Comment accéder au début d'une chaîne spécifique à l'aide de la classe String