Afin de défendre la décision déconcertante de quelqu'un, les gens disent souvent que cette personne va au-dessus de la tête de tout le monde et joue aux «échecs en trois dimensions». Maintenant, c'est votre chance de jouer aux échecs en 3 dimensions!
Règles
Il existe de nombreuses variantes des échecs 3D , mais pour ce défi, j'ai inventé le mien. Ma version est comme les échecs ordinaires, sauf que les pièces sont à l'intérieur de cubes au lieu de carrés, et ont maintenant une dimension de mouvement supplémentaire. Pour rendre ce simple défi , il y a pas des pions et pas de roque .
Mouvement de pièce
(Les directions de la boussole se réfèrent au mouvement qui se produirait sur un échiquier standard, Up et Down se réfèrent au déplacement vertical sur l'échiquier 3D).
- Roi - dispose de 26 cases pour un tour donné: N, NE, E, SE, S, SW, W, NW; ainsi que vers le haut, le bas et le haut / bas + l'une des directions de la boussole.
- Reine - peut se déplacer dans les mêmes directions que le roi, mais autant qu'elle le souhaite dans ces directions.
- Tour - peut se déplacer dans 6 directions: N, E, S, W, haut et bas,
- Bishop - a 8 directions de voyage triagonales: NE + haut / bas, SE + haut / bas, SW + haut / bas, NW + haut / bas
- Knight - déplace 2 espaces sur un axe, puis 1 espace sur un autre. Tout comme les échecs ordinaires, le chevalier est la seule pièce qui peut sauter par-dessus d'autres pièces.
Testeur de pièces
Utilisez cet extrait pour voir comment les différentes pièces se déplacent sur la carte 3D ( astuce : consultez les *Test
fonctions dans le JS pour des moyens rapides de déterminer si un carré est un mouvement valide, simplement en fonction de sa distance absolue par rapport à la pièce.):
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>
Défi
Étant donné un tableau n x n x n , déterminez si le roi blanc est en échec et mat.
Contribution
- (Facultatif) n ≥ 2 - la taille de la carte
- Le plateau de jeu
- Peut être sous la forme d'un tableau 1d- 2d- ou 3d-, ou tout autre format similaire. La notation peut être dans n'importe quel format simple. Par exemple, KQRBN (blanc) et kqrbn (noir) avec # pour les cubes vides. Ou utilisez des nombres pour les différentes valeurs.
- Considérez l'échiquier 3D comme plusieurs planches empilées les unes sur les autres et répertoriées de haut en bas. Ensuite, chaque planche individuelle est notée de gauche à droite, de l'arrière vers l'avant (côté noir vers côté blanc).
- Imaginez ce cas 2x2x2 donné comme un tableau 3D:
[ [[bq] [##]] [[bn] [KQ]] ]
carte "supérieure": carte "inférieure":
Sortie
- booléen (valeur vérité / fausse) - vrai si le roi blanc est en échec et mat, faux sinon.
Échec et mat
Le roi blanc vérifie si une pièce noire menace de la capturer au prochain tour de Black. Pour sortir de l'échec, les Blancs doivent mettre son roi en sécurité, le défendre avec une autre pièce ou capturer la pièce menaçante. Si les Blancs n'ont aucun moyen de sortir de l'échec, alors le roi blanc est en échec et mat . Rappelez-vous, si les Blancs ne sont pas en échec, mais ne peuvent pas bouger sans entrer en échec, alors c'est une impasse , qui n'est pas un échec et mat.
spécification
- Vous ne recevrez pas de tableau où le roi noir essaie de "vérifier" le roi blanc, ni de tableau où les deux rois sont en échec (scénarios impossibles).
Cas de test
n = 3,
[###,n##,#rr],[#b#,###,###],[###,###,bRK]
Sortie: vrai
Explication: le roi reçoit un chèque de la tour au dernier étage. La tour blanche est incapable de bloquer l'attaque ou de capturer la tour menaçante, donc le roi doit essayer de s'écarter. Examinons les options de déplacement du roi:
- c2 (I) - gardé par l'évêque au b3 (II)
- b2 (I) - gardé par un chevalier en a2 (III)
- c1 (II) - gardé par tour à c1 (III)
- b1 (II) - gardé par tour à b1 (III)
- c2 (II) - gardé par un chevalier en a2 (III)
- b2 (II) - gardé par l'évêque en a1 (I)
Puisque le roi ne peut pas échapper au chèque, c'est un échec et mat!
n = 3,
[b#b,###,###],[###,###,RNR],[#q#,###,#K#]
Sortie: faux Explication: Le roi reçoit un chèque de la reine et n'a aucun mouvement pour s'échapper ou bloquer. Cependant, le chevalier peut capturer la reine.
n = 3,
[#q#,#b#,###],[n##,###,###],[#k#,###,#KB]
Sortie: faux Explication: les blancs n'ont aucun moyen de capturer la reine menaçante ou de mettre son roi en sécurité. Cependant, en déplaçant son évêque vers b2 (II), Blanc peut bloquer la menace de la reine.
n = 4,
[####,####,r###,####],[####,#q##,####,####],[##r#,###b,####,BRnn],[####,####,#N##,#KQ#]
Sortie: vrai Explication: Dans ce cas, le roi reçoit un chèque de l'un des chevaliers et d'une reine. Même si Blanc peut capturer / bloquer l'une des pièces de contrôle, il ne peut pas capturer / bloquer les deux. Par conséquent, Blanc doit essayer de mettre son roi hors de contrôle, mais il n'a pas d'options.
n = 3,
[###,##b,r#r],[###,###,###],[#k#,###,#K#]
Sortie: faux Explication: le blanc n'est pas en échec, mais n'a aucun moyen de se déplacer sans entrer en échec. C'est donc une impasse, mais pas un échec et mat.
Sortie: vrai Explication: Blanc voudrait entrer avec sa reine pour défendre son roi, mais son chevalier bloque le chemin.
Sortie: vrai Explication: Blanc ne peut pas prendre la reine avec son chevalier, car alors la tour vérifiera le roi blanc.
Sortie: faux Explication: les blancs peuvent capturer la reine avec son roi.
Sortie: vrai Explication: Cette fois, la tour garde, donc le roi ne peut pas capturer la reine.
Sortie: faux Explication: Le roi blanc peut s'échapper en capturant le chevalier.
la source
cell.className = (i + j)%2 == 0 ? "black" : "white"
mieux dans l'extrait?Réponses:
Rubis ,
412413 octetsEssayez-le en ligne! Maintenant vérifié sur tous les cas de test. Code augmenté de 1 octet pour corriger un bug sur le cas 5 (cas de blocage.)
Fonction Llambda nécessitant une entrée sous forme de chaîne au format indiqué ci-dessous. Un deuxième paramètre facultatif peut être donné, indiquant quel groupe de 32 codes ASCII doit être pris en compte lors du prochain déplacement (par défaut, ce 2 correspond aux caractères majuscules / blancs, mais la fonction s'appelle récursivement en utilisant 3 correspondant aux caractères minuscules / noirs. )
Niveau de récursivité 1: essaie tous les mouvements possibles pour le blanc (n'importe quel cube vers n'importe quel cube) et parcourt tous les mouvements légaux. Niveau de récursivité 2: Dans chaque cas, il appelle alors lui-même à traverser tous les mouvements possibles pour le noir. Cela revient vrai si le roi blanc a survécu à tous les mouvements noirs possibles. Niveau de récursivité 1: si tous les mouvements blancs possibles conduisent à une situation où le roi blanc ne survit PAS à tous les mouvements noirs possibles, alors retournez vrai (sinon faux.)
En général, une pièce ne peut pas se déplacer vers une case occupée par une pièce amie. Afin de considérer le cas où le blanc ne bouge pas du tout (donc échec et mat ne se bloque pas), le cas où le roi "se déplace" sur la case où il se trouve déjà est également autorisé. Pour des raisons de code court, les autres pièces blanches sont également autorisées à se déplacer vers la place occupée par le roi blanc. C'est un mouvement absurde, mais le permettre n'affecte pas le résultat, donc ce n'est pas un problème.
Les tests suivants sont utilisés pour vérifier si un mouvement est valide pour chaque pièce.
x,y,z
sont les carrés des distances parcourues dans chaque axe.e
est la somme de ceux-ci (d'où le carré de la distance euclidienne) etd
est le maximum. Le type de pièce est ET avec 95 pour convertir les valeurs ASCII minuscules en majuscules.Code commenté
la source
?A
(il y a un exemple dans le code) donc c'est toujours 2 octets. Encore mieux que certaines langues qui l'exigent"A"
. Certaines manipulations ont mieux fonctionné avec les valeurs ASCII plutôt qu'avec les personnages (en particulier,o^k>31
ce qui garantit qu'une pièce peut se déplacer vers une case inoccupée ou occupée par une pièce amie mais pas hostile.)