Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.55% covered (success)
98.55%
68 / 69
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ChessPiece
98.55% covered (success)
98.55%
68 / 69
87.50% covered (warning)
87.50%
7 / 8
25
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 newFromHex
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
2
 getSymbol
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getColor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAsHex
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 getMovePatterns
95.24% covered (success)
95.24%
20 / 21
0.00% covered (danger)
0.00%
0 / 1
14
 getNotation
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * This file is a part of ChessBrowser.
4 *
5 * ChessBrowser is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * @file ChessPiece
19 * @ingroup ChessBrowser
20 * @author DannyS712
21 */
22
23namespace MediaWiki\Extension\ChessBrowser;
24
25use LogicException;
26
27class ChessPiece {
28
29    /** @var string */
30    private $type;
31
32    /** @var string */
33    private $color;
34
35    /** @var string */
36    private $symbol;
37
38    public const COLOR_WHITE = 'white';
39    public const COLOR_BLACK = 'black';
40
41    public const WHITE_PAWN = 0x01;
42    public const WHITE_KNIGHT = 0x02;
43    public const WHITE_KING = 0x03;
44    public const WHITE_BISHOP = 0x05;
45    public const WHITE_ROOK = 0x06;
46    public const WHITE_QUEEN = 0x07;
47
48    public const BLACK_PAWN = 0x09;
49    public const BLACK_KNIGHT = 0x0A;
50    public const BLACK_KING = 0x0B;
51    public const BLACK_BISHOP = 0x0D;
52    public const BLACK_ROOK = 0x0E;
53    public const BLACK_QUEEN = 0x0F;
54
55    /**
56     * @param string $symbol
57     * @throws ChessBrowserException
58     */
59    public function __construct( string $symbol ) {
60        $type = strtolower( $symbol );
61
62        $validTypes = [ 'p', 'b', 'n', 'r', 'q', 'k' ];
63
64        if ( !in_array( $type, $validTypes ) ) {
65            throw new ChessBrowserException( "Unknown type for '$symbol'" );
66        }
67
68        if ( $type === $symbol ) {
69            // Piece was already lowercase, so black
70            $color = self::COLOR_BLACK;
71        } else {
72            // Piece was uppercase, so white
73            $color = self::COLOR_WHITE;
74        }
75
76        $this->symbol = $symbol;
77        $this->type = $type;
78        $this->color = $color;
79    }
80
81    /**
82     * Create from the hex representation, for use in FenParser0x88
83     *
84     * @param int $hex
85     * @return ChessPiece
86     * @throws ChessBrowserException
87     */
88    public static function newFromHex( int $hex ): ChessPiece {
89        $mappings = [
90            self::WHITE_PAWN => 'P',
91            self::WHITE_KNIGHT => 'N',
92            self::WHITE_KING => 'K',
93            self::WHITE_BISHOP => 'B',
94            self::WHITE_ROOK => 'R',
95            self::WHITE_QUEEN => 'Q',
96            self::BLACK_PAWN => 'p',
97            self::BLACK_KNIGHT => 'n',
98            self::BLACK_KING => 'k',
99            self::BLACK_BISHOP => 'b',
100            self::BLACK_ROOK => 'r',
101            self::BLACK_QUEEN => 'q',
102        ];
103
104        if ( !array_key_exists( $hex, $mappings ) ) {
105            throw new ChessBrowserException( "Unknown hex representation '$hex'" );
106        }
107
108        return new ChessPiece( $mappings[$hex] );
109    }
110
111    /**
112     * Get the symbol for the piece
113     *
114     * @return string
115     */
116    public function getSymbol(): string {
117        return $this->symbol;
118    }
119
120    /**
121     * Get the type
122     *
123     * @return string
124     */
125    public function getType(): string {
126        return $this->type;
127    }
128
129    /**
130     * Get the color
131     *
132     * @return string
133     */
134    public function getColor(): string {
135        return $this->color;
136    }
137
138    /**
139     * Get the hex representation of the piece
140     *
141     * @return int
142     */
143    public function getAsHex(): int {
144        $mappings = [
145            'P' => self::WHITE_PAWN,
146            'N' => self::WHITE_KNIGHT,
147            'K' => self::WHITE_KING,
148            'B' => self::WHITE_BISHOP,
149            'R' => self::WHITE_ROOK,
150            'Q' => self::WHITE_QUEEN,
151            'p' => self::BLACK_PAWN,
152            'n' => self::BLACK_KNIGHT,
153            'k' => self::BLACK_KING,
154            'b' => self::BLACK_BISHOP,
155            'r' => self::BLACK_ROOK,
156            'q' => self::BLACK_QUEEN,
157        ];
158
159        return $mappings[$this->symbol];
160    }
161
162    /**
163     * Get the possible moves
164     *
165     * @return array
166     */
167    public function getMovePatterns(): array {
168        switch ( $this->symbol ) {
169            case 'P':
170                return [ 16, 32, 15, 17 ];
171            case 'p':
172                return [ -16, -32, -15, -17 ];
173            case 'N':
174            case 'n':
175                return [ -33, -31, -18, -14, 14, 18, 31, 33 ];
176            case 'K':
177            case 'k':
178                return [ -17, -16, -15, -1, 1, 15, 16, 17 ];
179            case 'B':
180            case 'b':
181                return [ -15, -17, 15, 17 ];
182            case 'R':
183            case 'r':
184                return [ -1, 1, -16, 16 ];
185            case 'Q':
186            case 'q':
187                return [ -15, -17, 15, 17, -1, 1, -16, 16 ];
188            default:
189                throw new LogicException( "Unexpected symbol: $this->symbol" );
190        }
191    }
192
193    /**
194     * Get the symbol to use for notation
195     *
196     * @return string
197     */
198    public function getNotation(): string {
199        if ( $this->type === 'p' ) {
200            return '';
201        }
202        return strtoupper( $this->type );
203    }
204
205}