Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
6.90% covered (danger)
6.90%
2 / 29
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CastlingTracker
6.90% covered (danger)
6.90%
2 / 29
25.00% covered (danger)
25.00%
1 / 4
222.60
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 checkCastle
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 updateCode
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 updateForMove
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
132
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 CastlingTracker
19 * @ingroup ChessBrowser
20 * @author DannyS712
21 */
22
23namespace MediaWiki\Extension\ChessBrowser;
24
25class CastlingTracker {
26
27    /** @var string */
28    private $castle;
29
30    /** @var int */
31    private $castleCode;
32
33    private const CODES = [
34        'K' => 8,
35        'Q' => 4,
36        'k' => 2,
37        'q' => 1
38    ];
39
40    /**
41     * @param string $fromFen
42     */
43    public function __construct( string $fromFen ) {
44        $this->castle = $fromFen ?: '-';
45        $this->updateCode();
46    }
47
48    /**
49     * Is a castle currently valid (solely based on moved pieces, not the current board)
50     *
51     * @param string $option
52     * @return bool whether this castle is valid
53     */
54    public function checkCastle( string $option ): bool {
55        $optionCode = self::CODES[$option] ?? 0;
56        return (bool)( $this->castleCode & $optionCode );
57    }
58
59    /**
60     * Set the castleCode
61     */
62    private function updateCode() {
63        $totalCode = 0;
64        foreach ( str_split( $this->castle ) as $option ) {
65            $totalCode += self::CODES[$option] ?? 0;
66        }
67        $this->castleCode = $totalCode;
68    }
69
70    /**
71     * Update the status after a move, and return the new castle status
72     *
73     * @param int $movedPiece
74     * @param int $from
75     * @return string
76     */
77    public function updateForMove( int $movedPiece, int $from ): string {
78        $currentCastle = $this->castle;
79        $newCastle = $currentCastle;
80        switch ( $movedPiece ) {
81            case ChessPiece::WHITE_KING:
82                $newCastle = str_replace( [ 'K', 'Q' ], "", $currentCastle );
83                break;
84            case ChessPiece::BLACK_KING:
85                $newCastle = str_replace( [ 'k', 'q' ], "", $currentCastle );
86                break;
87            case ChessPiece::WHITE_ROOK:
88                if ( $from === 0 ) {
89                    $newCastle = str_replace( 'Q', "", $currentCastle );
90                } elseif ( $from === 7 ) {
91                    $newCastle = str_replace( 'K', "", $currentCastle );
92                }
93                break;
94            case ChessPiece::BLACK_ROOK:
95                if ( $from === 112 ) {
96                    $newCastle = str_replace( 'q', "", $currentCastle );
97                } elseif ( $from === 119 ) {
98                    $newCastle = str_replace( 'k', "", $currentCastle );
99                }
100                break;
101        }
102        $newCastle = $newCastle ?: '-';
103        if ( $newCastle !== $currentCastle ) {
104            $this->castle = $newCastle;
105            $this->updateCode();
106        }
107        return $newCastle;
108    }
109
110}