рд╣рдо NodeJS, Express рдФрд░ Socket.IO рдкрд░ рдПрдХ рдСрдирд▓рд╛рдЗрди рдЧреЗрдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ

рд╣рд╛рдп% рд╣рдмрд░рдирд╛рдо%!





*** рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдЦреЗрд▓ рдореЗрдВ рд╣реА рддрд╛рд░реНрдХрд┐рдХ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд▓реЗрдЦ рдХреА рддрдХрдиреАрдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЦреЗрд▓рдирд╛ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реИ рдХрд┐ рд╢реАрд░реНрд╖рдХ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЬрд╛рд░реА рд░рдЦрд╛ рдЬрд╛рдПред рд╣рдо рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдЦреЗрд▓ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓рд╛рддреЗ рд╣реИрдВ


рдХреБрдЫ рд▓реЛрдЧ рдЖрдЬ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ NodeJS рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдкрддрд╛ рд╣реИ, рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╡реЗ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдмрд╛рддреЗрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рдореИрдВрдиреЗ рдЫрд╣ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ NodeJS рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХрд╛ рдЕрдкрдирд╛ рддрд░реАрдХрд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдерд╛, рддрдм рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рд╕рд┐рд░реНрдл рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдирдпрд╛ рдерд╛, рдореИрдВ рд╕реЛрдЪ рднреА рдирд╣реАрдВ рд╕рдХрддрд╛ рдерд╛ рдХрд┐ рдЫрд╣ рдорд╣реАрдиреЗ рдореЗрдВ рдпрд╣ рдореЗрд░рд╛ рдореБрдЦреНрдп рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдг рдмрди рдЬрд╛рдПрдЧрд╛ред

рдЪреВрдВрдХрд┐ рд╕рднреА рдкреНрд░рд╢рд┐рдХреНрд╖рдг рд╕рд╛рдордЧреНрд░реА рдпрд╛ рддреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкрд░ рд▓реЗрдЦ рд╣реИрдВ, рдпрд╛ рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдпрд╛ рдЪреИрдЯ рдХреЛ рдХреИрд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ, рдореБрдЭреЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдЦреБрдж рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдзреАрд░реЗ-рдзреАрд░реЗ рд╡рд┐рднрд┐рдиреНрди рдЫреЛрдЯреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд┐рдЦрд╛ рдЬреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкреАрдПрдЪрдкреА рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛ рдХрд╛рдо рдХрд░рддреЗ рдереЗред

рд▓реЗрдХрд┐рди рдЕрдм рдореИрдВ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреВрд░реНрдг рд╢реИрдХреНрд╖рд┐рдХ рдФрд░ рд╢реБрд░реБрдЖрддреА рд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╕реНрдд рд╕рд╛рдордЧреНрд░реА рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреА рддрд╛рдХрдд рдорд╣рд╕реВрд╕ рдХрд░рддрд╛ рд╣реВрдВред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдмрд▓реНрдХрд┐ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдФрд░ рд╕реЙрдХреЗрдЯ.рдЖрдИрдУ рдЯреВрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдСрдирд▓рд╛рдЗрди рдЧреЗрдо рд╣реИ, рд╣рд╛рдБ, рдПрдХ рдорд▓реНрдЯреАрдкреНрд▓реЗрдпрд░ рдЬреЛ рдХрд┐рд╕реА рднреА рдФрд╕рдд рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп js рдбреЗрд╡рд▓рдкрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдФрд░ рд╕реЙрдХреЗрдЯ.рдЖрдИрдУ рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдХреБрдЫ рд▓рд┐рдЦрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рд╡рд┐рдХрд╛рд╕ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдирд╛ред

рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЕрдЪреНрдЫреЗ рдкреБрд░рд╛рдиреЗ рдЯреИрдВрдХ рдЪреБрдирдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдирд╣реАрдВ рдЪреБрдирд╛, рд╣рдм рдкрд░ рдЙрд╕реЗ рджреВрд╕рд░рд╛ рд▓рд┐рдЦрдирд╛ рджреБрдЦрдж рд╣реЛрдЧрд╛ :)
рдореИрдВрдиреЗ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдФрд░ рдПрдХ рд╕рд░рд▓ рдЧреЗрдо рд▓реЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдореЗрд░реА рдкрд╕рдВрдж рдЯрд┐рдХ-рдЯреИрдХ-рдЯреЛ рдереА, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдХрд╛рдо рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд░реВрдк рд╕реЗ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдХреЗ рдХрд┐рд╕реА рднреА рдЖрдХрд╛рд░ рдФрд░ рдЬреАрддрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдереАред

