Skip to content
ahmadialireza220-wq edited this page Sep 12, 2025 · 1 revision

const bgColor = ['sienna', 'burlywood'], plrColor = ['' ,'wheat', '#500000'], visibility = { true : 'visible', false : 'hidden' }

let fields = [] //Фишки: кол-во, цвет, возможность хода map = [], mapC = [], mapP = [], dice = [], story = [], //История хода home = [], homeP = [], homeCans = []

let plr = 2, sel = 0

//Заготовка точек let dots = [] dots[0] = [] dots[1] = 0.5, 0.5;var home = [], homeP = [] var homeCans = [] dots[2] = 0.2, 0.8], [0.8, 0.2 dots[3] = 0.5, 0.5], [0.25, 0.75], [0.75, 0.25 dots[4] = 0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75 dots[5] = 0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75], [0.5, 0.5 dots[6] = 0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75], [0.5, 0.25], [0.5, 0.75

let dropBtn = document.getElementById('drop'), dBStyle = dropBtn.style, $home1 = document.getElementById('home1'), $home2 = document.getElementById('home2'), $top = document.querySelector('.top'), $bottom = document.querySelector('.bottom');

function newElem(s) { return document.createElement(s) }

//Единица поля class Field { constructor(i) { let td = newElem('td') td.id = i td.onclick = function(event) { select(i) } if (i < 13) { $top.appendChild(td) } else { $bottom.appendChild(td) } let can = newElem('canvas') td.appendChild(can)

this.td = td
this.can = can
this.index = i

}

redraw() { draw(this.index, this.can, map[this.index], mapC[this.index]) this.td.classList.remove('selected', 'possible1', 'possible2', 'possible3', 'possible4') if (deep(mapP[this.index])) { this.td.classList.add('possible' + deep(mapP[this.index])) } } }

