File Coverage

blib/lib/Games/Shogi.pm
Criterion Covered Total %
statement 10 22 45.4
branch 0 2 0.0
condition 0 3 0.0
subroutine 4 7 57.1
pod n/a
total 14 34 41.1


line stmt bran cond sub pod time code
1             package Games::Shogi;
2              
3 1     1   30630 use strict;
  1         3  
  1         41  
4 1     1   5 use warnings;
  1         3  
  1         42  
5 1     1   5 use vars qw($VERSION);
  1         6  
  1         1453  
6              
7             $VERSION = '0.03';
8              
9             sub size() { 9 }
10             sub promotion_zone() { 3 }
11             sub allow_drop() { 1 }
12 0     0     sub capture() { ['K'] }
13              
14             # {{{ Board static data
15             my @board = (
16             # 9 8 7 6 5 4 3 2 1
17             [qw( L N S G K G S N L )], # a
18             [qw( _ R _ _ _ _ _ B _ )], # b
19             [qw( P P P P P P P P P )], # c
20             [qw( _ _ _ _ _ _ _ _ _ )], # d
21             [qw( _ _ _ _ _ _ _ _ _ )], # e
22             [qw( _ _ _ _ _ _ _ _ _ )], # f
23             [qw( p p p p p p p p p )], # g
24             [qw( _ b _ _ _ _ _ r _ )], # h
25             [qw( l n s g k g s n l )] ); # i
26             # }}}
27              
28             # {{{ Pieces
29             my $pieces = {
30             # {{{ Bishop
31             b => {
32             name => 'Bishop',
33             romaji => 'kakugyo',
34             promote => 'dh',
35             neighborhood => [
36             q( ),
37             q( \ / ),
38             q( ^ ),
39             q( / \ ),
40             q( ) ] },
41             # }}}
42             # {{{ Gold General
43             g => {
44             name => 'Gold General',
45             romaji => 'kinsho',
46             neighborhood => [
47             q( ),
48             q( ooo ),
49             q( o^o ),
50             q( o ),
51             q( ) ] },
52             # }}}
53             # {{{ King
54             k => {
55             name => 'King',
56             romaji => 'osho',
57             neighborhood => [
58             q( ),
59             q( ooo ),
60             q( o^o ),
61             q( ooo ),
62             q( ) ] },
63             # }}}
64             # {{{ Knight
65             n => {
66             name => 'Knight',
67             romaji => 'keima',
68             promote => 'g',
69             neighborhood => [
70             q( x x ),
71             q( ),
72             q( ^ ),
73             q( ),
74             q( ) ] },
75             # }}}
76             # {{{ Lance
77             l => {
78             name => 'Lance',
79             romaji => 'kyosha',
80             promote => 'g',
81             neighborhood => [
82             q( ),
83             q( | ),
84             q( ^ ),
85             q( ),
86             q( ) ] },
87             # }}}
88             # {{{ Pawn
89             p => {
90             name => 'Pawn',
91             romaji => 'fuhyo',
92             promote => '+p',
93             neighborhood => [
94             q( ),
95             q( o ),
96             q( ^ ),
97             q( ),
98             q( ) ] },
99             # }}}
100             # {{{ Rook
101             r => {
102             name => 'Rook',
103             romaji => 'hisha',
104             promote => 'dk',
105             neighborhood => [
106             q( ),
107             q( | ),
108             q( -^- ),
109             q( | ),
110             q( ) ] },
111             # }}}
112             # {{{ Silver General
113             s => {
114             name => 'Silver General',
115             romaji => 'ginsho',
116             neighborhood => [
117             q( ),
118             q( ooo ),
119             q( ^ ),
120             q( o o ),
121             q( ) ] },
122             # }}}
123              
124             # {{{ Dragon Horse
125             dh => {
126             name => 'Dragon Horse',
127             romaji => 'ryume',
128             neighborhood => [
129             q( ),
130             q( \o/ ),
131             q( o^o ),
132             q( /o\ ),
133             q( ) ] },
134             # }}}
135             # {{{ Dragon King
136             dk => {
137             name => 'Dragon King',
138             romaji => 'ryuo',
139             neighborhood => [
140             q( ),
141             q( o|o ),
142             q( -^- ),
143             q( o|o ),
144             q( ) ] },
145             # }}}
146             # {{{ Promoted Pawn
147             '+p' => {
148             name => 'Promoted Pawn',
149             romaji => 'tokin',
150             neighborhood => [
151             q( ),
152             q( ooo ),
153             q( o^o ),
154             q( o ),
155             q( ) ] },
156             # }}}
157             };
158             # }}}
159              
160             # {{{ new
161             sub new {
162 0     0     my $proto = shift;
163 0           my $self = { pieces => $pieces };
164 0   0       bless $self, ref($proto) || $proto;
165 0           $self->{board} = $self->initial_board(\@board);
166 0           return $self }
167             # }}}
168              
169             # {{{ initial_board
170             sub initial_board {
171 0     0     my ($self,$board) = @_;
172              
173 0 0         return [ map { [ map { $_ eq '_' ? undef : $_ } @$_ ] } @$board ] }
  0            
  0            
