Опубликовано Оставить комментарий

Крестики-нолики

Игра крестики-нолики
Игра крестики-нолики

Крестики-нолики — логическая игра между двумя участниками на поле размером 3 на 3 клетки или бо́льшего размера. Один из участников использует «крестики», второй — «нолики». Игроки делают поочередно ходы на свободных клетках поля размером три на три. Выигрывает игрок, который первый выстроил в ряд (горизонтально, вертикально или по диагонали) три крестика или три нолика. После выстраивания трех знаком подряд, они перечеркиваются — игра завершается.

Вы выиграли!


х

Выиграл компьютер

Крестики-нолики

Для написания игры Крестики-нолики на JavaScript понадобилась HTML-разметка, содержащая общий контейнер, ему дан не красивый, но уникальный 🙂 идентификатор, игровое поле — контейнер с CSS-классом game (отдельные клетки реализованы гиперссылками) и два контейнера-окна с уведомлением о победе игрока или браузера.

<div id="game-krestiki-noliki">
    <div class="game">
        <a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a><a href="#" class="item"></a>
    </div>
        <div class="win">
         <h2>Вы выиграли!</h2>
         <div class="intro">
           <script type="text/javascript" src="http://yastatic.net/es5-shims/0.0.2/es5-shims.min.js" charset="utf-8"></script>
<script type="text/javascript" src="http://yastatic.net/share2/share.js" charset="utf-8"></script>
<div class="ya-share2" data-services="vkontakte,facebook,gplus,twitter,odnoklassniki" data-size="s"></div>
           <a href="#" class="close">х</a>
         </div>
        </div>
        <div class="lost">
         <h2>Выиграл компьютер</h2>
         <div class="intro">
           <a href="#" class="next">Еще</a>       
           <a href="#" class="close">х</a>
        </div>
</div>
</div>

Можно было спрятать окна и отдельные игровые поля в JS, создавая структуру на лету, но было принято решение не перенасыщать игру скриптами. Хотя для большей гибкости задействованы возможности JavaScript-библиотеки — jQuery.

	#game-krestiki-noliki{
	  position: relative;
	  width: 235px;
	  font: 1em Arial,sans-serif;
  	  float: left;
  	  margin-right:40px
	}
	#game-krestiki-noliki .game{
	 width: 175px;
	 height: 175px;
	 box-shadow: 0 0 3px #999;
	 padding: 0 30px;
	 background: #eee;
	 border-radius: 1px;
	}
	#game-krestiki-noliki .game .item,#game-krestiki-noliki .game span{
	 width: 58px;
	 height: 58px;
	 outline: 1px solid #ccc;
	 float: left;
	 text-align: center;
	 line-height: 58px;	 
	 background: #fff;
	 text-decoration: none;
	 font-size:2em;
	 color: #777;
	 text-shadow: 1px 1px 2px #999;
	}
	#game-krestiki-noliki .win,#game-krestiki-noliki .lost{
	 position: absolute;
	 width: 90%;
	 height: 120px;
	 top:0;
	 left:0;
	 right:0;
	 bottom:0;
	 margin: auto;
	 background-color: rgba(250,250,250,.6);
	 box-shadow: 0 0 3px #999;
	 border-radius: 2px;
	 display: none
	}

	#game-krestiki-noliki .win h2,#game-krestiki-noliki .lost h2{
	 text-align: center;
	 color: #777;
	}
	#game-krestiki-noliki .intro{
	 text-align: center;
	}
	#game-krestiki-noliki .intro a.next{
	 font: 0.8em Arial,sans-serif;
	 text-decoration: none;
	 color: #eee;
	 text-shadow: 1px 1px 1px #000;
	 background-color: #60B355;
	 border-radius: 2px;
	 padding: 4px 10px;
	 margin-bottom: 10px;
	}
	 #game-krestiki-noliki a.close{
	 position: absolute;
	 right: 2px;
	 top: 2px;
	 padding: 2px 8px;	 
	 background-color: #eee;
	 text-shadow: 0px 0px 1px #fff;
	 font: .8em Arial,sans-serif;
	 text-decoration: none;
	}
	#game-krestiki-noliki a.close:hover{
	 background-color: #dEdEdE;
	 text-shadow: 0px 0px 2px #fff;
	}

