chess 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (501) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +6 -2
  3. data/Rakefile +1 -1
  4. data/ext/board.c +1 -4
  5. data/ext/chess.c +98 -15
  6. data/ext/chess.h +5 -3
  7. data/ext/common.c +3 -3
  8. data/ext/common.h +4 -4
  9. data/ext/game.c +22 -7
  10. data/lib/chess/game.rb +48 -19
  11. data/lib/chess/gnuchess.rb +39 -12
  12. data/lib/chess/pgn.rb +2 -1
  13. data/lib/chess/version.rb +1 -1
  14. data/test/pgn_collection/checkmate/{black_wins → black_won}/0001.pgn +0 -0
  15. data/test/pgn_collection/checkmate/{black_wins → black_won}/0002.pgn +0 -0
  16. data/test/pgn_collection/checkmate/{black_wins → black_won}/0003.pgn +0 -0
  17. data/test/pgn_collection/checkmate/{black_wins → black_won}/0004.pgn +0 -0
  18. data/test/pgn_collection/checkmate/{black_wins → black_won}/0005.pgn +0 -0
  19. data/test/pgn_collection/checkmate/{black_wins → black_won}/0006.pgn +0 -0
  20. data/test/pgn_collection/checkmate/{black_wins → black_won}/0007.pgn +0 -0
  21. data/test/pgn_collection/checkmate/{black_wins → black_won}/0008.pgn +0 -0
  22. data/test/pgn_collection/checkmate/{black_wins → black_won}/0009.pgn +0 -0
  23. data/test/pgn_collection/checkmate/{black_wins → black_won}/0010.pgn +0 -0
  24. data/test/pgn_collection/checkmate/{black_wins → black_won}/0011.pgn +0 -0
  25. data/test/pgn_collection/checkmate/{black_wins → black_won}/0012.pgn +0 -0
  26. data/test/pgn_collection/checkmate/{black_wins → black_won}/0013.pgn +0 -0
  27. data/test/pgn_collection/checkmate/{black_wins → black_won}/0014.pgn +0 -0
  28. data/test/pgn_collection/checkmate/{black_wins → black_won}/0015.pgn +0 -0
  29. data/test/pgn_collection/checkmate/{black_wins → black_won}/0016.pgn +0 -0
  30. data/test/pgn_collection/checkmate/{black_wins → black_won}/0017.pgn +0 -0
  31. data/test/pgn_collection/checkmate/{black_wins → black_won}/0018.pgn +0 -0
  32. data/test/pgn_collection/checkmate/{black_wins → black_won}/0019.pgn +0 -0
  33. data/test/pgn_collection/checkmate/{black_wins → black_won}/0020.pgn +0 -0
  34. data/test/pgn_collection/checkmate/{black_wins → black_won}/0021.pgn +0 -0
  35. data/test/pgn_collection/checkmate/{black_wins → black_won}/0022.pgn +0 -0
  36. data/test/pgn_collection/checkmate/{black_wins → black_won}/0023.pgn +0 -0
  37. data/test/pgn_collection/checkmate/{black_wins → black_won}/0024.pgn +0 -0
  38. data/test/pgn_collection/checkmate/{black_wins → black_won}/0025.pgn +0 -0
  39. data/test/pgn_collection/checkmate/{black_wins → black_won}/0026.pgn +0 -0
  40. data/test/pgn_collection/checkmate/{black_wins → black_won}/0027.pgn +0 -0
  41. data/test/pgn_collection/checkmate/{black_wins → black_won}/0028.pgn +0 -0
  42. data/test/pgn_collection/checkmate/{black_wins → black_won}/0029.pgn +0 -0
  43. data/test/pgn_collection/checkmate/{black_wins → black_won}/0030.pgn +0 -0
  44. data/test/pgn_collection/checkmate/{black_wins → black_won}/0031.pgn +0 -0
  45. data/test/pgn_collection/checkmate/{black_wins → black_won}/0032.pgn +0 -0
  46. data/test/pgn_collection/checkmate/{black_wins → black_won}/0033.pgn +0 -0
  47. data/test/pgn_collection/checkmate/{black_wins → black_won}/0034.pgn +0 -0
  48. data/test/pgn_collection/checkmate/{black_wins → black_won}/0035.pgn +0 -0
  49. data/test/pgn_collection/checkmate/{black_wins → black_won}/0036.pgn +0 -0
  50. data/test/pgn_collection/checkmate/{black_wins → black_won}/0037.pgn +0 -0
  51. data/test/pgn_collection/checkmate/{black_wins → black_won}/0038.pgn +0 -0
  52. data/test/pgn_collection/checkmate/{black_wins → black_won}/0039.pgn +0 -0
  53. data/test/pgn_collection/checkmate/{black_wins → black_won}/0040.pgn +0 -0
  54. data/test/pgn_collection/checkmate/{black_wins → black_won}/0041.pgn +0 -0
  55. data/test/pgn_collection/checkmate/{black_wins → black_won}/0042.pgn +0 -0
  56. data/test/pgn_collection/checkmate/{black_wins → black_won}/0043.pgn +0 -0
  57. data/test/pgn_collection/checkmate/{black_wins → black_won}/0044.pgn +0 -0
  58. data/test/pgn_collection/checkmate/{black_wins → black_won}/0045.pgn +0 -0
  59. data/test/pgn_collection/checkmate/{black_wins → black_won}/0046.pgn +0 -0
  60. data/test/pgn_collection/checkmate/{black_wins → black_won}/0047.pgn +0 -0
  61. data/test/pgn_collection/checkmate/{black_wins → black_won}/0048.pgn +0 -0
  62. data/test/pgn_collection/checkmate/{black_wins → black_won}/0049.pgn +0 -0
  63. data/test/pgn_collection/checkmate/{black_wins → black_won}/0050.pgn +0 -0
  64. data/test/pgn_collection/checkmate/{black_wins → black_won}/0051.pgn +0 -0
  65. data/test/pgn_collection/checkmate/{black_wins → black_won}/0052.pgn +0 -0
  66. data/test/pgn_collection/checkmate/{black_wins → black_won}/0053.pgn +0 -0
  67. data/test/pgn_collection/checkmate/{black_wins → black_won}/0054.pgn +0 -0
  68. data/test/pgn_collection/checkmate/{black_wins → black_won}/0055.pgn +0 -0
  69. data/test/pgn_collection/checkmate/{black_wins → black_won}/0056.pgn +0 -0
  70. data/test/pgn_collection/checkmate/{black_wins → black_won}/0057.pgn +0 -0
  71. data/test/pgn_collection/checkmate/{black_wins → black_won}/0058.pgn +0 -0
  72. data/test/pgn_collection/checkmate/{black_wins → black_won}/0059.pgn +0 -0
  73. data/test/pgn_collection/checkmate/{black_wins → black_won}/0060.pgn +0 -0
  74. data/test/pgn_collection/checkmate/{black_wins → black_won}/0061.pgn +0 -0
  75. data/test/pgn_collection/checkmate/{black_wins → black_won}/0062.pgn +0 -0
  76. data/test/pgn_collection/checkmate/{black_wins → black_won}/0063.pgn +0 -0
  77. data/test/pgn_collection/checkmate/{black_wins → black_won}/0064.pgn +0 -0
  78. data/test/pgn_collection/checkmate/{black_wins → black_won}/0065.pgn +0 -0
  79. data/test/pgn_collection/checkmate/{black_wins → black_won}/0066.pgn +0 -0
  80. data/test/pgn_collection/checkmate/{black_wins → black_won}/0067.pgn +0 -0
  81. data/test/pgn_collection/checkmate/{black_wins → black_won}/0068.pgn +0 -0
  82. data/test/pgn_collection/checkmate/{black_wins → black_won}/0069.pgn +0 -0
  83. data/test/pgn_collection/checkmate/{black_wins → black_won}/0070.pgn +0 -0
  84. data/test/pgn_collection/checkmate/{black_wins → black_won}/0071.pgn +0 -0
  85. data/test/pgn_collection/checkmate/{black_wins → black_won}/0072.pgn +0 -0
  86. data/test/pgn_collection/checkmate/{black_wins → black_won}/0073.pgn +0 -0
  87. data/test/pgn_collection/checkmate/{black_wins → black_won}/0074.pgn +0 -0
  88. data/test/pgn_collection/checkmate/{black_wins → black_won}/0075.pgn +0 -0
  89. data/test/pgn_collection/checkmate/{black_wins → black_won}/0076.pgn +0 -0
  90. data/test/pgn_collection/checkmate/{black_wins → black_won}/0077.pgn +0 -0
  91. data/test/pgn_collection/checkmate/{black_wins → black_won}/0078.pgn +0 -0
  92. data/test/pgn_collection/checkmate/{white_wins → white_won}/0001.pgn +0 -0
  93. data/test/pgn_collection/checkmate/{white_wins → white_won}/0002.pgn +0 -0
  94. data/test/pgn_collection/checkmate/{white_wins → white_won}/0003.pgn +0 -0
  95. data/test/pgn_collection/checkmate/{white_wins → white_won}/0004.pgn +0 -0
  96. data/test/pgn_collection/checkmate/{white_wins → white_won}/0005.pgn +0 -0
  97. data/test/pgn_collection/checkmate/{white_wins → white_won}/0006.pgn +0 -0
  98. data/test/pgn_collection/checkmate/{white_wins → white_won}/0007.pgn +0 -0
  99. data/test/pgn_collection/checkmate/{white_wins → white_won}/0008.pgn +0 -0
  100. data/test/pgn_collection/checkmate/{white_wins → white_won}/0009.pgn +0 -0
  101. data/test/pgn_collection/checkmate/{white_wins → white_won}/0010.pgn +0 -0
  102. data/test/pgn_collection/checkmate/{white_wins → white_won}/0011.pgn +0 -0
  103. data/test/pgn_collection/checkmate/{white_wins → white_won}/0012.pgn +0 -0
  104. data/test/pgn_collection/checkmate/{white_wins → white_won}/0013.pgn +0 -0
  105. data/test/pgn_collection/checkmate/{white_wins → white_won}/0014.pgn +0 -0
  106. data/test/pgn_collection/checkmate/{white_wins → white_won}/0015.pgn +0 -0
  107. data/test/pgn_collection/checkmate/{white_wins → white_won}/0016.pgn +0 -0
  108. data/test/pgn_collection/checkmate/{white_wins → white_won}/0017.pgn +0 -0
  109. data/test/pgn_collection/checkmate/{white_wins → white_won}/0018.pgn +0 -0
  110. data/test/pgn_collection/checkmate/{white_wins → white_won}/0019.pgn +0 -0
  111. data/test/pgn_collection/checkmate/{white_wins → white_won}/0020.pgn +0 -0
  112. data/test/pgn_collection/checkmate/{white_wins → white_won}/0021.pgn +0 -0
  113. data/test/pgn_collection/checkmate/{white_wins → white_won}/0022.pgn +0 -0
  114. data/test/pgn_collection/checkmate/{white_wins → white_won}/0023.pgn +0 -0
  115. data/test/pgn_collection/checkmate/{white_wins → white_won}/0024.pgn +0 -0
  116. data/test/pgn_collection/checkmate/{white_wins → white_won}/0025.pgn +0 -0
  117. data/test/pgn_collection/checkmate/{white_wins → white_won}/0026.pgn +0 -0
  118. data/test/pgn_collection/checkmate/{white_wins → white_won}/0027.pgn +0 -0
  119. data/test/pgn_collection/checkmate/{white_wins → white_won}/0028.pgn +0 -0
  120. data/test/pgn_collection/checkmate/{white_wins → white_won}/0029.pgn +0 -0
  121. data/test/pgn_collection/checkmate/{white_wins → white_won}/0030.pgn +0 -0
  122. data/test/pgn_collection/checkmate/{white_wins → white_won}/0031.pgn +0 -0
  123. data/test/pgn_collection/checkmate/{white_wins → white_won}/0032.pgn +0 -0
  124. data/test/pgn_collection/checkmate/{white_wins → white_won}/0033.pgn +0 -0
  125. data/test/pgn_collection/checkmate/{white_wins → white_won}/0034.pgn +0 -0
  126. data/test/pgn_collection/checkmate/{white_wins → white_won}/0035.pgn +0 -0
  127. data/test/pgn_collection/checkmate/{white_wins → white_won}/0036.pgn +0 -0
  128. data/test/pgn_collection/checkmate/{white_wins → white_won}/0037.pgn +0 -0
  129. data/test/pgn_collection/checkmate/{white_wins → white_won}/0038.pgn +0 -0
  130. data/test/pgn_collection/checkmate/{white_wins → white_won}/0039.pgn +0 -0
  131. data/test/pgn_collection/checkmate/{white_wins → white_won}/0040.pgn +0 -0
  132. data/test/pgn_collection/checkmate/{white_wins → white_won}/0041.pgn +0 -0
  133. data/test/pgn_collection/checkmate/{white_wins → white_won}/0042.pgn +0 -0
  134. data/test/pgn_collection/checkmate/{white_wins → white_won}/0043.pgn +0 -0
  135. data/test/pgn_collection/checkmate/{white_wins → white_won}/0044.pgn +0 -0
  136. data/test/pgn_collection/checkmate/{white_wins → white_won}/0045.pgn +0 -0
  137. data/test/pgn_collection/checkmate/{white_wins → white_won}/0046.pgn +0 -0
  138. data/test/pgn_collection/checkmate/{white_wins → white_won}/0047.pgn +0 -0
  139. data/test/pgn_collection/checkmate/{white_wins → white_won}/0048.pgn +0 -0
  140. data/test/pgn_collection/checkmate/{white_wins → white_won}/0049.pgn +0 -0
  141. data/test/pgn_collection/checkmate/{white_wins → white_won}/0050.pgn +0 -0
  142. data/test/pgn_collection/checkmate/{white_wins → white_won}/0051.pgn +0 -0
  143. data/test/pgn_collection/checkmate/{white_wins → white_won}/0052.pgn +0 -0
  144. data/test/pgn_collection/checkmate/{white_wins → white_won}/0053.pgn +0 -0
  145. data/test/pgn_collection/checkmate/{white_wins → white_won}/0054.pgn +0 -0
  146. data/test/pgn_collection/checkmate/{white_wins → white_won}/0055.pgn +0 -0
  147. data/test/pgn_collection/checkmate/{white_wins → white_won}/0056.pgn +0 -0
  148. data/test/pgn_collection/checkmate/{white_wins → white_won}/0057.pgn +0 -0
  149. data/test/pgn_collection/checkmate/{white_wins → white_won}/0058.pgn +0 -0
  150. data/test/pgn_collection/checkmate/{white_wins → white_won}/0059.pgn +0 -0
  151. data/test/pgn_collection/checkmate/{white_wins → white_won}/0060.pgn +0 -0
  152. data/test/pgn_collection/checkmate/{white_wins → white_won}/0061.pgn +0 -0
  153. data/test/pgn_collection/checkmate/{white_wins → white_won}/0062.pgn +0 -0
  154. data/test/pgn_collection/checkmate/{white_wins → white_won}/0063.pgn +0 -0
  155. data/test/pgn_collection/checkmate/{white_wins → white_won}/0064.pgn +0 -0
  156. data/test/pgn_collection/checkmate/{white_wins → white_won}/0065.pgn +0 -0
  157. data/test/pgn_collection/checkmate/{white_wins → white_won}/0066.pgn +0 -0
  158. data/test/pgn_collection/checkmate/{white_wins → white_won}/0067.pgn +0 -0
  159. data/test/pgn_collection/checkmate/{white_wins → white_won}/0068.pgn +0 -0
  160. data/test/pgn_collection/checkmate/{white_wins → white_won}/0069.pgn +0 -0
  161. data/test/pgn_collection/checkmate/{white_wins → white_won}/0070.pgn +0 -0
  162. data/test/pgn_collection/checkmate/{white_wins → white_won}/0071.pgn +0 -0
  163. data/test/pgn_collection/checkmate/{white_wins → white_won}/0072.pgn +0 -0
  164. data/test/pgn_collection/checkmate/{white_wins → white_won}/0073.pgn +0 -0
  165. data/test/pgn_collection/checkmate/{white_wins → white_won}/0074.pgn +0 -0
  166. data/test/pgn_collection/{valid/checkmate/ciccio.pgn → checkmate/white_won/0075.pgn} +0 -1
  167. data/test/pgn_collection/valid/0003.pgn +13 -19
  168. data/test/pgn_collection/valid/0004.pgn +15 -18
  169. data/test/pgn_collection/valid/0006.pgn +12 -13
  170. data/test/pgn_collection/valid/0007.pgn +16 -18
  171. data/test/pgn_collection/valid/0008.pgn +12 -14
  172. data/test/pgn_collection/valid/0017.pgn +13 -20
  173. data/test/pgn_collection/valid/0019.pgn +16 -18
  174. data/test/pgn_collection/valid/0022.pgn +14 -19
  175. data/test/pgn_collection/valid/0029.pgn +12 -20
  176. data/test/pgn_collection/valid/0031.pgn +13 -18
  177. data/test/pgn_collection/valid/0035.pgn +12 -16
  178. data/test/pgn_collection/valid/0040.pgn +12 -17
  179. data/test/pgn_collection/valid/0042.pgn +13 -17
  180. data/test/pgn_collection/valid/0043.pgn +11 -20
  181. data/test/pgn_collection/valid/0044.pgn +15 -22
  182. data/test/pgn_collection/valid/0048.pgn +12 -15
  183. data/test/pgn_collection/valid/0052.pgn +18 -26
  184. data/test/pgn_collection/valid/0058.pgn +10 -12
  185. data/test/pgn_collection/valid/0059.pgn +13 -15
  186. data/test/pgn_collection/valid/0064.pgn +13 -17
  187. data/test/pgn_collection/valid/0066.pgn +12 -14
  188. data/test/pgn_collection/valid/0067.pgn +14 -15
  189. data/test/pgn_collection/valid/0068.pgn +15 -18
  190. data/test/pgn_collection/valid/0071.pgn +11 -15
  191. data/test/pgn_collection/valid/0075.pgn +13 -14
  192. data/test/pgn_collection/valid/0076.pgn +14 -20
  193. data/test/pgn_collection/valid/0077.pgn +11 -14
  194. data/test/pgn_collection/valid/0078.pgn +14 -22
  195. data/test/pgn_collection/valid/0080.pgn +13 -17
  196. data/test/pgn_collection/valid/0083.pgn +17 -23
  197. data/test/pgn_collection/valid/0085.pgn +18 -21
  198. data/test/pgn_collection/valid/0088.pgn +14 -19
  199. data/test/pgn_collection/valid/0089.pgn +16 -18
  200. data/test/pgn_collection/valid/0090.pgn +11 -14
  201. data/test/pgn_collection/valid/0093.pgn +14 -19
  202. data/test/pgn_collection/valid/0099.pgn +14 -17
  203. data/test/pgn_collection/valid/0100.pgn +16 -21
  204. data/test/pgn_collection/valid/0102.pgn +17 -19
  205. data/test/pgn_collection/valid/0110.pgn +13 -18
  206. data/test/pgn_collection/valid/0113.pgn +15 -20
  207. data/test/pgn_collection/valid/0116.pgn +15 -17
  208. data/test/pgn_collection/valid/0118.pgn +14 -20
  209. data/test/pgn_collection/valid/0124.pgn +12 -20
  210. data/test/pgn_collection/valid/0132.pgn +12 -17
  211. data/test/pgn_collection/valid/0134.pgn +15 -17
  212. data/test/pgn_collection/valid/0135.pgn +17 -19
  213. data/test/pgn_collection/valid/0139.pgn +19 -21
  214. data/test/pgn_collection/valid/0144.pgn +16 -23
  215. data/test/pgn_collection/valid/0146.pgn +12 -14
  216. data/test/pgn_collection/valid/0148.pgn +15 -20
  217. data/test/pgn_collection/valid/0149.pgn +12 -16
  218. data/test/pgn_collection/valid/0152.pgn +7 -14
  219. data/test/pgn_collection/valid/0153.pgn +16 -22
  220. data/test/pgn_collection/valid/0154.pgn +13 -15
  221. data/test/pgn_collection/valid/0161.pgn +16 -22
  222. data/test/pgn_collection/valid/0163.pgn +11 -15
  223. data/test/pgn_collection/valid/0164.pgn +15 -17
  224. data/test/pgn_collection/valid/0169.pgn +15 -21
  225. data/test/pgn_collection/valid/0171.pgn +11 -15
  226. data/test/pgn_collection/valid/0173.pgn +11 -13
  227. data/test/pgn_collection/valid/0174.pgn +16 -24
  228. data/test/pgn_collection/valid/0177.pgn +15 -19
  229. data/test/pgn_collection/valid/0178.pgn +16 -21
  230. data/test/pgn_collection/valid/0185.pgn +11 -14
  231. data/test/pgn_collection/valid/0186.pgn +13 -15
  232. data/test/pgn_collection/valid/0187.pgn +17 -19
  233. data/test/pgn_collection/valid/0189.pgn +16 -20
  234. data/test/pgn_collection/valid/0191.pgn +18 -26
  235. data/test/pgn_collection/valid/0193.pgn +16 -18
  236. data/test/pgn_collection/valid/0196.pgn +16 -21
  237. data/test/pgn_collection/valid/0197.pgn +15 -21
  238. data/test/pgn_collection/valid/0198.pgn +15 -20
  239. data/test/pgn_collection/valid/0199.pgn +11 -13
  240. data/test/pgn_collection/valid/0202.pgn +10 -12
  241. data/test/pgn_collection/valid/0203.pgn +11 -13
  242. data/test/pgn_collection/valid/0204.pgn +12 -14
  243. data/test/pgn_collection/valid/0205.pgn +10 -13
  244. data/test/pgn_collection/valid/0209.pgn +14 -20
  245. data/test/pgn_collection/valid/0210.pgn +13 -15
  246. data/test/pgn_collection/valid/0216.pgn +13 -17
  247. data/test/pgn_collection/valid/0217.pgn +15 -21
  248. data/test/pgn_collection/valid/0221.pgn +18 -26
  249. data/test/pgn_collection/valid/0222.pgn +12 -21
  250. data/test/pgn_collection/valid/0225.pgn +16 -19
  251. data/test/pgn_collection/valid/0226.pgn +14 -19
  252. data/test/pgn_collection/valid/0228.pgn +12 -21
  253. data/test/pgn_collection/valid/0229.pgn +13 -16
  254. data/test/pgn_collection/valid/0231.pgn +14 -22
  255. data/test/pgn_collection/valid/0235.pgn +16 -23
  256. data/test/pgn_collection/valid/0238.pgn +12 -16
  257. data/test/pgn_collection/valid/0239.pgn +18 -21
  258. data/test/pgn_collection/valid/0240.pgn +13 -15
  259. data/test/pgn_collection/valid/0241.pgn +12 -21
  260. data/test/pgn_collection/valid/0242.pgn +18 -26
  261. data/test/pgn_collection/valid/0243.pgn +10 -13
  262. data/test/pgn_collection/valid/0246.pgn +11 -15
  263. data/test/pgn_collection/valid/0256.pgn +15 -18
  264. data/test/pgn_collection/valid/0257.pgn +16 -22
  265. data/test/pgn_collection/valid/0261.pgn +14 -16
  266. data/test/pgn_collection/valid/0263.pgn +10 -12
  267. data/test/pgn_collection/valid/0266.pgn +10 -13
  268. data/test/pgn_collection/valid/0267.pgn +12 -14
  269. data/test/pgn_collection/valid/0271.pgn +20 -22
  270. data/test/pgn_collection/valid/0276.pgn +16 -24
  271. data/test/pgn_collection/valid/0278.pgn +13 -17
  272. data/test/pgn_collection/valid/0284.pgn +9 -11
  273. data/test/pgn_collection/valid/0289.pgn +15 -23
  274. data/test/pgn_collection/valid/0290.pgn +22 -24
  275. data/test/pgn_collection/valid/0291.pgn +14 -20
  276. data/test/pgn_collection/valid/0292.pgn +11 -15
  277. data/test/pgn_collection/valid/0298.pgn +18 -25
  278. data/test/pgn_collection/valid/0300.pgn +13 -15
  279. data/test/pgn_collection/valid/0304.pgn +12 -18
  280. data/test/pgn_collection/valid/0309.pgn +17 -19
  281. data/test/pgn_collection/valid/0310.pgn +17 -24
  282. data/test/pgn_collection/valid/0313.pgn +13 -15
  283. data/test/pgn_collection/valid/0314.pgn +18 -21
  284. data/test/pgn_collection/valid/0318.pgn +10 -12
  285. data/test/pgn_collection/valid/0320.pgn +13 -18
  286. data/test/pgn_collection/valid/0325.pgn +15 -21
  287. data/test/pgn_collection/valid/0328.pgn +11 -15
  288. data/test/pgn_collection/valid/0333.pgn +14 -16
  289. data/test/pgn_collection/valid/0338.pgn +20 -24
  290. data/test/pgn_collection/valid/0339.pgn +18 -22
  291. data/test/pgn_collection/valid/0343.pgn +11 -14
  292. data/test/pgn_collection/valid/0349.pgn +21 -30
  293. data/test/pgn_collection/valid/0350.pgn +14 -20
  294. data/test/pgn_collection/valid/0356.pgn +14 -17
  295. data/test/pgn_collection/valid/0359.pgn +15 -17
  296. data/test/pgn_collection/valid/0369.pgn +17 -25
  297. data/test/pgn_collection/valid/0373.pgn +15 -19
  298. data/test/pgn_collection/valid/0374.pgn +13 -16
  299. data/test/pgn_collection/valid/0381.pgn +11 -17
  300. data/test/pgn_collection/valid/0386.pgn +14 -21
  301. data/test/pgn_collection/valid/0387.pgn +12 -17
  302. data/test/pgn_collection/valid/0388.pgn +16 -20
  303. data/test/pgn_collection/valid/0393.pgn +15 -18
  304. data/test/pgn_collection/valid/0395.pgn +10 -13
  305. data/test/pgn_collection/valid/0399.pgn +20 -24
  306. data/test/pgn_collection/valid/0402.pgn +14 -22
  307. data/test/pgn_collection/valid/0409.pgn +15 -23
  308. data/test/pgn_collection/valid/0417.pgn +15 -21
  309. data/test/pgn_collection/valid/0421.pgn +21 -24
  310. data/test/pgn_collection/valid/0422.pgn +15 -22
  311. data/test/pgn_collection/valid/0423.pgn +17 -23
  312. data/test/pgn_collection/valid/0427.pgn +11 -14
  313. data/test/pgn_collection/valid/0429.pgn +12 -16
  314. data/test/pgn_collection/valid/0433.pgn +15 -17
  315. data/test/pgn_collection/valid/0434.pgn +11 -20
  316. data/test/pgn_collection/valid/0438.pgn +12 -16
  317. data/test/pgn_collection/valid/0439.pgn +22 -26
  318. data/test/pgn_collection/valid/0440.pgn +21 -24
  319. data/test/pgn_collection/valid/0447.pgn +21 -25
  320. data/test/pgn_collection/valid/0450.pgn +15 -16
  321. data/test/pgn_collection/valid/0451.pgn +11 -14
  322. data/test/pgn_collection/valid/0453.pgn +13 -15
  323. data/test/pgn_collection/valid/0462.pgn +17 -25
  324. data/test/pgn_collection/valid/0463.pgn +12 -14
  325. data/test/pgn_collection/valid/0469.pgn +16 -18
  326. data/test/pgn_collection/valid/0471.pgn +11 -15
  327. data/test/pgn_collection/valid/0472.pgn +20 -29
  328. data/test/pgn_collection/valid/0473.pgn +12 -19
  329. data/test/pgn_collection/valid/0474.pgn +15 -20
  330. data/test/pgn_collection/valid/0476.pgn +11 -18
  331. data/test/pgn_collection/valid/0477.pgn +21 -30
  332. data/test/pgn_collection/valid/0480.pgn +13 -18
  333. data/test/pgn_collection/valid/0488.pgn +12 -18
  334. data/test/pgn_collection/valid/0490.pgn +15 -21
  335. data/test/pgn_collection/valid/0491.pgn +10 -15
  336. data/test/pgn_collection/valid/0503.pgn +15 -23
  337. data/test/pgn_collection/valid/0508.pgn +10 -13
  338. data/test/pgn_collection/valid/0509.pgn +20 -22
  339. data/test/pgn_collection/valid/0515.pgn +10 -12
  340. data/test/pgn_collection/valid/0518.pgn +17 -23
  341. data/test/pgn_collection/valid/0530.pgn +16 -19
  342. data/test/pgn_collection/valid/0531.pgn +13 -18
  343. data/test/pgn_collection/valid/0533.pgn +17 -19
  344. data/test/pgn_collection/valid/0534.pgn +17 -25
  345. data/test/pgn_collection/valid/0535.pgn +13 -17
  346. data/test/pgn_collection/valid/0536.pgn +13 -21
  347. data/test/pgn_collection/valid/0537.pgn +12 -17
  348. data/test/pgn_collection/valid/0540.pgn +14 -19
  349. data/test/pgn_collection/valid/0541.pgn +12 -17
  350. data/test/pgn_collection/valid/0542.pgn +15 -17
  351. data/test/pgn_collection/valid/0545.pgn +15 -19
  352. data/test/pgn_collection/valid/0546.pgn +12 -21
  353. data/test/pgn_collection/valid/0547.pgn +15 -17
  354. data/test/pgn_collection/valid/0548.pgn +14 -17
  355. data/test/pgn_collection/valid/0552.pgn +16 -22
  356. data/test/pgn_collection/valid/0557.pgn +12 -14
  357. data/test/pgn_collection/valid/0558.pgn +15 -21
  358. data/test/pgn_collection/valid/0561.pgn +13 -15
  359. data/test/pgn_collection/valid/0568.pgn +12 -20
  360. data/test/pgn_collection/valid/0569.pgn +15 -20
  361. data/test/pgn_collection/valid/0572.pgn +13 -17
  362. data/test/pgn_collection/valid/0573.pgn +13 -17
  363. data/test/pgn_collection/valid/0579.pgn +18 -25
  364. data/test/pgn_collection/valid/0580.pgn +14 -19
  365. data/test/pgn_collection/valid/0581.pgn +10 -13
  366. data/test/pgn_collection/valid/0586.pgn +15 -20
  367. data/test/pgn_collection/valid/0587.pgn +12 -16
  368. data/test/pgn_collection/valid/0589.pgn +12 -15
  369. data/test/pgn_collection/valid/0590.pgn +17 -23
  370. data/test/pgn_collection/valid/0592.pgn +15 -21
  371. data/test/pgn_collection/valid/0595.pgn +14 -16
  372. data/test/pgn_collection/valid/0597.pgn +14 -20
  373. data/test/pgn_collection/valid/0598.pgn +13 -18
  374. data/test/pgn_collection/valid/0603.pgn +12 -21
  375. data/test/pgn_collection/valid/0605.pgn +14 -20
  376. data/test/pgn_collection/valid/0607.pgn +12 -16
  377. data/test/pgn_collection/valid/0609.pgn +11 -15
  378. data/test/pgn_collection/valid/0611.pgn +13 -21
  379. data/test/pgn_collection/valid/0612.pgn +17 -18
  380. data/test/pgn_collection/valid/0613.pgn +9 -12
  381. data/test/pgn_collection/valid/0614.pgn +11 -15
  382. data/test/pgn_collection/valid/0615.pgn +16 -18
  383. data/test/pgn_collection/valid/0617.pgn +18 -26
  384. data/test/pgn_collection/valid/0618.pgn +13 -19
  385. data/test/pgn_collection/valid/0620.pgn +13 -22
  386. data/test/pgn_collection/valid/0630.pgn +13 -15
  387. data/test/pgn_collection/valid/0631.pgn +15 -21
  388. data/test/pgn_collection/valid/0634.pgn +12 -16
  389. data/test/pgn_collection/valid/0639.pgn +14 -19
  390. data/test/pgn_collection/valid/0640.pgn +19 -22
  391. data/test/pgn_collection/valid/0641.pgn +11 -14
  392. data/test/pgn_collection/valid/0646.pgn +15 -18
  393. data/test/pgn_collection/valid/0648.pgn +23 -28
  394. data/test/pgn_collection/valid/0650.pgn +13 -16
  395. data/test/pgn_collection/valid/0655.pgn +15 -20
  396. data/test/pgn_collection/valid/0656.pgn +14 -22
  397. data/test/pgn_collection/valid/0658.pgn +18 -26
  398. data/test/pgn_collection/valid/0659.pgn +13 -22
  399. data/test/pgn_collection/valid/0660.pgn +19 -27
  400. data/test/pgn_collection/valid/0665.pgn +10 -13
  401. data/test/pgn_collection/valid/0667.pgn +12 -20
  402. data/test/pgn_collection/valid/0669.pgn +15 -22
  403. data/test/pgn_collection/valid/0671.pgn +16 -19
  404. data/test/pgn_collection/valid/0673.pgn +13 -19
  405. data/test/pgn_collection/valid/0674.pgn +13 -15
  406. data/test/pgn_collection/valid/0679.pgn +14 -16
  407. data/test/pgn_collection/valid/0680.pgn +15 -21
  408. data/test/pgn_collection/valid/0689.pgn +16 -24
  409. data/test/pgn_collection/valid/0692.pgn +18 -26
  410. data/test/pgn_collection/valid/0702.pgn +12 -18
  411. data/test/pgn_collection/valid/0712.pgn +11 -12
  412. data/test/pgn_collection/valid/0714.pgn +15 -21
  413. data/test/pgn_collection/valid/0715.pgn +13 -17
  414. data/test/pgn_collection/valid/0717.pgn +15 -23
  415. data/test/pgn_collection/valid/0720.pgn +16 -21
  416. data/test/pgn_collection/valid/0721.pgn +14 -19
  417. data/test/pgn_collection/valid/0722.pgn +22 -32
  418. data/test/pgn_collection/valid/0728.pgn +14 -16
  419. data/test/pgn_collection/valid/0732.pgn +19 -21
  420. data/test/pgn_collection/valid/0734.pgn +14 -20
  421. data/test/pgn_collection/valid/0739.pgn +12 -20
  422. data/test/pgn_collection/valid/0740.pgn +12 -15
  423. data/test/pgn_collection/valid/0743.pgn +12 -18
  424. data/test/pgn_collection/valid/0752.pgn +14 -18
  425. data/test/pgn_collection/valid/0754.pgn +16 -24
  426. data/test/pgn_collection/valid/0758.pgn +12 -14
  427. data/test/pgn_collection/valid/0759.pgn +15 -19
  428. data/test/pgn_collection/valid/0762.pgn +12 -16
  429. data/test/pgn_collection/valid/0764.pgn +17 -21
  430. data/test/pgn_collection/valid/0765.pgn +15 -21
  431. data/test/pgn_collection/valid/0767.pgn +17 -25
  432. data/test/pgn_collection/valid/0768.pgn +13 -15
  433. data/test/pgn_collection/valid/0770.pgn +19 -21
  434. data/test/pgn_collection/valid/0773.pgn +18 -24
  435. data/test/pgn_collection/valid/0775.pgn +12 -14
  436. data/test/pgn_collection/valid/0783.pgn +15 -21
  437. data/test/pgn_collection/valid/0789.pgn +15 -21
  438. data/test/pgn_collection/valid/0794.pgn +12 -14
  439. data/test/pgn_collection/valid/0795.pgn +17 -23
  440. data/test/pgn_collection/valid/0797.pgn +17 -24
  441. data/test/pgn_collection/valid/0800.pgn +9 -12
  442. data/test/pgn_collection/valid/0812.pgn +14 -16
  443. data/test/pgn_collection/valid/0814.pgn +18 -21
  444. data/test/pgn_collection/valid/0815.pgn +11 -20
  445. data/test/pgn_collection/valid/0817.pgn +14 -19
  446. data/test/pgn_collection/valid/0818.pgn +10 -12
  447. data/test/pgn_collection/valid/0822.pgn +18 -25
  448. data/test/pgn_collection/valid/0828.pgn +11 -12
  449. data/test/pgn_collection/valid/0830.pgn +12 -16
  450. data/test/pgn_collection/valid/0837.pgn +11 -15
  451. data/test/pgn_collection/valid/0842.pgn +20 -29
  452. data/test/pgn_collection/valid/0843.pgn +15 -18
  453. data/test/pgn_collection/valid/0856.pgn +17 -23
  454. data/test/pgn_collection/valid/0861.pgn +12 -14
  455. data/test/pgn_collection/valid/0866.pgn +17 -24
  456. data/test/pgn_collection/valid/0867.pgn +13 -17
  457. data/test/pgn_collection/valid/0875.pgn +11 -13
  458. data/test/pgn_collection/valid/0882.pgn +14 -17
  459. data/test/pgn_collection/valid/0883.pgn +12 -14
  460. data/test/pgn_collection/valid/0888.pgn +19 -27
  461. data/test/pgn_collection/valid/0889.pgn +27 -39
  462. data/test/pgn_collection/valid/0891.pgn +12 -17
  463. data/test/pgn_collection/valid/0892.pgn +15 -18
  464. data/test/pgn_collection/valid/0903.pgn +14 -22
  465. data/test/pgn_collection/valid/0905.pgn +13 -18
  466. data/test/pgn_collection/valid/0906.pgn +10 -12
  467. data/test/pgn_collection/valid/0917.pgn +18 -21
  468. data/test/pgn_collection/valid/0918.pgn +11 -14
  469. data/test/pgn_collection/valid/0920.pgn +17 -23
  470. data/test/pgn_collection/valid/0921.pgn +13 -15
  471. data/test/pgn_collection/valid/0922.pgn +17 -25
  472. data/test/pgn_collection/valid/0926.pgn +14 -17
  473. data/test/pgn_collection/valid/0928.pgn +12 -14
  474. data/test/pgn_collection/valid/0929.pgn +16 -20
  475. data/test/pgn_collection/valid/0935.pgn +19 -27
  476. data/test/pgn_collection/valid/0936.pgn +11 -15
  477. data/test/pgn_collection/valid/0938.pgn +11 -14
  478. data/test/pgn_collection/valid/0940.pgn +13 -15
  479. data/test/pgn_collection/valid/0946.pgn +15 -18
  480. data/test/pgn_collection/valid/0952.pgn +19 -27
  481. data/test/pgn_collection/valid/0957.pgn +15 -19
  482. data/test/pgn_collection/valid/0959.pgn +15 -23
  483. data/test/pgn_collection/valid/0966.pgn +14 -16
  484. data/test/pgn_collection/valid/0972.pgn +14 -17
  485. data/test/pgn_collection/valid/0974.pgn +17 -24
  486. data/test/pgn_collection/valid/0975.pgn +12 -14
  487. data/test/pgn_collection/valid/0977.pgn +10 -14
  488. data/test/pgn_collection/valid/0979.pgn +17 -19
  489. data/test/pgn_collection/valid/0981.pgn +12 -21
  490. data/test/pgn_collection/valid/0982.pgn +13 -18
  491. data/test/pgn_collection/valid/0984.pgn +19 -27
  492. data/test/pgn_collection/valid/0987.pgn +13 -15
  493. data/test/pgn_collection/valid/0993.pgn +11 -15
  494. data/test/pgn_collection/valid/0997.pgn +16 -24
  495. data/test/test_checkmate.rb +4 -2
  496. data/test/test_insufficient_material.rb +3 -2
  497. data/test/test_pgn_collection.rb +5 -1
  498. data/test/test_stalemate.rb +1 -0
  499. metadata +313 -319
  500. data/test/pgn_collection/valid/checkmate/0925.pgn +0 -26
  501. data/test/pgn_collection/valid/checkmate/checkmate.pgn +0 -11
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5e8d9bcf7754e4c8e0d2b1d4d01c582e0e7b528f
4
+ data.tar.gz: 6c8c63bd47574c15439dc41ce39203b9aaaf4d01
5
+ SHA512:
6
+ metadata.gz: cf55d121ea3c0f8d32a146506730f03a277526cdcbf34a2e9a06ca98332354162a5c76ded3d5fbf239a3f7ac150e482e8b7a867fff7ee0359aeac72c97c8915e
7
+ data.tar.gz: c642b34d64cd9358b1649b03a1197c32850f8620248ee2584a5d3b192284129731a7bd08ca5b26ff96241fbd05d46939208044134a898792ef54ba4a840e63df
data/README.rdoc CHANGED
@@ -5,6 +5,10 @@ This library is quite fast because rappresent
5
5
  the game situations with bitboards. In addition, the