рдФрд░ рдЗрд╕рд▓рд┐рдП, рдпрд╣ рддрдп рд╣реИ! рдореИрдВ рдЯрд┐рдХ-рдЯреИрдХ-рдЯреВ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рд╣рдо рднрд╡рд┐рд╖реНрдп рдХреЗ рдЦреЗрд▓ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╣рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП:


рдореИрдВрдиреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рд╡рд┐рдХрд╛рд╕ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдореИрдВрдиреЗ рдХреНрд░рдорд╢рдГ jQuery рдФрд░ jQueryUI рдврд╛рдВрдЪреЗ рдХреЛ рдЪреБрдирд╛ред

рдкреЗрдЬ рдмрдирд╛рдиреЗ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╢реИрд▓рд┐рдпреЛрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж, jqueryUI:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/vader/jquery-ui.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> 

рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реНрдерд┐рддрд┐ рдкрдЯреНрдЯреА, рд╕рд╛рдВрдЦреНрдпрд┐рдХреА рд╕рд╛рдЗрдбрдмрд╛рд░ рдФрд░ рдЧреЗрдо рдлрд╝реАрд▓реНрдб рдХреЛ рд╣реА рдмрдирд╛рддрд╛ рд╣реИ, рд╕рдм рдХреБрдЫ рд╕рд╛рдзрд╛рд░рдг рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
 <table border="0" width="100%"> <thead> <th colspan="2" id="status" class="ui-widget ui-state-hover ui-corner-all">  ...</th> </thead> <tbody> <td id="stats" class="ui-widget" valign="top"><br /><button id="reload"> </button><br /><br /></td> <td id="board" class="ui-widget" valign="top"><div id="masked" class="ui-widget-shadow ui-corner-all ui-widget-overlay"></div> <table class="ui-widget ui-corner-all" cellpadding="0" cellspacing="0" align="left" id="board-table"></table> </td> </tbody> </table> 


рдпрд╣рд╛рдВ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рд╕рдм рдХреБрдЫ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рдЕрдЧрд▓рд╛, рд╕реАрдПрд╕рдПрд╕ рдЬрд▓реНрджреА рд╕реЗ рд╕реНрдХреЗрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдФрд░ рдореИрдВрдиреЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред

рдореИрдВрдиреЗ рд╕рднреА рдХреЛрдб рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕рдлрд╛рдИ рд╕реЗ рдФрд░ рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдЗрд╕ рдЙрдореНрдореАрдж рдХреЗ рд╕рд╛рде рдХрд┐ рдпрд╣ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рд╕рд╛рдордЧреНрд░реА рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рдЕрдЪреНрдЫреА рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЫреЛрдЯреА рдЪреАрдЬреЛрдВ рдореЗрдВ рднреА :)

