{"id":316,"date":"2013-06-22T18:10:28","date_gmt":"2013-06-22T17:10:28","guid":{"rendered":"http:\/\/chezdom.net\/etu\/?p=316"},"modified":"2013-06-22T19:02:50","modified_gmt":"2013-06-22T18:02:50","slug":"online-morpion-serveur","status":"publish","type":"post","link":"https:\/\/chezdom.net\/etu\/2013\/06\/22\/online-morpion-serveur\/","title":{"rendered":"Online Morpion serveur"},"content":{"rendered":"<p>Voici le code du serveur. La version courante ne g\u00e8re pas la fin de partie (victoire de l&rsquo;un des joueurs ou match nul)<\/p>\n<pre class=\"brush: java; gutter: true; first-line: 1; highlight: []; html-script: false\">package net.chezdom.nouakchott.onlinemorpion;\r\n\r\nimport java.io.IOException;\r\nimport java.net.ServerSocket;\r\n\r\npublic class OMServer extends Thread {\r\n\r\n\tprivate static int DEFAULTPORT = 9091;\r\n\tprivate ServerSocket listener;\r\n\tprivate Player playerX=null;\r\n\tprivate Player playerO=null;\r\n\tprivate Game game=null;\r\n\r\n\tpublic OMServer(int port) {\r\n\t\ttry {\r\n\t\t\tlistener = new ServerSocket(port);\r\n\t\t\tSystem.out.println(&quot;Online Morpion Server lanc\u00e9 sur le port &quot;+port);\r\n\t\t} catch (IOException e) {\r\n\t\t\tSystem.out.println(&quot;Impossible de lancer Online Morpion Server sur le port &quot;+port);\r\n\t\t\tSystem.exit(0);\r\n\t\t}\r\n\t\tstart();\r\n\t}\r\n\t\r\n\tpublic void run() {\r\n\t\tSocketHelper s=null;\r\n\t\twhile (true) {\r\n\t\t\ttry {\r\n\t\t\t\ts=new SocketHelper();\r\n\t\t\t\ts.open(listener.accept());\r\n\t\t\t\tSystem.out.println(&quot;Tentative de connexion d&#039;un client&quot;);\r\n\t\t\t\t\r\n\t\t\t\tif ((playerX!=null) &amp;&amp; (playerO!=null)) {\r\n\t\t\t\t\tSystem.out.println(&quot;Connexion refus\u00e9e (d\u00e9j\u00e0 2 joueurs)&quot;);\r\n\t\t\t\t\ts.sendMessage(&quot;FULL&quot;);\r\n\t\t\t\t\ts.close();\r\n\t\t\t\t\ts=null;\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tString shakehands=s.readMessage();\r\n\t\t\t\t\tif (shakehands.equals(&quot;OMCP&quot;)) {\r\n\t\t\t\t\t\tif (playerX==null) playerX=new Player(s,&#039;X&#039;,this);\r\n\t\t\t\t\t\telse playerO=new Player(s,&#039;O&#039;,this);\r\n\t\t\t\t\t\tif ((playerX!=null) &amp;&amp; (playerO!=null))\r\n\t\t\t\t\t\t\tgame=new Game(playerX,playerO);\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\ts.sendMessage(&quot;ERROR&quot;);\r\n\t\t\t\t\t\ts.close();\r\n\t\t\t\t\t\ts=null;\r\n\t\t\t\t\t\tSystem.out.println(&quot;Connexion refus\u00e9e : protocole incorrect&quot;);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t} catch (IOException e) {\r\n\t\t\t\te.printStackTrace();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void disconnect(Player p) {\r\n\t\tSystem.out.println(&quot;Deconnexion du client &quot;+p.getMark());\r\n\t\tif (p==playerX) playerX=null;\r\n\t\telse playerO=null;\r\n\t\tgame=null;\r\n\t}\r\n\r\n\r\n\tpublic static void Usage() {\r\n\t\tSystem.out.println(&quot;Usage: java OMServer [-h] [portnumber]&quot;);\r\n\t\tSystem.exit(0);\r\n\t}\t\r\n\t\r\n\tpublic static void main(String[] args) {\r\n\t\tint port=DEFAULTPORT;\r\n\t\tif (args.length&gt;0) {\r\n\t\t\tif ((args[0].equals(&quot;-h&quot;)) || (args.length&gt;1)) Usage();\r\n\t\t\ttry {\r\n\t\t\t\tport=Integer.parseInt(args[0]);\r\n\t\t\t}\r\n\t\t\tcatch (NumberFormatException e) {\r\n\t\t\t\tUsage();\r\n\t\t\t}\r\n\t\t}\r\n\t\tnew OMServer(port);\r\n\t}\r\n\r\n}\r\n\r\nclass Game {\r\n\tprivate Player playerX;\r\n\tprivate Player playerO;\r\n\tprivate Player nextPlayer;\r\n\t\r\n\tprivate Player[] board = {\r\n\t        null, null, null,\r\n\t        null, null, null,\r\n\t        null, null, null};\r\n\t\r\n\tpublic Game(Player playerX, Player playerO) {\r\n\t\tsuper();\r\n\t\tthis.playerX = playerX;\r\n\t\tthis.playerO = playerO;\r\n\t\tthis.playerX.setOtherPlayer(this.playerO, this);\r\n\t\tthis.playerO.setOtherPlayer(this.playerX, this);\r\n\t\tnextPlayer=playerX;\r\n\t\tSystem.out.println(&quot;La partie commence&quot;);\r\n\t\tnextPlayer.startGame();\r\n\t\tnextPlayer.giveHand();\r\n\t}\r\n\r\n\tpublic boolean play(int sel, Player player) {\r\n\t\tif (board[sel]==null) {\r\n\t\t\tSystem.out.println(&quot;Valid move on &quot;+sel);\r\n\t\t\tboard[sel]=player;\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\t\/\/System.out.println(&quot;Cell &quot;+sel+&quot;already in use&quot;);\r\n\t\treturn false;\r\n\t}\r\n\t\r\n\tpublic void nextPlayer() {\r\n\t\tif (nextPlayer==playerX) nextPlayer=playerO;\r\n\t\telse nextPlayer=playerX;\r\n\t\tnextPlayer.giveHand();\r\n\t}\r\n\t\r\n\tpublic Player hasWinner() {\r\n\t\tfor (int i=0;i&lt;3;i++) {\r\n\t\t\tif ((board[i*3]!=null) &amp;&amp; (board[i*3]==board[i*3+1]) &amp;&amp; (board[i*3]==board[i*3+2]))\r\n\t\t\t\treturn board[i*3]; \r\n\t\t\tif ((board[i]!=null) &amp;&amp; (board[i]==board[i+3]) &amp; (board[i]==board[i+6]))\r\n\t\t\t\treturn board[i];\r\n\t\t\tif ((board[4]!=null) &amp;&amp; (board[0]==board[4]) &amp; (board[4]==board[8]))\r\n\t\t\t\treturn board[4];\r\n\t\t\tif ((board[4]!=null) &amp;&amp; (board[2]==board[4]) &amp; (board[4]==board[6]))\r\n\t\t\t\treturn board[4];\r\n\t\t}\r\n\t\treturn null;\r\n\t}\r\n\r\n\tpublic boolean isTie() {\r\n\t\tfor (int i=0;i&lt;9;i++)\r\n\t\t\tif (board[i]==null) { System.out.println(i);return false;}\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nclass Player extends Thread {\r\n    private char mark;\r\n    private SocketHelper socket;\r\n    private boolean alive;\r\n    private OMServer server;\r\n    private String playerName = &quot;Unknown&quot;;\r\n    private String otherPlayerName = &quot;Unknown&quot;;\r\n    private Player otherPlayer=null;\r\n    private Game game;\r\n    \r\n    public Player(SocketHelper socket, char mark, OMServer server) {\r\n        this.socket = socket;\r\n        this.mark = mark;\r\n        this.server = server;\r\n        System.out.println(&quot;Player &quot;+mark+&quot; connect\u00e9&quot;);\r\n\t\tsocket.sendMessage(&quot;WELCOME &quot;+mark);\r\n\t\talive=true;\r\n\t\tstart();\r\n    }\r\n    \r\n    public char getMark() {\r\n\t\treturn mark;\r\n\t}\r\n        \r\n\tpublic String getPlayerName() {\r\n\t\treturn playerName;\r\n\t}\r\n\r\n\tpublic void setOtherPlayer(Player otherPlayer, Game game) {\r\n\t\tthis.otherPlayer = otherPlayer;\r\n\t\tthis.game=game;\r\n\t\tthis.otherPlayerName = otherPlayer.getPlayerName();\r\n\t\tsocket.sendMessage(&quot;OTHERNAME &quot;+otherPlayerName);\r\n\t}\r\n\t\r\n\tpublic void setOtherPlayerName(String otherPlayerName) {\r\n\t\tthis.otherPlayerName = otherPlayerName;\r\n\t\tsocket.sendMessage(&quot;OTHERNAME &quot;+otherPlayerName);\r\n\t}\r\n\r\n\tpublic void otherPlayerCancel() {\r\n\t\tsocket.sendMessage(&quot;OTHERCANCEL&quot;);\r\n\t\totherPlayer=null;\r\n\t\totherPlayerName=&quot;Unknown&quot;;\r\n\t}\r\n\r\n\tpublic void startGame() {\r\n\t\tsocket.sendMessage(&quot;START&quot;);\r\n\t\totherPlayer.socket.sendMessage(&quot;START&quot;);\r\n\t}\r\n\t\r\n\tpublic void giveHand() {\r\n\t\tsocket.sendMessage(&quot;HAND&quot;);\r\n\t}\r\n\t\r\n\tpublic void run() {\r\n    \twhile (alive) {\r\n    \t\tString answer=socket.readMessage();\r\n    \t\tif (answer!=null) {\r\n    \t\t\tSystem.out.println(&quot;RECU &quot;+answer+&quot; DE &quot;+mark);\r\n    \t\t\tif (answer.equals(&quot;CANCEL&quot;)) {\r\n    \t\t\t\t\/\/ Deconnection du joueur, abandon de la partie, lib\u00e9ration d&#039;une place\r\n    \t\t\t\tif (otherPlayer!=null) otherPlayer.otherPlayerCancel();\r\n    \t\t\t\tserver.disconnect(this);\r\n    \t\t\t\talive=false;\r\n    \t\t\t} else if (answer.startsWith(&quot;NAME&quot;)) {\r\n    \t\t\t\tplayerName=answer.substring(5);\r\n    \t\t        System.out.println(&quot;Player &quot;+mark+&quot; name : &quot;+playerName);\r\n    \t\t        if (this.otherPlayer!=null) this.otherPlayer.setOtherPlayerName(playerName);\r\n    \t\t\t} else if (answer.startsWith(&quot;PLAY&quot;)) {\r\n    \t\t\t\t\/\/ Le joueur a cliqu\u00e9 sur une case\r\n    \t\t\t\tint sel=Integer.parseInt(answer.substring(5));\r\n    \t\t\t\tif (game.play(sel,this)) {\r\n    \t\t\t\t\tsocket.sendMessage(&quot;VALID&quot;);\r\n    \t\t\t\t\totherPlayer.socket.sendMessage(&quot;OTHERPLAY &quot;+sel);\r\n    \t\t\t\t\tif (game.hasWinner()!=null) {\r\n    \t\t\t\t\t\tsocket.sendMessage(&quot;WIN&quot;);\r\n    \t\t\t\t\t\totherPlayer.socket.sendMessage(&quot;LOST&quot;);\r\n    \t\t\t\t\t} else if (game.isTie()) {\r\n    \t\t\t\t\t\tsocket.sendMessage(&quot;TIE&quot;);\r\n    \t\t\t\t\t\totherPlayer.socket.sendMessage(&quot;TIE&quot;);\r\n    \t\t\t\t\t} else\r\n    \t\t\t\t\t\tgame.nextPlayer();\r\n    \t\t\t\t} else \r\n    \t\t\t\t\tsocket.sendMessage(&quot;WRONG&quot;);\r\n    \t\t\t}\r\n    \t\t}\r\n    \t}\r\n    \tsocket.close();\r\n    }\r\n}\r\n<\/pre>\n<p>Le serveur utilise la classe outil SocketHelper suivante pour encapsuler la gestion des sockets. Vous pouvez utiliser cette classe aussi pour le client.<\/p>\n<pre class=\"brush: java; gutter: true; first-line: 1; highlight: []; html-script: false\">import java.io.BufferedReader;\r\nimport java.io.IOException;\r\nimport java.io.InputStreamReader;\r\nimport java.io.PrintStream;\r\nimport java.net.Socket;\r\nimport java.net.UnknownHostException;\r\n\r\npublic class SocketHelper {\r\n\tprivate Socket socket;\r\n\tprivate BufferedReader input;\r\n\tprivate PrintStream out;\r\n\tprivate String errorMessage;\r\n\t\r\n\tpublic boolean open(Socket socket) {\r\n\t\tthis.socket=socket;\r\n\t\treturn openStreams();\r\n\t}\r\n\t\r\n\tpublic boolean open(String server, int port) {\r\n\t\ttry {\r\n\t\t\tsocket=new Socket(server,port);\r\n\t\t} catch (UnknownHostException e) {\r\n\t\t\tsocket=null;\r\n\t\t\terrorMessage=&quot;Serveur inconnu&quot;;\r\n\t\t} catch (IOException e) {\r\n\t\t\tsocket=null;\r\n\t\t\terrorMessage=&quot;Impossible d&#039;\u00e9tablir la connexion avec &quot;+server+&quot;sur le port &quot;+port;\r\n\t\t}\r\n\r\n\t\tif (socket==null) return false;\r\n\t\treturn openStreams();\r\n\t}\r\n\t\r\n\tpublic boolean openStreams() {\r\n\t\tif (socket==null) return false;\r\n\t\t\r\n\t\ttry {\r\n\t\t\tinput=new BufferedReader(new InputStreamReader(socket.getInputStream()));\r\n\t\t\tout=new PrintStream(socket.getOutputStream());\r\n\t\t} catch (IOException e) {\r\n\t\t\ttry {\r\n\t\t\t\tsocket.close();\r\n\t\t\t} catch (IOException e1) {\/*Nothing to do here*\/}\r\n\t\t\tsocket=null;\r\n\t\t\terrorMessage=&quot;Impossible d&#039;ouvrir les flux d&#039;E\/S.&quot;;\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\t\r\n\tpublic void close() {\r\n\t\ttry {\r\n\t\t\tinput.close();\r\n\t\t\tout.close();\r\n\t\t\tsocket.close();\r\n\t\t} catch (IOException e) {\r\n\t\t\tSystem.err.println(&quot;Cannot close socket!&quot;);\r\n\t\t\t\/*Nothing to do here*\/}\r\n\t\tsocket=null;\r\n\t}\r\n\t\r\n\tpublic boolean isConnected() {\r\n\t\treturn socket!=null;\r\n\t}\r\n\t\r\n\tpublic String getErrorMessage() {\r\n\t\treturn errorMessage;\r\n\t}\r\n\r\n\tpublic boolean sendMessage(String msg) {\r\n\t\tif (socket==null) return false;\r\n\t\tout.println(msg);\r\n\t\treturn true;\r\n\t}\r\n\t\r\n\tpublic String readMessage() {\r\n\t\tif (socket==null) return null;\r\n\t\tString answer=null;\r\n\t\ttry {\r\n\t\t\tanswer = input.readLine();\r\n\t\t} catch (IOException e) {\r\n\t\t\tanswer=null;\r\n\t\t}\r\n\t\treturn answer;\r\n\t}\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Voici le code du serveur. La version courante ne g\u00e8re pas la fin de partie (victoire de l&rsquo;un des joueurs ou match nul) package net.chezdom.nouakchott.onlinemorpion; import java.io.IOException; import java.net.ServerSocket; public class OMServer extends Thread { private static int DEFAULTPORT =<span class=\"ellipsis\">&hellip;<\/span> <span class=\"read-more\"><a href=\"https:\/\/chezdom.net\/etu\/2013\/06\/22\/online-morpion-serveur\/\">Lire la suite &#8250;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[10],"tags":[],"class_list":["post-316","post","type-post","status-publish","format-standard","hentry","category-nouakchott"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9qu1A-56","_links":{"self":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/316","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/comments?post=316"}],"version-history":[{"count":5,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/316\/revisions"}],"predecessor-version":[{"id":322,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/posts\/316\/revisions\/322"}],"wp:attachment":[{"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/media?parent=316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/categories?post=316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chezdom.net\/etu\/wp-json\/wp\/v2\/tags?post=316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}