add leychessalpha files

This commit is contained in:
tilera 2017-08-01 22:59:29 +02:00 committed by GitHub
parent d42c8ab046
commit 907d1684b2
7 changed files with 6262 additions and 5145 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
<h1>Credits</h1>
<pre>
LeyChessAlpha is based on Metamachy.
Inventor: tilera
Developer: tilera
Inventor of Metamachy: Jean-Louis Cazaux
Developer of Jocly: Michel Gutierrez
Piece Graphic Designer:
Michel Gutierrez
jcfrog
</pre>

View file

@ -0,0 +1 @@
<p>LeyChessAlpha is a 12*12 Chess Variant with Fairy Pieces based on Metamachy.</p>

View file

@ -0,0 +1,574 @@
/*
* Copyright(c) 2013-2017 - jocly.com
*
* You are allowed to use and modify this source code as long as it is exclusively for use in the Jocly API.
*
* Original authors: Jocly team
*
*/
(function() {
var geometry = Model.Game.cbBoardGeometryGrid(12,12);
Model.Game.cbDefine = function() {
var $this = this;
/*
* Movement/capture graph for the prince
*/
function PrinceGraph(side) {
var graph={};
for(var pos=0;pos<geometry.boardSize;pos++) {
graph[pos]=[];
var forward=[]; // hold the pos line in front of the piece
var pos1=geometry.Graph(pos,[0,side]);
if(pos1!=null) {
forward.push(pos1 | $this.cbConstants.FLAG_MOVE | $this.cbConstants.FLAG_CAPTURE); // capture and move allowed at first forward position
pos1=geometry.Graph(pos1,[0,side]);
if(pos1!=null)
forward.push(pos1 | $this.cbConstants.FLAG_MOVE); // move to second forward only, no capture
graph[pos].push($this.cbTypedArray(forward));
}
}
return $this.cbMergeGraphs(geometry,
$this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[-1,0],[1,0],[1,-1],[1,1],[0,-side]]), // direction other than forward
graph // forward direction
);
}
/*
* Movement/capture graph for the eagle
*/
function EagleGraph() {
var flags = $this.cbConstants.FLAG_MOVE | $this.cbConstants.FLAG_CAPTURE;
var graph={};
for(var pos=0;pos<geometry.boardSize;pos++) {
graph[pos]=[];
[[-1,-1],[-1,1],[1,-1],[1,1]].forEach(function(delta) { // loop on all 4 diagonals
var pos1=geometry.Graph(pos,delta);
if(pos1!=null) {
for(var dir=0;dir<2;dir++) { // dir=0 for row, dir=1 for column
var away=[] // hold the sliding line
for(var n=1;n<11;n++) { // board is 12 cells long, so only consider max 11 cell displacements
var delta2=[];
delta2[dir]=delta[dir]*n;
delta2[1-dir]=0; // delta2 is now only about moving orthogonally, away from the piece
var pos2=geometry.Graph(pos1,delta2);
if(pos2!=null) {
if(n==1) // possible to slide at least 1 cell, make sure the diagonal cell is not occupied, but cannot move to this cell
away.push(pos1 | $this.cbConstants.FLAG_STOP);
away.push(pos2 | flags);
}
}
if(away.length>0)
graph[pos].push($this.cbTypedArray(away));
}
}
});
}
return $this.cbMergeGraphs(geometry,
$this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[1,-1],[1,1]]),
graph
);
}
return {
geometry: geometry,
pieceTypes: {
0: {
name: 'pawn-w',
aspect: 'fr-pawn',
graph: this.cbPawnGraph(geometry,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: false,
},
1: {
name: 'ipawn-w',
aspect: 'fr-pawn',
graph: this.cbInitialPawnGraph(geometry,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:1,p:24},{s:1,p:25},{s:1,p:26},{s:1,p:27},{s:1,p:28},{s:1,p:29},{s:1,p:30},{s:1,p:31},{s:1,p:32},{s:1,p:33},{s:1,p:34},{s:1,p:35}],
epTarget: true,
epCatch: false,
},
2: {
name: 'pawn-b',
aspect: 'fr-pawn',
graph: this.cbPawnGraph(geometry,-1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: false,
},
3: {
name: 'ipawn-b',
aspect: 'fr-pawn',
graph: this.cbInitialPawnGraph(geometry,-1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:-1,p:108},{s:-1,p:109},{s:-1,p:110},{s:-1,p:111},{s:-1,p:112},{s:-1,p:113},{s:-1,p:114},{s:-1,p:115},{s:-1,p:116},{s:-1,p:117},{s:-1,p:118},{s:-1,p:119}],
epTarget: true,
epCatch: false,
},
4: {
name: 'knight',
aspect: 'fr-knight',
graph: this.cbKnightGraph(geometry),
value: 2.9,
abbrev: 'N',
initial: [{s:1,p:14},{s:1,p:21},{s:-1,p:122},{s:-1,p:129}],
},
5: {
name: 'bishop',
aspect: 'fr-bishop',
graph: this.cbBishopGraph(geometry),
value: 3.1,
abbrev: 'B',
initial: [{s:1,p:15},{s:1,p:20},{s:-1,p:123},{s:-1,p:128}],
},
6: {
name: 'rook',
aspect: 'fr-rook',
graph: this.cbRookGraph(geometry),
value: 5,
abbrev: 'R',
initial: [{s:1,p:13},{s:1,p:22},{s:-1,p:121},{s:-1,p:130}],
castle: true,
},
7: {
name: 'queen',
aspect: 'fr-queen',
graph: this.cbQueenGraph(geometry),
value: 9,
abbrev: 'Q',
initial: [{s:1,p:18},{s:-1,p:126}],
},
8: {
name: 'king',
aspect: 'fr-king',
isKing: true,
graph: this.cbKingGraph(geometry),
abbrev: 'K',
initial: [{s:1,p:17},{s:-1,p:125}],
},
9: {
name: 'cannon',
aspect: 'fr-cannon2',
graph: this.cbXQCannonGraph(geometry),
value: 3.5,
abbrev: 'C',
initial: [{s:1,p:0},{s:1,p:11},{s:-1,p:132},{s:-1,p:143}],
},
10: {
name: 'elephant',
aspect: 'fr-elephant',
graph: this.cbShortRangeGraph(geometry,[[-1,-1],[-1,1],[1,-1],[1,1],[-2,-2],[-2,2],[2,-2],[2,2]]),
value: 2.5,
abbrev: 'E',
initial: [{s:1,p:12},{s:1,p:23},{s:-1,p:120},{s:-1,p:131}],
},
11: {
name: 'prince-w',
aspect: 'fr-admiral',
graph: PrinceGraph(1),
value: 3,
epTarget: true,
abbrev: 'I',
initial: [{s:1,p:16},{s:1,p:19}],
},
12: {
name: 'prince-b',
aspect: 'fr-admiral',
graph: PrinceGraph(-1),
epTarget: true,
value: 3,
abbrev: 'I',
initial: [{s:-1,p:124},{s:-1,p:127}],
},
13: {
name: 'camel',
aspect: 'fr-camel',
graph: this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]]),
value: 2,
abbrev: 'M',
initial: [{s:1,p:1},{s:1,p:10},{s:-1,p:133},{s:-1,p:142}],
},
14: {
name: 'lion',
aspect: 'fr-lion',
graph: this.cbShortRangeGraph(geometry,[
[-1,-1],[-1,1],[1,-1],[1,1],[1,0],[0,1],[-1,0],[0,-1],
[-2,0],[-2,-1],[-2,-2],[-1,-2],[0,-2],
[1,-2],[2,-2],[2,-1],[2,0],[2,1],
[2,2],[1,2],[0,2],[-1,2],[-2,2],[-2,1]]),
value: 7.5,
abbrev: 'L',
initial: [{s:1,p:5},{s:-1,p:137}],
},
15: {
name: 'eagle',
aspect: 'fr-eagle',
graph: EagleGraph(),
value: 8,
abbrev: 'A',
initial: [{s:1,p:6},{s:-1,p:138}],
},
16: {
name: 'unicorn',
aspect: 'fr-unicorn',
graph: this.cbMergeGraphs(geometry,
this.cbShortRangeGraph(geometry,[
[-2,-2],[-2,0],[-2,2],[0,2],[2,2],[2,0],[2,-2],[0,-2],
[-3,-3],[-3,0],[-3,3],[0,3],[3,3],[3,0],[3,-3],[0,-3]]),
this.cbKingGraph(geometry),
this.cbKnightGraph(geometry),
this.cbLongRangeGraph(geometry,[[2,-1],[2,1],[-2,-1],[-2,1],[-1,2],[-1,-2],[1,2],[1,-2]]),
this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]])
),
value: 13,
abbrev: 'Pa',
initial: [{s:1,p:2},{s:-1,p:134}],
},
17: {
name: 'dragon',
aspect: 'fr-dragon',
graph: this.cbMergeGraphs(geometry,
this.cbQueenGraph(geometry),
EagleGraph()),
value: 14,
abbrev: 'D',
initial: [{s:1,p:4},{s:-1,p:136}],
},
18: {
name: 'lighthouse',
aspect: 'fr-lighthouse',
graph: this.cbMergeGraphs(geometry,
this.cbQueenGraph(geometry),
this.cbXQCannonGraph(geometry),
this.cbLongRangeGraph(geometry,[[1,-1],[-1,-1],[-1,1],[1,1]],null,this.cbConstants.FLAG_MOVE | this.cbConstants.FLAG_SCREEN_CAPTURE)),
value: 12,
abbrev: 'LH',
initial: [{s:1,p:3},{s:-1,p:135}],
},
19: {
name: 'emperor',
aspect: 'fr-crowned-rook',
graph: this.cbMergeGraphs(geometry,
this.cbQueenGraph(geometry),
this.cbXQCannonGraph(geometry),
this.cbLongRangeGraph(geometry,[[1,-1],[-1,-1],[-1,1],[1,1]],null,this.cbConstants.FLAG_MOVE | this.cbConstants.FLAG_SCREEN_CAPTURE),
EagleGraph(),
this.cbShortRangeGraph(geometry,[
[-2,-2],[-2,0],[-2,2],[0,2],[2,2],[2,0],[2,-2],[0,-2],
[-3,-3],[-3,0],[-3,3],[0,3],[3,3],[3,0],[3,-3],[0,-3]]),
this.cbKnightGraph(geometry),
this.cbLongRangeGraph(geometry,[[2,-1],[2,1],[-2,-1],[-2,1],[-1,2],[-1,-2],[1,2],[1,-2]]),
this.cbShortRangeGraph(geometry,[[-3,-1],[-3,1],[3,-1],[3,1],[1,3],[1,-3],[-1,3],[-1,-3]])),
value: 20,
abbrev: 'EM',
},
20: {
name: 'commander',
aspect: 'fr-amazon',
graph: this.cbMergeGraphs(geometry,
this.cbQueenGraph(geometry),
this.cbKnightGraph(geometry)),
value: 13,
abbrev: 'Co',
initial: [{s:1,p:7},{s:-1,p:139}],
},
21: {
name: 'cardinal',
aspect: 'fr-cardinal',
graph: this.cbMergeGraphs(geometry,
this.cbBishopGraph(geometry),
this.cbKnightGraph(geometry)),
value: 6,
abbrev: 'Ca',
initial: [{s:1,p:9},{s:-1,p:141}],
},
22: {
name: 'chancellor',
aspect: 'fr-marshall',
graph: this.cbMergeGraphs(geometry,
this.cbRookGraph(geometry),
this.cbKnightGraph(geometry)),
value: 9,
abbrev: 'Ch',
initial: [{s:1,p:8},{s:-1,p:140}],
castle: true,
},
},
promote: function(aGame,piece,move) {
if(piece.t==1 && geometry.R(move.t)==11)
return [14,15,20,16,17,18];
else if(piece.t==3 && geometry.R(move.t)==0)
return [14,15,20,16,17,18];
else if(piece.t==11 && geometry.R(move.t)==11)
return [19];
else if(piece.t==12 && geometry.R(move.t)==0)
return [19];
return [];
},
};
}
/*
* Model.Board.GenerateMoves:
* - handle setup phase
* - handle king special move: a kind of castle involving only the king
*/
var kingLongMoves={
"1": {
17: [ [15,16],[19,18],[41,29],[39,28],[43,30],[3,4,16],[27,16,28],[40,28,29],[42,29,30],[31,18,30],[7,18,6] ],
5: [ [3,4],[7,8],[29,17],[27,16],[31,18],[15,4,6],[28,16,17],[30,17,18],[19,6,18] ],
},
"-1": {
125: [ [127,126],[123,124],[101,113],[99,112],[103,114],[135,124,136],[111,112,124],[100,112,113],[102,113,114],[115,114,126],[139,126,138] ],
137: [ [139,138],[135,136],[113,125],[115,126],[111,124],[127,126,138],[114,125,126],[112,124,125],[123,124,136] ],
},
}
var SuperModelBoardGenerateMoves=Model.Board.GenerateMoves;
Model.Board.GenerateMoves = function(aGame) {
// first moves (white and black) are managed specifically to setup K,Q,E,L initial position
if(this.setupState===undefined) {
this.mMoves=[{}];
return;
}
if(this.setupState=="setup") {
this.mMoves=[];
for(var i=0;i<12;i++)
this.mMoves.push({setup:i});
return;
}
SuperModelBoardGenerateMoves.apply(this,arguments); // call regular GenerateMoves method
// now consider special 2 cases king moves
var kPiece=this.pieces[this.board[this.kings[this.mWho]]];
if(!kPiece.m && !this.check) {
var lMoves=kingLongMoves[this.mWho][kPiece.p];
for(var i=0;i<lMoves.length;i++) {
var lMove=lMoves[i];
if(this.board[lMove[0]]>=0)
continue;
var canMove=true;
var oppInCheck=false;
for(var j=0;j<lMove.length;j++) {
var pos=lMove[j];
var tmpOut=this.board[pos];
this.board[pos]=-1; // remove possible piece to prevent problems when quick-applying/unapplying
var undo=this.cbQuickApply(aGame,{
f: kPiece.p,
t: pos,
});
var inCheck=this.cbGetAttackers(aGame,pos,this.mWho,true).length>0;
if(!inCheck && j==0)
oppInCheck=this.cbGetAttackers(aGame,this.kings[-this.mWho],-this.mWho,true).length>0;
this.cbQuickUnapply(aGame,undo);
this.board[pos]=tmpOut;
this.cbIntegrity(aGame);
if(inCheck) {
canMove=false;
break;
}
}
if(canMove)
this.mMoves.push({
f: kPiece.p,
t: lMove[0],
c: null,
ck: oppInCheck,
a: 'K',
});
}
}
}
/*
* Model.Board.CopyFrom overriding to copy setupState property
*/
var SuperModelBoardCopyFrom = Model.Board.CopyFrom;
Model.Board.CopyFrom = function(aBoard) {
SuperModelBoardCopyFrom.apply(this,arguments);
this.setupState = aBoard.setupState;
}
/*
* Model.Board.Evaluate overriding: in setup phase, no evaluation
*/
var SuperModelBoardEvaluate = Model.Board.Evaluate;
Model.Board.Evaluate = function(aGame) {
if(this.setupState===undefined || this.setupState=="setup")
return;
SuperModelBoardEvaluate.apply(this,arguments);
}
/*
* Model.Board.ApplyMove overriding: setup phase and king special move
*/
var SuperModelBoardApplyMove=Model.Board.ApplyMove;
Model.Board.ApplyMove = function(aGame,move) {
if(this.setupState===undefined)
this.setupState="setup";
else if(this.setupState=="setup") {
var $this=this, piece;
// at this point, KQLE have arbitrary positions. remember those piece indexes so we can move them
var starting={
"1": { K: 17, Q: 18, L: 5, E: 6 },
"-1": { K: 125, Q: 126, L: 137, E: 138 },
}
var indexes={ "1": {}, "-1": {} };
["1","-1"].forEach(function(side) {
for(var p in starting[side])
indexes[side][p]=$this.board[starting[side][p]];
});
// remove KQLE from the board
[5,6,17,18,125,126,137,138].forEach(function(pos) {
var pIndex=$this.board[pos];
$this.board[pos]=-1;
piece = $this.pieces[pIndex];
piece.p=-1;
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,pos);
});
// setup KQLE positions according to the setup
var setup=move.setup;
var remaining={};
if(setup/6<1) {
this.board[17]=indexes[1].K;
piece = this.pieces[indexes[1].K];
piece.p=17;
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,17);
this.kings[1]=17;
remaining[1]=[18,5,6];
this.board[125]=indexes[-1].K;
piece = this.pieces[indexes[-1].K];
piece.p=125;
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,125);
this.kings[-1]=125;
remaining[-1]=[126,137,138];
} else {
this.board[5]=indexes[1].K;
piece = this.pieces[indexes[1].K];
piece.p=5;
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,5);
this.kings[1]=5;
remaining[1]=[17,18,6];
this.board[137]=indexes[-1].K;
piece = this.pieces[indexes[-1].K];
piece.p=137;
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,137);
this.kings[-1]=137;
remaining[-1]=[125,126,138];
}
setup%=6;
var queen=Math.floor(setup/2);
this.board[remaining[1][queen]]=indexes[1].Q;
piece = this.pieces[indexes[1].Q];
piece.p=remaining[1][queen];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][queen]);
remaining[1].splice(queen,1);
this.board[remaining[-1][queen]]=indexes[-1].Q;
piece = this.pieces[indexes[-1].Q];
piece.p=remaining[-1][queen];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[-1][queen]);
remaining[-1].splice(queen,1);
var eagle,lion;
setup%=2;
if(setup==0) {
eagle=0;
lion=1;
} else {
eagle=1;
lion=0;
}
this.board[remaining[1][eagle]]=indexes[1].E;
piece = this.pieces[indexes[1].E];
piece.p=remaining[1][eagle];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][eagle]);
this.board[remaining[1][lion]]=indexes[1].L;
piece = this.pieces[indexes[1].L];
piece.p=remaining[1][lion];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][lion]);
this.board[remaining[-1][eagle]]=indexes[-1].E;
piece = this.pieces[indexes[-1].E];
piece.p=remaining[-1][eagle];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[-1][eagle]);
this.board[remaining[-1][lion]]=indexes[-1].L;
piece = this.pieces[indexes[-1].L];
piece.p=remaining[-1][lion];
$this.zSign=aGame.zobrist.update($this.zSign,"board",piece.t,remaining[1][lion]);
this.setupState="done";
} else
SuperModelBoardApplyMove.apply(this,arguments);
}
/*
* Model.Move.ToString overriding for setup notation
*/
var SuperModelMoveToString = Model.Move.ToString;
Model.Move.ToString = function() {
if(this.f===undefined) {
if(this.setup===undefined)
return "--";
else
return "#"+this.setup;
}
return SuperModelMoveToString.apply(this,arguments);
}
/*
* Model.Board.CompactMoveString overriding to help reading PJN game transcripts
*/
var SuperModelBoardCompactMoveString = Model.Board.CompactMoveString;
Model.Board.CompactMoveString = function(aGame,aMove,allMoves) {
if(typeof aMove.ToString!="function") // ensure proper move object, if necessary
aMove=aGame.CreateMove(aMove);
if(this.setupState===undefined || this.setupState=="setup")
return aMove.ToString();
return SuperModelBoardCompactMoveString.apply(this,arguments);
}
/*
* Model.Board.StaticGenerateMoves overriding to prevent using AI during the setup phase
*/
Model.Board.StaticGenerateMoves = function(aGame) {
if(this.setupState=="setup")
return [aGame.CreateMove({setup:Math.floor(Math.random()*12)})];
return null;
}
})();