174             # }}}
175              
176             # {{{ neighbor
177             sub neighbor {
178             my ($self,$piece) = @_;
179             return unless $self->{pieces}->{lc $piece};
180              
181             my $reverse = {
182             U => 'D', D => 'U', R => 'L', L => 'R',
183             u => 'd', d => 'u', r => 'l', l => 'r',
184             };
185             my @dir_map = (
186             [qw( uuulll uuull uuul uuu uuur uuurr uuurrr)],
187             [qw( uulll uull uul uu uur uurr uurrr )],
188             [qw( ulll ull ul u ur urr urrr )],
189             [qw( lll ll l _ r rr rrr )],
190             [qw( dlll dll dl d dr drr drrr )],
191             [qw( ddlll ddll ddl dd ddr ddrr ddrrr )],
192             [qw( dddlll dddll dddl ddd dddr dddrr dddrrr)] );
193             my $dir_center = int(@dir_map/2);
194              
195             my $desc = $self->{pieces}->{lc $piece}{neighborhood};
196             my @foo = map { [ split // ] } @$desc;
197             my $center = int(@$desc/2);
198             my $neighbors = [];
199              
200             for my $dx (-$center..+$center) {
201             for my $dy (-$center..+$center) {
202             next if $dx == 0 and $dy == 0; # Center
203             my $move = $foo[$center+$dx][$center+$dy];
204             if($move =~ /\d/) {
205             my $td = $dir_map[$dir_center+$dx][$dir_center+$dy];
206             if($td=~/(\w)(\w)/) {
207             push @$neighbors,$1 x $move.$2 x $move }
208             else {
209             push @$neighbors,$td x $move } }
210             elsif($move =~ /[xo]/) {
211             push @$neighbors,$dir_map[$dir_center+$dx][$dir_center+$dy] }
212             elsif($move =~ m{[-|\\/]} and abs($dx) < 2 and abs($dy) < 2) {
213             push @$neighbors,uc $dir_map[$dir_center+$dx][$dir_center+$dy] }
214             elsif($move =~ m{[-|\\/]}) { $neighbors->[-1] .= '*' } } }
215 1     1   502 use YAML;die Dump($neighbors) if lc $piece eq 'do';
  0            
  0            
216              
217             return [ map { s/([udlrUDLR])/$reverse->{$1}/g; $_ } @$neighbors ]
218             if uc $piece eq $piece;
219             return $neighbors }
220             # }}}
221              
222             sub board { return shift->{board} }
223             sub english_name { return shift->{pieces}{lc shift()}{name} }
224             sub japanese_name { return shift->{pieces}{lc shift()}{romaji} }
225             sub promote { return shift->{pieces}{lc shift()}{promote} }
226              
227             1;
228             __END__