/Генерация поля!/ function generateHtml() { for (let i = 12, j = 13; i > 0; i--, j++) { fields[i] = new Field(i) //top fields[j] = new Field(j) //bottom //Перегородка if (i == 7) { let el = newElem('td') el.setAttribute('rowspan', 2) el.classList.add('dark') el.style = "border: 1px solid" $top.appendChild(el) } }

//Создание canvas'ов homeCans[1] = newElem('canvas'); $home1.appendChild(homeCans[1]);

homeCans[2] = newElem('canvas'); $home2.appendChild(homeCans[2]); } generateHtml();

window.onresize = function(event) { refresh(); };

//Новая игра function newGame() { for (let i = 1; i < 25; i++) { map[i] = 0 mapC[i] = 0 mapP[i] = [0, 0, 0, 0, 0] //Возможность каждого кубика (1, 2, 3, 4) } map[1] = 15 mapC[1] = 1 map[13] = 15 mapC[13] = 2 dice = [0, 0, 0, 0, 0]

story[0] = 1; //Индекс пустого значения for (let i = 1; i < 5; i++){ story[i] = [0, 0] }

home[1] = -1 //0 = в домике home[2] = -1 homeP[1] = [0, 0, 0, 0, 0] homeP[2] = [0, 0, 0, 0, 0] }

/Перерисовка/ function refresh() { drawField(); drawDice(); drawDrop(); checkWin(); }

/Победа!/ function checkWin() { if (home[plr] == 15){ alert('Победа Игрока' + plr); } }

/Отображение кнопки Броска/ function drawDrop() { //Цвет кости dBStyle.backgroundColor = plrColor[plr % 2 + 1]; dBStyle.visibility = visibility[!deep(dice)]; }

/Отображение кубиков/ function drawDice() { for (let i = 1; i < 5; i++){

canvas = document.querySelector('#dice' + i + ' canvas');

//Рисунок на кости
w = document.body.clientWidth * 0.07;
canvas.width = w;
canvas.height = w;

let dc = document.querySelector('#dice' + i);
dc.style.visibility = visibility[Boolean(dice[i])]

if (dice[i]) {

  var ctx = canvas.getContext("2d");
  ctx.fillStyle = plrColor[plr % 2 + 1];
  for (let d = 0; d < dice[i]; d++){
    var dot = dots[dice[i]][d];
    drawTrick (ctx, dot[0] * w, dot[1] * w, w / 10);
  }
  
  //Цвет кости
  if (plr == 1) {
    dc.classList.remove("black");
    dc.classList.add("white");
  } else {
    dc.classList.remove("white");
    dc.classList.add("black");
  }
}

} }

/Отрисовка поля/ function drawField() { for (let i = 1; i < 25; i++) { fields[i].redraw(); }

var el = document.getElementById('home' + plr) el.classList.remove('selected', 'possible1', 'possible2', 'possible3', 'possible4'); if (deep(homeP[plr])) { el.classList.add('possible' + deep(homeP[plr])); }

draw(0, homeCans[1], home[1], 1); draw(0, homeCans[2], home[2], 2); //Выделенный элемент if (sel) { document.getElementById(sel).classList.add('selected'); } }

/Отображение глубины хода/ function drawDeepHome() { if (home[plr] >= 0) { var elField = document.querySelector('#home' + plr); elField.classList.remove('possible1', 'possible2', 'possible3', 'possible4'); if (deep(homeP[plr])) { elField.classList.add('possible' + deep(homeP[plr])); } } }

/Отрисовка канвы/ function draw(i, canvas, count, colorN){ var w = document.body.clientWidth / 15; var h = document.body.clientHeight * 13 / 30; if (i == 0) h *= 2; canvas.width = w; canvas.height = h;

var kX = (((h - w) / 15) + ((16 * w - h) / 15) * (1 - (count / 15))**3); var ctx = canvas.getContext("2d");

//Цвет фона if (i) { ctx.fillStyle = bgColor[0]; if (i % 2 == 1) { ctx.fillStyle = bgColor[1]; } drawTriangle(ctx, w, h); }

if (count) { ctx.fillStyle = plrColor[colorN]; for (let k = 0; k < count; k++){ drawTrick(ctx, w / 2, k * kX + (w / 2), w / 2 - 2); }

  //Подпись количества
  ctx.fillStyle = plrColor[colorN % 2 + 1];
  drawCount(ctx, w / 2 - ('' + count).length * 10, (count - 1) * kX + (w / 2) + 10, count);

}
}

/Треугольник/ function drawTriangle (ctx, w, h) { ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(w / 2, h); ctx.lineTo(w, 0); ctx.fill(); ctx.closePath(); ctx.stroke(); }

/Фишка/ function drawTrick (ctx, x, y, r) { ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2, false); ctx.fill() ctx.closePath(); ctx.stroke(); }

function drawCount(ctx, x, y, count) { ctx.beginPath(); ctx.font = "italic 20pt Arial"; ctx.fillText(count, x, y); ctx.closePath(); ctx.stroke(); }

/Клик/ function select(id) { if (deep(dice) == 0) { return 0 }; id = Number(id); //Выбор хода if (deep(mapP[id])) { move(sel, id); return; }

//Выбор позиции if ((sel != id) && (selectAbility(id))) { clearPossibility(); sel = id; //Проверка возможных ходов var x = [0, dice[1], dice[2], dice[3], dice[4]]; trace(x, sel); } else clearPossibility(); refresh(); }

/Очистка массивов возможностей/ function clearPossibility() { for (let i = 1; i < 25; i++) { mapP[i] = [0, 0, 0, 0, 0]; if (map[i] == 0) {mapC[i] = 0}; } homeP[1] = [0, 0, 0, 0, 0]; homeP[2] = [0, 0, 0, 0, 0]; sel = 0; }

/Возможность выбора клетки/ function selectAbility(i) { if ((map[i] == 0) || (mapC[i] != plr) || (sel == i)) { return 0; } if (i == (plr - 1) * 12 + 1) for (let j = 1; j < story[0]; j++) { if (story[j][0] == i) { return 0; } } return 1; }

/Определение глубины клетки/ function deep(map){ return (map[1] + map[2] + map[3] + map[4]) }

/Ход/ function move(from, to) {

mapC[to] = plr; map[to]++; map[from]--;

story[story[0]++] = [from, to];

//Обнуление кубика, запись хода в историю for (let i = 1; i < 5; i++){ dice[i] = dice[i] * (1 - mapP[to][i]); } //Сброс выделения clearPossibility();

refresh(); fullAbility(); }

/Ход в дом/ function moveHome() { if (deep(homeP[plr]) == 0) return;

home[plr]++; map[sel]--;

story[story[0]++] = [sel, 0];

//Обнуление кубика, запись хода в историю for (let i = 1; i < 5; i++){ dice[i] = dice[i] * (1 - homeP[plr][i]); } //Сброс выделения clearPossibility(); refresh(); fullAbility(); }

/Бросок/ function drop(){ dice[1] = 1 + Math.floor(Math.random() * 6); dice[2] = 6 - Math.floor(Math.random() * 6); //Дубль if (dice[1] == dice[2]){ dice[3] = dice[1]; dice[4] = dice[1]; } //Смена игрока plr = plr % 2 + 1; //Сброс истории story[0] = 1;

checkHome(); refresh(); fullAbility();
}

/* Отслеживание состояний домиков */ function checkHome() { if (home[plr] == -1){ for (let i = 1; i < 19; i++){ var point = i + (plr - 1) * 12; point = (point - 1) % 24 + 1; if (mapC[point] == plr) { if (map[point]){ //Найдена фишка за домиком return 0; } } } home[plr] = 0; } }

/Проверка возможности хода/ function fullAbility() {

var x = [0, dice[1], dice[2], dice[3], dice[4]]; for (let i = 1; i < 25; i++){ if (selectAbility(i)) if (trace(x, i)){ clearPossibility(); return 1; } } //Сброс выделения clearPossibility(); alert('Ход невозможен! Кубики: ' + dice[1] + ' и ' + dice[2]); dice = [0, 0, 0, 0, 0]; refresh(); return 0; }

/Трассировка/ function trace(x, point){

var flag = [0, 0, 0, 0, 0, 0, 0]; //flag[0] = сумма остальных

if (deep(x) == 0) {return 1;} else

for (let i = 1; i < 5; i++){ if (x[i] && (flag[x[i]] == 0)) { var newP = (point + x[i] - 1) % 24 + 1; var newHomePoint = (point + x[i]) - ((plr % 2 + 1) * 12);

  if (traceAbility(point, newP)) {
    flag[x[i]]++;
    var y = [0, x[1], x[2], x[3], x[4]];
    y[i] = 0;
    mapP[newP][1] = (mapP[newP][1] || mapP[point][1]);
    mapP[newP][2] = (mapP[newP][2] || mapP[point][2]);
    mapP[newP][3] = (mapP[newP][3] || mapP[point][3]);
    mapP[newP][4] = (mapP[newP][4] || mapP[point][4]);
    mapP[newP][i] = 1;
    flag[0] += 1 + trace(y, newP);
  }
  
  if (home[plr] >= 0){
    if (newHomePoint == 1){
      flag[x[i]]++;
      flag[0]++;
      homeP[plr][1] = (mapP[point][1]);
      homeP[plr][2] = (mapP[point][2]);
      homeP[plr][3] = (mapP[point][3]);
      homeP[plr][4] = (mapP[point][4]);
      homeP[plr][i] = 1;
    } else
    if (newHomePoint > 1){
      if (checkBefore(point) == 0){
        flag[x[i]]++;
        flag[0]++;
        homeP[plr] = [0, 0, 0, 0, 0];
        homeP[plr][i] = 1;
      }
    }
  
  }
}

}

return flag[0]; }

function checkBefore(point) { for (let i = point - 6; i < point; i++){ if ((mapC[i] == plr) && (map[i])){ return 1; } } return 0; }

/* Возможность трассировочного хода */ function traceAbility(from, to) { if (mapC[to] == plr % 2 + 1) { return 0; } if (plr == 1){ if ((from >= 19) && (to < 7)) { return 0; } } else { if ((from >= 7) && (from < 13)) { if (to >= 13) { return 0; } } } return 1; }

newGame(); refresh();

Clone this wiki locally