View file

@ -0,0 +1,177 @@
<h1 style="font-size:300%;">LeyChessAlpha Rules</h1>
<h1>Setup</h1>
<img src="res/visuals/leychessalpha-600x600-2d.jpg" alt="Your Browser suck:(" style="width:320px;height:320px;">
<h1>Pieces</h1>
<h2>King</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-king.png'>
</p>
<p class='piece-details'>Exactly as in usual Chess.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/king.png'>
</p>
<h2>Queen</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-queen.png'>
</p>
<p class='piece-details'>Exactly as in usual Chess.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/queen.png'>
</p>
<h2>Bishop</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-bishop.png'>
</p>
<p class='piece-details'>Exactly as in usual Chess.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/bishop.png'>
</p>
<h2>Knight</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-knight.png'>
</p>
<p class='piece-details'>Moves as in usual Chess.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/knight.png'>
</p>
<h2>Rook</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-rook.png'>
</p>
<p class='piece-details'>Exactly as in usual Chess.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/rook.png'>
</p>
<h2>Pawn</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-pawn.png'>
</p>
<p class='piece-details'>The Pawn is almost similar to usual Chess. There is a difference: it can advance one or two square from ANY position on the board. However, its capturing move is unchanged: one square diagonally forward. As a consequence, the en-passant capture is possible every time the opposite Pawn or Corporal or Prince has advanced two squares.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/pawn.png'>
</p>
<h2>Prince</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-admiral.png'>
</p>
<p class='piece-details'>This piece is simply a non-royal King combined with a Pawn. It can be found in Metamachy and has been inspired by medieval games like the Courier chess , an old chess variant, played in Germany, where it is called "Man". It moves one square in an arbitrary direction, like the King, but without being hindered by check. Here, like the Pawn, he can move without capturing to the second square straight ahead. When the Prince reaches the last row it promotes to an Emperor.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/leychess/lcb/prince.png' style="width:50%;height:50%;">
</p>
<h2>Elephant</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-elephant.png'>
</p>
<p class='piece-details'>As in Shako.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/elephant.png'>
</p>
<h2>Lion</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-lion.png'>
</p>
<p class='piece-details'>As in Metamachy, inspired (although with some simplification) by Chu Shogi, the most popular variant of the Japanese Chess. Here the Lion may move as a King (a single step move in any direction), or it may jump to a position two squares away, jumping in any orthogonal or diagonal direction, or alternatively jumping as a Knight in usual Chess. (Then this Lion has the same range but is more restricted than the Lion in Chu Shogi which can move two times in a turn). </p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/lion.png'>
</p>
<h2>Eagle</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-eagle.png'>
</p>
<p class='piece-details'>As in Metamachy, moves one square diagonally and then, goes away of an indefinite number of cases vertically or horizontally. It is authorized to go only one square diagonal. It can not jump and the unobstructed path must start with the diagonal movement. This piece is almost as powerful as the Queen and is inspired by the Giraffe from Tamerlane's Chess and the Aanca from Alfonso X's Grande Acedrex.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/eagle.png'>
</p>
<h2>Camel</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-camel.png'>
</p>
<p class='piece-details'>As in Metamachy, a well known piece from medieval Muslim great Chess like Tamerlane's Chess. It jumps to the opposite case of a 2x4 rectangle, like an extended Knight. No matter what intermediate cases contain. Note that it always stays on the same color of square.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/camel.png'>
</p>
<h2>Cannon</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-cannon.png'>
</p>
<p class='piece-details'>As in Xiangqi, in Shako and in Metamachy. (Also known as Pao by problemists).</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/cannon.png'>
</p>
<h2>Chancellor</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-marshall.png'>
</p>
<p class='piece-details'>It combines the move of Rook and Knight. It can be found in many, many chess variants since Carrera, Bird, Capablanca and many others like Grand Chess or Gothic Chess. (under many other names: Champion, Guard, Empress, Concubine, Chancellor, etc. The later is sometimes preferred, however it is confusing since Capablanca used it once for R+N and once for B+N. It is an Elephant in Seirawan Chess).</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/marshall.png'>
</p>
<h2>Cardinal</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-cardinal.png'>
</p>
<p class='piece-details'>It combines the move of Bishop and Knight. It can be found in many, many chess variants since Carrera, Bird, Capablanca, Modern and many others like Grand Chess or Gothic Chess. (under many other names: Centaur, Minister, Equerry, Janus, Archbishop, Princess, Chancellor, etc. It is a Hawk in Seirawan Chess). </p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/cardinal.png'>
</p>
<h2>Commander</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-amazon.png'>
</p>
<p class='piece-details'>It combines the move of Queen and Knight. It was used in the Turkish-Indian Grand Chess (as a Giraffe). </p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/amazon.png'>
</p>
<h2>Lighthouse</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-lighthouse.png'>
</p>
<p class='piece-details'>It combines the Star and the Queen.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/leychess/lcb/lighthouse.png' style="width:25%;height:25%;">
</p>
<h2>Unicorn</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-unicorn.png'>
</p>
<p class='piece-details'>The Unicorn combines the Camel, Lion and Antelope and additionaly it can jump infinite times like a Knight in the same direction(like the Knightrider).</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/leychess/lcb/unicorn.png' style="width:25%;height:25%;">
</p>
<h2>Dragon</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-dragon.png'>
</p>
<p class='piece-details'>The Dragon combines the Queen and the Eagle.</p>
<div style='clear:both'></div>
<p>
<img class='piece-graph' src='res/rules/graphs/leychess/lcb/dragon.png' style="width:25%;height:25%;">
</p>
<h2>Emperor</h2>
<p>
<img class='piece-icon' src='res/fairy/icons/w-emperor.png'>
</p>
<p class='piece-details'>The Emperor combines the Dragon, Unicorn and Lighthouse. That means, that every Piece is included in the Emperor. You can only get the Emperor, when you promote a Prince.</p>
<div style='clear:both'></div>
<h1>Promotion</h1>
<h2>Pawn</h2>
<img alt='Restart your Browser' src='res/rules/graphs/leychess/lca/pawnpromo.png'>
<h2>Prince</h2>
<img alt='Restart your Browser' src='res/rules/graphs/leychess/lca/princepromo.png'>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,220 @@
/*
* Copyright(c) 2013-2017 - jocly.com
*
* You are allowed to use and modify this source code as long as it is exclusively for use in the Jocly API.
*
* Original authors: Jocly team
*
*/
(function() {
View.Game.cbDefineView = function() {
var metamachyBoardDelta = {
//notationMode: 'in',
//notationDebug: true,
};
var metamachyBoard3d = $.extend(true,{},this.cbGridBoardClassic3DMargin,metamachyBoardDelta);
var metamachyBoard2d = $.extend(true,{},this.cbGridBoardClassic2DNoMargin,metamachyBoardDelta);
return {
coords: {
"2d": this.cbGridBoard.coordsFn.call(this,metamachyBoard2d),
"3d": this.cbGridBoard.coordsFn.call(this,metamachyBoard3d),
},
boardLayout: [
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
".#.#.#.#.#.#",
"#.#.#.#.#.#.",
],
board: {
"2d": {
draw: this.cbDrawBoardFn(metamachyBoard2d),
},
"3d": {
display: this.cbDisplayBoardFn(metamachyBoard3d),
},
},
clicker: {
"2d": {
width: 1000,
height: 1000,
},
"3d": {
scale: [.6,.6,.6],
},
},
pieces: this.cbFairyPieceStyle({
"default": {
"3d": {
scale: [.4,.4,.4],
},
"2d": {
width: 900,
height: 900,
},
},
}),
};
}
/*
* Make the knight & the camel jump when moving, the elephant & the lion when moving 2 squares, the cannon when capturing
*/
View.Board.cbMoveMidZ = function(aGame,aMove,zFrom,zTo) {
if(aMove.a=='N' || aMove.a=='M' || (aMove.a=='E' && aGame.g.distGraph[aMove.f][aMove.t]==2) || (aMove.a=='L' && aGame.g.distGraph[aMove.f][aMove.t]==2) || (aMove.a=='K' && aGame.g.distGraph[aMove.f][aMove.t]==2) || (aMove.a=='C' && aMove.c!=null))
return Math.max(zFrom,zTo)+1500;
else
return (zFrom+zTo)/2;
}
/*
* View.Game.xdInit overriding to create initial setup gadgets
*/
var SuperViewGameXdInit = View.Game.xdInit;
View.Game.xdInit = function(xdv) {
var $this=this;
SuperViewGameXdInit.apply(this,arguments);
var size=600;
xdv.createGadget("setup-board",{
base: {
type: "element",
x: 0,
y: 0,
width: size*12,
height: size*9,
z: 108,
css: {
"background-color": "White",
},
},
});
var setups={
0: "KQEL",
1: "KQLE",
2: "KEQL",
3: "KLQE",
4: "KELQ",
5: "KLEQ",
6: "QEKL",
7: "QLKE",
8: "EQKL",
9: "LQKE",
10: "ELKQ",
11: "LEKQ",
}
var imageOffsets={
K: 500, Q: 400, E: 1100, L: 1200,
}
for(var setup in setups) {
(function(setup) {
var x=((setup%4)-1.5)*3*size;
var y=(Math.floor(setup/4)-1)*3*size;
xdv.createGadget("setup#"+setup,{
base: {
type: "canvas",
x: x,
y: y,
width: 2*size,
height: 2*size,
z: 109,
draw: function(ctx) {
ctx.fillStyle="#c0c0c0";
ctx.rect(-size,-size,size*2,size*2);
ctx.fill();
ctx.save();
this.getResource("image|"+$this.g.fullPath+"/res/fairy/wikipedia-fairy-sprites.png",function(image) {
for(var i=0;i<4;i++) {
var x=i%2, y=Math.floor(i/2), p=setups[setup].charAt(i);
ctx.drawImage(image,imageOffsets[p],0,100,100,(x-1)*size,(y-1)*size,size,size);
}
ctx.restore();
});
}
},
});
})(setup);
}
}
/*
* View.Board.xdInput overriding to handle setup phase
*/
var SuperViewBoardxdInput = View.Board.xdInput;
View.Board.xdInput = function(xdv, aGame) {
if(this.setupState===undefined) {
return {
initial: {},
getActions: function(moves,currentInput) { return null; },
}
} else if(this.setupState=="setup") {
return {
initial: {
setupDone: false,
},
getActions: function(moves,currentInput) {
var actions={};
if(!currentInput.setupDone) {
moves.forEach(function(move) {
actions[move.setup]={
view: ["setup#"+move.setup],
click: ["setup#"+move.setup],
moves: [move],
validate: { setupDone: true },
}
});
}
return actions;
},
furnitures: ["setup-board"],
}
} else
return SuperViewBoardxdInput.apply(this,arguments);
}
/*
* View.Board.cbAnimate overriding to prevent animation on setup
*/
var SuperViewBoardcbAnimate = View.Board.cbAnimate;
View.Board.cbAnimate = function(xdv,aGame,aMove,callback) {
if(this.setupState===undefined || this.setupState=="setup")
callback();
else
SuperViewBoardcbAnimate.apply(this,arguments);
}
/*
* View.Board.xdDisplay overriding to prevent displaying KQEL before setup
*/
var SuperViewBoardxdDisplay = View.Board.xdDisplay;
View.Board.xdDisplay = function(xdv, aGame) {
if(this.setupState===undefined || this.setupState=="setup") {
var $this=this;
var hidden={};
[5,6,17,18,125,126,137,138].forEach(function(pos) {
var pIndex=$this.board[pos];
hidden[pos]=pIndex;
$this.pieces[pIndex].p=-1;
});
SuperViewBoardxdDisplay.apply(this,arguments);
for(var pos in hidden)
this.pieces[hidden[pos]].p=parseInt(pos);
} else
SuperViewBoardxdDisplay.apply(this,arguments);
}
})();