a javascript library for managing shogi games
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

357 lines
8.0 KiB

  1. /**
  2. @license Copyright (c) 2012, Christopher Ramey | http://github.com/cramey/shogi.js/LICENSE"
  3. */
  4. var Shogi = {
  5. KING : 0,
  6. ROOK : 1,
  7. BISHOP : 2,
  8. GOLD_GENERAL : 3,
  9. SILVER_GENERAL : 4,
  10. KNIGHT : 5,
  11. LANCE : 6,
  12. PAWN : 7,
  13. PROMOTED_ROOK : 9,
  14. PROMOTED_BISHOP : 10,
  15. PROMOTED_SILVER : 12,
  16. PROMOTED_KNIGHT : 13,
  17. PROMOTED_LANCE : 14,
  18. PROMOTED_PAWN : 15,
  19. desc_king : [
  20. 'reigning', 'challenging'
  21. ],
  22. desc_piece : [
  23. 'King', 'Rook', 'Bishop', 'Gold General',
  24. 'Silver General', 'Knight', 'Lance', 'Pawn'
  25. ],
  26. piecePromoted : function(n)
  27. {
  28. return (n & 8) != 0;
  29. },
  30. pieceCanPromote : function(b, l){
  31. var piece = b[l];
  32. if(piece == -1){ return false; }
  33. var pe = piece & 15;
  34. if(pe < 1 || pe > 7){ return false; }
  35. var player = this.piecePlayer(piece);
  36. if(player == 0 && l > 26){ return false; }
  37. if(player == 1 && l < 54){ return false; }
  38. return true;
  39. },
  40. piecePlayer : function(n)
  41. {
  42. return (n & 16) >> 4;
  43. },
  44. pieceName : function(n)
  45. {
  46. return this.desc_piece[n & 7];
  47. },
  48. pieceMoves : function(b, l)
  49. {
  50. var piece = b[l];
  51. var player = this.piecePlayer(piece);
  52. var moves = [];
  53. switch(piece & 15){
  54. case this.KING:
  55. var i = l + 9;
  56. if(i <= 80 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  57. moves.push(i);
  58. }
  59. i = l - 9;
  60. if(i >= 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  61. moves.push(i);
  62. }
  63. i = l + 1;
  64. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  65. moves.push(i);
  66. }
  67. i = l - 1;
  68. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  69. moves.push(i);
  70. }
  71. i = l + 8;
  72. if(i <= 80 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  73. moves.push(i);
  74. }
  75. i = l + 10;
  76. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  77. moves.push(i);
  78. }
  79. i = l - 10;
  80. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  81. moves.push(i);
  82. }
  83. i = l - 8;
  84. if(i >= 0 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  85. moves.push(i);
  86. }
  87. break;
  88. case this.GOLD_GENERAL:
  89. case this.PROMOTED_SILVER:
  90. case this.PROMOTED_PAWN:
  91. case this.PROMOTED_LANCE:
  92. case this.PROMOTED_KNIGHT:
  93. var i = l + 9;
  94. if(i <= 80 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  95. moves.push(i);
  96. }
  97. i = l - 9;
  98. if(i >= 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  99. moves.push(i);
  100. }
  101. i = l + 1;
  102. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  103. moves.push(i);
  104. }
  105. i = l - 1;
  106. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  107. moves.push(i);
  108. }
  109. if(player){
  110. i = l + 8;
  111. if(i <= 80 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  112. moves.push(i);
  113. }
  114. i = l + 10;
  115. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  116. moves.push(i);
  117. }
  118. } else {
  119. i = l - 10;
  120. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  121. moves.push(i);
  122. }
  123. i = l - 8;
  124. if(i >= 0 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  125. moves.push(i);
  126. }
  127. }
  128. break;
  129. case this.KNIGHT:
  130. var i = l + (player ? 19 : -19);
  131. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  132. moves.push(i);
  133. }
  134. i = l + (player ? 17 : -17);
  135. if(i >= 0 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  136. moves.push(i);
  137. }
  138. break;
  139. case this.LANCE:
  140. if(player){
  141. for(var i = l + 9; i <= 80; i += 9){
  142. if(b[i] == -1){ moves.push(i); }
  143. else if(this.piecePlayer(b[i]) != player){
  144. moves.push(i); break;
  145. } else { break; }
  146. }
  147. } else {
  148. for(var i = l - 9; i >= 0; i -= 9){
  149. if(b[i] == -1){ moves.push(i); }
  150. else if(this.piecePlayer(b[i]) != player){
  151. moves.push(i); break;
  152. } else { break; }
  153. }
  154. }
  155. break;
  156. case this.PROMOTED_ROOK:
  157. var i = l - 10;
  158. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  159. moves.push(i);
  160. }
  161. i = l - 8;
  162. if(i >= 0 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  163. moves.push(i);
  164. }
  165. i = l + 8;
  166. if(i <= 80 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  167. moves.push(i);
  168. }
  169. i = l + 10;
  170. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  171. moves.push(i);
  172. }
  173. case this.ROOK:
  174. for(var i = l - 9; i >= 0; i -= 9){
  175. if(b[i] == -1){ moves.push(i); }
  176. else if(this.piecePlayer(b[i]) != player){
  177. moves.push(i); break;
  178. } else { break; }
  179. }
  180. for(var i = l - 1; i % 9 != 8; i--){
  181. if(b[i] == -1){ moves.push(i); }
  182. else if(this.piecePlayer(b[i]) != player){
  183. moves.push(i); break;
  184. } else { break; }
  185. }
  186. for(var i = l + 1; i % 9 != 0; i++){
  187. if(b[i] == -1){ moves.push(i); }
  188. else if(this.piecePlayer(b[i]) != player){
  189. moves.push(i); break;
  190. } else { break; }
  191. }
  192. for(var i = l + 9; i <= 80; i += 9){
  193. if(b[i] == -1){ moves.push(i); }
  194. else if(this.piecePlayer(b[i]) != player){
  195. moves.push(i); break;
  196. } else { break; }
  197. }
  198. break;
  199. case this.PROMOTED_BISHOP:
  200. var i = l + 9;
  201. if(i <= 80 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  202. moves.push(i);
  203. }
  204. i = l - 9;
  205. if(i >= 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  206. moves.push(i);
  207. }
  208. i = l + 1;
  209. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  210. moves.push(i);
  211. }
  212. i = l - 1;
  213. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  214. moves.push(i);
  215. }
  216. case this.BISHOP:
  217. for(var i = l - 8; i >= 0 && i % 9 != 0; i -= 8){
  218. if(b[i] == -1){ moves.push(i); }
  219. else if(this.piecePlayer(b[i]) != player){
  220. moves.push(i); break;
  221. } else { break; }
  222. }
  223. for(var i = l - 10; i >= 0 && i % 9 != 8; i -= 10){
  224. if(b[i] == -1){ moves.push(i); }
  225. else if(this.piecePlayer(b[i]) != player){
  226. moves.push(i); break;
  227. } else { break; }
  228. }
  229. for(var i = l + 8; i <= 80 && i % 9 != 8; i += 8){
  230. if(b[i] == -1){ moves.push(i); }
  231. else if(this.piecePlayer(b[i]) != player){
  232. moves.push(i); break;
  233. } else { break; }
  234. }
  235. for(var i = l + 10; i <= 80 && i % 9 != 0; i += 10){
  236. if(b[i] == -1){ moves.push(i); }
  237. else if(this.piecePlayer(b[i]) != player){
  238. moves.push(i); break;
  239. } else { break; }
  240. }
  241. break;
  242. case this.PAWN:
  243. var i = l + (player ? 9 : -9);
  244. if(i >= 0 && i <= 80 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  245. moves.push(i);
  246. }
  247. break;
  248. case this.SILVER_GENERAL:
  249. i = l + (player ? 9 : -9);
  250. if(i >= 0 && i <= 80 && (b[i] == -1 || this.piecePlayer(b[i]))){
  251. moves.push(i);
  252. }
  253. var i = l - 10;
  254. if(i >= 0 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  255. moves.push(i);
  256. }
  257. i = l - 8;
  258. if(i >= 0 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  259. moves.push(i);
  260. }
  261. i = l + 8;
  262. if(i <= 80 && i % 9 != 8 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  263. moves.push(i);
  264. }
  265. i = l + 10;
  266. if(i <= 80 && i % 9 != 0 && (b[i] == -1 || this.piecePlayer(b[i]) != player)){
  267. moves.push(i);
  268. }
  269. break;
  270. }
  271. return moves;
  272. },
  273. pieceDescription : function(n)
  274. {
  275. var pl = (n & 16) >> 4;
  276. var pe = n & 7;
  277. return (this.piecePromoted(n) ? 'Promoted ' : '') +
  278. this.pieceName(n) +
  279. (pe == this.KING ? ' (' + this.desc_king[pl] + ')' : '');
  280. },
  281. boardStandard: function()
  282. {
  283. return [
  284. 22,21,20,19,16,19,20,21,22,
  285. -1,18,-1,-1,-1,-1,-1,17,-1,
  286. 23,23,23,23,23,23,23,23,23,
  287. -1,-1,-1,-1,-1,-1,-1,-1,-1,
  288. -1,-1,-1,-1,-1,-1,-1,-1,-1,
  289. -1,-1,-1,-1,-1,-1,-1,-1,-1,
  290. 7, 7, 7, 7, 7, 7, 7, 7, 7,
  291. -1, 1,-1,-1,-1,-1,-1, 2,-1,
  292. 6, 5, 4, 3, 0, 3, 4, 5, 6
  293. ];
  294. }
  295. };