рдЦреЗрд▓ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛:
 var TicTacToe = { gameId: null, //      ID . turn: null, //    ,   X  O i: false, //   ,    init: function() { ... }, //         startGame: function (gameId, turn, x, y) { ... }, //         mask: function(state) { ... }, //    ,            :) move: function (id, turn, win) { ... }, //      endGame: function (turn, win) { ... } //  ,   } 


рдЕрдм рд╣рдо рдмрджрд▓реЗ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдЯрд┐рдкреНрдкрдгреА рдХреА рдЬрд╛рдПрдЧреА, рдФрд░ рдЗрд╕рд▓рд┐рдП Init ():
 $(function() { // UI    $('#reload').button({icons:{primary:'ui-icon-refresh'}}).click(function(){window.location.reload();}); //    nodejs  socket.io var socket = io.connect(window.location.hostname + ':1337', {resource: 'api'}); //   event' ()   socket.io //  socket.on('connect', function () { $('#status').html('    '); }); //  socket.on('reconnect', function () { $('#connect-status').html(',  '); }); //   socket.on('reconnecting', function () { $('#status').html('   , ...'); }); //  socket.on('error', function (e) { $('#status').html(': ' + (e ? e : ' ')); }); //        //   socket.on('wait', function(){ $('#status').append('...  ...'); }); //   socket.on('exit', function() { //           TicTacToe.endGame(TicTacToe.turn, 'exit'); }); //    ,   //  ID ,        xy socket.on('ready', function(gameId, turn, x, y) { $('#status').html('   !  ! ' + (turn == 'X' ? '   ' : '  ') + '!'); //        TicTacToe.startGame(gameId, turn, x, y); //     ,    :) $('#stats').append($('<div/>').attr('class', 'turn ui-state-hover ui-corner-all').html(' : <b>' + (turn=='X'?'':'') + '</b>')); //       ,   $("#board-table td").click(function (e) { //  ,      ID   ID  ,    XxY if(TicTacToe.i) socket.emit('step', TicTacToe.gameId, e.target.id); //        }).hover(function(){ $(this).toggleClass('ui-state-hover'); }, function(){ $(this).toggleClass('ui-state-hover'); }); }); //   socket.on('step', function(id, turn, win) { //  ID ,      . win          TicTacToe.move(id, turn, win); }); //  socket.on('stats', function (arr) { var stats = $('#stats'); stats.find('div').not('.turn').remove(); for(val in arr) { stats.prepend($('<div/>').attr('class', 'ui-state-hover ui-corner-all').html(arr[val])); } }); }); 


рдЕрдм рдЦреЗрд▓ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдкрд░ рдПрдХ рдХрд░реАрдм рд╕реЗ рджреЗрдЦреЛ:
 startGame: function (gameId, turn, x, y) { //  ID  this.gameId = gameId; //    this.turn = turn; //   ,  X        :) this.i = (turn == 'X'); //    var table = $('#board-table').empty(); //      for(var i = 1; i <= y; i++) { var tr = $('<tr/>'); for(var j = 0; j < x; j++) { //        ID  X  Y  (id="2x3") tr.append($('<td/>').attr('id', (j+1) + 'x' + i).addClass('ui-state-default').html(' ')); } table.append(tr); } //   $("#board").show(); //     ,   this.mask(!this.i); }, 


рдореИрдВ рдореБрдЦреМрдЯрд╛ рдХреЗ рдХрд╛рд░реНрдп рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдп рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдХрджрдо рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп:
 move: function (id, turn, win) { //  : ID    ,  ,     this.i = (turn != this.turn); //    $("#" + id).attr('class', 'ui-state-hover').html(turn); //     if (!win) { //   ,   this.mask(!this.i); //        $('#status').html(' ' + (this.i ? ' ' : ' ')); //   } else { this.endGame(turn, win); //    ,   } }, 


рдЦреЗрд▓ рдкреВрд░рд╛:
 endGame: function (turn, win) { //  :   ,    var text = ''; //     3  switch(win) { case 'none': text = '!'; break; //     case 'exit': text = '    !  '; break; //    default: text = ' ' + (this.i ? '! =(' : '! =)'); //   } //        $("<div/>").html(text).dialog({ title: ' ', modal: true, closeOnEscape: false, resizable: false, buttons: { "  ": function() { $(this).dialog("close"); window.location.reload(); }}, close: function() { window.location.reload(); } }); } 


рд╡рд╣ рд╕рдм рд╣реИ! рд╕рднреА рдмрдирд╛рдИ рдЧрдИ рдлрд╛рдЗрд▓реЗрдВ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдирд╛рдордХ рдПрдХ рдирдП рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдбрд╛рд▓ рджреА рдЬрд╛рддреА рд╣реИрдВред

рдХреНрдпрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдерд╛? рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ!


рдЖрд╡рд╢реНрдпрдХ рдореЙрдбреНрдпреВрд▓ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
 npm install express npm install socket.io 


рд╣рдо рд╢реБрд░реБрдЖрддреА рдлрд╝рд╛рдЗрд▓ index.js рдмрдирд╛рддреЗ рд╣реИрдВ, рдЕрдм рддрдХ рд╕рд░рд▓ рд╣реИ, рдЖрдЗрдП рдЗрд╕реЗ рд╕рдордЭреЗрдВ:
 //    var express = require('express'), socketio = require('socket.io'); //      express var app = express.createServer(); //        express  //      ,      var io = socketio.listen(app); //   express    app.use(express.static(__dirname + '/public')); //       app.listen(80); //     socket.io       3,     io.set('log level', 3); //     ,     /socket.io io.set('resource', '/api'); 


рдЕрдм рд╣рдо рдПрдХ рд╣реА рдмрд╛рдд рд▓рд┐рдЦрддреЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдмрд┐рдирд╛ рдФрд░ рд╕рд░рд▓ рд░реВрдк рдореЗрдВ, рдЗрд╕рд▓рд┐рдП рдХреНрд▓реАрдирд░:
 var express = require('express'), app = express.createServer(), io = require('socket.io').listen(app), TicTacToe = require('./models/tictactoe'); app.use(express.static(__dirname + '/public')); app.listen(1337); io.set('log level', 1); io.set('resource', '/api'); 


рдпрджрд┐ рдЖрдкрдиреЗ рдпрд╣рд╛рдБ рдзреНрдпрд╛рди рджрд┐рдпрд╛, рддреЛ рдореИрдВрдиреЗ рдПрдХ рдореЙрдбрд▓ рднреА рдЬреЛрдбрд╝рд╛
 TicTacToe = require('./models/tictactoe'); 

рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рд╣рдо рдЕрдм рд▓рд┐рдЦрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, index.js рдирд╛рдо рдХреЗ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рдПрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдПрдХ tictactoe.js рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ
рдпрд╣ рдиреЛрдбрдЬ рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдореЙрдбреНрдпреВрд▓ рд╣реИ рдФрд░ рдирд┐рд░реНрдпрд╛рдд рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╣ рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдХрд╛ рджрд┐рд▓ рд╣реЛрдЧрд╛, рд╕рднреА рддрд░реНрдХред

рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рдСрдирд▓рд╛рдЗрди рдЧреЗрдо рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╢реБрд░реВ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛, рдЧреЗрдо рдФрд░ рдЙрдирдХреЗ рд╕рдВрдЧреНрд░рд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдереАред

рдореБрдЦреНрдп рд╡рд╕реНрддреБрдПрдВ рдмрдирд╛рдПрдВ:
 //    ,  ,          var TicTacToe = module.exports = function() { //  id  =   this.games = []; //    = id  this.users = []; //        this.free = []; //   this.x = 6; this.y = 6; //    this.stepsToWin = 4; } //  ,       var GameItem = function(user, opponent, x, y, stepsToWin) { //        this.board[id  ] =   this.board = []; //  this.user = user; // X this.opponent = opponent; // O //   this.x = x; this.y = y; //    this.stepsToWin = stepsToWin; // -   this.steps = 0; } 


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдм рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ TicTacToe рдЧреЗрдо рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрдиреЗрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо TicTacToe рд╕рдВрдЧреНрд░рд╣ рдХреЗ рднреАрддрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд GameItem рдЧреЗрдо рдмрдирд╛рдПрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдХреМрди рдХрд┐рд╕рдХреЗ рд╕рд╛рде рдФрд░ рдХрд┐рди рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдЦреЗрд▓рддрд╛ рд╣реИред

рдЕрдм рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдЗрди рдмрд╣реБрдд рдЦреЗрд▓ рдмрдирд╛рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
 TicTacToe.prototype.start = function(user, cb) { //     -    //     Object.keys      if(Object.keys(this.free).length > 0) { //       ID var opponent = Object.keys(this.free).shift(); //      var game = new GameItem(user, opponent, this.x, this.y, this.stepsToWin); //   ID   ID  var id = user + opponent; //      this.games[id] = game; //       this.users[user] = id; //      this.users[opponent] = id; //  callback    cb(true, id, opponent, this.x, this.y); } else { //  ,    this.free[user] = true; //  callback    cb(false); } } 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рдореИрдВ рдкреВрд░реЗ рдЦреЗрд▓ рдореЗрдВ рд▓реЗрдЦрди рд╡рд┐рдзрд┐ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди (рдХреЙрд▓рдмреИрдХ) рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред

рдореИрдВ рдЬрд▓реНрджреА рд╕реЗ рдлрд┐рд░ рд╕реЗ рд╕рдордЭрд╛рдКрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдЕрднреА рддрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджрд░реНрдЬрдиреЛрдВ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдирд╣реАрдВ рдкрдврд╝рд╛ рд╣реИ :)

рддреЛ рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рд░реНрд╡рд░ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ рдФрд░ рдЧреЗрдо рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдЦреБрд╢реА рд╕реЗ рдЗрд╕рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ рдареАрдХ рд╣реИ, рдореИрдВ рдЖрдкрдХреЗ рдЧреЗрдо рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдХрд░рддрд╛ рд╣реВрдВ:
 1. -->    2. TicTacToe.start(); 3. <--   


рддреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪрд░рдг 1 рдХреЗ рдмрд╛рдж, рдЪрд░рдг 2 рдФрд░ 3 рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рдЕрд░реНрдерд╛рдд, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЧреЗрдо рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдЙрддреНрддрд░ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддрд░реНрдХ рдХреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдмрджрд▓рддреЗ рд╣реИрдВ:

 1. -->    2. TicTacToe.start(function(){ 3. <--   }); 


рдЕрдм, рдЪрд░рдг 1 рдХреЗ рдмрд╛рдж, рд╣рдо рдХреЗрд╡рд▓ рдЪрд░рдг 2 рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреЙрд▓рдмреИрдХ рдХреЗ рдмрд╛рдж рд╣реА рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░рдг 3 рдкрд░ рдЬрд╛рддрд╛ рд╣реИред

рд╡рд╛рдкрд╕ рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдПред рд╣рдордиреЗ рдЙрд╕реЗ рдЦреЗрд▓ рд╕реНрдерд╛рдиреЛрдВ рдХреА рдХрддрд╛рд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдЬреЛрдбрд╝реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдЦрд╛рдпрд╛ред

рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЦреЗрд▓ рдХреИрд╕реЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдЧрд╛:
 TicTacToe.prototype.end = function(user, cb) { //          delete this.free[user]; //      ,     if(this.users[user] === undefined) return; //  ID      var gameId = this.users[user]; //     ,  if(this.games[gameId] === undefined) return; //      ID var game = this.games[gameId]; //      var opponent = (user == game.user ? game.opponent : game.user); //    delete this.games[gameId]; //   game = null; //     delete this.users[user]; //  ID   ID     cb(gameId, opponent); } 


рдЕрдм рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВ, рдЯрд┐рдХ рдЯреАрдПрд╕реА рдХреЛ рдкреИрд░ рдХреА рдЕрдВрдЧреБрд▓реА рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИред

рдЗрд╕ рдмрд╛рд░ рд╣рдо рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХреЗрд╡рд▓ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рд╣реА рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЦреЗрд▓ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рднреА рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рд╣рдо рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рдПрдБрдЧреЗ:
 TicTacToe.prototype.step = function(gameId, x, y, user, cb) { //     proxy             this.games[gameId].step(x, y, user, cb); } GameItem.prototype.step = function(x, y, user, cb) { //        if(this.board[x + 'x' + y] !== undefined) return; //   X  Y    ,          this.board[x + 'x' + y] = this.getTurn(user); //     this.steps++; //            cb(this.checkWinner(x, y, this.getTurn(user)), this.getTurn(user)); } 

рдЖрдЗрдП рд░реБрдХреЗрдВ рдФрд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЗрд╕рдореЗрдВ рджреЛ рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рдХреЙрд▓ рд╣реИрдВ, рдпрд╣ .get (), рдпрд╣ рд╡рд╛рдкрд╕ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдХрд┐ рдХрд┐рд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдЗрд╕ рдореВрд╡ рдХреЛ рдЪрд▓рд╛рдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдпреВрдЬрд╝рд░ рдЖрдИрдбреА рдкрд╛рд╕ рдХрд░реЗрдВ, рдФрд░ рдпрд╣рд╛рдБ рдлрдВрдХреНрд╢рди рд╣реА рд╣реИ, рдЬрд┐рд╕реЗ рдЧреЗрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ:
 GameItem.prototype.getTurn = function(user) { return (user == this.user ? 'X' : 'O'); } 


рдпрд╣ рд╕рд░рд▓ рд╣реИ, рдЕрдЧрд░ рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реИ рдЬрд┐рд╕рдиреЗ рдЧреЗрдо рдмрдирд╛рдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╡рд╣ рдПрдХреНрд╕ рдЪрд▓рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдкреНрд░рддрд┐рджреНрд╡рдВрджреНрд╡реА рдУ рд╣реИред

рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рджреВрд╕рд░рд╛ рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рдЬреЗрддрд╛ рдЪреЗрдХ рд╣реИ:
 GameItem.prototype.checkWinner = function(x, y, turn) { //   ,      if(this.steps == (this.x * this.y)) { //  return 'none'; //    } else if( //      this.checkWinnerDynamic('-', x, y, turn) || this.checkWinnerDynamic('|', x, y, turn) || this.checkWinnerDynamic('\\', x , y, turn) || this.checkWinnerDynamic('/', x, y, turn) ) { //   return true; } else { //   return false; } } 


рд╣рдордиреЗ рдлрд┐рд░ рд╕реЗ рдЕрдкрдиреЗ рдЧреЗрдо рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝реАред рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╣рдо рдлрд┐рд░ рд╕реЗ рдХрджрдо рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рдХреНрдпрд╛ рдЧрдПред рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд┐рддрдиреА рдЪрд╛рд▓реЗрдВ рд╣реИрдВ, рдЗрд╕рдХреА рддреБрд░рдВрдд рдЬрд╛рдБрдЪ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХрд┐рддрдиреА рдЪрд╛рд▓реЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рдЗрд╕реЗ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЖрдпрд╛рдореЛрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдХреЗ рдЧрд┐рдиреЗрдВред

рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА рдореБрдлреНрдд рд╕реЗрд▓ рд╣реИрдВ, рддреЛ рдЦреЗрд▓ рдЕрднреА рдЦрддреНрдо рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, рд╢рд╛рдпрдж рдПрдХ рд╡рд┐рдЬреЗрддрд╛ рд╣реИред рд╡рд┐рдЬреЗрддрд╛ рдХреА рдЬрд╛рдБрдЪ рдкреВрд░реЗ рдЦреЗрд▓ рдореЗрдВ рд╕рдмрд╕реЗ рдХрдард┐рди рдХрд╛рд░реНрдп рд╣реИ, рд╣рдо рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рдиреАрдЪреЗ рд╕рдордЭреЗрдВрдЧреЗред рдпрджрд┐ рдХреЛрдИ рд╡рд┐рдЬреЗрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЭреВрдареЗ рд▓реМрдЯреЗрдВред

рдЕрдм рд╡рд┐рдЬреЗрддрд╛ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдЗрд╕рдХреЗ 4 рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ:
1 - рдЦреЛрдЬ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо, рдЗрд╕рдореЗрдВ рдорд╛рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ -,ред /, рдФрд░ \ (рд╣рд╛рдБ, рдПрдХ рдмреИрдХрд╕реНрд▓реИрд╢, рдХреНрдпреЛрдВрдХрд┐ рдЙрджреНрдзрд░рдг рдЪрд┐рд╣реНрди рдХреЛрдб рдореЗрдВ рдмрдЪ рдЧрдП рд╣реИрдВ) рдЖрдк рдЖрдЗрдХрди рд╕реЗ рдХреНрдпреЛрдВ рдкреВрдЫрддреЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдпреЗ рд╡реЗ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛рдПрдВ рд╣реИрдВ рдЬреЛ рдЖрдк рдЬрд╛рдБрдЪ рд░рд╣реЗ рд╣реИрдВ, рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЙрдиреНрд╣реЗрдВред
2,3 - рдЪрд╛рд▓ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ
4 - рдХреНрдпрд╛ рдЧрдпрд╛

рдЕрдм рдпрд╣ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдФрд░ рдЕрдиреВрдард╛ рдХрд╛рд░реНрдп рд╣реИ, рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЗрд╕реЗ рджреЗрдЦрдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВ рдФрд░ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рд▓рдЧрднрдЧ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рджрд┐рдЦрддрд╛ рд╣реИ, рдФрд░ рдХреЛрдб рдХреЗ рдмрд╛рдж рдХреНрдпрд╛ рдЕрдВрддрд░ рд╣реИ:
 GameItem.prototype.checkWinnerDynamic = function(a, x, y, turn) { //    4 : ,   2  //          ,,     4  var win = 1; switch(a) { //    case '-': var toLeft = toRight = true, min = x - this.stepsToWin, max = x + this.stepsToWin; min = (min < 1) ? 1 : min; max = (max > this.x) ? this.x : max; for(var i = 1; i <= this.stepsToWin; i++) { if(win >= this.stepsToWin) return true; if(!toLeft && !toRight) return false; if(toLeft && min <= (xi) && this.board[(xi) + 'x' + y] == turn) { win++; } else { toLeft = false; } if(toRight && (x+i) <= max && this.board[(x+i) + 'x' + y] == turn) { win++; } else { toRight = false; } } break; //    case '|': var toUp = toDown = true, min = y - this.stepsToWin, max = y + this.stepsToWin; min = (min < 1) ? 1 : min; max = (max > this.y) ? this.y : max; for(var i = 1; i <= this.stepsToWin; i++) { if(win >= this.stepsToWin) return true; if(!toUp && !toDown) return false; if(toUp && min <= (yi) && this.board[x + 'x' + (yi)] == turn) { win++; } else { toUp = false; } if(toDown && (y+i) <= max && this.board[x + 'x' + (y+i)] == turn) { win++; } else { toDown = false; } } break; //      case '\\': var toUpLeft = toDownRight = true, minX = x - this.stepsToWin, maxX = x + this.stepsToWin, minY = y - this.stepsToWin, maxY = y + this.stepsToWin; minX = (minX < 1) ? 1 : minX; maxX = (maxX > this.x) ? this.x : maxX; minY = (minY < 1) ? 1 : minY; maxY = (maxY > this.y) ? this.y : maxY; for(var i = 1; i <= this.stepsToWin; i++) { if(win >= this.stepsToWin) return true; if(!toUpLeft && !toDownRight) return false; if(toUpLeft && minX <= (xi) && minY <= (yi) && this.board[(xi) + 'x' + (yi)] == turn) { win++; } else { toUpLeft = false; } if(toDownRight && (x+i) <= maxX && (y+i) <= maxY && this.board[(x+i) + 'x' + (y+i)] == turn) { win++; } else { toDownRight = false; } } break; //      case '/': var toDownLeft = toUpRight = true, minX = x - this.stepsToWin, maxX = x + this.stepsToWin, minY = y - this.stepsToWin, maxY = y + this.stepsToWin; minX = (minX < 1) ? 1 : minX; maxX = (maxX > this.x) ? this.x : maxX; minY = (minY < 1) ? 1 : minY; maxY = (maxY > this.y) ? this.y : maxY; for(var i = 1; i <= this.stepsToWin; i++) { if(win >= this.stepsToWin) return true; if(!toDownLeft && !toUpRight) return false; if(toDownLeft && minX <= (xi) && (y+i) <= maxY && this.board[(xi) + 'x' + (y+i)] == turn) { win++; } else { toDownLeft = false; } if(toUpRight && (x+i) <= maxX && (yi) <= maxY && this.board[(x+i) + 'x' + (yi)] == turn) { win++; } else { toUpRight = false; } } break; default: return false; break; } return(win >= this.stepsToWin); } 


algorithmization


рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓рд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рдЕрд▓рдЧ рдЬрд╛рдВрдЪ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрди рд╕рднреА рдореЗрдВ рдПрдХ рдЪреАрдЬ рд╕рдорд╛рди рд╣реИ, рдпрд╣ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рд╕реЗ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдмрджрд▓рд╛рд╡ рд╣реИ рдФрд░ рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдореВрд▓реНрдп рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рд╣реИред
рдЪреВрдВрдХрд┐ рдореИрдВ рд╢реБрд░реВ рдореЗрдВ рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЦреЗрд▓ рдореЗрдВ рдХрд┐рд╕реА рднреА рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЖрдХрд╛рд░, рд╕рд╛рде рд╣реА рдЬреАрддрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрджрдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдВрдЪ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:



рд╣рдордиреЗ рдЕрдкрдиреЗ рдЦреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИред рд╕рднреА рдХрд╛рд░реНрдп рддреИрдпрд╛рд░ рд╣реИрдВ! рдЕрдм рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рд╣реИрдВрдбрд▓рд░ рд▓рдЯрдХрд╛рдПрдВрдЧреЗ рдФрд░ рдпрд╣ рд╕рдм рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗред

рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдореБрдЦреНрдп рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖрддреЗ рд╣реИрдВред рдЬреЗрдПрд╕, рд╣рдо рд╕реЙрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред рдЗрд╕рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЦреЗрд▓ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдЪрд░ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
 //    ,      ,        var countGames = onlinePlayers = onlineGames = 0, countPlayers = [], Game = new TicTacToe(); //   ,         Game.x = Game.y = 6; // Default: 6 //  -      Game.stepsToWin = 4; // Default: 4 //         io.sockets.on('connection', function (socket) { //          ID  IP  console.log('%s: %s - connected', socket.id.toString(), socket.handshake.address.address); //       stats       io.sockets.emit('stats', [ ' : ' + countGames, ' : ' + Object.keys(countPlayers).length, ' : ' + onlineGames, ' : ' + onlinePlayers ]); //       5 ,    setInterval(function() { io.sockets.emit('stats', [ ' : ' + countGames, ' : ' + Object.keys(countPlayers).length, ' : ' + onlineGames, ' : ' + onlinePlayers ]); }, 5000); //    ,  ID     ID   md5  Game.start(socket.id.toString(), function(start, gameId, opponent, x, y){ //  callback'       ,      //       ,       null if(start) { //        ID  ID  //      socket.io socket.join(gameId); //   ()        io.sockets.socket(opponent).join(gameId); //          socket.emit('ready', gameId, 'X', x, y); //     io.sockets.socket(opponent).emit('ready', gameId, 'O', x, y); //          countGames++; onlineGames++; } else { //  ,      io.sockets.socket(socket.id).emit('wait'); } //        ip     if(countPlayers[socket.handshake.address.address] == undefined) countPlayers[socket.handshake.address.address] = true; //     onlinePlayers++; }); //     socket.on('step', function (gameId, id) { //   ID   XxY var coordinates = id.split('x'); //       ,   proxy        Game.step(gameId, parseInt(coordinates[0]), parseInt(coordinates[1]), socket.id.toString(), function(win, turn) { //     ,  ,             //       in()        io.sockets.in(gameId).emit('step', id, turn, win); //      if(win) { //      ,     Game.end(socket.id.toString(), function(gameId, opponent) { //          socket.leave(gameId); //     io.sockets.socket(opponent).leave(gameId); }); } }); }); //             socket.on('disconnect', function () { //     ,      //       ,   Game.end(socket.id.toString(), function(gameId, opponent) { //     ,    Game.end       , ID  io.sockets.socket(opponent).emit('exit'); //     socket.leave(gameId); //     io.sockets.socket(opponent).leave(gameId); //     onlineGames--; }); //    onlinePlayers--; //      console.log('%s: %s - disconnected', socket.id.toString(), socket.handshake.address.address); }); }); 


рд╣рдордиреЗ рдЕрдкрдирд╛ рдЦреЗрд▓ рд▓рд┐рдЦрдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ! рд╣рдо NodeJS рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рдЧрдП, рдпрд╛рдж рдЖрдпрд╛ рдХрд┐ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреНрдпрд╛ рдерд╛, рдХрд╛рдо рдореЗрдВ рд╕реЙрдХреЗрдЯ.рдЖрдИрдУ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдФрд░ рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдХреА рдПрдХ рдЭрд▓рдХ рднреА рдкрдХрдбрд╝реАред

рдЕрдм рдЖрдк рдЦреЗрд▓ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ "рдирдпрд╛ рдЦреЗрд▓" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
ivan.zhuravlev.name/game - 6x6 рдлрд╝реАрд▓реНрдб 4 рдЪрд╛рд▓ рдХреЗ рд╕рд╛рде рдЬреАрддрдиреЗ рдХреЗ рд▓рд┐рдП
ivan.zhuravlev.name/game3 - 3x3 рдлрд╝реАрд▓реНрдб 3 рдЪрд╛рд▓реЛрдВ рд╕реЗ рдЬреАрддреЗрдВ
рд╕реНрд░реЛрдд рджреЗрдЦреЗрдВ: github .com / intech / TicTacToe
рдореИрдВрдиреЗ рд╣рдмреНрд░ рдЗрдлреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛, рд╕реНрдЯреЗрдЯрд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдХреНрд╕реА рдирдЧреНрдиреЗрдХреНрд╕ рд▓рдЧрд╛рдпрд╛, рд╡реЗрдмрд╕реЛрдХреЗрдЯ рдПрдХ рдЕрд▓рдЧ рдкреЛрд░реНрдЯ 1337 рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЧрд┐рд░реЗрдЧрд╛, рд╕рдм рдХреБрдЫ рд╕рд┐рд▓реЗрдХреНрдЯреЗрдб рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╣реИ, рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдкрд░ 8 рдХреЛрд░ 1GB RAM рдХреЗ рд╕рдВрд╕рд╛рдзрди рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП рдЕрдЧрд░ рдореИрдВ рдмрдврд╝рд╛рдКрдВред :)
- рд╕рднреА рд╡рд┐рдХрд╛рд╕ рдФрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдореЗрдВ рд▓рдЧ рдЧрдП: 12 рдШрдВрдЯреЗ 22 рдорд┐рдирдЯред
рдХреБрд▓ рд╕рдордп рдмреАрдд рдЪреБрдХрд╛ рд╣реИ: 3 рджрд┐рди, рдЪреМрдереЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛

рдЖрдВрдХрдбрд╝реЗ


рдкреНрд░реЛрд╕реЗрд╕рд░

рд╕реНрдореГрддрд┐

рдореИрдВ рдЧреВрдЧрд▓ рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕ рдХреЛ рджреЗрдЦрддрд╛ рд╣реВрдВ рдФрд░ рдПрдХ рдЕрдиреНрдп рдореЙрдирд┐рдЯрд░ рдкрд░ рдореЗрд░реЗ рдкрд╛рд╕ рд╕рд░реНрд╡рд░ рдХрд╛ рд╕рд╛рд░рд╛ рдбреЗрдЯрд╛ рдЦреБрд▓рд╛ рд╣реИред
рдФрд╕рддрди, 30 рд╕реЗ 50 рд▓реЛрдЧ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдСрдирд▓рд╛рдЗрди рд╣реИрдВ, рд╕рд░реНрд╡рд░ рдкрд░ рд▓реЛрдб рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ, рдмрд╣реБрдд рдЫреЛрдЯреЗ рдХреВрдж рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЗрд╕реЗ рд▓реЛрдб рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдЫреЛрдЯреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/In132544/


All Articles