Чтобы отстаивать чье-то непонятное решение, люди часто говорят, что этот человек проходит через все головы и играет в «трехмерные шахматы». Теперь у вас есть шанс сыграть в трехмерные шахматы!
правила
Существует много вариантов 3D-шахмат , но для этого испытания я создал свой собственный. Моя версия похожа на обычные шахматы, за исключением того, что фигуры находятся внутри кубов, а не квадратов, и теперь имеют дополнительное измерение движения. Чтобы упростить эту задачу, здесь нет пешек и рокировки .
Движение части
(Направления компаса относятся к движению, которое происходит на стандартной шахматной доске, вверх и вниз - к вертикальному движению на трехмерной шахматной доске).
- Король - имеет 26 квадратов, на которые он может пойти в данный ход: N, NE, E, SE, S, SW, W, NW; а также вверх, вниз и вверх / вниз + одно из направлений компаса.
- Королева - может двигаться в том же направлении, что и король, но так далеко, как она хочет в этих направлениях.
- Ладья - может двигаться в 6 направлениях: N, E, S, W, Вверх и Вниз,
- Епископ - имеет 8 трехугольных направлений движения: NE + Вверх / Вниз, SE + Вверх / Вниз, SW + Вверх / Вниз, NW + Вверх / Вниз
- Рыцарь - перемещает 2 пробела по одной оси, затем 1 пробел по другой. Как и обычные шахматы, рыцарь - единственная фигура, которая может перепрыгивать через другие фигуры.
Тестер
Используйте этот фрагмент, чтобы увидеть, как различные фигуры движутся на 3D-доске ( совет : посмотрите *Test
функции в JS, чтобы быстро определить, является ли квадрат правильным ходом, просто на основе его абсолютного расстояния от фигуры.):
const color = "Black";
const pieces = ["N","B","R","Q","K"];
const urls = ["https://image.ibb.co/gyS9Cx/Black_N.png","https://image.ibb.co/dknnzc/Black_B.png","https://image.ibb.co/kb3hXx/Black_R.png","https://image.ibb.co/hGO5kH/Black_Q.png","https://image.ibb.co/jApd5H/Black_K.png"];
var dragPiece;
var size = 3;
var index = 0;
function start() {
Array.prototype.add = function(a) {return [this[0]+a[0],this[1]+a[1],this[2]+a[2]]};
document.getElementById("n").onchange=function() {
size = parseInt(this.value);
var s = document.getElementsByClassName("selected");
var pos;
if(s.length > 0) {
pos = s[0].pos;
}
document.body.removeChild(document.body.firstChild);
createBoards();
if(pos != null && valid(...pos)) {
cellAt(...pos).click();
}
};
createBoards();
}
function createBoards() {
var boards = document.createElement("div");
boards.style.counterReset = "board-count "+(size+1);
boards.name=size;
for(var x = 0;x<size;x++) {
var t = document.createElement("table");
for(var i = 0;i<size;i++) {
var row = document.createElement("tr");
row.className="row";
for(var j = 0;j<size;j++) {
var cell = document.createElement("td");
cell.className = (size+i+j)%2 == 1 ? "black" : "white";
var im = document.createElement("img");
im.draggable = true;
im.ondragstart = function(e) {dragPiece = this;e.dataTransfer.setData("piece",this.parentElement.name);
this.parentElement.classList.add("start");
this.classList.add("dragged");
};
im.ondragend = function(e) {this.parentElement.classList.remove("start");this.classList.remove("dragged");};
im.hidden = true;
cell.appendChild(im);
cell.pos = [j,i,x];
cell.ondragover = function(e) {e.preventDefault();};
cell.ondragenter = function(e) {this.classList.add("drag");};
cell.ondragleave = function(e) {this.classList.remove("drag");};
cell.ondrop = function(e) { e.preventDefault();this.classList.remove("drag");
if(this != dragPiece.parentElement && this.firstChild.hidden ){
dragPiece.hidden=true;
setPiece(this,e.dataTransfer.getData("piece"));
}
};
cell.onclick = function() {
if(this.firstChild.hidden == false && this.classList.contains("selected")) {
index++;
if(index == pieces.length) index = 0;
}
setPiece(this,pieces[index]);
};
row.appendChild(cell);
}
t.appendChild(row);
}
boards.appendChild(t);
}
document.body.insertBefore(boards,document.body.firstChild);
}
function clearHighlighted() {
var sel = document.getElementsByClassName("highlighted");
while(sel.length > 0) {
sel[0].classList.remove("highlighted");
}
}
function setPiece(cell,piece) {
var s=document.getElementsByClassName("selected");
if(s.length > 0){ s[0].firstChild.hidden=true;s[0].classList.remove("selected");}
cell.classList.add("selected");
cell.firstChild.hidden = false;
cell.name = piece;
cell.firstChild.src = urls[index];
clearHighlighted();
showMoves(cell,piece);
}
function showMoves(cell,piece) {
if(piece=="K") selector(cell,kingTest)
else if(piece=="N") selector(cell,knightTest);
else if(piece=="Q") selector(cell,queenTest);
else if(piece=="R") selector(cell,rookTest);
else if(piece=="B") selector(cell,bishopTest);
}
function cellAt(col,row,board) {
return document.body.firstChild.children[board].children[row].children[col];
}
function valid(col,row,board) {
return 0<=col && col<size && 0<=row && row<size && 0<=board && board<size;
}
function select(cell) {
if(cell != null && cell.firstChild.hidden) cell.classList.add("highlighted");
}
function rookTest(dist) {
var d = [].concat(dist).sort();
return d[0] == 0 && d[1] == 0;
}
function knightTest(dist) {
var d = [].concat(dist).sort();
return d[0] == 0 && d[1] == 1 && d[2] == 2;
}
function kingTest(dist) {
return dist[0] <= 1 && dist[1] <= 1 && dist[2] <= 1;
}
function bishopTest(dist) {
return dist[0]==dist[1] && dist[1]==dist[2];
}
function queenTest(dist) {
var d = [].concat(dist).sort();
return rookTest(dist) || bishopTest(dist) || (d[0]==0 && d[1]==d[2]) ;
}
function dist(cell,x,y,z) {
return [Math.abs(cell.pos[0]-x),Math.abs(cell.pos[1]-y),Math.abs(cell.pos[2]-z)];
}
function selector(cell,test) {
for(var i = 0;i<size;i++) {
for(var j = 0;j<size;j++) {
for(var k = 0;k<size;k++) {
if(test(dist(cell,k,j,i))) {
var c = cellAt(k,j,i);
if(c != cell) select(c);
}
}
}
}
}
table
{
padding: 10px;
display:inline-block;
}
table:after
{
counter-increment: board-count -1;
content: "("counter(board-count,upper-roman)")";
float:right;
}
td
{
width:28px;
height:28px;
border: 1px solid;
cursor: pointer;
}
.black
{
background-color: rgba(127,127,127,0.6);
}
.white
{
background-color: white;
}
.start {
background-color: rgba(0,204,0,0.6);
}
.highlighted {
background-color: rgba(0,255,0,0.6);
}
.drag
{
background-color: rgba(0,204,255,0.6);
}
.selected {
background-color: green;
cursor: grab;
}
.selected img
{
display:block;
}
.dragged {
cursor: grabbing;
}
<body data-size=3 onload="start()"
<label for="n">Size: </label><select id="n">
<option>2</option>
<option selected>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
<div>Click or drag to place the piece. Click on the piece to change its type.</div>
</body>
Вызов
По заданной доске n x n x n определите, находится ли белый король в мате.
вход
- (Необязательно) n ≥ 2 - размер платы
- Игровая доска
- Может быть в виде 1d-2d- или 3d-массива или другого аналогичного формата. Запись может быть в любом простом формате. Например, KQRBN (белый) и kqrbn (черный) с # для пустых кубов. Или используйте числа для разных значений.
- Думайте о трехмерной шахматной доске как о нескольких досках, сложенных друг на друге и перечисленных сверху вниз. Затем каждая отдельная доска записывается слева направо, сзади вперед (с черной стороны на белую).
- Представьте себе этот случай 2x2x2 в виде трехмерного массива:
[ [[Бк] [##]] [[Млрд] [Ко]] ]
«верхняя» доска: «нижняя» доска:
Выход
- логическое (значение истина / ложь) - истина, если белый король находится в мате, ложь в противном случае.
Мат
Белый король проверяет, угрожает ли чёрная фигура захватить его в следующий ход черных. Чтобы выйти из-под контроля, белым нужно перевести своего короля в безопасное место, защитить его другой частью или захватить угрожающую часть. Если у белых нет возможности выйти из-под контроля, то белый король в мате . Помните, что если белые не контролируются, но не могут двигаться без проверки, то это тупик , который не является матом.
Спецификация
- Вам не дадут доску, где черный король пытается «проверить» белого короля, или доску, где оба короля находятся под контролем (невозможные сценарии).
Тестовые случаи
п = 3,
[###,n##,#rr],[#b#,###,###],[###,###,bRK]
Вывод: правда
Пояснение: Король получает чек от ладьи на верхнем этаже. Белая ладья не может блокировать атаку или захватить угрожающую ладью, поэтому король должен попытаться уйти с дороги. Давайте рассмотрим варианты хода короля:
- c2 (I) - охраняется епископом на b3 (II)
- b2 (I) - охраняется рыцарем в a2 (III)
- c1 (II) - охраняется ладьей в c1 (III)
- b1 (II) - охраняется ладьей на b1 (III)
- с2 (II) - охраняется рыцарем на а2 (III)
- b2 (II) - охраняется епископом в a1 (I)
Так как король не может избежать проверки, это мат!
п = 3,
[b#b,###,###],[###,###,RNR],[#q#,###,#K#]
Вывод: false Объяснение: Король получает чек от королевы и не имеет ходов, чтобы сбежать или заблокировать. Тем не менее, рыцарь может захватить королеву.
п = 3,
[#q#,#b#,###],[n##,###,###],[#k#,###,#KB]
Вывод: false Объяснение: у белых нет способа захватить угрожающую королеву или переместить своего короля в безопасное место. Однако, переместив своего слона в b2 (II), белые могут блокировать угрозу королевы.
п = 4,
[####,####,r###,####],[####,#q##,####,####],[##r#,###b,####,BRnn],[####,####,#N##,#KQ#]
Выходные данные: true Объяснение: В этом случае король получает чек от одного из рыцарей и королевы. Несмотря на то, что белые могут захватить / заблокировать одну из контрольных фигур, они не могут захватить / заблокировать обе. Поэтому белые должны попытаться вывести своего короля из-под контроля, но у него нет других вариантов.
п = 3,
[###,##b,r#r],[###,###,###],[#k#,###,#K#]
Вывод: false Объяснение: Белые не контролируются, но не могут двигаться без проверки. Следовательно, это тупик, а не мат.
Вывод: верно Объяснение: Белые хотели бы напасть со своей королевой, чтобы защитить своего короля, но их рыцарь блокирует путь.
Вывод: верно Объяснение: Белые не могут взять королеву со своим рыцарем, потому что тогда ладья будет проверять короля белых.
Вывод: false Объяснение: белые могут захватить королеву вместе со своим королем.
Вывод: true Объяснение: На этот раз ладья охраняет, поэтому король не может захватить королеву.
Вывод: false Объяснение: Белый король может сбежать, захватив рыцаря.
источник
cell.className = (i + j)%2 == 0 ? "black" : "white"
будет ли лучше во фрагменте?Ответы:
Рубин ,
412413 байтПопробуйте онлайн! Сейчас проверено на всех тестовых случаях. Код увеличен на 1 байт, чтобы исправить ошибку в случае 5 (тупик).
Функция лямбда, требующая ввода в виде строки в формате, показанном ниже. Можно указать необязательный второй параметр, указывающий, какая группа из 32 кодов ASCII должна учитываться при следующем перемещении (по умолчанию это 2 соответствует заглавным / белым символам, но функция вызывает себя рекурсивно, используя 3, соответствующие строчным / черным символам. )
Уровень рекурсии 1: пробует все возможные ходы для белых (от любого куба до любого куба) и перебирает все легальные. Уровень рекурсии 2: В каждом случае он призывает себя пройти все возможные ходы для черных. Это возвращает истину, если белый король пережил все возможные ходы черных. Уровень рекурсии 1: Если все возможные ходы белых приводят к ситуации, когда белый король НЕ переживает все возможные ходы черных, верните true (иначе false).
В общем, фигура не может двигаться на квадрат, занятый дружественной фигурой. Чтобы рассмотреть случай, когда белые вообще не двигаются (следовательно, мат не находится в тупике), также допускается случай, когда король «движется» к клетке, на которой он уже находится. Из-за короткого кода другим белым фигурам также разрешается перемещаться на площадь, занятую белым королем. Это бессмысленный ход, но его разрешение не влияет на результат, поэтому это не проблема.
Следующие тесты используются, чтобы проверить, является ли ход действительным для каждой фигуры.
x,y,z
квадраты расстояний, пройденных по каждой оси.e
является их суммой (отсюда квадрат евклидова расстояния) иd
является максимумом. Тип фигуры - AND с 95, чтобы преобразовать строчные ASCII-значения в прописные.Код комментария
источник
?A
(есть пример в коде), поэтому оно по-прежнему составляет 2 байта. Все еще лучше, чем некоторые языки, которые требуют"A"
. Были определенные манипуляции, которые лучше выполнялись со значениями ASCII, а не с персонажами (в частности,o^k>31
которые гарантируют, что фигура может переместиться на незанятую клетку или на площадь, занятую дружественной фигурой, но не враждебную.)