JavaScript код игры Крестики-нолики


jQuery(function(){
 $ = $ || jQuery;
 var a = $(".game .item");
 var fields; //массив исходных позиций
 var firstStep; //случайный первых ход компьютера

 $("#game-krestiki-noliki div .next,#game-krestiki-noliki div .close").on("click",function (e){
  a.off("click",clickGamer);
  e.preventDefault();
  $(this).parents(".window").hide();
  init();
 });

function init(){
 fields = [0,0,0,0,0,0,0,0,0];
 firstStep = rand(0,fields.length-1);
 //инициализация массива исходных ходов
 fields[firstStep] = 1;
 a.on("click",clickGamer);
 //расставляем начальную позицию
 a.each(function(i,e){
 $(e).html( symbol(fields[i]) );
 });
}

function clickGamer(e){
 var self = this, num;
 e.preventDefault();
 //отключаем обработчик нажатия
 $(this).off("click",clickGamer);
 //выводим символ игрока - "o"
 $(this).html(symbol(2));
 //узнаем по какой ссылке нажали: номер ссылки помещаем в num
 a.each(function(i,e){
  if( self == e ) {
   num = i;
   fields[i] = 2;
  }
 });
//выполняем ход компьютера
clickComp(fields);
if ( checkWin(fields,2) ) {
  $("#game-krestiki-noliki .win").show();
} else
if ( checkWin(fields,1) ) {
  $("#game-krestiki-noliki .lost").show();
} else if ( checkFullStep(fields) == 0 )
  init();
}

function clickComp(fields){
 var steps = getStep(fields);
 var step = steps[rand(0, steps.length-1)];
 console.log("Шаг компа: "+step);
 fields[step] = 1;
 //узнаем по какой ссылке нажали: номер ссылки помещаем в num
 a.each(function(i,e){
 if( i == step ) {
  $(e).off("click",clickGamer);
  $(e).html(symbol(1));
 }
});
}

function checkWin(fields, sym){
 var flag = true, tmp = [], sum = 0;
 //приобразуем линейный массив в двумерный для упрощения пробега
 for(var i = 0; i < 3; i++){
  tmp[i] = [];
  for(var j = 0; j < 3; j++){
   tmp[i][j] = fields[i*3+j];
  }
 }
 //пробегаем по горизонтали
 for(var i = 0; i < 3; i++){
  flag = true;
   for(var j = 0; j < 3; j++){
    if( tmp[i][j] != sym )
     flag = false;
   }
  if( flag ) return true;
}

//пробегаем по вертикали
for(var i = 0; i < 3; i++){
 flag = true;
 for(var j = 0; j < 3; j++){
  if( tmp[j][i] != sym )
   flag = false;
  }
 if( flag ) return true;
}

//пробегаем по диагоналям
if(
 tmp[0][0] == sym &&
 tmp[1][1] == sym &&
 tmp[2][2] == sym ||
 tmp[0][2] == sym &&
 tmp[1][1] == sym &&
 tmp[2][0] == sym
) return true;
}

function checkFullStep(arr){
 return arr.join("").split(0).length - 1;
}

init();

});

//возвращает случайное целое значение из диапазона
function rand(n,m){
 return Math.round(Math.random()*(m-n)+n);
}

//функция выбирающая символы для показа
function symbol(input){
 switch( input ){
  case 0: return "";
  case 1: return "×";
  case 2: return "o";
 }
}

//возвращает массив доступных для ходов полей
function getStep(arr){
 var tmp = [],p;
 for( p in arr ){
  if ( !arr[p] )
  tmp.push(p);
 }
return tmp;
}

//клонирование массива
function arrayClone(arr){
 var tmp = [];
 for(var p in arr)
  tmp[p] = arr[p];
  return tmp;
 }
Добавить комментарий