6
6
  move generator is written in C as a Ruby extension.
7
7
 
8
+ == Requirements
9
+
10
+ * Ruby 1.9 or higher
11
+
8
12
  == Installation
9
13
 
10
14
  gem install chess
@@ -13,13 +17,13 @@ move generator is written in C as a Ruby extension.
13
17
 
14
18
  require 'chess'
15
19
  g = Chess::Game.new
16
- while (!g.over?)
20
+ until g.over?
17
21
  begin
18
22
  print "Give me a #{g.active_player} move: "
19
23
  input = gets.chop
20
24
  break if input == 'quit'
21
25
  g << input
22
- puts g.board
26
+ puts g
23
27
  puts g.moves.last
24
28
  rescue Chess::IllegalMoveError => e
25
29
  puts 'Illegal move!'
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ Rake::RDocTask.new do |rd|
6
6
  rd.main = 'README.rdoc'
7
7
  rd.rdoc_dir = 'doc'
8
8
  rd.rdoc_files.include('README.rdoc', 'lib/**/*.rb', 'ext/*.c')
9
- rd.options << '-f' << 'horo'
9
+ #rd.options << '-f' << 'horo'
10
10
  end
11
11
 
12
12
  require 'rake/testtask'
data/ext/board.c CHANGED
@@ -408,10 +408,7 @@ try_move (Board *board, int from, int to, char promote_in, Board *new_board, cha
408
408
  if (require_a_promotion (new_board))
409
409
  {
410
410
  if (!promote (new_board, to, promote_in))
411
- {
412
- free (new_board);
413
- return 0;
414
- }
411
+ return FALSE;
415
412
  }
416
413
  else
417
414
  promote_in = 0;
data/ext/chess.c CHANGED
@@ -18,7 +18,7 @@ VALUE board_klass;
18
18
  VALUE
19
19
  game_alloc (VALUE class)
20
20
  {
21
- Game *g = init_game (g);
21
+ Game *g = init_game ();
22
22
  return Data_Wrap_Struct (class, 0, free_game, g);
23
23
  // VALUE tdata = Data_Wrap_Struct (class, 0, free_game, g);
24
24
  // rb_obj_call_init (tdata, 0, 0);
@@ -83,8 +83,8 @@ game_move (VALUE self, VALUE rb_piece, VALUE rb_disambiguating, VALUE rb_to_coor
83
83
  * Make a move. This add a new Board in the Game.
84
84
  *
85
85
  * Parameters are:
86
- * +from+:: The 2 character string representing the starting square of the moving piece <em>('a1', 'a2', ... , 'h7', 'h8')</em>.
87
- * +to+:: The 2 character string representing the ending square of the moving piece <em>('a1', 'a2', ... , 'h7', 'h8')</em>.
86
+ * +from+:: the 2 character string representing the starting square of the moving piece <em>('a1', 'a2', ... , 'h7', 'h8')</em>.
87
+ * +to+:: the 2 character string representing the ending square of the moving piece <em>('a1', 'a2', ... , 'h7', 'h8')</em>.
88
88
  * +promote_in+:: the character of promotion piece <em>('R', 'N', 'B', 'Q')</em>. If no promotion occured, this param will be ignored.
89
89
  * This method returns a string that represents the short algebraic chess notation of the move or raise an IllegalMoveError if the move is illegal.
90
90
  */
@@ -120,8 +120,8 @@ game_move2 (VALUE self, VALUE rb_from, VALUE rb_to, VALUE rb_promote_in)
120
120
  * +-------------------------
121
121
  * a b c d e f g h
122
122
  * Parameters are:
123
- * +from+:: The integer representing the starting square of the moving piece.
124
- * +to+:: The integer representing the ending square of the moving piece.
123
+ * +from+:: the integer representing the starting square of the moving piece.
124
+ * +to+:: the integer representing the ending square of the moving piece.
125
125
  * +promote_in+:: the character of promotion piece <em>('R', 'N', 'B', 'Q')</em>. If no promotion occured, this param will be ignored.
126
126
  * This method returns a string that represents the short algebraic chess notation of the move or raise an IllegalMoveError if the move is illegal.
127
127
  */
@@ -140,6 +140,45 @@ game_move3 (VALUE self, VALUE rb_from, VALUE rb_to, VALUE rb_promote_in)
140
140
  rb_raise (illegal_move_error, "Illegal move");
141
141
  }
142
142
 
143
+ /*
144
+ * call-seq: resign(color)
145
+ *
146
+ * The game result is set to '1-0' if +color+ is "black", otherwise is set to '0-1' if color is "white".
147
+ *
148
+ * Parameters are:
149
+ * +color+:: the color of the player who resigns the game; it can be +:white+ or +:black+.
150
+ */
151
+ VALUE
152
+ game_resign (VALUE self, VALUE color)
153
+ {
154
+ Game *g;
155
+ Data_Get_Struct (self, Game, g);
156
+ const char *c;
157
+ if (TYPE (color) == T_SYMBOL)
158
+ c = rb_id2name (SYM2ID (color));
159
+ else
160
+ c = StringValuePtr (color);
161
+ if (strcmp (c, "black") == 0)
162
+ g->result = WHITE_WON;
163
+ else if (strcmp (c, "white") == 0)
164
+ g->result = BLACK_WON;
165
+ return Qnil;
166
+ }
167
+
168
+ /*
169
+ * call-seq: draw
170
+ *
171
+ * The game result is set to draw.
172
+ */
173
+ VALUE
174
+ game_draw (VALUE self)
175
+ {
176
+ Game *g;
177
+ Data_Get_Struct (self, Game, g);
178
+ g->result = DRAW;
179
+ return Qnil;
180
+ }
181
+
143
182
  /*
144
183
  * call-seq: [n]
145
184
  *
@@ -160,10 +199,10 @@ game_boards (VALUE self, VALUE index)
160
199
  /*
161
200
  * call-seq: current
162
201
  *
163
- * Returns the current Board of the Game.
202
+ * Returns the current Board of the Game (the current chess position of the game).
164
203
  */
165
204
  VALUE
166
- game_last_board (VALUE self)
205
+ game_current_board (VALUE self)
167
206
  {
168
207
  Game *g;
169
208
  Data_Get_Struct (self, Game, g);
@@ -225,8 +264,8 @@ game_threefold_repetition (VALUE self)
225
264
  *
226
265
  * Returns the result of the game:
227
266
  * *:: game in progress;
228
- * 1-0:: white wins;
229
- * 0-1:: black wins;
267
+ * 1-0:: white won;
268
+ * 0-1:: black won;
230
269
  * 1/2-1/2:: draw
231
270
  */
232
271
  VALUE
@@ -289,19 +328,59 @@ game_rollback (VALUE self)
289
328
  return self;
290
329
  }
291
330
 
331
+ /*
332
+ * call-seq: to_s
333
+ *
334
+ * Current board to string.
335
+ */
336
+ VALUE
337
+ game_to_s (VALUE self)
338
+ {
339
+ Game *g;
340
+ Data_Get_Struct (self, Game, g);
341
+ Board *b = get_board (g, g->current-1);
342
+ char *s = print_board (b);
343
+ VALUE rb_s = rb_str_new2 (s);
344
+ free (s);
345
+ return rb_s;
346
+ }
347
+
292
348
  // Board
293
349
 
294
350
  /*
295
- * call-seq: [square]
351
+ * call-seq: placement { |piece, index| block }
296
352
  *
297
- * Return the piece in +square+ of the board.
353
+ * Calls +block+ once for each square in the board, passing the
354
+ * +piece+ in the square and the +index+ as parameters. Return self.
355
+ * If no block is given, the array of pieces is returned instead.
298
356
  */
299
357
  VALUE
300
- board_get_piece_at (VALUE self, VALUE square)
358
+ board_placement (VALUE self)
301
359
  {
302
360
  Board *board;
303
361
  Data_Get_Struct (self, Board, board);
304
- return CHR2FIX (board->placement[NUM2INT (square)]);
362
+ int i;
363
+ char piece[2];
364
+ piece[1] = '\0';
365
+ if (!rb_block_given_p ())
366
+ {
367
+ VALUE placement = rb_ary_new ();
368
+ for (i = 0; i < 64; i++)
369
+ {
370
+ piece[0] = board->placement[i];
371
+ rb_ary_push (placement, rb_str_new2 (piece));
372
+ }
373
+ return placement;
374
+ }
375
+ else
376
+ {
377
+ for (i = 0; i < 64; i++)
378
+ {
379
+ piece[0] = board->placement[i];
380
+ rb_yield_values (2, rb_str_new2 (piece), INT2FIX (i));
381
+ }
382
+ return self;
383
+ }
305
384
  }
306
385
 
307
386
  /*
@@ -475,8 +554,10 @@ Init_chess ()
475
554
  rb_define_method (game, "move", game_move, 4);
476
555
  rb_define_method (game, "move2", game_move2, 3);
477
556
  rb_define_method (game, "move3", game_move3, 3);
557
+ rb_define_method (game, "resign", game_resign, 1);
558
+ rb_define_method (game, "draw", game_draw, 0);
478
559
  rb_define_method (game, "[]", game_boards, 1);
479
- rb_define_method (game, "board", game_last_board, 0);
560
+ rb_define_method (game, "current", game_current_board, 0);
480
561
  rb_define_method (game, "moves", game_moves, 0);
481
562
  rb_define_method (game, "full_moves", game_full_moves, 0);
482
563
  rb_define_method (game, "threefold_repetition?", game_threefold_repetition, 0);
@@ -484,6 +565,8 @@ Init_chess ()
484
565
  rb_define_method (game, "size", game_size, 0);
485
566
  rb_define_method (game, "each", game_each, 0);
486
567
  rb_define_method (game, "rollback!", game_rollback, 0);
568
+ rb_define_method (game, "to_s", game_to_s, 0);
569
+ rb_define_alias (game, "board", "current");
487
570
 
488
571
  /*
489
572
  * This class rappresents a chess board.
@@ -491,7 +574,7 @@ Init_chess ()
491
574
  * This ensures a fast library.
492
575
  */
493
576
  board_klass = rb_define_class_under (chess, "Board", rb_cObject);
494
- rb_define_method (board_klass, "[]", board_get_piece_at, 1);
577
+ rb_define_method (board_klass, "placement", board_placement, 0);
495
578
  rb_define_method (board_klass, "check?", board_king_in_check, 0);
496
579
  rb_define_method (board_klass, "checkmate?", board_king_in_checkmate, 0);
497
580
  rb_define_method (board_klass, "stalemate?", board_stalemate, 0);
data/ext/chess.h CHANGED
@@ -15,8 +15,10 @@ VALUE game_set_fen (VALUE self, VALUE fen);
15
15
  VALUE game_move (VALUE self, VALUE rb_piece, VALUE rb_disambiguating, VALUE rb_to_coord, VALUE rb_promote_in);
16
16
  VALUE game_move2 (VALUE self, VALUE rb_from, VALUE rb_to, VALUE rb_promote_in);
17
17
  VALUE game_move3 (VALUE self, VALUE rb_from, VALUE rb_to, VALUE rb_promote_in);
18
+ VALUE game_resign (VALUE self, VALUE color);
19
+ VALUE game_draw (VALUE self);
18
20
  VALUE game_boards (VALUE self, VALUE index);
19
- VALUE game_board (VALUE self);
21
+ VALUE game_current_board (VALUE self);
20
22
  VALUE game_moves (VALUE self);
21
23
  VALUE game_full_moves (VALUE self);
22
24
  VALUE game_threefold_repetition (VALUE self);
@@ -24,11 +26,11 @@ VALUE game_result (VALUE self);
24
26
  VALUE game_size (VALUE self);
25
27
  VALUE game_each (VALUE self);
26
28
  VALUE game_rollback (VALUE self);
27
-
29
+ VALUE game_to_s (VALUE self);
28
30
 
29
31
  // Board
30
32
 
31
- VALUE board_get_piece_at (VALUE self, VALUE square);
33
+ VALUE board_placement (VALUE self);
32
34
  VALUE board_king_in_check (VALUE self);
33
35
  VALUE board_king_in_checkmate (VALUE self);
34
36
  VALUE board_stalemate (VALUE self);
data/ext/common.c CHANGED
@@ -59,10 +59,10 @@ result_to_s (unsigned short int r)
59
59
  char *s = (char *) malloc (8);
60
60
  switch (r)
61
61
  {
62
- case WHITE_WINS:
62
+ case WHITE_WON:
63
63
  strcpy (s, "1-0");
64
64
  break;
65
- case BLACK_WINS:
65
+ case BLACK_WON:
66
66
  strcpy (s, "0-1");
67
67
  break;
68
68
  case DRAW:
@@ -100,7 +100,7 @@ en_passant_to_s (short int en_passant)
100
100
  return s;
101
101
  }
102
102
 
103
- bool
103
+ int
104
104
  compare (const void *a, const void *b)
105
105
  {
106
106
  return strcmp (*(const char **) a, *(const char **) b);
data/ext/common.h CHANGED
@@ -90,12 +90,12 @@
90
90
  #define BLACK_SHORT_CASTLING 3
91
91
  #define BLACK_LONG_CASTLING 4
92
92
 
93
- #define WHITE_WINS 0
94
- #define BLACK_WINS 1
93
+ #define WHITE_WON 0
94
+ #define BLACK_WON 1
95
95
  #define DRAW 2
96
96
  #define IN_PROGRESS 3
97
97
 
98
- typedef int bool;
98
+ typedef unsigned short bool;
99
99
 
100
100
  char square_to_file (int square);
101
101
  char square_to_rank (int square);
@@ -105,6 +105,6 @@ char* ft_to_full_move (int from, int to, char promote_in);
105
105
  char* result_to_s (unsigned short int r);
106
106
  char* castling_to_s (short int castling);
107
107
  char* en_passant_to_s (short int en_passant);
108
- bool compare (const void * a, const void * b);
108
+ int compare (const void *a, const void *b);
109
109
 
110
110
  #endif
data/ext/game.c CHANGED
@@ -138,9 +138,14 @@ rollback (Game *g)
138
138
  bool
139
139
  threefold_repetition (Game *g)
140
140
  {
141
+ if (g->current < 6) // Minimum moves to get a threefold repetition
142
+ return FALSE;
141
143
  char placement[65];
144
+ char turn;
142
145
  char *fen, *castling, *ep;
143
- char* s[g->current];
146
+ char* s[g->current + 1];
147
+ s[0] = (char *) malloc (80);
148
+ strcpy (s[0], "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -");
144
149
  int i, j;
145
150
  bool found = FALSE;
146
151
  for (i = 0; i < g->current; i++)
@@ -149,16 +154,17 @@ threefold_repetition (Game *g)
149
154
  for (j = 0; fen[j] != ' '; j++)
150
155
  placement[j] = fen[j];
151
156
  placement[j] = '\0';
152
- s[i] = (char *) malloc (80);
157
+ s[i+1] = (char *) malloc (80);
158
+ turn = g->boards[i]->active_color ? 'b' : 'w';
153
159
  castling = castling_to_s (g->boards[i]->castling);
154
160
  ep = en_passant_to_s (g->boards[i]->en_passant);
155
- sprintf (s[i], "%s %s %s", placement, castling, ep);
161
+ sprintf (s[i+1], "%s %c %s %s", placement, turn, castling, ep);
156
162
  free (fen);
157
163
  free (castling);
158
164
  free (ep);
159
165
  }
160
- qsort (s, g->current, sizeof (char *), compare);
161
- for (i = 0; i < g->current-2; i++)
166
+ qsort (s, g->current + 1, sizeof (char *), compare);
167
+ for (i = 0; i < g->current - 1; i++)
162
168
  {
163
169
  if (strcmp (s[i], s[i+1]) == 0 && strcmp (s[i], s[i+2]) == 0)
164
170
  {
@@ -167,16 +173,25 @@ threefold_repetition (Game *g)
167
173
  }
168
174
  free (s[i]);
169
175
  }
176
+ free (s[g->current]);
170
177
  free (s[g->current-1]);
171
- free (s[g->current-2]);
172
178
  return found;
173
179
  }
174
180
 
181
+ /*
182
+ A FEN string is composed of 6 parts separated by " " (space).
183
+ 1. Piece placement (from white's perspective).
184
+ 2. Active color. "w" means white moves next, "b" means black.
185
+ 3. Castling availability. If neither side can castle, this is "-".
186
+ 4. En passant target square in algebraic notation. If there's no en passant target square, this is "-".
187
+ 5. Halfmove clock: this is the number of halfmoves since the last pawn advance or capture.
188
+ 6. Fullmove number: the number of the full move. It starts at 1, and is incremented after black's move.
189
+ */
175
190
  void
176
191
  set_fen (Game *g, const char *fen)
177
192
  {
178
193
  Board *board = NEW_BOARD;
179
- int i = 0, j, k, pos, square;
194
+ int i = 0, j, k, square;
180
195
  char *pch;
181
196
  char *s = (char *) malloc (strlen (fen));
182
197
  strcpy (s, fen);
data/lib/chess/game.rb CHANGED
@@ -17,14 +17,27 @@ module Chess
17
17
  pgn = Chess::Pgn.new(file)
18
18
  game = Chess::Game.new
19
19
  pgn.moves.each { |m| game.move(m) }
20
+ if !game.over?
21
+ case pgn.result
22
+ when '1-0'
23
+ game.resign(:black)
24
+ when '0-1'
25
+ game.resign(:white)
26
+ when '1/2-1/2'
27
+ if game.board.insufficient_material? || game.board.stalemate? ||
28
+ game.threefold_repetition? || game.board.fifty_rule_move?
29
+ game.draw
30
+ end
31
+ end
32
+ end
20
33
  return game
21
34
  end
22
35
 
23
36
  # Creates a new game from a FEN string.
24
- # *Warning*: this game do not have history before the FEN placement.
25
37
  # May be raise an InvalidFenFormatError.
38
+ # *Warning*: this game do not have history before the FEN placement.
26
39
  def self.load_fen(fen)
27
- if fen =~ /^((?:[PRNBQKprnbqk1-8]{1,8}\/){7}[RNBQKPrnbqkp1-8]{1,8})\s(w|b)\s(K?Q?k?q?|\-)\s([a-h][1-8]|\-)\s(\d+)\s(\d+)$/
40
+ if fen =~ /^((?:[PRNBQKprnbqk1-8]{1,8}\/){7}[RNBQKPrnbqkp1-8]{1,8})\s(w|b)\s(K?Q?k?q?|-)\s([a-h][1-8]|-)\s(\d+)\s(\d+)$/
28
41
  game = Chess::Game.new
29
42
  game.set_fen!(fen)
30
43
  return game
@@ -72,24 +85,40 @@ module Chess
72
85
  # Returns the status of the game.
73
86
  # Possible states are:
74
87
  # * +in_progress+:: the game is in progress.
75
- # * +white_wins+:: white player checkmate the black king.
76
- # * +black_wins+:: black player checkmate the white king.
77
- # * +stalemate+:: draw for stalemate
88
+ # * +white_won+:: white player has won with a checkmate.
89
+ # * +black_won+:: black player has won with a checkmate.
90
+ # * +white_won_resign+:: white player has won for resign.
91
+ # * +black_won_resign+:: black player has won for resign.
92
+ # * +stalemate+:: draw for stalemate.
78
93
  # * +insufficient_material+:: draw for insufficient material to checkmate.
94
+ # * +fifty_rule_move+:: draw for fifty rule move.
95
+ # * +threefold_repetition+:: draw for threefold_repetition.
79
96
  # * +unknown+:: something went wrong.
80
97
  def status
81
98
  case self.result
82
99
  when '*'
83
100
  return :in_progress
84
101
  when '1-0'
85
- return :white_wins
102
+ if self.board.checkmate?
103
+ return :white_won
104
+ else
105
+ return :white_won_resign
106
+ end
86
107
  when '0-1'
87
- return :black_wins
108
+ if self.board.checkmate?
109
+ return :black_won
110
+ else
111
+ return :black_won_resign
112
+ end
88
113
  when '1/2-1/2'
89
114
  if self.board.stalemate?
90
115
  return :stalemate
91
116
  elsif self.board.insufficient_material?
92
117
  return :insufficient_material
118
+ elsif self.board.fifty_rule_move?
119
+ return :fifty_rule_move
120
+ elsif self.threefold_repetition?
121
+ return :threefold_repetition
93
122
  end
94
123
  end
95
124
  return :unknown
@@ -111,28 +140,28 @@ module Chess
111
140
  private
112
141
 
113
142
  # Expand the short algebraic chess notation string +m+ in a hash like this:
114
- # Ngxe2 ==> { :name => 'N', :dis => 'g', :from => nil, :to => 'e2', :promotion => '' }
143
+ # Ngxe2 ==> { name: 'N', dis: 'g', from: nil, to: 'e2', promotion: '' }
115
144
  def expand_move(m)
116
- if match = m.match(/^(R|N|B|Q|K)?([a-h]?[1-8]?)(?:x)?([a-h][1-8])(?:=?(R|N|B|Q))?(?:ep)?(?:\+|\#)?$/)
145
+ if match = m.match(/^([RNBQK])?([a-h]?[1-8]?)(?:x)?([a-h][1-8])(?:=?([RrNnBbQq]))?(?:ep)?(?:\+|\#)?$/)
117
146
  expand = {
118
- :name => match[1] || 'P', # Piece name (P|R|N|B|Q|K)
119
- :dis => match[2], # Disambiguating move
120
- :to => match[3], # Move to
121
- :promotion => match[4].to_s, # Promote with
147
+ name: match[1] || 'P', # Piece name [RNBQK]
148
+ dis: match[2], # Disambiguating move
149
+ to: match[3], # Move to
150
+ promotion: match[4].to_s, # Promote with
122
151
  }
123
152
  expand[:from] = match[2] if match[2] && match[2].size == 2
124
153
  return expand
125
- elsif m =~ /^(0|O)-(0|O)(\+|\#)?$/
154
+ elsif m =~ /^([0O])-([0O])([\+#])?$/
126
155
  if self.board.active_color # black king short castling
127
- return { :name => 'K', :dis => '', :from => 'e8', :to => 'g8', :promotion => '' }
156
+ return { name: 'K', dis: '', from: 'e8', to: 'g8', promotion: '' }
128
157
  else # white king short castling
129
- return { :name => 'K', :dis => '', :from => 'e1', :to => 'g1', :promotion => '' }
158
+ return { name: 'K', dis: '', from: 'e1', to: 'g1', promotion: '' }
130
159
  end
131
- elsif m =~ /^(0|O)-(0|O)-(0|O)(\+|\#)?$/
160
+ elsif m =~ /^([0O])-([0O])-([0O])([\+#])?$/
132
161
  if self.board.active_color # black king long castling
133
- return { :name => 'K', :dis => '', :from => 'e8', :to => 'c8', :promotion => '' }
162
+ return { name: 'K', dis: '', from: 'e8', to: 'c8', promotion: '' }
134
163
  else # white king long castling
135
- return { :name => 'K', :dis => '', :from => 'e1', :to => 'c1', :promotion => '' }
164
+ return { name: 'K', dis: '', from: 'e1', to: 'c1', promotion: '' }
136
165
  end
137
166
  end
138
167
  raise BadNotationError.new(m)