Implementation of Lucifers Pastime
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

507 rindas
7.8KB

  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. use utf8;
  5. my $PAD_AXIS = " ";
  6. my $PAD_EVEN = " ";
  7. my $PAD_ODD = " ";
  8. my $HEX_1 = '-/--\-';
  9. my $HEX_2 = '| __ |';
  10. my $HEX_3 = '| |';
  11. my $XBOX_CHR = chr(0x2573);
  12. my $SHADE_CHR = chr(0x2591);
  13. my $ALT_US = chr(0x2017);
  14. my $ALT_PIPE = chr(0x2016);
  15. my $HL_1 = "|_____";
  16. my $HL_2 = $ALT_PIPE.$ALT_US.$ALT_US.$ALT_US.$ALT_US.$ALT_US;
  17. my $SUB_CHR = "_";
  18. my $ALT_SUB_CHR = $ALT_US;
  19. my $PREF_1 = substr($HEX_1, -2, 2);
  20. my $PREF_2 = ' ';
  21. my $PREF_3 = ' ';
  22. my $TRAIL_1 = substr($HEX_1, 0, 1);
  23. my $TRAIL_2 = substr($HEX_1, -1, 1);
  24. my $TRAIL_3 = substr($HEX_1, 0, 2);
  25. # Pieces
  26. my $MG_A = "A"; # Apprentice
  27. my $MG_I = "I"; # Iron Maiden
  28. my $MG_N = "N"; # Nekomata
  29. my $MG_IT = "It"; # Ittan-Momen
  30. my $MG_H = "H"; # Harpy
  31. my $MG_S = "S"; # Slime
  32. my $MG_RC = "Rc"; # Redcap
  33. my $MG_RO = "Hs"; # Red Oni
  34. my $MG_HS = "Ro"; # Holstaur
  35. my $MG_B = "B"; # Blue Oni
  36. my $MG_P = "P"; # Preistess
  37. my $MG_IM = "Im"; # Imp
  38. my $MG_F = "F"; # False Angel
  39. my $MG_QS = "Qs"; # Queen slime
  40. my $MG_AU = "Au"; # Automaton
  41. my $MG_SY = "Sy"; # Sylph
  42. my $MG_Q = "Q"; # Queen
  43. # Players
  44. my $P1 = "P1";
  45. my $P2 = "P2";
  46. my $DIV = ":";
  47. my %AXIS = (
  48. "A" => 1,
  49. "B" => 2,
  50. "C" => 3,
  51. "D" => 4,
  52. "E" => 5,
  53. "F" => 6,
  54. "G" => 7,
  55. "H" => 8,
  56. "I" => 9,
  57. "J" => 10,
  58. "K" => 11
  59. );
  60. my %AXIS_RV = map {
  61. $AXIS{$_} => $_
  62. } keys(%AXIS);
  63. #
  64. # /--\ +1
  65. # | __ |
  66. # | |+1
  67. # \--/
  68. # -1 -1
  69. #
  70. # ODD
  71. # UP: 0, +1
  72. # DOWN: -1, -1
  73. # EVEN
  74. # UP: +1, +1
  75. # DOWN: +0, -1
  76. # [Row move, Diag move]
  77. my %MOVE = (
  78. $MG_A => [
  79. [-1, 1],
  80. [ 0, 1]
  81. ],
  82. $MG_Q => [
  83. [ 0, 1],
  84. [ 1, 0],
  85. [-1, 0],
  86. [ 0,-1],
  87. ],
  88. $MG_I => [
  89. [0,0]
  90. ],
  91. $MG_IT => [
  92. [ 0,-1],
  93. [ 1,-1]
  94. ],
  95. $MG_N => [
  96. [-1, 2],
  97. [ 1,-2]
  98. ],
  99. $MG_H => [
  100. [-3, 2],
  101. [-1,-2],
  102. [ 1, 2],
  103. [ 3,-2]
  104. ],
  105. $MG_RC => [
  106. [-1, 0],
  107. [-2, 0],
  108. [ 0, 1],
  109. [ 0, 2]
  110. ],
  111. $MG_S => [
  112. [-1, 1],
  113. [-2, 2],
  114. [ 0, 1],
  115. [ 0, 2],
  116. [ 0,-1],
  117. [ 0,-2],
  118. [ 1,-1],
  119. [ 2,-2],
  120. ],
  121. $MG_HS => [
  122. [-3, 1],
  123. [-2,-1],
  124. [ 2, 1],
  125. [ 3,-1]
  126. ],
  127. $MG_RO => [
  128. [-1, 1],
  129. [ 0, 1],
  130. [ 1, 1],
  131. [ 1,-2]
  132. ],
  133. $MG_B => [
  134. [-1, 1],
  135. [ 0, 1],
  136. [ 0,-2],
  137. [ 1,-2]
  138. ],
  139. $MG_P => [
  140. [-4, 2],
  141. [-2, 1],
  142. [-2,-2],
  143. [-1,-1],
  144. [ 1, 1],
  145. [ 2,-1],
  146. [ 2, 2],
  147. [ 4,-2]
  148. ],
  149. $MG_IM => [
  150. [-2, 1],
  151. [-1,-1],
  152. [-1, 2],
  153. [ 1, 1],
  154. [ 1,-1],
  155. [ 1,-2],
  156. [ 2,-1]
  157. ],
  158. $MG_F => [
  159. [-1, 0],
  160. [-1, 1],
  161. [ 0, 1],
  162. [ 0,-1],
  163. [ 1, 0],
  164. [ 1,-1]
  165. ],
  166. $MG_QS => [
  167. [-3, 3],
  168. [-2, 2],
  169. [-2, 0],
  170. [-1, 0],
  171. [-1, 1],
  172. [ 0, 1],
  173. [ 0, 2],
  174. [ 0, 3],
  175. [ 0,-1],
  176. [ 0,-2],
  177. [ 0,-3],
  178. [ 1, 0],
  179. [ 1,-1],
  180. [ 2, 0],
  181. [ 2,-2],
  182. [ 3,-3],
  183. ],
  184. $MG_AU => [
  185. [-1, 0],
  186. [-1, 1],
  187. [ 0, 1],
  188. [ 0,-1],
  189. [ 1, 0],
  190. [ 1,-1]
  191. ],
  192. $MG_SY => [
  193. [-4, 4],
  194. [-3, 3],
  195. [-3, 2],
  196. [-1,-2],
  197. [ 0,-2],
  198. [ 0,-3],
  199. [ 0, 3],
  200. [ 0, 4],
  201. [ 1, 2],
  202. [ 3,-2],
  203. [ 3,-3],
  204. [ 4,-4]
  205. ]
  206. );
  207. # Special cells
  208. my $EMPTY_CELL = "_";
  209. my %board;
  210. # Display pieces
  211. #==================================================
  212. sub f_1($$){
  213. my $p = shift;
  214. my $c0 = shift;
  215. my $s0;
  216. $p =~ s/($P1|$P2)$DIV//;
  217. $p .= "_" if length($p) < 2;
  218. $s0 = $HEX_2;
  219. $s0 =~ s/$SUB_CHR{1,2}/$p/;
  220. if($c0 % 2 == 0){
  221. $s0 =~ s/$SUB_CHR/$ALT_SUB_CHR/g;
  222. }
  223. return $s0;
  224. }
  225. # Display lines
  226. #==================================================
  227. sub disp_1($$){
  228. my ($r0, $c0) = (shift, shift);
  229. return $HEX_1;
  230. }
  231. sub disp_2($$){
  232. my ($r0, $c0) = (shift, shift);
  233. my $p;
  234. # Cell notation
  235. my $not;
  236. $not = cell_index_rev($c0, $r0);
  237. $p = $board{$not};
  238. return f_1($p, $c0);
  239. # my ($r0, $c0) = (shift, shift);
  240. # return $HEX_2;
  241. }
  242. sub disp_3($$){
  243. my ($r0, $c0) = (shift, shift);
  244. return $HEX_3;
  245. }
  246. sub disp_y_axis($$$$){
  247. my ($s0, $s1, $s2, $r0) = @_;
  248. my $n0;
  249. $n0 = length($r0);
  250. $s0 = $r0 % 2 == 1 ? $PAD_ODD : $PAD_EVEN.$PREF_1;
  251. $s1 = $r0 % 2 == 1 ? $PAD_ODD : $PAD_EVEN.$PREF_2;
  252. $s1 =~ s/^ {$n0}/$r0/;
  253. $s2 = $r0 % 2 == 1 ? $PAD_ODD : $PAD_EVEN.$PREF_3;
  254. return ($s0, $s1, $s2);
  255. }
  256. # Display cell
  257. #==================================================
  258. sub add_cell($$$$$){
  259. my ($s0, $s1, $s2, $r0, $c0) = @_;
  260. $s0 .= disp_1($r0, $c0);
  261. $s1 .= disp_2($r0, $c0);
  262. $s2 .= disp_3($r0, $c0);
  263. # if($c0 % 2 == 0){
  264. # $s0 =~ s/ /$SHADE_CHR/g;
  265. # $s1 =~ s/ /$SHADE_CHR/g;
  266. # $s2 =~ s/ /$SHADE_CHR/g;
  267. # }
  268. return ($s0, $s1, $s2);
  269. }
  270. sub disp_0($){
  271. my $r0;
  272. my ($s0, $s1, $s2);
  273. $r0 = shift;
  274. # Append the y axis
  275. ($s0, $s1, $s2) = disp_y_axis($s0, $s1, $s2, $r0);
  276. # Iterate through the cells
  277. for my $i (1..11){
  278. ($s0, $s1, $s2) = add_cell($s0, $s1, $s2, $r0, $i);
  279. }
  280. return $s0."\n".$s1."\n".$s2."\n";
  281. }
  282. # Display row
  283. #==================================================
  284. sub disp_row($){
  285. my $row;
  286. my $r0;
  287. $r0 = shift;
  288. $row = disp_0($r0);
  289. # Handle trailing characters
  290. if($r0 % 2 == 1){
  291. # Trim the start of the first line
  292. $row =~ s/$TRAIL_1/ /;
  293. # Trim the end of the first line
  294. $row =~ s/\n/$TRAIL_3\n/
  295. }else{
  296. # Trim the end of the last line
  297. $row =~ s/$TRAIL_2\n/ \n/m;
  298. }
  299. return $row;
  300. }
  301. sub disp_trailing_row(){
  302. my $s0;
  303. my $s1;
  304. $s0 = $PAD_EVEN.$PREF_1;
  305. # Clear some chars from
  306. # our hex patterns
  307. $s1 = $HEX_1;
  308. substr($s1, 2,2) = " ";
  309. # Append hex pattern to
  310. # trailing row
  311. for my $i (1..11){
  312. $s0 .= $s1;
  313. }
  314. # Clear one last pair of
  315. # chrs
  316. substr($s0, -2,2) = " ";
  317. $s0 .= "\n";
  318. return $s0;
  319. }
  320. sub disp_x_axis(){
  321. my $s0;
  322. $s0 = $PAD_AXIS;
  323. $s0 .= join(
  324. $PAD_AXIS, map{
  325. $AXIS_RV{$_}
  326. }(1..11));
  327. $s0 .= "\n";
  328. $s0 .= $PAD_AXIS;
  329. $s0 .= join(
  330. "", map{
  331. $_ % 2 == 1 ? $HL_1 : $HL_2
  332. }(1..11));
  333. $s0 .= "\n";
  334. return $s0
  335. }
  336. # Display board
  337. #==================================================
  338. sub disp_board(){
  339. my $b;
  340. for my $i (map {11-$_+1} (1..11)) {
  341. $b .= disp_row($i);
  342. }
  343. $b .= disp_trailing_row();
  344. $b .= disp_x_axis();
  345. $b =~ s/$TRAIL_1$TRAIL_3\n/\n/m;
  346. for my $i (1..11-1){
  347. substr($b, 2+6*$i, 2) = " ";
  348. }
  349. printf("%s", $b);
  350. }
  351. sub cell_index_rev($$){
  352. return $AXIS_RV{$_[0]}.$_[1];
  353. }
  354. sub cell_index($){
  355. my ($chr1, $chr2) = (split(//, $_[0]));
  356. return ($AXIS{$chr1}, $chr2);
  357. }
  358. sub apply_shift($$){
  359. my ($not, $my_shift) = (shift, shift);
  360. my $r0;
  361. my $c0;
  362. ($r0, $c0) = cell_index($not);
  363. $r0 += $my_shift->[0];
  364. $c0 += $my_shift->[1];
  365. die "cell index [$r0, $c0]: out of bound exception" if $r0 > 11 or $c0 > 11 or $r0 < 1 or $c0 < 1;
  366. return cell_index_rev($r0, $c0);
  367. }
  368. sub calc_move($$){
  369. my ($not, $mov) = (shift, shift);
  370. my $r0;
  371. my $c0;
  372. my $x_shift;
  373. my $y_shift;
  374. my $n0;
  375. my $ni;
  376. ($r0, $c0) = cell_index($not);
  377. # Calc y_shift
  378. $y_shift = $mov->[1];
  379. # Calc x_shift
  380. $x_shift = $mov->[0];
  381. # make adjustment
  382. $ni = ($y_shift / ($y_shift * -1));
  383. $ni *= -1;
  384. $n0 = ($r0 + 1) % 2;
  385. $x_shift += int(($y_shift + ($n0 * $ni)) / 2);
  386. return apply_shift($not, [$x_shift, $y_shift]);
  387. }
  388. # Main starts here!
  389. binmode(STDOUT, ":utf8");
  390. # Creates a hash of the the form
  391. # $board{cell_notation} = piece_enum
  392. %board = map {
  393. $_ => $EMPTY_CELL
  394. } map {
  395. my $l0;
  396. $l0 = $_;
  397. (map {$l0.$_} ("1".."11"))
  398. } map {
  399. $AXIS_RV{$_}
  400. }(1...11);
  401. my $m1 = "F4";
  402. my $c1 = $MG_A;
  403. $board{$m1} = $P1.$DIV.$c;
  404. for my $mv in $MOVE{}
  405. printf("%s\n", calc_move($m1, [-2,-2]));
  406. # printf("%s\n", calc_move($m1, [-6,6]));
  407. disp_board();