diff --git a/src/games/chessbase/index.js b/src/games/chessbase/index.js index f2b7933..9afde63 100644 --- a/src/games/chessbase/index.js +++ b/src/games/chessbase/index.js @@ -5166,6 +5166,128 @@ exports.games = (function () { }, "viewScripts": config_view_js_giga }, + { + "name": "leychessalpha-chess", + "modelScripts": modelScripts_lca, + "config": { + "status": true, + "model": { + "title-en": "LeyChessAlpha", + "summary": "Chess on 12x12 with fairy pieces", + "rules": { + "en": "leychessalpha-rules.html" + }, + "module": "chessbase", + "plazza": "true", + "thumbnail": "leychessalpha-thumb.png", + "released": 1402412178, + "credits": { + "en": "leychessalpha-credits.html" + }, + "gameOptions": config_model_gameOptions, + "obsolete": false, + "js": modelScripts_lca, + "description": { + "en": "leychessalpha-description.html" + }, + "levels": config_model_levels_15 + }, + "view": { + "title-en": "Chessbase view", + "visuals": { + "600x600": [ + "res/visuals/leychessalpha-600x600-3d.jpg", + "res/visuals/leychessalpha-600x600-2d.jpg" + ] + }, + "xdView": true, + "css": config_view_css, + "preferredRatio": 1, + "useShowMoves": true, + "useNotation": true, + "module": "chessbase", + "defaultOptions": config_view_defaultOptions, + "skins": [ + { + "name": "skin3d", + "title": "3D Classic", + "3d": true, + "preload": [ + "smoothedfilegeo|0|/res/ring-target.js", + "image|/res/images/cancel.png", + "image|/res/images/wikipedia.png", + "smoothedfilegeo|0|/res/fairy/pawn/pawn.js", + "image|/res/fairy/pawn/pawn-diffusemap.jpg", + "image|/res/fairy/pawn/pawn-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/knight/knight.js", + "image|/res/fairy/knight/knight-diffusemap.jpg", + "image|/res/fairy/knight/knight-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/bishop/bishop.js", + "image|/res/fairy/bishop/bishop-diffusemap.jpg", + "image|/res/fairy/bishop/bishop-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/queen/queen.js", + "image|/res/fairy/queen/queen-diffusemap.jpg", + "image|/res/fairy/queen/queen-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/king/king.js", + "image|/res/fairy/king/king-diffusemap.jpg", + "image|/res/fairy/king/king-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/rook/rook.js", + "image|/res/fairy/rook/rook-diffusemap.jpg", + "image|/res/fairy/rook/rook-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/cannon2/cannon2.js", + "image|/res/fairy/cannon2/cannon2-diffusemap.jpg", + "image|/res/fairy/cannon2/cannon2-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/elephant/elephant.js", + "image|/res/fairy/elephant/elephant-diffusemap.jpg", + "image|/res/fairy/elephant/elephant-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/admiral/admiral.js", + "image|/res/fairy/admiral/admiral-diffusemap.jpg", + "image|/res/fairy/admiral/admiral-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/camel/camel.js", + "image|/res/fairy/camel/camel-diffusemap.jpg", + "image|/res/fairy/camel/camel-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/lion/lion.js", + "image|/res/fairy/lion/lion-diffusemap.jpg", + "image|/res/fairy/lion/lion-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/eagle/eagle.js", + "image|/res/fairy/eagle/eagle-diffusemap.jpg", + "image|/res/fairy/eagle/eagle-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/unicorn/unicorn.js", + "image|/res/fairy/unicorn/unicorn-diffusemap.jpg", + "image|/res/fairy/unicorn/unicorn-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/lighthouse/lighthouse.js", + "image|/res/fairy/lighthouse/lighthouse-diffusemap.jpg", + "image|/res/fairy/lighthouse/lighthouse-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/amazon/amazon.js", + "image|/res/fairy/amazon/amazon-diffusemap.jpg", + "image|/res/fairy/amazon/amazon-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/cardinal/cardinal.js", + "image|/res/fairy/cardinal/cardinal-diffusemap.jpg", + "image|/res/fairy/cardinal/cardinal-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/marshall/marshall.js", + "image|/res/fairy/marshall/marshall-diffusemap.jpg", + "image|/res/fairy/marshall/marshall-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/dragon/dragon.js", + "image|/res/fairy/dragon/dragon-diffusemap.jpg", + "image|/res/fairy/dragon/dragon-normalmap.jpg", + "smoothedfilegeo|0|/res/fairy/crowned-rook/crowned-rook.js", + "image|/res/fairy/crowned-rook/crowned-rook-diffusemap.jpg", + "image|/res/fairy/crowned-rook/crowned-rook-normalmap.jpg", + ], + "world": config_view_skins_world, + "camera": config_view_skins_camera + }, + config_view_skins_9 + ], + "animateSelfMoves": false, + "switchable": true, + "sounds": config_view_sounds, + "js": config_view_js_lca, + "useAutoComplete": true + } + }, + "viewScripts": config_view_js_lca + }, { "name": "knightet-chess", "modelScripts": modelScripts_k, diff --git a/src/games/chessbase/leychessalpha-description.html b/src/games/chessbase/leychessalpha-description.html new file mode 100644 index 0000000..dea2b87 --- /dev/null +++ b/src/games/chessbase/leychessalpha-description.html @@ -0,0 +1 @@ +

LeyChessAlpha is a 12*12 Chess Variant with Fairy Pieces based on Metamachy.

diff --git a/src/games/chessbase/leychessalpha-model.js b/src/games/chessbase/leychessalpha-model.js new file mode 100644 index 0000000..17a8324 --- /dev/null +++ b/src/games/chessbase/leychessalpha-model.js @@ -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;pos0) + 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=0) + continue; + var canMove=true; + var oppInCheck=false; + for(var j=0;j0; + 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; + } + +})(); diff --git a/src/games/chessbase/leychessalpha-view.js b/src/games/chessbase/leychessalpha-view.js new file mode 100644 index 0000000..4a17bb5 --- /dev/null +++ b/src/games/chessbase/leychessalpha-view.js @@ -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); + } + +})(); +