
Крестики-нолики — логическая игра между двумя участниками на поле размером 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;
}