БлогNot. Играем в Бандеры :)

Играем в Бандеры :)

Писал эту "игру" трижды по несколько минут на стареньком компьютере, бывшем "под рукой" в отпуске, хотелось сделать что-то с цветными клетками, решаемое только кликами по этим клеткам :-)

Идея состоит в том, что на квадратном поле размещены цветные поля, щёлкая по которым можно менять картину распределения цветов.

Цвета из массива colors по кругу "вытесняют" друг друга, как и играх инь-ян-хрень "камень-ножницы-бумага" или "воздух, земля, огонь и вода".

То есть, если имеются белые, красные и чёрные клетки, то щелчок по белой клетке делает её красной (красный цвет сильнее белого), красная становится чёрной, а чёрная - снова белой.

Подобрав правила изменения цветов соседних клеток в зависимости от цвета клетки, по которой выполнен щелчок, можно получить любое количество различных между собой игр.

В моём варианте клетка, по которой мы щёлкаем, получает следующий по списку цвет (функция next), а соседние клетки того же цвета (соседними считаются все 8 прилегающих клеток, игровое поле замкнуто на тор) "уменьшают" свой цвет (функции neigthbour и prev).

Название менялось от "Пиздрики" и "Белое, красное, чёрное" до "Бандеры", последнее кажется мне удачным, коль скоро цель игры - избавиться от красных и чёрных клеток, оставив только белые. Число очков начисляется обратно пропорционально числу потраченных кликов и не может превышать значения size*size.

Исходный текст и скрипт в работе:

 файл с игрой в формате HTML (4 Кб)

файл empty.gif для заполнения полей, 1 на 1 пиксел прозрачного фона
файл empty.gif для заполнения полей, 1 на 1 пиксел прозрачного фона

 Играть в Бандеры

<script type="text/javascript">
 var e=new Image(); e.src="empty.gif";
 var size=10; //размер поля
 var itemPx=32; //размер клетки в пикселах
 var colors=new Array ('white','red','black'); //массив цветов
 var cols=colors.length;
 var f=new Array(size); //игровое поле
 for (i=0; i<size; i++) f[i]=new Array(size);
 var begin=1; //метка обновления поля
 var step=0; //номер хода

 document.writeln ('<table align="center" width="'+(itemPx*size)+'" height="'+(itemPx*size)+
  '" cellpadding="1" cellspacing="0" border="1" style="border-color: #999999;border-style: solid;">');
 for (i=0; i<size; i++) { //отрисовка поля
  document.writeln ('<tr>');
  for (j=0; j<size; j++)
   document.writeln 
    ('<td><a href="javascript:click('+i+','+j+')"><img src="empty.gif" width="'+itemPx+
    '" height="'+itemPx+'" border="0" id="#'+i+'#'+j+'"></a></td>');
  document.writeln ('</tr>');
 }
 document.writeln ('</table><div align="center" id="score"></div>');

 function rand(n) { //Случайное целое число [0;n-1]
  return Math.floor(Math.random()*n);
 }

 function help () {
  window.alert ('Игра Бандеры. Правила:\n'+
   'Как можно быстрее избавьтесь от красных и чёрных,\nоставьте только белых');
 }

 function start() { //Начало игры
  document.getElementById('score').innerHTML = 
   'Кликните по любому полю; F5 - заново; <a href="javascript:help()">Правила</a>';
  for (i=0; i<size; i++)
  for (j=0; j<size; j++) {
   f[i][j]=colors[rand(cols)];
   document.getElementById('#'+i+'#'+j).style.backgroundColor = f[i][j];
  }
  step=begin=0;
 }

 function end() { //Конец игры
  g=f[0][0];
  i=0; j=1;
  while (1) {
   if (f[i][j]!=g) return 0;
   if (j<size-1) j++;
   else {
    if (i<size-1) { j=0; i++; }
    else break;
   }
  }
  return 1;
 } 

 function next (col) {
  index=-1;
  for (i=0; i<cols; i++) if (colors[i]==col) {
   index=(i<cols-1?i+1:0);
  }
  return colors[index];
 }

 function prev (col) {
  index=-1;
  for (i=cols-1; i>-1; i--) if (colors[i]==col) {
   index=(i>0?i-1:cols-1);
  }
  return colors[index];
 }

 function neigthbour (r,c,color) {
  if (r<0) r=size-1; else if (r>size-1) r=0;
  if (c<0) c=size-1; else if (c>size-1) c=0;
  if (f[r][c]==color) {
   f[r][c]=prev(f[r][c]);
   document.getElementById('#'+r+'#'+c).style.backgroundColor = f[r][c];
  }
 }

 function click (i,j) { //Клик по клетке i,j
  if (begin) { start(); return; }
  step++; 
  document.getElementById('score').innerHTML = 'Играем. Клик '+step;
  oldColor = f[i][j];
  newColor = next (f[i][j]);
  f[i][j] = newColor;
  document.getElementById('#'+i+'#'+j).style.backgroundColor = f[i][j];
  neigthbour (i-1,j-1,oldColor);
  neigthbour (i-1,j,oldColor);
  neigthbour (i-1,j+1,oldColor);
  neigthbour (i,j-1,oldColor);
  neigthbour (i,j+1,oldColor);
  neigthbour (i+1,j-1,oldColor);
  neigthbour (i+1,j,oldColor);
  neigthbour (i+1,j+1,oldColor);
  if (end()) {
   document.getElementById('score').innerHTML = 
    'Игра окончена, результат '+cnt()+', рекорд '+cntmax();
   begin=1;
  }
 }

 var count=0, maxcount=0;
 function cnt() {
  if (step>size*size) count=0;
  else count=size*size-step;
  return count;
 }
 function cntmax() { 
  if (count>maxcount) maxcount=count;
  return maxcount;
 }

 if (begin) start();
