added losing chess

This commit is contained in:
mig 2017-05-17 22:44:20 +02:00
parent 87c59055e3
commit 531d33a56f
4 changed files with 486 additions and 0 deletions

View file

@ -1188,6 +1188,103 @@ exports.games = (function () {
},
"viewScripts": config_view_js
},
{
"name": "losing-chess",
"modelScripts": [
"base-model.js",
"grid-geo-model.js",
"losing-model.js"
],
"config": {
"status": true,
"model": {
"title-en": "Losing Chess",
"summary": "Also known as Antichess, Suicide Chess, Giveaway Chess, ...",
"thumbnail": "knight-inv-thumbnail.png",
"module": "chessbase",
"plazza": "true",
"released": 1495039002,
"rules": {
"en": "losing-rules.html",
},
"credits": {
"en": "credits.html",
"fr": "credits-fr.html"
},
"gameOptions": config_model_gameOptions,
"js": [
"base-model.js",
"grid-geo-model.js",
"losing-model.js"
],
"levels": config_model_levels_5
},
"view": {
"title-en": "Chessbase view",
"visuals": {
"600x600": [
"res/visuals/classic-chess-600x600-3d.jpg",
"res/visuals/classic-chess-600x600-2d.jpg"
]
},
"xdView": true,
"css": config_view_css,
"preferredRatio": 1,
"useShowMoves": true,
"useNotation": true,
"module": "chessbase",
"defaultOptions": config_view_defaultOptions,
"skins": [
config_view_skins,
{
"name": "skin3dflat",
"title": "3D Flat",
"3d": true,
"preload": [
"smoothedfilegeo|0|/res/ring-target.js",
"image|/res/images/cancel.png",
"image|/res/images/wikipedia.png",
"image|/res/extruded/wood.jpg",
"image|/res/extruded/wikipedia-pieces-diffuse-white.jpg",
"image|/res/extruded/wikipedia-pieces-diffuse-black.jpg",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-king.js",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-queen.js",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-pawn.js",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-rook.js",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-knight.js",
"smoothedfilegeo|0|/res/extruded/flat3dpieces-bishop.js"
],
"world": config_view_skins_world,
"camera": config_view_skins_camera_2
},
{
"name": "skin2dfull",
"title": "2D Classic",
"3d": false,
"preload": config_view_skins_preload_2
},
{
"name": "skin2dwood",
"title": "2D Wood",
"3d": false,
"preload": [
"image|/res/images/cancel.png",
"image|/res/images/whitebg.png",
"image|/res/images/wikipedia.png",
"image|/res/images/woodenpieces2d2.png",
"image|/res/images/wood.jpg"
]
}
],
"animateSelfMoves": false,
"switchable": true,
"sounds": config_view_sounds,
"js": config_view_js,
"useAutoComplete": true
}
},
"viewScripts": config_view_js
},
{
"name": "xiangqi",
"modelScripts": modelScripts_2,

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,340 @@
(function() {
var geometry = Model.Game.cbBoardGeometryGrid(8,8);
var USE_TYPED_ARRAYS = typeof Int32Array != "undefined";
var MASK = 0xffff; // unreachable position
var FLAG_MOVE = 0x10000; // move to if target pos empty
var FLAG_CAPTURE = 0x20000; // capture if occupied by enemy
var FLAG_STOP = 0x40000; // stop if occupied
var FLAG_SCREEN_CAPTURE = 0x80000; // capture if occupied by and a piece has been jumped in the path (like cannon in xiangqi)
Model.Game.cbDefine = function() {
return {
geometry: geometry,
pieceTypes: {
0: {
name: 'pawn-w',
aspect: 'pawn',
graph: this.cbPawnGraph(geometry,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: true,
},
1: {
name: 'ipawn-w',
aspect: 'pawn',
graph: this.cbInitialPawnGraph(geometry,1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:1,p:8},{s:1,p:9},{s:1,p:10},{s:1,p:11},{s:1,p:12},{s:1,p:13},{s:1,p:14},{s:1,p:15}],
epTarget: true,
},
2: {
name: 'pawn-b',
aspect: 'pawn',
graph: this.cbPawnGraph(geometry,-1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
epCatch: true,
},
3: {
name: 'ipawn-b',
aspect: 'pawn',
graph: this.cbInitialPawnGraph(geometry,-1),
value: 1,
abbrev: '',
fenAbbrev: 'P',
initial: [{s:-1,p:48},{s:-1,p:49},{s:-1,p:50},{s:-1,p:51},{s:-1,p:52},{s:-1,p:53},{s:-1,p:54},{s:-1,p:55}],
epTarget: true,
},
4: {
name: 'knight',
graph: this.cbKnightGraph(geometry),
value: 2.9,
abbrev: 'N',
initial: [{s:1,p:1},{s:1,p:6},{s:-1,p:57},{s:-1,p:62}],
},
5: {
name: 'bishop',
graph: this.cbBishopGraph(geometry),
value: 3.1,
abbrev: 'B',
initial: [{s:1,p:2},{s:1,p:5},{s:-1,p:58},{s:-1,p:61}],
},
6: {
name: 'rook',
graph: this.cbRookGraph(geometry),
value: 5,
abbrev: 'R',
initial: [{s:1,p:0},{s:1,p:7},{s:-1,p:56},{s:-1,p:63}],
},
7: {
name: 'queen',
graph: this.cbQueenGraph(geometry),
value: 9,
abbrev: 'Q',
initial: [{s:1,p:3},{s:-1,p:59}],
},
8: {
name: 'king',
graph: this.cbKingGraph(geometry),
abbrev: 'K',
initial: [{s:1,p:4},{s:-1,p:60}],
},
},
promote: function(aGame,piece,move) {
if(piece.t==1)
return [0];
else if(piece.t==3)
return [2];
else if(piece.t==0 && geometry.R(move.t)==7)
return [4,5,6,7,8];
else if(piece.t==2 && geometry.R(move.t)==0)
return [4,5,6,7,8];
return [];
}
};
}
Model.Board.Evaluate = function(aGame) {
var debug=arguments[3]=="debug";
var $this=this;
this.mEvaluation=0;
var who=this.mWho;
var g=aGame.g;
var material;
if(USE_TYPED_ARRAYS)
material={
'1': {
count: new Uint8Array(g.pTypes.length),
byType: {},
},
'-1': {
count: new Uint8Array(g.pTypes.length),
byType: {},
}
}
else {
material={
'1': {
count: [],
byType: {},
},
'-1': {
count: [],
byType: {},
}
}
for(var i=0;i<g.pTypes.length;i++)
material["1"].count[i]=material["-1"].count[i]=0;
}
if(aGame.mOptions.preventRepeat && aGame.GetRepeatOccurence(this)>2) {
this.mFinished=true;
this.mWinner=aGame.cbOnPerpetual?who*aGame.cbOnPerpetual:JocGame.DRAW;
return;
}
var pieceValue={ '1': 0, '-1': 0 };
var pieceCount={ '1': 0, '-1': 0 };
var posValue={ '1': 0, '-1': 0 };
var pieces=this.pieces;
var piecesLength=pieces.length;
for(var i=0;i<piecesLength;i++) {
var piece=pieces[i];
if(piece.p>=0) {
var s=piece.s;
var pType=g.pTypes[piece.t];
pieceValue[s]+=pType.value;
pieceCount[s]++;
posValue[s]+=aGame.cbVar.geometry.distEdge[piece.p];
var mat=material[s];
mat.count[piece.t]++;
var byType=mat.byType;
if(byType[piece.t]===undefined)
byType[piece.t]=[piece];
else
byType[piece.t].push(piece);
}
}
if(pieceCount['1']==0) {
this.mFinished = true;
this.mWinner = 1;
return;
}
if(pieceCount['-1']==0) {
this.mFinished = true;
this.mWinner = -1;
return;
}
if(this.lastMove && this.lastMove.c!=null) {
var piece=this.pieces[this.board[this.lastMove.t]];
pieceValue[-piece.s]+=this.cbStaticExchangeEval(aGame,piece.p,piece.s,{piece:piece})
}
var evalValues={
"pieceValue": pieceValue['-1']-pieceValue['1'],
"pieceValueRatio": (pieceValue['-1']-pieceValue['1'])/(pieceValue['-1']+pieceValue['1']+1),
"posValue": posValue['-1']-posValue['1']
}
var evParams=aGame.mOptions.levelOptions;
for(var name in evalValues) {
var value=evalValues[name];
var factor=evParams[name+'Factor'] || 0;
var weighted=value*factor;
if(debug)
console.log(name,"=",value,"*",factor,"=>",weighted);
this.mEvaluation+=weighted;
}
if(debug)
console.log("Evaluation",this.mEvaluation);
}
Model.Board.cbGeneratePseudoLegalMoves = function(aGame) {
var $this=this;
var moves=[];
var cbVar=aGame.cbVar;
var who=this.mWho;
function PromotedMoves(piece,move) {
var promoFnt=aGame.cbVar.promote;
if(!promoFnt) {
moves.push(move);
return;
}
var promo=promoFnt.call($this,aGame,piece,move);
if(promo==null)
return;
if(promo.length==0)
moves.push(move);
else if(promo.length==1) {
move.pr=promo[0];
moves.push(move);
} else {
for(var i=0;i<promo.length;i++) {
var pr=promo[i];
moves.push({
f: move.f,
t: move.t,
c: move.c,
pr: pr,
ept: move.ept,
ep: move.ep,
a: move.a,
});
}
}
}
var piecesLength=this.pieces.length;
for(var i=0;i<piecesLength;i++) {
var piece=this.pieces[i];
if(piece.p<0 || piece.s!=who)
continue;
var pType=aGame.g.pTypes[piece.t];
var graph, graphLength;
graph=pType.graph[piece.p];
graphLength=graph.length;
for(var j=0;j<graphLength;j++) {
var line=graph[j];
var screen=false;
var lineLength=line.length;
var lastPos=null;
for(var k=0;k<lineLength;k++) {
var tg1=line[k];
var pos1=tg1 & MASK;
var index1=this.board[pos1];
if(index1<0 && (!pType.epCatch || !this.epTarget || this.epTarget.p!=pos1)) {
if((tg1 & FLAG_MOVE) && screen==false)
PromotedMoves(piece,{
f: piece.p,
t: pos1,
c: null,
a: pType.abbrev,
ept: lastPos==null || !pType.epTarget?undefined:lastPos,
});
} else if(tg1 & FLAG_SCREEN_CAPTURE) {
if(screen) {
var piece1=this.pieces[index1];
if(piece1.s!=piece.s)
PromotedMoves(piece,{
f: piece.p,
t: pos1,
c: piece1.i,
a: pType.abbrev,
});
break;
} else
screen=true;
} else {
var piece1;
if(index1<0)
piece1=this.pieces[this.epTarget.i];
else
piece1=this.pieces[index1];
if(piece1.s!=piece.s && (tg1 & FLAG_CAPTURE))
PromotedMoves(piece,{
f: piece.p,
t: pos1,
c: piece1.i,
a: pType.abbrev,
ep: index1<0,
});
break;
}
lastPos=pos1;
}
}
}
return moves;
}
Model.Board.GenerateMoves = function(aGame) {
var moves=this.cbGeneratePseudoLegalMoves(aGame);
var captMoves = [];
var nonCaptMoves = [];
for(var i=0; i<moves.length; i++) {
var move = moves[i];
if(move.c!=null)
captMoves.push(move);
else
nonCaptMoves.push(move);
}
if(captMoves.length>0)
this.mMoves = captMoves;
else
this.mMoves = nonCaptMoves;
if(this.mMoves.length==0) {
this.mFinished=true;
this.mWinner=this.mWho;
}
}
})();

View file

@ -0,0 +1,49 @@
<style>
table.psymbs {
text-align: center;
}
.psymb {
background-image: url({GAME}/res/images/wikipedia.png);
width: 100px;
height: 200px;
}
.psymbs td {
padding: 0 10px 0 10px;
}
.psymb-bold {
font-weight: bold;
}
.side {
float: right;
max-width: 100%;
}
@media screen and (max-width: 520px) {
.side {
float: none;
display: block;
max-width: 100%;
margin-right: auto;
margin-left: auto;
}
}
h1,h2,h3,h4 {
clear: both;
}
</style>
<p>Losing Chess is a game played by two people on a chessboard, with sixteen pieces (of six types) for each player. Each type of piece moves in a distinct way.
The goal of the game is be unable to make a move, either by not having any piece left on the board, or
by having all remaining pieces blocked.</p>
<p>Losing Chess follows the normal <a href="http://en.wikipedia.org/wiki/Rules_of_chess" target="_blank">Chess rules</a>,
with the following changes:</p>
<ul>
<li>capturing is compulsary: if there is a possible move that captures an opponent's piece, then
any move that does not result in a capture is invalid</li>
<li>the king has no special status: it can be captured and checks are not considered</li>
<li>castling is not possible</li>
<li>a pawn reaching the last row can promote to a king (in addition to Knight, Bishop, Rook and Queen)</li>
<li>stalemate is a win for the player that cannot make a move</li>
</ul>