</script>
<noscript>
 <div align="center">Извините, для работы приложения нужен включённый Javascript</div>
</noscript>

Изначально предполагалось, что цветов будет гораздо больше, например:

var colors=new Array ('white','yellow','green','orange','red',
 'blue','navy','magenta','black');

или

var colors=new Array ('FFFFFF','FFE0E0','FFC0C0','FFA0A0',
 'FF8080','FF6060','FF4040','FF2020','FF0000');

а игровое поле будет маленьким, 3x3 клетки:

var size=3; //размер поля

В таком варианте, помнится, осмысленной показалось игра, в которой клик на клетке пусть давал ей случайный новый цвет, больший текущего:

function findIndex (col) {
 res=-1;
 for (k=0; k<cols; k++) if (col==colors[k]) { res = k; break; }
 return res;
}
//...
oldColorIndex = findIndex(oldColor);
if (oldColorIndex==cols-1) newColor = colors[0];
else newColor = colors[oldColorIndex+rand(cols-oldColorIndex)];

...а цвета соседей, меньшие нового цвета клетки, уменьшались на 1. Правда, в этом случае и стратегия игры оказывается простейшей - щелкать по цвету, клеток с которым меньше всего. По крайней мере, на поле 3x3, для которого все клетки - соседи.

Полезные функции на Javascript из решения:

  • rand(n) - вернёт случайное целое число из диапазона [0;n-1]
  • end() - вернёт 1, если все элементы матрицы f[size][size] совпадают, в противном случае 0
  • next(col) - для элемента col вернёт следующий элемент из кольцевого списка colors размерности cols
  • prev(col) - для элемента col вернёт предыдущий элемент из кольцевого списка colors размерности cols

Кстати:

получить случайное целое число в диапазоне [min,max] на Javascript можно так:

  function getRandomInt(min, max) {
   return Math.floor(Math.random() * (max - min + 1)) + min;
  }

28.08.2014, 15:15 [10032 просмотра]


теги: javascript игра цвет

К этой статье пока нет комментариев, Ваш будет первым