<!DOCTYPE html> <html xmlns='www.w3.org/1999/xhtml'>
<head> <title>Code coverage for Rubychess</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <script src='./assets/0.12.3/application.js' type='text/javascript'></script> <link href='./assets/0.12.3/application.css' media='screen, projection, print' rel='stylesheet' type='text/css' /> <link rel="shortcut icon" type="image/png" href="./assets/0.12.3/favicon_yellow.png" /> <link rel="icon" type="image/png" href="./assets/0.12.3/favicon.png" /> </head> <body> <div id="loading"> <img src="./assets/0.12.3/loading.gif" alt="loading"/> </div> <div id="wrapper" class="hide"> <div class="timestamp">Generated <abbr class="timeago" title="2021-11-08T19:36:46-07:00">2021-11-08T19:36:46-07:00</abbr></div> <ul class="group_tabs"></ul> <div id="content"> <div class="file_list_container" id="AllFiles"> <h2> <span class="group_name">All Files</span> (<span class="covered_percent"> <span class="yellow"> 83.27%
</span>
</span> covered at <span class="covered_strength"> <span class="green"> 3002.98 </span> </span> hits/line ) </h2> <a name="AllFiles"></a> <div> <b>11</b> files in total. </div> <div class="t-line-summary"> <b>526</b> relevant lines, <span class="green"><b>438</b> lines covered</span> and <span class="red"><b>88</b> lines missed. </span> (<span class="yellow"> 83.27%
</span> )
</div> <div class="file_list--responsive"> <table class="file_list"> <thead> <tr> <th>File</th> <th class="cell--number">% covered</th> <th class="cell--number">Lines</th> <th class="cell--number">Relevant Lines</th> <th class="cell--number">Lines covered</th> <th class="cell--number">Lines missed</th> <th class="cell--number">Avg. Hits / Line</th> </tr> </thead> <tbody> <tr class="t-file"> <td class="strong t-file__name"><a href="#91ab4d7be4145acb64a3e23c9709be21c7fec330" class="src_link" title="lib/chess_game.rb">lib/chess_game.rb</a></td> <td class="red strong cell--number t-file__coverage">71.53 %</td> <td class="cell--number">716</td> <td class="cell--number">288</td> <td class="cell--number">206</td> <td class="cell--number">82</td> <td class="cell--number">203.84</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#0346b6aa7b85877d500fabfee4fb1c1e2683c843" class="src_link" title="lib/chess_pieces/bishop.rb">lib/chess_pieces/bishop.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">36</td> <td class="cell--number">13</td> <td class="cell--number">13</td> <td class="cell--number">0</td> <td class="cell--number">149.31</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#30f2d2cbf5e7cd02f151cca75c7f5d9de00e8056" class="src_link" title="lib/chess_pieces/chess_piece.rb">lib/chess_pieces/chess_piece.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">146</td> <td class="cell--number">50</td> <td class="cell--number">50</td> <td class="cell--number">0</td> <td class="cell--number">5089.44</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#51ea61d5881c586a230eb10e0dc018496f7c33ab" class="src_link" title="lib/chess_pieces/king.rb">lib/chess_pieces/king.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">58</td> <td class="cell--number">20</td> <td class="cell--number">20</td> <td class="cell--number">0</td> <td class="cell--number">114.80</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#893ceaf52ac95fe8e4c435897ad565bd04fd9d7d" class="src_link" title="lib/chess_pieces/knight.rb">lib/chess_pieces/knight.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">33</td> <td class="cell--number">10</td> <td class="cell--number">10</td> <td class="cell--number">0</td> <td class="cell--number">598.40</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#3dabe0a14d569a6ebe6d07ef2c1c7cd1d9b6bdd8" class="src_link" title="lib/chess_pieces/move_tree.rb">lib/chess_pieces/move_tree.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">87</td> <td class="cell--number">29</td> <td class="cell--number">29</td> <td class="cell--number">0</td> <td class="cell--number">37900.83</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#7bfa93b283d8934f2cce410c4838162e6bd6e0be" class="src_link" title="lib/chess_pieces/move_tree_node.rb">lib/chess_pieces/move_tree_node.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">71</td> <td class="cell--number">19</td> <td class="cell--number">19</td> <td class="cell--number">0</td> <td class="cell--number">7210.53</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#7bee78754871089633ea736943782a75b63ba324" class="src_link" title="lib/chess_pieces/pawn.rb">lib/chess_pieces/pawn.rb</a></td> <td class="green strong cell--number t-file__coverage">91.43 %</td> <td class="cell--number">196</td> <td class="cell--number">70</td> <td class="cell--number">64</td> <td class="cell--number">6</td> <td class="cell--number">232.44</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#11a28e07fe55c493d7e58a6d563478e1d7b85847" class="src_link" title="lib/chess_pieces/queen.rb">lib/chess_pieces/queen.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">38</td> <td class="cell--number">13</td> <td class="cell--number">13</td> <td class="cell--number">0</td> <td class="cell--number">137.69</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#b6d42288caf4c05ee8d7fd46fbe359b9c7cb64b3" class="src_link" title="lib/chess_pieces/rook.rb">lib/chess_pieces/rook.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">37</td> <td class="cell--number">13</td> <td class="cell--number">13</td> <td class="cell--number">0</td> <td class="cell--number">152.38</td> </tr> <tr class="t-file"> <td class="strong t-file__name"><a href="#5d87e27a4b21f1f4beee25d74eac8997394978df" class="src_link" title="lib/invalid_move_error.rb">lib/invalid_move_error.rb</a></td> <td class="green strong cell--number t-file__coverage">100.00 %</td> <td class="cell--number">4</td> <td class="cell--number">1</td> <td class="cell--number">1</td> <td class="cell--number">0</td> <td class="cell--number">1.00</td> </tr> </tbody> </table> </div>
</div>
</div> <div id="footer"> Generated by <a href="https://github.com/simplecov-ruby/simplecov">simplecov</a> v0.21.2 and simplecov-html v0.12.3<br/> using RSpec </div> <div class="source_files"> <div class="source_table" id="91ab4d7be4145acb64a3e23c9709be21c7fec330"> <div class="header"> <h3>lib/chess_game.rb</h3> <h4> <span class="red"> 71.53%
</span>
lines covered </h4> <div class="t-line-summary"> <b>288</b> relevant lines. <span class="green"><b>206</b> lines covered</span> and <span class="red"><b>82</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require 'colorize'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="4"> <span class="hits">1</span> <code class="ruby">require 'stringio'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="5"> <span class="hits">1</span> <code class="ruby">require 'yaml'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="6"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/pawn'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/rook'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="8"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/knight'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="9"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/bishop'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="10"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/queen'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="11"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_pieces/king'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="12"> <span class="hits">1</span> <code class="ruby">require_relative 'invalid_move_error'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="15"> <code class="ruby"># A chess game that contains the game board, rules,</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="16"> <code class="ruby"># validation of moves, and computing check/checkmate.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="17"> <span class="hits">1</span> <code class="ruby">class ChessGame</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="18"> <span class="hits">1</span> <code class="ruby"> WHITE_SQUARE = { background: :light_red }.freeze</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="19"> <span class="hits">1</span> <code class="ruby"> BLACK_SQAURE = { background: :red }.freeze</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="20"> <span class="hits">1</span> <code class="ruby"> BLANK_SQUARE = ' '</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="21"> <span class="hits">1</span> <code class="ruby"> BOARD_TO_COORDINATES = { 'a' => 0, 'b' => 1, 'c' => 2, 'd' => 3,</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> 'e' => 4, 'f' => 5, 'g' => 6, 'h' => 7 }.freeze</code> </li> </div> <div> <li class="covered" data-hits="9" data-linenumber="23"> <span class="hits">9</span> <code class="ruby"> COORDINATES_TO_BOARD = BOARD_TO_COORDINATES.each_with_object({}) { |pair, obj| obj[pair[1]] = pair[0] }.freeze</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="25"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="26"> <code class="ruby"> # Creates instance variables and sets up the board for</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="27"> <code class="ruby"> # the start of the game.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="28"> <span class="hits">1</span> <code class="ruby"> def initialize(white_player = 'human', black_player = 'human')</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="29"> <span class="hits">57</span> <code class="ruby"> @board = setup_board</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="30"> <span class="hits">57</span> <code class="ruby"> @current_player_color = 'white'</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="31"> <span class="hits">57</span> <code class="ruby"> @king_locs = { white: [0, 4], black: [7, 4] }</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="32"> <span class="hits">57</span> <code class="ruby"> @move_history = []</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="33"> <span class="hits">57</span> <code class="ruby"> @game_winner = nil</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="34"> <span class="hits">57</span> <code class="ruby"> @check_in_play = false</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="35"> <span class="hits">57</span> <code class="ruby"> @castle_king = false</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="36"> <span class="hits">57</span> <code class="ruby"> @players = { 'white' => white_player, 'black' => black_player }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="38"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="39"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="40"> <code class="ruby"> # Runs the main game loop for a chess game, which is comprised</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> # of several stages:</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="42"> <code class="ruby"> # 1. Parse player input</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="43"> <code class="ruby"> # 2. Attempt to make a move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"> # 3. Check for check/checkmate</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="45"> <code class="ruby"> # 4. Repeat until game over or saved</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="46"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"> # @return [String] @game_winner The winner of the game if there is one.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="48"> <span class="hits">1</span> <code class="ruby"> def play</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="49"> <code class="ruby"> puts self</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="50"> <code class="ruby"> while @game_winner.nil?</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="51"> <code class="ruby"> puts "It's #{@current_player_color}'s turn."</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="52"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="53"> <code class="ruby"> input_command = case @players[@current_player_color]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="54"> <code class="ruby"> when 'human'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="55"> <code class="ruby"> player_input</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="56"> <code class="ruby"> when 'random'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="57"> <code class="ruby"> random_move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="58"> <code class="ruby"> else</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="59"> <code class="ruby"> random_move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="60"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="61"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="62"> <code class="ruby"> if input_command.nil?</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="63"> <code class="ruby"> puts 'Please input a legal move. Type "help" for an example.'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="64"> <code class="ruby"> next</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="65"> <code class="ruby"> elsif input_command == 'save'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="66"> <code class="ruby"> break</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="67"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="68"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="69"> <code class="ruby"> case input_command.size</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="70"> <code class="ruby"> when 2</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="71"> <code class="ruby"> from, to = input_command</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="72"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="73"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="74"> <code class="ruby"> begin</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="75"> <code class="ruby"> make_move(from, to)</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="76"> <code class="ruby"> @move_history << "#{convert_algebraic_coordinates(from)}#{convert_algebraic_coordinates(to)}"</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="77"> <code class="ruby"> puts self</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="78"> <code class="ruby"> rescue InvalidMoveError => e</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="79"> <code class="ruby"> puts 'Invalid move!'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="80"> <code class="ruby"> puts e.message</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="81"> <code class="ruby"> next</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="82"> <code class="ruby"> rescue StandardError => e</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="83"> <code class="ruby"> puts e.message</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="84"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="85"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="86"> <code class="ruby"> # Check whether the game is over or not</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="87"> <code class="ruby"> case check_game_over</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="88"> <code class="ruby"> when 'Checkmate'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="89"> <code class="ruby"> @game_winner = @current_player_color == 'white' ? 'black' : 'white'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="90"> <code class="ruby"> puts 'Checkmate!'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="91"> <code class="ruby"> when 'Stalemate'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="92"> <code class="ruby"> @game_winner = 'Stalemate'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="93"> <code class="ruby"> puts 'It\'s a draw!'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="94"> <code class="ruby"> else</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="95"> <code class="ruby"> @game_winner = board_pieces_by_color.map(&:size) == [1, 1] ? 'stalemate' : nil</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="96"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="97"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="98"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="99"> <code class="ruby"> @game_winner</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="100"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="101"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="102"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="103"> <code class="ruby"> # Accepts player input and either returns the components needed to input a</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="104"> <code class="ruby"> # move or saves the game.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="105"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="106"> <code class="ruby"> # @return [Array<Array<Integer>>] An array of arrays of length 2 representing</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="107"> <code class="ruby"> # +from+ and +to+ to pass into #make_move.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="108"> <span class="hits">1</span> <code class="ruby"> def player_input</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="109"> <code class="ruby"> input = gets.chomp</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="110"> <code class="ruby"> input = input&.downcase</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="111"> <code class="ruby"> case player_input_type(input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="112"> <code class="ruby"> when 'move'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="113"> <code class="ruby"> parse_move(input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="114"> <code class="ruby"> when 'help'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="115"> <code class="ruby"> print_help_menu</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="116"> <code class="ruby"> when 'save'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="117"> <code class="ruby"> save_game</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="118"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="119"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="120"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="121"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="122"> <code class="ruby"> # Parses a move input string to determine the type of input given. The</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="123"> <code class="ruby"> # different suppored moves are:</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="124"> <code class="ruby"> # 1. A string of length 4 indicating the start space and the end space.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="125"> <code class="ruby"> # - e.g 'a2a4' would return [[0, 1], [0, 3]]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="126"> <code class="ruby"> # 2. A string of length 8 in the form of "[start] to [end]"</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="127"> <code class="ruby"> # - e.g 'a2 to a4' would return [[0, 1], [0, 3]]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="128"> <code class="ruby"> # TODO : Add more supported moves</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="129"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="130"> <code class="ruby"> # @param [String] input The raw player input</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="131"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="132"> <code class="ruby"> # @return [Array<Array<Integer>>] An array of arrays of length 2 representing</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="133"> <code class="ruby"> # +from+ and +to+ to pass into #make_move.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="134"> <span class="hits">1</span> <code class="ruby"> def parse_move(input)</code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="135"> <span class="hits">4</span> <code class="ruby"> case input.size</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="136"> <code class="ruby"> when 4</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="137"> <span class="hits">2</span> <code class="ruby"> from = convert_coordinates(input[0..1])</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="138"> <span class="hits">2</span> <code class="ruby"> to = convert_coordinates(input[2..3])</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="139"> <span class="hits">2</span> <code class="ruby"> [from, to]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="140"> <code class="ruby"> when 8</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="141"> <span class="hits">2</span> <code class="ruby"> from = convert_coordinates(input[0..1])</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="142"> <span class="hits">2</span> <code class="ruby"> to = convert_coordinates(input[-2..-1])</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="143"> <span class="hits">2</span> <code class="ruby"> [from, to]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="144"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="145"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="146"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="147"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="148"> <code class="ruby"> # Converts algebraic notation space names to coordinates corresponding with</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="149"> <code class="ruby"> # @board.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="150"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="151"> <code class="ruby"> # @param [String] coord_str A string of length 2 that has encoded within it</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="152"> <code class="ruby"> # the column and row of a space on the chess board.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="153"> <code class="ruby"> # @return [Array<Integer>] An array of integers of length 2 denoting the row</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="154"> <code class="ruby"> # and column positions corresponding to @board.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="155"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="156"> <code class="ruby"> # For example, passing in 'a4' would return [0, 3].</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="157"> <span class="hits">1</span> <code class="ruby"> def convert_coordinates(coord_str)</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="158"> <span class="hits">8</span> <code class="ruby"> [(coord_str[1].to_i - 1), BOARD_TO_COORDINATES[coord_str[0]]]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="159"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="160"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="161"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="162"> <code class="ruby"> # Converts coordinates into algebraic notation space names. Inverse method</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="163"> <code class="ruby"> # of +convert_coordinates+.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="164"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="165"> <code class="ruby"> # @param [Array<Integer>] coord_arr An array of integers of length 2</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="166"> <code class="ruby"> # corresponding to the row and column of</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="167"> <code class="ruby"> # the space on +@board+.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="168"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="169"> <code class="ruby"> # @return [String] The string corresponding to the row and column name of the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="170"> <code class="ruby"> # space of the board using algebraic notation.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="171"> <span class="hits">1</span> <code class="ruby"> def convert_algebraic_coordinates(coord_arr)</code> </li> </div> <div> <li class="covered" data-hits="7" data-linenumber="172"> <span class="hits">7</span> <code class="ruby"> "#{COORDINATES_TO_BOARD[coord_arr[1]]}#{coord_arr[0] + 1}"</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="173"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="174"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="175"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="176"> <code class="ruby"> # Returns the type of player input, whether they input a game-ending command</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="177"> <code class="ruby"> # or a move command.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="178"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="179"> <code class="ruby"> # @param [String] input String of the player input to parse and determine the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="180"> <code class="ruby"> # type of input.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="181"> <code class="ruby"> # @return [String] The type of player input; 'save', 'help', or 'move'.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="182"> <span class="hits">1</span> <code class="ruby"> def player_input_type(input)</code> </li> </div> <div> <li class="covered" data-hits="59" data-linenumber="183"> <span class="hits">59</span> <code class="ruby"> %w[save quit exit end].each { |end_word| return 'save' if input.include?(end_word) }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="184"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="33" data-linenumber="185"> <span class="hits">33</span> <code class="ruby"> %w[help tutorial ?].each { |help_word| return 'help' if input.include?(help_word) }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="186"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="187"> <span class="hits">6</span> <code class="ruby"> 'move'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="188"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="189"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="190"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="191"> <code class="ruby"> # Saves the game by dumping the object into a YAML file.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="192"> <span class="hits">1</span> <code class="ruby"> def save_game</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="193"> <code class="ruby"> puts 'Please input a name for the save file.'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="194"> <code class="ruby"> file_name = gets.chomp</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="195"> <code class="ruby"> while File.exist?("saves/#{file_name}")</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="196"> <code class="ruby"> puts "saves/#{file_name} already exists; please choose a different name."</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="197"> <code class="ruby"> file_name = gets.chomp</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="198"> <code class="ruby"> end</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="199"> <code class="ruby"> save_file = File.new("saves/#{file_name}", 'w')</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="200"> <code class="ruby"> save_file.write(YAML.dump(self))</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="201"> <code class="ruby"> save_file.close</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="202"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="203"> <code class="ruby"> 'save'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="204"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="205"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="206"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="207"> <code class="ruby"> # Prints the help menu complete with tutorial and move explanations</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="208"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="209"> <code class="ruby"> # @return [String] 'help_menu' after printing the help menu.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="210"> <span class="hits">1</span> <code class="ruby"> def print_help_menu</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="211"> <code class="ruby"> puts <<~HELP_MENU</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="212"> <code class="ruby"> To move a piece, type the two character location of the piece and then the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="213"> <code class="ruby"> two character location of where you want it to move. For example, if you</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="214"> <code class="ruby"> want to move the pawn at a2 forward two spaces, type "a2a4" or "a2 to a4".</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="215"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="216"> <code class="ruby"> To save the game, type 'save', 'exit', or 'quit', and you will be prompted</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="217"> <code class="ruby"> to name the save file.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="218"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="219"> <code class="ruby"> To get this menu back, simply type 'help', 'tutorial' or '?'.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="220"> <code class="ruby"> HELP_MENU</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="221"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="222"> <code class="ruby"> print_out_of_check_moves if @check_in_play</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="223"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="224"> <code class="ruby"> 'help_menu'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="225"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="226"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="227"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="228"> <code class="ruby"> # Prints the moves that the current player can make to get out of check.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="229"> <span class="hits">1</span> <code class="ruby"> def print_out_of_check_moves</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="230"> <code class="ruby"> puts 'Here are potential moves to get out of of check:'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="231"> <code class="ruby"> available_moves.each do |from_loc, to_loc_array|</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="232"> <code class="ruby"> puts "#{convert_algebraic_coordinates(from_loc)} => #{to_loc_array.map do |to|</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="233"> <code class="ruby"> convert_algebraic_coordinates(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="234"> <code class="ruby"> end }"</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="235"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="236"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="237"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="238"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="239"> <code class="ruby"> # Moves a piece at a given location to another location if</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="240"> <code class="ruby"> # the move is valid. Raises an InvalidMoveError otherwise.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="241"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="242"> <code class="ruby"> # @param [Array<Integer>] from An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="243"> <code class="ruby"> # position of the piece to move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="244"> <code class="ruby"> # @param [Array<Integer>] to An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="245"> <code class="ruby"> # position to move the piece at +from+ to.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="246"> <span class="hits">1</span> <code class="ruby"> def make_move(from, to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="247"> <code class="ruby"> # Raises an execption if the move isn't valid</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="248"> <span class="hits">12</span> <code class="ruby"> validate_move(from, to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="249"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="250"> <span class="hits">12</span> <code class="ruby"> frow, fcol = from</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="251"> <span class="hits">12</span> <code class="ruby"> piece = @board[frow][fcol]</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="252"> <span class="hits">12</span> <code class="ruby"> trow, tcol = to</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="253"> <span class="hits">12</span> <code class="ruby"> other_space = @board[trow][tcol]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="254"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="255"> <code class="ruby"> # Keep track of move_counts for Pawns and Kings</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="256"> <span class="hits">12</span> <code class="ruby"> case piece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="257"> <code class="ruby"> when King</code> </li> </div> <div> <li class="covered" data-hits="3" data-linenumber="258"> <span class="hits">3</span> <code class="ruby"> reset_move_count = piece.moved?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="259"> <code class="ruby"> when Pawn</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="260"> <span class="hits">8</span> <code class="ruby"> reset_move_count = piece.move_count</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="261"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="262"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="263"> <code class="ruby"> # Capture a piece if the pawn performed En Passant</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="264"> <span class="hits">12</span> <code class="ruby"> @board[frow][tcol] = BLANK_SQUARE if piece.is_a?(Pawn) && get_en_passant_moves(piece).include?(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="265"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="266"> <code class="ruby"> # Move the piece on the board</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="267"> <span class="hits">12</span> <code class="ruby"> @board[trow][tcol] = if piece.is_a?(Pawn)</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="268"> <span class="hits">8</span> <code class="ruby"> piece.move(to, @players[@current_player_color])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="269"> <code class="ruby"> else</code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="270"> <span class="hits">4</span> <code class="ruby"> piece.move(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="271"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="272"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="273"> <span class="hits">12</span> <code class="ruby"> @board[frow][fcol] = BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="274"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="275"> <code class="ruby"> # If a piece is a king, do special checks</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="276"> <span class="hits">12</span> <code class="ruby"> if piece.is_a?(King)</code> </li> </div> <div> <li class="covered" data-hits="3" data-linenumber="277"> <span class="hits">3</span> <code class="ruby"> @king_locs[@current_player_color.to_sym] = to</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="278"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="279"> <code class="ruby"> # Check if the king is being castled</code> </li> </div> <div> <li class="covered" data-hits="3" data-linenumber="280"> <span class="hits">3</span> <code class="ruby"> if @castle_king</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="281"> <code class="ruby"> # Reset the flag for the other player's king</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="282"> <code class="ruby"> @castle_king = false</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="283"> <code class="ruby"> if tcol == fcol - 2</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="284"> <code class="ruby"> @board[trow][tcol + 1] = @board[trow][0].move([trow, tcol + 1])</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="285"> <code class="ruby"> @board[trow][0] = BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="286"> <code class="ruby"> else</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="287"> <code class="ruby"> @board[trow][tcol - 1] = @board[trow][7].move([trow, tcol - 1])</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="288"> <code class="ruby"> @board[trow][7] = BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="289"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="290"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="291"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="292"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="293"> <code class="ruby"> # Check for check</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="294"> <span class="hits">12</span> <code class="ruby"> check_piece = check_check</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="295"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="296"> <span class="hits">12</span> <code class="ruby"> @check_in_play = !check_check.nil?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="297"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="298"> <span class="hits">12</span> <code class="ruby"> unless check_piece.nil?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="299"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="300"> <code class="ruby"> # Move keeps/makes their own king in check.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="301"> <span class="hits">1</span> <code class="ruby"> if check_piece.color != @current_player_color || check_piece.is_a?(King)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="302"> <code class="ruby"> # Undo the move</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="303"> <code class="ruby"> @board[frow][fcol] = piece.move(from)</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="304"> <code class="ruby"> @board[trow][tcol] = other_space</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="305"> <code class="ruby"> # Undo movement for tracking ones</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="306"> <code class="ruby"> case piece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="307"> <code class="ruby"> when King</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="308"> <code class="ruby"> piece.moved = reset_move_count</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="309"> <code class="ruby"> when Pawn</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="310"> <code class="ruby"> piece.move_count -= 2</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="311"> <code class="ruby"> end</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="312"> <code class="ruby"> raise(InvalidMoveError, "Moving that #{piece.class} leaves your king in check!")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="313"> <code class="ruby"> else</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="314"> <span class="hits">1</span> <code class="ruby"> puts 'Check!'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="315"> <span class="hits">1</span> <code class="ruby"> puts 'Type "help" to get a list of moves to get out of check!'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="316"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="317"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="318"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="319"> <code class="ruby"> # Change whose turn it is</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="320"> <span class="hits">12</span> <code class="ruby"> change_turn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="321"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="322"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="323"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="324"> <code class="ruby"> # Determines whether or not the move is a valid move. If the move is valid,</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="325"> <code class="ruby"> # it returns that space on the board.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="326"> <code class="ruby"> # Raises an InvalidMoveError with a specific message if the move is invalid.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="327"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="328"> <code class="ruby"> # @param [Array<Integer>] from An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="329"> <code class="ruby"> # position of the piece to move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="330"> <code class="ruby"> # @param [Array<Integer>] to An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="331"> <code class="ruby"> # position to move the piece at +from+ to.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="332"> <span class="hits">1</span> <code class="ruby"> def validate_move(from, to)</code> </li> </div> <div> <li class="covered" data-hits="97" data-linenumber="333"> <span class="hits">97</span> <code class="ruby"> frow, fcol = from</code> </li> </div> <div> <li class="covered" data-hits="97" data-linenumber="334"> <span class="hits">97</span> <code class="ruby"> piece = @board[frow][fcol]</code> </li> </div> <div> <li class="covered" data-hits="97" data-linenumber="335"> <span class="hits">97</span> <code class="ruby"> raise(InvalidMoveError, "No piece at #{convert_algebraic_coordinates(from)}") unless piece.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="336"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="96" data-linenumber="337"> <span class="hits">96</span> <code class="ruby"> unless piece.color == @current_player_color</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="338"> <span class="hits">2</span> <code class="ruby"> raise(InvalidMoveError,</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="339"> <code class="ruby"> "You cannot move opponent's piece at #{convert_algebraic_coordinates(from)}")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="340"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="341"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="94" data-linenumber="342"> <span class="hits">94</span> <code class="ruby"> possible_moves = legal_moves(piece)</code> </li> </div> <div> <li class="covered" data-hits="94" data-linenumber="343"> <span class="hits">94</span> <code class="ruby"> unless possible_moves.include?(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="344"> <code class="ruby"> # Check if it's trying to castle the king</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="345"> <span class="hits">2</span> <code class="ruby"> if piece.is_a?(King) && !piece.moved? && can_castle?(from, to)</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="346"> <code class="ruby"> @castle_king = true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="347"> <code class="ruby"> else</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="348"> <span class="hits">2</span> <code class="ruby"> raise(InvalidMoveError,</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="349"> <code class="ruby"> "Your #{piece.class} cannot move from #{convert_algebraic_coordinates(from)} to #{convert_algebraic_coordinates(to)}.")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="350"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="351"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="352"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="92" data-linenumber="353"> <span class="hits">92</span> <code class="ruby"> trow, tcol = to</code> </li> </div> <div> <li class="covered" data-hits="92" data-linenumber="354"> <span class="hits">92</span> <code class="ruby"> @board[trow][tcol]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="355"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="356"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="357"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="358"> <code class="ruby"> # Returns whether or not a king can make the castle move or not</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="359"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="360"> <code class="ruby"> # @param [Array<Integer>] from An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="361"> <code class="ruby"> # position of the piece to move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="362"> <code class="ruby"> # @param [Array<Integer>] to An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="363"> <code class="ruby"> # position to move the piece at +from+ to.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="364"> <code class="ruby"> # @return [Boolean] whether the king can make the castle move or not.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="365"> <span class="hits">1</span> <code class="ruby"> def can_castle?(from, to)</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="366"> <span class="hits">8</span> <code class="ruby"> return false unless from[0] == to[0] && to[1].between?(from[1] - 2, from[1] + 2)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="367"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="368"> <span class="hits">8</span> <code class="ruby"> tcol = to[1]</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="369"> <span class="hits">8</span> <code class="ruby"> fcol = from[1]</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="370"> <span class="hits">8</span> <code class="ruby"> row = from[0]</code> </li> </div> <div> <li class="covered" data-hits="8" data-linenumber="371"> <span class="hits">8</span> <code class="ruby"> case fcol - tcol</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="372"> <code class="ruby"> when 2 # Moving left, check all the left spaces are empty</code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="373"> <span class="hits">4</span> <code class="ruby"> @board[row][0].is_a?(Rook) && @board[row][1] == BLANK_SQUARE && @board[row][2] == BLANK_SQUARE && @board[row][3] == BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="374"> <code class="ruby"> when -2 # Moving right</code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="375"> <span class="hits">4</span> <code class="ruby"> @board[row][7].is_a?(Rook) && @board[row][6] == BLANK_SQUARE && @board[row][5] == BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="376"> <code class="ruby"> else</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="377"> <code class="ruby"> false</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="378"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="379"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="380"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="381"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="382"> <code class="ruby"> # Determines whether the game ends with a checkmate or stalemate.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="383"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="384"> <code class="ruby"> # @return [String] "Checkmate" for a game over, "Stalemate" for a draw, and</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="385"> <code class="ruby"> # "continue" otherwise.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="386"> <span class="hits">1</span> <code class="ruby"> def check_game_over</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="387"> <span class="hits">6</span> <code class="ruby"> immovable = available_moves.nil?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="388"> <code class="ruby"> # Checkmate condition</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="389"> <span class="hits">6</span> <code class="ruby"> return 'Checkmate' if @check_in_play && immovable</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="390"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="391"> <code class="ruby"> # Stalemate condition</code> </li> </div> <div> <li class="covered" data-hits="5" data-linenumber="392"> <span class="hits">5</span> <code class="ruby"> return 'Stalemate' if !@check_in_play && immovable</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="393"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="394"> <code class="ruby"> # Neither conidtions met</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="395"> <span class="hits">1</span> <code class="ruby"> 'continue'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="396"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="397"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="398"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="399"> <code class="ruby"> # Returns an array of the legal moves that the piece can make.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="400"> <code class="ruby"> # This will prevent pieces from going through other pieces (except for the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="401"> <code class="ruby"> # knight, of course). It does so by iterating through +chess_piece+'s move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="402"> <code class="ruby"> # tree in level order, dequeing any nodes that are invalid.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="403"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="404"> <code class="ruby"> # @param [ChessPiece] chess_piece The ChessPiece to find the legal moves of.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="405"> <code class="ruby"> # @return [Array<Array<Integer>>] Array of legal move spaces that the piece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="406"> <code class="ruby"> # can move to.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="407"> <span class="hits">1</span> <code class="ruby"> def legal_moves(chess_piece)</code> </li> </div> <div> <li class="covered" data-hits="1218" data-linenumber="408"> <span class="hits">1218</span> <code class="ruby"> return pawn_legal_moves(chess_piece) if chess_piece.is_a? Pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="409"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="737" data-linenumber="410"> <span class="hits">737</span> <code class="ruby"> move_tree = chess_piece.possible_moves</code> </li> </div> <div> <li class="covered" data-hits="737" data-linenumber="411"> <span class="hits">737</span> <code class="ruby"> legal_moves_array = []</code> </li> </div> <div> <li class="covered" data-hits="737" data-linenumber="412"> <span class="hits">737</span> <code class="ruby"> visit_queue = move_tree.root.children</code> </li> </div> <div> <li class="covered" data-hits="737" data-linenumber="413"> <span class="hits">737</span> <code class="ruby"> until visit_queue.empty?</code> </li> </div> <div> <li class="covered" data-hits="3770" data-linenumber="414"> <span class="hits">3770</span> <code class="ruby"> current_node = visit_queue.shift</code> </li> </div> <div> <li class="covered" data-hits="3770" data-linenumber="415"> <span class="hits">3770</span> <code class="ruby"> row, col = current_node.loc</code> </li> </div> <div> <li class="covered" data-hits="3770" data-linenumber="416"> <span class="hits">3770</span> <code class="ruby"> space = @board[row][col]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="417"> <code class="ruby"> # If it's a chess piece, check if it can capture.</code> </li> </div> <div> <li class="covered" data-hits="3770" data-linenumber="418"> <span class="hits">3770</span> <code class="ruby"> if space.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="419"> <code class="ruby"> # If the piece can capture it, add it as a valid space, but don't</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="420"> <code class="ruby"> # add any of its children to visit_queue.</code> </li> </div> <div> <li class="covered" data-hits="1292" data-linenumber="421"> <span class="hits">1292</span> <code class="ruby"> next unless chess_piece.can_capture?(space)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="422"> <code class="ruby"> else</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="423"> <code class="ruby"> # If there's not piece, it can continue along the move tree.</code> </li> </div> <div> <li class="covered" data-hits="3886" data-linenumber="424"> <span class="hits">3886</span> <code class="ruby"> current_node.children.each { |child| visit_queue << child }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="425"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="426"> <code class="ruby"> # Append legal move locations</code> </li> </div> <div> <li class="covered" data-hits="2563" data-linenumber="427"> <span class="hits">2563</span> <code class="ruby"> legal_moves_array << current_node.loc</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="428"> <code class="ruby"> end</code> </li> </div> <div> <li class="covered" data-hits="737" data-linenumber="429"> <span class="hits">737</span> <code class="ruby"> legal_moves_array</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="430"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="431"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="432"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="433"> <code class="ruby"> # Returns an array of legal moves that a pawn can make. Since a pawn can only</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="434"> <code class="ruby"> # move diagonally if it can capture a piece, it is its own special case.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="435"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="436"> <code class="ruby"> # @param [Pawn] pawn The pawn to find the legal moves of.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="437"> <code class="ruby"> # @return [Array<Array<Integer>>] Array of legal move spaces that the pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="438"> <code class="ruby"> # can move to.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="439"> <span class="hits">1</span> <code class="ruby"> def pawn_legal_moves(pawn)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="440"> <code class="ruby"> # Assign the move tree for pawn</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="441"> <span class="hits">481</span> <code class="ruby"> pawn.possible_moves</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="442"> <code class="ruby"> # Check if pawn can capture right diagonal piece</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="443"> <span class="hits">481</span> <code class="ruby"> r_diag = pawn.move_tree.root.children[1]</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="444"> <span class="hits">481</span> <code class="ruby"> l_diag = pawn.move_tree.root.children[2]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="445"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="446"> <span class="hits">481</span> <code class="ruby"> unless r_diag.nil?</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="447"> <span class="hits">481</span> <code class="ruby"> r_diag_loc = r_diag.loc</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="448"> <span class="hits">481</span> <code class="ruby"> r_diag_piece = @board[r_diag_loc[0]][r_diag_loc[1]]</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="449"> <span class="hits">481</span> <code class="ruby"> pawn.move_tree.trim_branch!(r_diag_loc) unless pawn.can_capture?(r_diag_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="450"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="451"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="452"> <span class="hits">481</span> <code class="ruby"> unless l_diag.nil?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="453"> <code class="ruby"> # Check if pawn can capture left diagonal piece</code> </li> </div> <div> <li class="covered" data-hits="370" data-linenumber="454"> <span class="hits">370</span> <code class="ruby"> l_diag_loc = l_diag.loc</code> </li> </div> <div> <li class="covered" data-hits="370" data-linenumber="455"> <span class="hits">370</span> <code class="ruby"> l_diag_piece = @board[l_diag_loc[0]][l_diag_loc[1]]</code> </li> </div> <div> <li class="covered" data-hits="370" data-linenumber="456"> <span class="hits">370</span> <code class="ruby"> pawn.move_tree.trim_branch!(l_diag_loc) unless pawn.can_capture?(l_diag_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="457"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="458"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="459"> <code class="ruby"> # Check if the two spaces ahead of an unmoved pawn is occupied</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="460"> <span class="hits">481</span> <code class="ruby"> unless pawn.move_tree.root.children[0].children.empty?</code> </li> </div> <div> <li class="covered" data-hits="443" data-linenumber="461"> <span class="hits">443</span> <code class="ruby"> front_loc = pawn.move_tree.root.children[0].children[0].loc</code> </li> </div> <div> <li class="covered" data-hits="443" data-linenumber="462"> <span class="hits">443</span> <code class="ruby"> front_piece = @board[front_loc[0]][front_loc[1]]</code> </li> </div> <div> <li class="covered" data-hits="443" data-linenumber="463"> <span class="hits">443</span> <code class="ruby"> pawn.move_tree.trim_branch!(front_loc) if front_piece.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="464"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="465"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="466"> <code class="ruby"> # Check if there is a piece immediately in front of the pawn</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="467"> <span class="hits">481</span> <code class="ruby"> front_loc = pawn.move_tree.root.children[0].loc</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="468"> <span class="hits">481</span> <code class="ruby"> front_piece = @board[front_loc[0]][front_loc[1]]</code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="469"> <span class="hits">481</span> <code class="ruby"> pawn.move_tree.trim_branch!(front_loc) if front_piece.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="470"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="481" data-linenumber="471"> <span class="hits">481</span> <code class="ruby"> pawn.move_tree.to_a + get_en_passant_moves(pawn)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="472"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="473"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="474"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="475"> <code class="ruby"> # Returns an array of the valid En Passant moves for a given pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="476"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="477"> <code class="ruby"> # @param [Pawn] pawn The pawn to find the En Passant moves of.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="478"> <code class="ruby"> # @return [Array<Array<Integer>>] Array of legal move spaces that the pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="479"> <code class="ruby"> # can move to where En Passant applies.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="480"> <span class="hits">1</span> <code class="ruby"> def get_en_passant_moves(pawn)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="481"> <code class="ruby"> # Check spaces beside the pawn for En Passant</code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="482"> <span class="hits">489</span> <code class="ruby"> pawn_row, pawn_col = pawn.position</code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="483"> <span class="hits">489</span> <code class="ruby"> r_piece_loc = [pawn_row + pawn.direction, pawn_col + 1]</code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="484"> <span class="hits">489</span> <code class="ruby"> r_piece = @board[pawn_row][pawn_col + 1]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="485"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="486"> <span class="hits">489</span> <code class="ruby"> l_piece_loc = [pawn_row + pawn.direction, pawn_col - 1]</code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="487"> <span class="hits">489</span> <code class="ruby"> l_piece = @board[pawn_row][pawn_col - 1]</code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="488"> <span class="hits">489</span> <code class="ruby"> en_passant_moves = []</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="489"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="490"> <span class="hits">489</span> <code class="ruby"> en_passant_moves << r_piece_loc if (r_piece.is_a? Pawn) && pawn.can_capture?(r_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="491"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="492"> <span class="hits">489</span> <code class="ruby"> en_passant_moves << l_piece_loc if (l_piece.is_a? Pawn) && pawn.can_capture?(l_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="493"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="489" data-linenumber="494"> <span class="hits">489</span> <code class="ruby"> en_passant_moves</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="495"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="496"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="497"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="498"> <code class="ruby"> # Checks whether a king is currently in check. If it is, it returns the piece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="499"> <code class="ruby"> # that puts it in check and nil otherwise.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="500"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="501"> <code class="ruby"> # @return [ChessPiece or nil] The piece that puts a king in check and</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="502"> <code class="ruby"> # nil otherwise.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="503"> <span class="hits">1</span> <code class="ruby"> def check_check</code> </li> </div> <div> <li class="covered" data-hits="107" data-linenumber="504"> <span class="hits">107</span> <code class="ruby"> white_pieces, black_pieces = board_pieces_by_color</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="505"> <code class="ruby"> # If black king is in check</code> </li> </div> <div> <li class="covered" data-hits="107" data-linenumber="506"> <span class="hits">107</span> <code class="ruby"> white_pieces.each do |piece|</code> </li> </div> <div> <li class="covered" data-hits="588" data-linenumber="507"> <span class="hits">588</span> <code class="ruby"> return piece if legal_moves(piece).include? @king_locs[:black]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="508"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="509"> <code class="ruby"> # If white king is in check</code> </li> </div> <div> <li class="covered" data-hits="88" data-linenumber="510"> <span class="hits">88</span> <code class="ruby"> black_pieces.each do |piece|</code> </li> </div> <div> <li class="covered" data-hits="464" data-linenumber="511"> <span class="hits">464</span> <code class="ruby"> return piece if legal_moves(piece).include? @king_locs[:white]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="512"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="513"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="514"> <code class="ruby"> nil</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="515"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="516"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="517"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="518"> <code class="ruby"> # Returns an hash of moves that will allow the current player to be out of</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="519"> <code class="ruby"> # check. If the list is empty, nil is returned instead.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="520"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="521"> <code class="ruby"> # @return [Hash <Array, Array> or nil] Array of valid moves unless it's empty.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="522"> <span class="hits">1</span> <code class="ruby"> def available_moves</code> </li> </div> <div> <li class="covered" data-hits="10" data-linenumber="523"> <span class="hits">10</span> <code class="ruby"> player_pieces = board_pieces_by_color[@current_player_color == 'white' ? 0 : 1]</code> </li> </div> <div> <li class="covered" data-hits="10" data-linenumber="524"> <span class="hits">10</span> <code class="ruby"> valid_moves = {}</code> </li> </div> <div> <li class="covered" data-hits="10" data-linenumber="525"> <span class="hits">10</span> <code class="ruby"> player_pieces.each do |piece|</code> </li> </div> <div> <li class="covered" data-hits="32" data-linenumber="526"> <span class="hits">32</span> <code class="ruby"> valid_moves[piece.position] = []</code> </li> </div> <div> <li class="covered" data-hits="32" data-linenumber="527"> <span class="hits">32</span> <code class="ruby"> legal_moves(piece).each do |move|</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="528"> <span class="hits">80</span> <code class="ruby"> valid_moves[piece.position] << forecast_move(piece.position, move)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="529"> <code class="ruby"> rescue StandardError</code> </li> </div> <div> <li class="covered" data-hits="55" data-linenumber="530"> <span class="hits">55</span> <code class="ruby"> next</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="531"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="532"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="533"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="42" data-linenumber="534"> <span class="hits">42</span> <code class="ruby"> valid_moves.filter! { |_key, val| !val.empty? }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="535"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="10" data-linenumber="536"> <span class="hits">10</span> <code class="ruby"> valid_moves.empty? ? nil : valid_moves</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="537"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="538"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="539"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="540"> <code class="ruby"> # Chooses a random move from the list of available moves.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="541"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="542"> <code class="ruby"> # @return [Array<Array<Integer>>] [from, to]</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="543"> <span class="hits">1</span> <code class="ruby"> def random_move</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="544"> <code class="ruby"> move_hash = available_moves</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="545"> <code class="ruby"> from = move_hash.keys.sample</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="546"> <code class="ruby"> to = move_hash[from].sample</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="547"> <code class="ruby"> [from, to]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="548"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="549"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="550"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="551"> <code class="ruby"> # Returns an array with 2 arrays, the first of which is all the white pieces</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="552"> <code class="ruby"> # and the second is all the black pieces.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="553"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="554"> <code class="ruby"> # @return [Array<Array<ChessPieces>>] Array of arrays for white and black</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="555"> <code class="ruby"> # pieces.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="556"> <span class="hits">1</span> <code class="ruby"> def board_pieces_by_color</code> </li> </div> <div> <li class="covered" data-hits="7800" data-linenumber="557"> <span class="hits">7800</span> <code class="ruby"> pieces = @board.flatten.filter { |space| space.is_a? ChessPiece }</code> </li> </div> <div> <li class="covered" data-hits="1371" data-linenumber="558"> <span class="hits">1371</span> <code class="ruby"> white_pieces = pieces.filter { |piece| piece.color == 'white' }</code> </li> </div> <div> <li class="covered" data-hits="1371" data-linenumber="559"> <span class="hits">1371</span> <code class="ruby"> black_pieces = pieces.filter { |piece| piece.color == 'black' }</code> </li> </div> <div> <li class="covered" data-hits="120" data-linenumber="560"> <span class="hits">120</span> <code class="ruby"> [white_pieces, black_pieces]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="561"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="562"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="563"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="564"> <code class="ruby"> # Returns a string of a board with pieces and appropriately</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="565"> <code class="ruby"> # shaded spaces.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="566"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="567"> <code class="ruby"> # @return [String] The chess board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="568"> <span class="hits">1</span> <code class="ruby"> def to_s</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="569"> <code class="ruby"> string_stream = StringIO.new</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="570"> <code class="ruby"> history_offset = @move_history.size</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="571"> <code class="ruby"> 8.downto(1) do |row|</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="572"> <code class="ruby"> string_stream << " #{row} "</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="573"> <code class="ruby"> @board[row - 1].each_with_index do |col, col_num|</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="574"> <code class="ruby"> bg_color = (row - 1) % 2 == col_num % 2 ? BLACK_SQAURE : WHITE_SQUARE</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="575"> <code class="ruby"> string_stream << col.to_s.colorize(bg_color)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="576"> <code class="ruby"> end</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="577"> <code class="ruby"> string_stream << "\t"</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="578"> <code class="ruby"> move_index = 8 - row + (history_offset - 8)</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="579"> <code class="ruby"> move_index = 8 - row if (history_offset - 8).negative?</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="580"> <code class="ruby"> string_stream << "#{move_index + 1}. #{@move_history[move_index]}"</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="581"> <code class="ruby"> string_stream << "\n"</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="582"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="583"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="584"> <code class="ruby"> string_stream << ' a b c d e f g h '</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="585"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="586"> <code class="ruby"> string_stream.string</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="587"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="588"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="589"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="590"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="591"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="592"> <code class="ruby"> # Returns an array that sets the board up for the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="593"> <code class="ruby"> # start of the game.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="594"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="595"> <code class="ruby"> # @return [Array<Array>] The chess board represented as an array.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="596"> <span class="hits">1</span> <code class="ruby"> def setup_board</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="597"> <span class="hits">57</span> <code class="ruby"> rows = place_pieces('white')</code> </li> </div> <div> <li class="covered" data-hits="285" data-linenumber="598"> <span class="hits">285</span> <code class="ruby"> rows += Array.new(4) { Array.new(8, BLANK_SQUARE) }</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="599"> <span class="hits">57</span> <code class="ruby"> rows += place_pieces('black')</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="600"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="601"> <span class="hits">57</span> <code class="ruby"> rows</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="602"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="603"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="604"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="605"> <code class="ruby"> # Returns the 2 arrays of the chess pieces in the proper places based od</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="606"> <code class="ruby"> # their color.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="607"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="608"> <code class="ruby"> # @param [String] color A string denoting the color of pieces to place.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="609"> <code class="ruby"> # @return [Array<Array<ChessPiece>>] The two rows of chess pieces for the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="610"> <code class="ruby"> # standard setup of the chess board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="611"> <span class="hits">1</span> <code class="ruby"> def place_pieces(color)</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="612"> <span class="hits">114</span> <code class="ruby"> pawns = place_pawns(color)</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="613"> <span class="hits">114</span> <code class="ruby"> back_row_pieces = place_back_row(color)</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="614"> <span class="hits">114</span> <code class="ruby"> if color == 'white'</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="615"> <span class="hits">57</span> <code class="ruby"> [back_row_pieces, pawns]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="616"> <code class="ruby"> else</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="617"> <span class="hits">57</span> <code class="ruby"> [pawns, back_row_pieces]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="618"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="619"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="620"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="621"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="622"> <code class="ruby"> # Returns an array of pawns of the appropriate color on the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="623"> <code class="ruby"> # appropriate row based on +color+.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="624"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="625"> <code class="ruby"> # @param [String] color A string denoting the color of pawns to place.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="626"> <code class="ruby"> # @return [Array<Pawn>] Row of pawns to place on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="627"> <span class="hits">1</span> <code class="ruby"> def place_pawns(color)</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="628"> <span class="hits">114</span> <code class="ruby"> pawn_row = color == 'white' ? 1 : 6</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="629"> <span class="hits">114</span> <code class="ruby"> pawns = []</code> </li> </div> <div> <li class="covered" data-hits="1026" data-linenumber="630"> <span class="hits">1026</span> <code class="ruby"> 8.times { |col| pawns << Pawn.new(color, [pawn_row, col]) }</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="631"> <span class="hits">114</span> <code class="ruby"> pawns</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="632"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="633"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="634"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="635"> <code class="ruby"> # Returns an array of back row pieces of the appropriate color</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="636"> <code class="ruby"> # on the appropriate row based on +color+.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="637"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="638"> <code class="ruby"> # @param [String] color A string denoting the color of pieces to place.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="639"> <code class="ruby"> # @return [Array<ChessPiece>] The row of chess pieces in the standard setup.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="640"> <span class="hits">1</span> <code class="ruby"> def place_back_row(color)</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="641"> <span class="hits">114</span> <code class="ruby"> back_row = color == 'white' ? 0 : 7</code> </li> </div> <div> <li class="covered" data-hits="114" data-linenumber="642"> <span class="hits">114</span> <code class="ruby"> [Rook.new(color, [back_row, 0]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="643"> <code class="ruby"> Knight.new(color, [back_row, 1]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="644"> <code class="ruby"> Bishop.new(color, [back_row, 2]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="645"> <code class="ruby"> Queen.new(color, [back_row, 3]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="646"> <code class="ruby"> King.new(color, [back_row, 4]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="647"> <code class="ruby"> Bishop.new(color, [back_row, 5]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="648"> <code class="ruby"> Knight.new(color, [back_row, 6]),</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="649"> <code class="ruby"> Rook.new(color, [back_row, 7])]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="650"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="651"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="652"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="653"> <code class="ruby"> # Changes whose turn it is by switching between 'black' and 'white'.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="654"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="655"> <code class="ruby"> # @return [String] @current_player_color The current player color whose turn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="656"> <code class="ruby"> # it is.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="657"> <span class="hits">1</span> <code class="ruby"> def change_turn</code> </li> </div> <div> <li class="covered" data-hits="12" data-linenumber="658"> <span class="hits">12</span> <code class="ruby"> @current_player_color = @current_player_color == 'white' ? 'black' : 'white'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="659"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="660"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="661"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="662"> <code class="ruby"> # Moves a piece at a given location to another location, checks if the the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="663"> <code class="ruby"> # move leaves the current player's king in check, returns the piece to its</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="664"> <code class="ruby"> # original spot, and returns the move if valid.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="665"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="666"> <code class="ruby"> # @param [Array<Integer>] from An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="667"> <code class="ruby"> # position of the piece to move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="668"> <code class="ruby"> # @param [Array<Integer>] to An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="669"> <code class="ruby"> # position to move the piece at +from+ to.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="670"> <span class="hits">1</span> <code class="ruby"> def forecast_move(from, to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="671"> <code class="ruby"> # Raises an execption if the move isn't valid</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="672"> <span class="hits">80</span> <code class="ruby"> validate_move(from, to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="673"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="674"> <span class="hits">80</span> <code class="ruby"> frow, fcol = from</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="675"> <span class="hits">80</span> <code class="ruby"> piece = @board[frow][fcol]</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="676"> <span class="hits">80</span> <code class="ruby"> trow, tcol = to</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="677"> <span class="hits">80</span> <code class="ruby"> other_space = @board[trow][tcol]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="678"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="679"> <code class="ruby"> # Keep track of move_counts for Kings</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="680"> <span class="hits">80</span> <code class="ruby"> has_moved = piece.moved? if piece.is_a?(King)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="681"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="682"> <code class="ruby"> # Move the piece on the board</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="683"> <span class="hits">80</span> <code class="ruby"> @board[trow][tcol] = if piece.is_a?(Pawn)</code> </li> </div> <div> <li class="covered" data-hits="16" data-linenumber="684"> <span class="hits">16</span> <code class="ruby"> piece.move(to, @players[@current_player_color])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="685"> <code class="ruby"> else</code> </li> </div> <div> <li class="covered" data-hits="64" data-linenumber="686"> <span class="hits">64</span> <code class="ruby"> piece.move(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="687"> <code class="ruby"> end</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="688"> <span class="hits">80</span> <code class="ruby"> @board[frow][fcol] = BLANK_SQUARE</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="689"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="690"> <span class="hits">80</span> <code class="ruby"> @king_locs[@current_player_color.to_sym] = to if piece.is_a?(King)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="691"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="692"> <code class="ruby"> # Check for check</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="693"> <span class="hits">80</span> <code class="ruby"> check_piece = check_check</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="694"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="695"> <code class="ruby"> # Undo the move</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="696"> <span class="hits">80</span> <code class="ruby"> @king_locs[@current_player_color.to_sym] = from if piece.is_a?(King)</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="697"> <span class="hits">80</span> <code class="ruby"> @board[frow][fcol] = piece.move(from)</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="698"> <span class="hits">80</span> <code class="ruby"> @board[trow][tcol] = other_space</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="699"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="700"> <code class="ruby"> # Undo movement for tracking ones</code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="701"> <span class="hits">80</span> <code class="ruby"> case piece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="702"> <code class="ruby"> when King</code> </li> </div> <div> <li class="covered" data-hits="27" data-linenumber="703"> <span class="hits">27</span> <code class="ruby"> piece.moved = has_moved</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="704"> <code class="ruby"> when Pawn</code> </li> </div> <div> <li class="covered" data-hits="16" data-linenumber="705"> <span class="hits">16</span> <code class="ruby"> piece.move_count -= 2</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="706"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="707"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="80" data-linenumber="708"> <span class="hits">80</span> <code class="ruby"> unless check_piece.nil? || (check_piece.color == @current_player_color && !check_piece.is_a?(King))</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="709"> <code class="ruby"> # If check_piece is a King, then both kings are in check and it's an illegal</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="710"> <code class="ruby"> # move.</code> </li> </div> <div> <li class="covered" data-hits="55" data-linenumber="711"> <span class="hits">55</span> <code class="ruby"> raise(InvalidMoveError, "Moving that #{piece.class} leaves your king in check!")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="712"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="713"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="25" data-linenumber="714"> <span class="hits">25</span> <code class="ruby"> to</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="715"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="716"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="0346b6aa7b85877d500fabfee4fb1c1e2683c843"> <div class="header"> <h3>lib/chess_pieces/bishop.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>13</b> relevant lines. <span class="green"><b>13</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># Bishop piece for a game of chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class Bishop < ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="8"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"> # Initializes a new bishop piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="14"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="15"> <span class="hits">242</span> <code class="ruby"> @move_tree_template = build_bishop_move_tree</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="16"> <span class="hits">242</span> <code class="ruby"> super(color == 'white' ? '♝'.white : '♗', color, position, 3)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="19"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> # Builds a Bishop's move tree. The Bishop can move diagonally as far as the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> # board permits.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="25"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the bishop.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="26"> <span class="hits">1</span> <code class="ruby"> def build_bishop_move_tree</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="27"> <span class="hits">242</span> <code class="ruby"> move_tree_template = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="29"> <span class="hits">242</span> <code class="ruby"> move_tree_template.root.add_child(build_directional_tree_nodes([1, 1]))</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="30"> <span class="hits">242</span> <code class="ruby"> move_tree_template.root.add_child(build_directional_tree_nodes([-1, 1]))</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="31"> <span class="hits">242</span> <code class="ruby"> move_tree_template.root.add_child(build_directional_tree_nodes([1, -1]))</code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="32"> <span class="hits">242</span> <code class="ruby"> move_tree_template.root.add_child(build_directional_tree_nodes([-1, -1]))</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="242" data-linenumber="34"> <span class="hits">242</span> <code class="ruby"> move_tree_template</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="30f2d2cbf5e7cd02f151cca75c7f5d9de00e8056"> <div class="header"> <h3>lib/chess_pieces/chess_piece.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>50</b> relevant lines. <span class="green"><b>50</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require 'colorize'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="4"> <span class="hits">1</span> <code class="ruby">require_relative 'move_tree'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="7"> <code class="ruby"># An abstract class for a chess piece (pawn, king, rook, etc.)</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="8"> <span class="hits">1</span> <code class="ruby">class ChessPiece</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="9"> <span class="hits">1</span> <code class="ruby"> include Comparable</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="10"> <span class="hits">1</span> <code class="ruby"> attr_reader :name, :color, :position, :points, :move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # Initializes a piece with its name, color, position, and score.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="15"> <code class="ruby"> # @param [String] name The name of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="16"> <code class="ruby"> # @param [String] color What side the piece is on.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> # @param [Array<Integer>] position An array of length two representing the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"> # row and column ([row, col]).</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="19"> <code class="ruby"> # @param [Integer] points An integer indicating how many points</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"> # the piece is worth.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="21"> <span class="hits">1</span> <code class="ruby"> def initialize(name, color, position, points)</code> </li> </div> <div> <li class="covered" data-hits="1948" data-linenumber="22"> <span class="hits">1948</span> <code class="ruby"> @name = name</code> </li> </div> <div> <li class="covered" data-hits="1948" data-linenumber="23"> <span class="hits">1948</span> <code class="ruby"> @color = color</code> </li> </div> <div> <li class="covered" data-hits="1948" data-linenumber="24"> <span class="hits">1948</span> <code class="ruby"> @position = position</code> </li> </div> <div> <li class="covered" data-hits="1948" data-linenumber="25"> <span class="hits">1948</span> <code class="ruby"> @points = points</code> </li> </div> <div> <li class="covered" data-hits="1948" data-linenumber="26"> <span class="hits">1948</span> <code class="ruby"> @move_tree = MoveTree.new(position)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="27"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="29"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="30"> <code class="ruby"> # Updates position to be the +to+. Returns the piece with the updated</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="31"> <code class="ruby"> # location.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="32"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby"> # @param [Array<Integer>] to An integer array of length 2 denoting the new</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="34"> <code class="ruby"> # location of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"> # @return [ChessPiece]</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="36"> <span class="hits">1</span> <code class="ruby"> def move(to)</code> </li> </div> <div> <li class="covered" data-hits="190" data-linenumber="37"> <span class="hits">190</span> <code class="ruby"> @position = to</code> </li> </div> <div> <li class="covered" data-hits="190" data-linenumber="38"> <span class="hits">190</span> <code class="ruby"> self</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="39"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="40"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="42"> <code class="ruby"> # Returns a move tree of legal move positions.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="43"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"> # This method takes the @move_tree_template and @position attributes and</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="45"> <code class="ruby"> # uses them to create a new MoveTree object with the exact coordinates.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="46"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"> # @return [MoveTree] A move tree of moves based on the current position that</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="48"> <code class="ruby"> # are currently in bounds.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="49"> <span class="hits">1</span> <code class="ruby"> def possible_moves</code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="50"> <span class="hits">1319</span> <code class="ruby"> row, col = @position</code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="51"> <span class="hits">1319</span> <code class="ruby"> @move_tree = @move_tree_template.clone || move_tree</code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="52"> <span class="hits">1319</span> <code class="ruby"> @move_tree.each do |node|</code> </li> </div> <div> <li class="covered" data-hits="22197" data-linenumber="53"> <span class="hits">22197</span> <code class="ruby"> r, c = node.loc</code> </li> </div> <div> <li class="covered" data-hits="22197" data-linenumber="54"> <span class="hits">22197</span> <code class="ruby"> potential_space = [row + r, col + c]</code> </li> </div> <div> <li class="covered" data-hits="22197" data-linenumber="55"> <span class="hits">22197</span> <code class="ruby"> node.loc = potential_space</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="56"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="57"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="58"> <span class="hits">1319</span> <code class="ruby"> move_tree_in_bounds</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="59"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="60"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="61"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="62"> <code class="ruby"> # Returns and assigns @move_tree with all moves in bounds</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="63"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="64"> <code class="ruby"> # @return[MoveTree] A move tree of moves that are within the bounds of the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="65"> <code class="ruby"> # 8 x 8 chess board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="66"> <span class="hits">1</span> <code class="ruby"> def move_tree_in_bounds</code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="67"> <span class="hits">1319</span> <code class="ruby"> @move_tree.each do |node|</code> </li> </div> <div> <li class="covered" data-hits="59005" data-linenumber="68"> <span class="hits">59005</span> <code class="ruby"> @move_tree.trim_branch!(node) unless node.loc.all? { |coord| coord.between?(0, 7) }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="69"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="70"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1319" data-linenumber="71"> <span class="hits">1319</span> <code class="ruby"> @move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="72"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="73"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="74"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="75"> <code class="ruby"> # Returns whether the piece can capture another piece given its position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="76"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="77"> <code class="ruby"> # @param [ChessPiece] other_piece The ChessPiece that is the proposed target.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="78"> <code class="ruby"> # @return [true] if self can move there (overridden by the Pawn class)</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="79"> <span class="hits">1</span> <code class="ruby"> def can_capture?(other_piece)</code> </li> </div> <div> <li class="covered" data-hits="1292" data-linenumber="80"> <span class="hits">1292</span> <code class="ruby"> return true unless other_piece.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="81"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1292" data-linenumber="82"> <span class="hits">1292</span> <code class="ruby"> return false if other_piece.color == @color</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="83"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="84"> <code class="ruby"> # Most pieces can capture if they can move there. Pawns are the exception.</code> </li> </div> <div> <li class="covered" data-hits="85" data-linenumber="85"> <span class="hits">85</span> <code class="ruby"> possible_moves.to_a.include?(other_piece.position)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="86"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="87"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="88"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="89"> <code class="ruby"> # Returns the name of the piece with a space after it.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="90"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="91"> <code class="ruby"> # @return [String] The name of the piece of its color with a space after it.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="92"> <span class="hits">1</span> <code class="ruby"> def to_s</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="93"> <span class="hits">1</span> <code class="ruby"> "#{@name} ".colorize(color: @color.to_sym)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="94"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="95"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="96"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="97"> <code class="ruby"> # Add children to move tree nodes such that each move is a child node of</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="98"> <code class="ruby"> # the move that precedes it.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="99"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="100"> <code class="ruby"> # @param [Array<Integer>] direction An array of integers of length 2</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="101"> <code class="ruby"> # indicating the movement in</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="102"> <code class="ruby"> # the vertical and horizontal net changes.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="103"> <code class="ruby"> # For just vertical movement, direction is</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="104"> <code class="ruby"> # [1, 0]. For diagonal moves, it's [1, 1].</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="105"> <code class="ruby"> # @return [MoveTreeNode] The MoveTreeNode that has as its children all the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="106"> <code class="ruby"> # spaces in the given direction.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="107"> <span class="hits">1</span> <code class="ruby"> def build_directional_tree_nodes(direction = [1, 0])</code> </li> </div> <div> <li class="covered" data-hits="2920" data-linenumber="108"> <span class="hits">2920</span> <code class="ruby"> vertical_movement, horizontal_movement = direction</code> </li> </div> <div> <li class="covered" data-hits="2920" data-linenumber="109"> <span class="hits">2920</span> <code class="ruby"> closest_move = MoveTreeNode.new(direction)</code> </li> </div> <div> <li class="covered" data-hits="2920" data-linenumber="110"> <span class="hits">2920</span> <code class="ruby"> (2..7).each do |spaces|</code> </li> </div> <div> <li class="covered" data-hits="17520" data-linenumber="111"> <span class="hits">17520</span> <code class="ruby"> current_child = closest_move</code> </li> </div> <div> <li class="covered" data-hits="61320" data-linenumber="112"> <span class="hits">61320</span> <code class="ruby"> (spaces - 2).times { current_child = current_child.children[0] }</code> </li> </div> <div> <li class="covered" data-hits="17520" data-linenumber="113"> <span class="hits">17520</span> <code class="ruby"> current_child.add_child([spaces * vertical_movement, spaces * horizontal_movement])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="114"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="115"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="2920" data-linenumber="116"> <span class="hits">2920</span> <code class="ruby"> closest_move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="117"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="118"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="119"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="120"> <code class="ruby"> # Compare pieces based on their point values.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="121"> <code class="ruby"> # Note: Since Bishop and Knight point values are equal, it returns -1 if</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="122"> <code class="ruby"> # this piece is a knight and 1 if this piece is a bishop. This is an</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="123"> <code class="ruby"> # arbitrary choice to differentiate them.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="124"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="125"> <code class="ruby"> # @param [ChessPiece] other The ChessPiece object to compare against self.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="126"> <code class="ruby"> # @returns [Integer] 0 if the pieces are equal in point values, 1 if self has</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="127"> <code class="ruby"> # a greater point value, and -1 otherwise.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="128"> <span class="hits">1</span> <code class="ruby"> def <=>(other)</code> </li> </div> <div> <li class="covered" data-hits="23" data-linenumber="129"> <span class="hits">23</span> <code class="ruby"> return nil unless other.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="130"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="15" data-linenumber="131"> <span class="hits">15</span> <code class="ruby"> value_comparison = @points <=> other.points</code> </li> </div> <div> <li class="covered" data-hits="15" data-linenumber="132"> <span class="hits">15</span> <code class="ruby"> return value_comparison unless value_comparison.zero? && @points == 3</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="133"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="134"> <span class="hits">6</span> <code class="ruby"> pieces = [@name, other.name].sort</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="135"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="24" data-linenumber="136"> <span class="hits">24</span> <code class="ruby"> both_knights = ['♞'.white, '♘'].repeated_combination(2).any? { |combo| pieces == combo }</code> </li> </div> <div> <li class="covered" data-hits="24" data-linenumber="137"> <span class="hits">24</span> <code class="ruby"> both_bishops = ['♝'.white, '♗'].repeated_combination(2).any? { |combo| pieces == combo }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="138"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="139"> <span class="hits">6</span> <code class="ruby"> return 0 if both_knights || both_bishops</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="140"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="141"> <span class="hits">4</span> <code class="ruby"> return -1 if (@name == '♞'.white) || (@name == '♘')</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="142"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="143"> <code class="ruby"> # This piece is a bishop and the other is a knight, so return 1.</code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="144"> <span class="hits">2</span> <code class="ruby"> 1</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="145"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="146"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="51ea61d5881c586a230eb10e0dc018496f7c33ab"> <div class="header"> <h3>lib/chess_pieces/king.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>20</b> relevant lines. <span class="green"><b>20</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># King piece for a gameof chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class King < ChessPiece</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="8"> <span class="hits">1</span> <code class="ruby"> attr_writer :moved</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # Initializes a new king piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="15"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="16"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="17"> <span class="hits">134</span> <code class="ruby"> @move_tree_template = build_king_move_tree</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="18"> <span class="hits">134</span> <code class="ruby"> @moved = false</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="19"> <span class="hits">134</span> <code class="ruby"> super(color == 'white' ? '♚'.white : '♔', color, position, 10_000)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> # Flags a king as having moved after the first move</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="24"> <span class="hits">1</span> <code class="ruby"> def move(to)</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="25"> <span class="hits">57</span> <code class="ruby"> @moved = true</code> </li> </div> <div> <li class="covered" data-hits="57" data-linenumber="26"> <span class="hits">57</span> <code class="ruby"> super(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="27"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="29"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="30"> <code class="ruby"> # Returns whether or not the king has moved before for the purpose of</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="31"> <code class="ruby"> # whether or not the king can castle or not.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="32"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby"> # @return [Boolean] @moved Whether or not the king has moved.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="34"> <span class="hits">1</span> <code class="ruby"> def moved?</code> </li> </div> <div> <li class="covered" data-hits="30" data-linenumber="35"> <span class="hits">30</span> <code class="ruby"> @moved</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="38"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="39"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="40"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> # Builds a king move tree where the king can move in any direction up to</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="42"> <code class="ruby"> # one space.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="43"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the king.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="45"> <span class="hits">1</span> <code class="ruby"> def build_king_move_tree</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="46"> <span class="hits">134</span> <code class="ruby"> move_tree_template = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="48"> <code class="ruby"> # Get the 8 surrounding spaces</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="49"> <span class="hits">134</span> <code class="ruby"> locations = [-1, 0, 1].repeated_permutation(2).to_a</code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="50"> <span class="hits">134</span> <code class="ruby"> locations.delete([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="51"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="52"> <span class="hits">134</span> <code class="ruby"> locations.each do |loc|</code> </li> </div> <div> <li class="covered" data-hits="1072" data-linenumber="53"> <span class="hits">1072</span> <code class="ruby"> move_tree_template.root.add_child(loc)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="54"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="55"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="134" data-linenumber="56"> <span class="hits">134</span> <code class="ruby"> move_tree_template</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="57"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="58"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="893ceaf52ac95fe8e4c435897ad565bd04fd9d7d"> <div class="header"> <h3>lib/chess_pieces/knight.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>10</b> relevant lines. <span class="green"><b>10</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># Knight piece for a game of chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class Knight < ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="8"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"> # Initializes a new knight piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="14"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="230" data-linenumber="15"> <span class="hits">230</span> <code class="ruby"> @move_tree_template = build_knight_move_tree</code> </li> </div> <div> <li class="covered" data-hits="230" data-linenumber="16"> <span class="hits">230</span> <code class="ruby"> super(color == 'white' ? '♞'.white : '♘', color, position, 3)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="19"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"> # Builds the Knight move tree. The Knight can move in an L shape in any</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> # direction as long as the board permits. The permutations given represent</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> # the 8 spaces a Knight may move to.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the knight.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="25"> <span class="hits">1</span> <code class="ruby"> def build_knight_move_tree</code> </li> </div> <div> <li class="covered" data-hits="230" data-linenumber="26"> <span class="hits">230</span> <code class="ruby"> move_tree = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="27"> <code class="ruby"> # Get all possible net changes for a knight</code> </li> </div> <div> <li class="covered" data-hits="2990" data-linenumber="28"> <span class="hits">2990</span> <code class="ruby"> knight_moves_delta = [1, -1, 2, -2].permutation(2).reject { |n| n.sum.zero? }</code> </li> </div> <div> <li class="covered" data-hits="2070" data-linenumber="29"> <span class="hits">2070</span> <code class="ruby"> knight_moves_delta.each { |move| move_tree.root.add_child(move) }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="30"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="230" data-linenumber="31"> <span class="hits">230</span> <code class="ruby"> move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="32"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="3dabe0a14d569a6ebe6d07ef2c1c7cd1d9b6bdd8"> <div class="header"> <h3>lib/chess_pieces/move_tree.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>29</b> relevant lines. <span class="green"><b>29</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'move_tree_node'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># A tree structure for the possible moves of a chess piece.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class MoveTree</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="8"> <span class="hits">1</span> <code class="ruby"> include Enumerable</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="9"> <span class="hits">1</span> <code class="ruby"> attr_reader :root</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> # Assigns a MoveTreeNode to be the root.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby"> # @param [Array<Integer>] root_position An integer array of length 2</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="15"> <code class="ruby"> # representing the starting location</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="16"> <code class="ruby"> # for a piece.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="17"> <span class="hits">1</span> <code class="ruby"> def initialize(root_position)</code> </li> </div> <div> <li class="covered" data-hits="4381" data-linenumber="18"> <span class="hits">4381</span> <code class="ruby"> @root = MoveTreeNode.new(root_position)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="19"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> # Iterates through the tree using level order.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> # @param [Block or Proc] The block to call each node in the the tree on.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="25"> <span class="hits">1</span> <code class="ruby"> def each(&block)</code> </li> </div> <div> <li class="covered" data-hits="15670" data-linenumber="26"> <span class="hits">15670</span> <code class="ruby"> visit_queue = [@root]</code> </li> </div> <div> <li class="covered" data-hits="15670" data-linenumber="27"> <span class="hits">15670</span> <code class="ruby"> until visit_queue.empty?</code> </li> </div> <div> <li class="covered" data-hits="185354" data-linenumber="28"> <span class="hits">185354</span> <code class="ruby"> current_node = visit_queue.shift</code> </li> </div> <div> <li class="covered" data-hits="185354" data-linenumber="29"> <span class="hits">185354</span> <code class="ruby"> block.call(current_node)</code> </li> </div> <div> <li class="covered" data-hits="352550" data-linenumber="30"> <span class="hits">352550</span> <code class="ruby"> current_node.children.each { |child| visit_queue << child }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="31"> <code class="ruby"> end</code> </li> </div> <div> <li class="covered" data-hits="11553" data-linenumber="32"> <span class="hits">11553</span> <code class="ruby"> self</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="34"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby"> # Creates a deep copy of the move tree.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="38"> <code class="ruby"> # @return [MoveTree] A deep copy of self.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="39"> <span class="hits">1</span> <code class="ruby"> def clone</code> </li> </div> <div> <li class="covered" data-hits="1308" data-linenumber="40"> <span class="hits">1308</span> <code class="ruby"> Marshal.load(Marshal.dump(self))</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="42"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="43"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"> # Removes a node and its children from the MoveTree.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="45"> <code class="ruby"> # Returns the trimmed child if it was found and nil if it wasn't found in the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="46"> <code class="ruby"> # tree.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="48"> <code class="ruby"> # @param [Array<Integer>] loc A location array (2 integers) or a MoveTreeNode</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="49"> <code class="ruby"> # to remove from the the tree.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="50"> <code class="ruby"> # @raise [ArgumentError] if +loc+ is not an Array or MoveTreeNode.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="51"> <span class="hits">1</span> <code class="ruby"> def trim_branch!(loc)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="52"> <code class="ruby"> # Raise an error if the argument is not either an array or a MoveTreeNode</code> </li> </div> <div> <li class="covered" data-hits="12446" data-linenumber="53"> <span class="hits">12446</span> <code class="ruby"> unless (loc.is_a? Array) || (loc.is_a? MoveTreeNode)</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="54"> <span class="hits">1</span> <code class="ruby"> raise(ArgumentError, "Argument is a #{loc.class}; should be Array or MoveTreeNode")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="55"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="56"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="57"> <code class="ruby"> # Convert loc to an array so that node.children.include?(loc) can</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="58"> <code class="ruby"> # find the right node.</code> </li> </div> <div> <li class="covered" data-hits="12445" data-linenumber="59"> <span class="hits">12445</span> <code class="ruby"> loc = loc.is_a?(Array) ? loc : loc.loc</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="60"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="12445" data-linenumber="61"> <span class="hits">12445</span> <code class="ruby"> each do |node|</code> </li> </div> <div> <li class="covered" data-hits="138413" data-linenumber="62"> <span class="hits">138413</span> <code class="ruby"> children_arr = node.children.map(&:loc)</code> </li> </div> <div> <li class="covered" data-hits="138413" data-linenumber="63"> <span class="hits">138413</span> <code class="ruby"> if children_arr.include?(loc)</code> </li> </div> <div> <li class="covered" data-hits="4117" data-linenumber="64"> <span class="hits">4117</span> <code class="ruby"> node.remove_child(loc)</code> </li> </div> <div> <li class="covered" data-hits="4117" data-linenumber="65"> <span class="hits">4117</span> <code class="ruby"> return loc</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="66"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="67"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="68"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="69"> <code class="ruby"> # Return nothing if the node was not found.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="70"> <code class="ruby"> nil</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="71"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="72"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="73"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="74"> <code class="ruby"> # Returns an array of the Move Tree using level order</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="75"> <code class="ruby"> # (for ease of writing test cases)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="76"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="77"> <code class="ruby"> # @return [Array<Array<Integer>>] tree_array The array of locations of the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="78"> <code class="ruby"> # move tree.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="79"> <span class="hits">1</span> <code class="ruby"> def to_a</code> </li> </div> <div> <li class="covered" data-hits="585" data-linenumber="80"> <span class="hits">585</span> <code class="ruby"> tree_array = []</code> </li> </div> <div> <li class="covered" data-hits="3123" data-linenumber="81"> <span class="hits">3123</span> <code class="ruby"> each { |node| tree_array << node.loc }</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="82"> <code class="ruby"> # Remove the root node since staying in the same location</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="83"> <code class="ruby"> # is not a move.</code> </li> </div> <div> <li class="covered" data-hits="585" data-linenumber="84"> <span class="hits">585</span> <code class="ruby"> tree_array.shift</code> </li> </div> <div> <li class="covered" data-hits="585" data-linenumber="85"> <span class="hits">585</span> <code class="ruby"> tree_array</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="86"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="87"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="7bfa93b283d8934f2cce410c4838162e6bd6e0be"> <div class="header"> <h3>lib/chess_pieces/move_tree_node.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>19</b> relevant lines. <span class="green"><b>19</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="3"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"># A node structure for the tree representation of a pieces potential moves.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby"># See MoveTree.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="6"> <span class="hits">1</span> <code class="ruby">class MoveTreeNode</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby"> attr_accessor :loc</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="8"> <span class="hits">1</span> <code class="ruby"> attr_reader :children</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # Initialize a node with its location and an empty children array.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # @param [Array<Integer>] loc An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby"> # location the node represents.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="15"> <span class="hits">1</span> <code class="ruby"> def initialize(loc)</code> </li> </div> <div> <li class="covered" data-hits="36714" data-linenumber="16"> <span class="hits">36714</span> <code class="ruby"> @loc = loc</code> </li> </div> <div> <li class="covered" data-hits="36714" data-linenumber="17"> <span class="hits">36714</span> <code class="ruby"> @children = []</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="19"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> # Add a child to the array of children nodes.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> # @param [Array<Integer>] loc An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> # location of the node to add.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="25"> <code class="ruby"> # @raises [ArgumentError] if +loc+ isn't an Array or MoveTreeNode.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="26"> <span class="hits">1</span> <code class="ruby"> def add_child(loc)</code> </li> </div> <div> <li class="covered" data-hits="28185" data-linenumber="27"> <span class="hits">28185</span> <code class="ruby"> return @children << MoveTreeNode.new(loc) if loc.is_a? Array</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="2924" data-linenumber="29"> <span class="hits">2924</span> <code class="ruby"> return @children << loc if loc.is_a? MoveTreeNode</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="30"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="31"> <code class="ruby"> # Raise an error if the argument is not either an array or a MoveTreeNode</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="32"> <span class="hits">1</span> <code class="ruby"> raise(ArgumentError, "Argument is a #{loc.class}; should be Array or MoveTreeNode")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="33"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="34"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby"> # Removes a child from the array of children nodes.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="38"> <code class="ruby"> # @param [Array<Integer>] loc An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="39"> <code class="ruby"> # location of the node to remove, or a</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="40"> <code class="ruby"> # MoveTreeNode object with the loc to match.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> # @raises [ArgumentError] if +loc+ isn't an Array or MoveTreeNode.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="42"> <span class="hits">1</span> <code class="ruby"> def remove_child(loc)</code> </li> </div> <div> <li class="covered" data-hits="4124" data-linenumber="43"> <span class="hits">4124</span> <code class="ruby"> return @children.delete(MoveTreeNode.new(loc)) if loc.is_a? Array</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="4" data-linenumber="45"> <span class="hits">4</span> <code class="ruby"> return @children.delete(loc) if loc.is_a? MoveTreeNode</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="46"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"> # Raise an error if the argument is not either an array or a MoveTreeNode</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="48"> <span class="hits">1</span> <code class="ruby"> raise(ArgumentError, "Argument is a #{loc.class}; should be Array or MoveTreeNode")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="49"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="50"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="51"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="52"> <code class="ruby"> # Returns a string representation of the node using its location</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="53"> <code class="ruby"> # and a list of its children.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="54"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="55"> <code class="ruby"> # @returns [String] String with the node's location and children.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="56"> <span class="hits">1</span> <code class="ruby"> def to_s</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="57"> <span class="hits">1</span> <code class="ruby"> "#{@loc}: #{@children}"</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="58"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="59"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="60"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="61"> <code class="ruby"> # Define equality between two nodes by same location.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="62"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="63"> <code class="ruby"> # @param [MoveTreeNode] other The other MoveTreeNode to compare the location</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="64"> <code class="ruby"> # for equality.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="65"> <code class="ruby"> # @return [true] if the locations match, false otherwise.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="66"> <span class="hits">1</span> <code class="ruby"> def ==(other)</code> </li> </div> <div> <li class="covered" data-hits="14162" data-linenumber="67"> <span class="hits">14162</span> <code class="ruby"> return false unless other.is_a? MoveTreeNode</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="68"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="14162" data-linenumber="69"> <span class="hits">14162</span> <code class="ruby"> @loc == other.loc</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="70"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="71"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="7bee78754871089633ea736943782a75b63ba324"> <div class="header"> <h3>lib/chess_pieces/pawn.rb</h3> <h4> <span class="green"> 91.43%
</span>
lines covered </h4> <div class="t-line-summary"> <b>70</b> relevant lines. <span class="green"><b>64</b> lines covered</span> and <span class="red"><b>6</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="4"> <span class="hits">1</span> <code class="ruby">require_relative 'queen'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="5"> <span class="hits">1</span> <code class="ruby">require_relative 'rook'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="6"> <span class="hits">1</span> <code class="ruby">require_relative 'bishop'</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">require_relative 'knight'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="8"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"># Pawn piece for a game of chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="11"> <span class="hits">1</span> <code class="ruby">class Pawn < ChessPiece</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="12"> <span class="hits">1</span> <code class="ruby"> attr_reader :direction</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="13"> <span class="hits">1</span> <code class="ruby"> attr_accessor :move_count</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="14"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="15"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="16"> <code class="ruby"> # Initializes a new pawn piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="19"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="21"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="953" data-linenumber="22"> <span class="hits">953</span> <code class="ruby"> @move_count = 0</code> </li> </div> <div> <li class="covered" data-hits="953" data-linenumber="23"> <span class="hits">953</span> <code class="ruby"> @direction = color == 'white' ? 1 : -1</code> </li> </div> <div> <li class="covered" data-hits="953" data-linenumber="24"> <span class="hits">953</span> <code class="ruby"> @back_row = color == 'white' ? 7 : 0</code> </li> </div> <div> <li class="covered" data-hits="953" data-linenumber="25"> <span class="hits">953</span> <code class="ruby"> @move_tree_template = build_pawn_move_tree</code> </li> </div> <div> <li class="covered" data-hits="953" data-linenumber="26"> <span class="hits">953</span> <code class="ruby"> super(color == 'white' ? '♙'.white : '♙', color, position, 1)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="27"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="29"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="30"> <code class="ruby"> # Possible moves rewrite for the pawn</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="31"> <span class="hits">1</span> <code class="ruby"> def possible_moves</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="32"> <code class="ruby"> # Remove the two space move on the Pawn's first move</code> </li> </div> <div> <li class="covered" data-hits="485" data-linenumber="33"> <span class="hits">485</span> <code class="ruby"> @move_tree_template = @move_count.zero? ? build_pawn_move_tree_first_move : build_pawn_move_tree</code> </li> </div> <div> <li class="covered" data-hits="485" data-linenumber="34"> <span class="hits">485</span> <code class="ruby"> super</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="38"> <code class="ruby"> # Moves the Pawn and updates @move_count</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="39"> <code class="ruby"> # If the pawn reaches the back row of the opposing side, it returns a queen.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="40"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="41"> <code class="ruby"> # @param [Array<Integer>] An integer array of length 2 denoting the new</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="42"> <code class="ruby"> # location of the pawn.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="43"> <code class="ruby"> # @param [String] The type of player whose pawn it is. Used mainly for pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="44"> <code class="ruby"> # promotion.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="45"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="46"> <code class="ruby"> # @return [ChessPiece] A pawn if the pawn moves or a Queen if the pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="47"> <code class="ruby"> # reaches the end of the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="48"> <span class="hits">1</span> <code class="ruby"> def move(to, player_type = 'human')</code> </li> </div> <div> <li class="covered" data-hits="64" data-linenumber="49"> <span class="hits">64</span> <code class="ruby"> @move_count += 1</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="50"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="64" data-linenumber="51"> <span class="hits">64</span> <code class="ruby"> if to[0] == @back_row</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="52"> <span class="hits">6</span> <code class="ruby"> piece_type = new_piece_type(player_type)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="53"> <code class="ruby"> # Pawn becomes a new piece</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="54"> <span class="hits">6</span> <code class="ruby"> return piece_type.new(@color, to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="55"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="56"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="58" data-linenumber="57"> <span class="hits">58</span> <code class="ruby"> super(to)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="58"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="59"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="60"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="61"> <code class="ruby"> # Returns whether or not the move the Pawn is on or just finished</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="62"> <code class="ruby"> # its first ever move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="63"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="64"> <code class="ruby"> # @return [true] if the pawn is on or just finished its first move.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="65"> <span class="hits">1</span> <code class="ruby"> def first_move?</code> </li> </div> <div> <li class="covered" data-hits="20" data-linenumber="66"> <span class="hits">20</span> <code class="ruby"> @move_count <= 1</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="67"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="68"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="69"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="70"> <code class="ruby"> # Returns whether the pawn can capture a piece at a given location</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="71"> <code class="ruby"> # based on its current position. This only possible if the opposing</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="72"> <code class="ruby"> # piece is in front of and diagonal to the current space.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="73"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="74"> <code class="ruby"> # @param [ChessPiece] other_piece The ChessPiece that is the proposed target.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="75"> <code class="ruby"> # @return [true] if pawn can capture the piece.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="76"> <span class="hits">1</span> <code class="ruby"> def can_capture?(other_piece)</code> </li> </div> <div> <li class="covered" data-hits="1631" data-linenumber="77"> <span class="hits">1631</span> <code class="ruby"> return false unless other_piece.is_a? ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="78"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="813" data-linenumber="79"> <span class="hits">813</span> <code class="ruby"> return false if other_piece.color == @color</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="80"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="25" data-linenumber="81"> <span class="hits">25</span> <code class="ruby"> occupied_position = other_piece.position</code> </li> </div> <div> <li class="covered" data-hits="25" data-linenumber="82"> <span class="hits">25</span> <code class="ruby"> in_front = occupied_position[0] == (@position[0] + @direction)</code> </li> </div> <div> <li class="covered" data-hits="25" data-linenumber="83"> <span class="hits">25</span> <code class="ruby"> diagonal = [@position[1] + 1, @position[1] - 1].include?(occupied_position[1])</code> </li> </div> <div> <li class="covered" data-hits="25" data-linenumber="84"> <span class="hits">25</span> <code class="ruby"> in_front && diagonal || en_passant(other_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="85"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="86"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="87"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="88"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="89"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="90"> <code class="ruby"> # Prompt the user for input to determine what piece to return when the pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="91"> <code class="ruby"> # advances to the last square</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="92"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="93"> <code class="ruby"> # @param [String] The type of player whose pawn it is. Used mainly for pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="94"> <code class="ruby"> # promotion.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="95"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="96"> <code class="ruby"> # @return [Class] The type of piece the pawn is turning into.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="97"> <span class="hits">1</span> <code class="ruby"> def new_piece_type(player_type = 'human')</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="98"> <span class="hits">6</span> <code class="ruby"> case player_type</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="99"> <code class="ruby"> when 'human'</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="100"> <span class="hits">6</span> <code class="ruby"> puts 'Your pawn is being promoted! What peice would you like it to become?'</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="101"> <span class="hits">6</span> <code class="ruby"> print_piece_types</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="102"> <span class="hits">6</span> <code class="ruby"> player_input = $stdin.gets</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="103"> <span class="hits">6</span> <code class="ruby"> player_input = player_input&.chomp</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="104"> <span class="hits">6</span> <code class="ruby"> player_input = player_input&.downcase</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="105"> <code class="ruby"> when 'random'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="106"> <code class="ruby"> player_input = %w[1 2 3 4].sample</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="107"> <code class="ruby"> else</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="108"> <code class="ruby"> player_input = '1'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="109"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="110"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="111"> <span class="hits">6</span> <code class="ruby"> return Queen if %w[1 queen q].include?(player_input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="112"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="3" data-linenumber="113"> <span class="hits">3</span> <code class="ruby"> return Rook if %w[2 rook r].include?(player_input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="114"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="2" data-linenumber="115"> <span class="hits">2</span> <code class="ruby"> return Bishop if %w[3 bishop b].include?(player_input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="116"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="117"> <span class="hits">1</span> <code class="ruby"> return Knight if %w[4 knight k].include?(player_input)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="118"> <code class="ruby"></code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="119"> <code class="ruby"> raise(StandardError, "'#{player_input}' is not a valid input.")</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="120"> <code class="ruby"> rescue StandardError => e</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="121"> <code class="ruby"> puts e.message</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="122"> <code class="ruby"> puts 'Please select an option from the menu.'</code> </li> </div> <div> <li class="missed" data-hits="0" data-linenumber="123"> <code class="ruby"> retry</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="124"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="125"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="126"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="127"> <code class="ruby"> # Prints the menu for pieces the pawn can become.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="128"> <span class="hits">1</span> <code class="ruby"> def print_piece_types</code> </li> </div> <div> <li class="covered" data-hits="6" data-linenumber="129"> <span class="hits">6</span> <code class="ruby"> puts <<~PAWN_MENU</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="130"> <code class="ruby"> Please select one of the following options:</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="131"> <code class="ruby"> 1. Queen (Q) ♛ 3. Bishop (B) ♝</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="132"> <code class="ruby"> 2. Rook (R) ♜ 4. Knight (K) ♞</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="133"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="134"> <code class="ruby"> You may use the number, letter, or name to select the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="135"> <code class="ruby"> e.g - "1", "Queen", or "Q" all select the queen.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="136"> <code class="ruby"> PAWN_MENU</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="137"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="138"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="139"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="140"> <code class="ruby"> # Returns whether the Pawn can capture another Pawn using the rule</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="141"> <code class="ruby"> # "En passant."</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="142"> <code class="ruby"> # See {the Wikipeida entry}[https://en.wikipedia.org/wiki/En_passant].</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="143"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="144"> <code class="ruby"> # @param [ChessPiece] other_piece The ChessPiece that is the proposed target.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="145"> <code class="ruby"> # @return [true] if the other piece is a capturable pawn using En Passant.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="146"> <span class="hits">1</span> <code class="ruby"> def en_passant(other_piece)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="147"> <code class="ruby"> # Only applies to other Pawns</code> </li> </div> <div> <li class="covered" data-hits="17" data-linenumber="148"> <span class="hits">17</span> <code class="ruby"> return false unless other_piece.is_a? Pawn</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="149"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="150"> <code class="ruby"> # Only applies when the other Pawn just finished its first move</code> </li> </div> <div> <li class="covered" data-hits="17" data-linenumber="151"> <span class="hits">17</span> <code class="ruby"> return false unless other_piece.first_move?</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="152"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="153"> <code class="ruby"> # Check beside on the right</code> </li> </div> <div> <li class="covered" data-hits="15" data-linenumber="154"> <span class="hits">15</span> <code class="ruby"> beside = other_piece.position == [@position[0], @position[1] + 1]</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="155"> <code class="ruby"> # Check beside on the left</code> </li> </div> <div> <li class="covered" data-hits="15" data-linenumber="156"> <span class="hits">15</span> <code class="ruby"> beside || (other_piece.position == [@position[0], @position[1] - 1])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="157"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="158"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="159"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="160"> <code class="ruby"> # Builds the Pawn move tree. The pawn can move forward 2 spaces on its first</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="161"> <code class="ruby"> # move, but otherwise can only move one space forward. The Pawn may also move</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="162"> <code class="ruby"> # diagonally to capture an enemy piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="163"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="164"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the pawn.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="165"> <span class="hits">1</span> <code class="ruby"> def build_pawn_move_tree_first_move</code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="166"> <span class="hits">447</span> <code class="ruby"> move_tree = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="167"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="168"> <code class="ruby"> # Create changes based on @direction because pawns can only move one</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="169"> <code class="ruby"> # direction.</code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="170"> <span class="hits">447</span> <code class="ruby"> move_tree.root.add_child([@direction, 0])</code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="171"> <span class="hits">447</span> <code class="ruby"> move_tree.root.children[0].add_child([2 * @direction, 0])</code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="172"> <span class="hits">447</span> <code class="ruby"> move_tree.root.add_child([@direction, 1])</code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="173"> <span class="hits">447</span> <code class="ruby"> move_tree.root.add_child([@direction, -1])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="174"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="447" data-linenumber="175"> <span class="hits">447</span> <code class="ruby"> move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="176"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="177"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="178"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="179"> <code class="ruby"> # Builds the Pawn move tree without the two-space forward move.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="180"> <code class="ruby"> # The pawn can move forward 2 spaces on its first move, but otherwise can</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="181"> <code class="ruby"> # only move one space forward. The Pawn may also move diagonally to capture</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="182"> <code class="ruby"> # an enemy piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="183"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="184"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the pawn.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="185"> <span class="hits">1</span> <code class="ruby"> def build_pawn_move_tree</code> </li> </div> <div> <li class="covered" data-hits="991" data-linenumber="186"> <span class="hits">991</span> <code class="ruby"> move_tree = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="187"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="188"> <code class="ruby"> # Create changes based on @direction because pawns can only move one</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="189"> <code class="ruby"> # direction.</code> </li> </div> <div> <li class="covered" data-hits="991" data-linenumber="190"> <span class="hits">991</span> <code class="ruby"> move_tree.root.add_child([@direction, 0])</code> </li> </div> <div> <li class="covered" data-hits="991" data-linenumber="191"> <span class="hits">991</span> <code class="ruby"> move_tree.root.add_child([@direction, 1])</code> </li> </div> <div> <li class="covered" data-hits="991" data-linenumber="192"> <span class="hits">991</span> <code class="ruby"> move_tree.root.add_child([@direction, -1])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="193"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="991" data-linenumber="194"> <span class="hits">991</span> <code class="ruby"> move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="195"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="196"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="11a28e07fe55c493d7e58a6d563478e1d7b85847"> <div class="header"> <h3>lib/chess_pieces/queen.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>13</b> relevant lines. <span class="green"><b>13</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># Queen piece for a game of chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class Queen < ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="8"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"> # Initializes a new queen piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="14"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="15"> <span class="hits">119</span> <code class="ruby"> @move_tree_template = build_queen_move_tree</code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="16"> <span class="hits">119</span> <code class="ruby"> super(color == 'white' ? '♛'.white : '♕', color, position, 9)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="19"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> # Builds the Queen's move tree. The Queen can move in any direction as far as</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> # the board permits.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="25"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the Queen.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="26"> <span class="hits">1</span> <code class="ruby"> def build_queen_move_tree</code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="27"> <span class="hits">119</span> <code class="ruby"> move_tree_template = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"> # Get directions</code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="29"> <span class="hits">119</span> <code class="ruby"> directions = [-1, 0, 1].repeated_permutation(2).to_a</code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="30"> <span class="hits">119</span> <code class="ruby"> directions.delete([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="31"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="32"> <span class="hits">119</span> <code class="ruby"> directions.each do |direction|</code> </li> </div> <div> <li class="covered" data-hits="952" data-linenumber="33"> <span class="hits">952</span> <code class="ruby"> move_tree_template.root.add_child(build_directional_tree_nodes(direction))</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="34"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="35"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="119" data-linenumber="36"> <span class="hits">119</span> <code class="ruby"> move_tree_template</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="38"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="b6d42288caf4c05ee8d7fd46fbe359b9c7cb64b3"> <div class="header"> <h3>lib/chess_pieces/rook.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>13</b> relevant lines. <span class="green"><b>13</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">require_relative 'chess_piece'</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="5"> <code class="ruby">##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="6"> <code class="ruby"># Rook piece for a game of chess</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="7"> <span class="hits">1</span> <code class="ruby">class Rook < ChessPiece</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="8"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="9"> <code class="ruby"> # Initializes a new rook piece with color and position.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="10"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="11"> <code class="ruby"> # @param [String] color A string denoting the color of the piece.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="12"> <code class="ruby"> # @param [Array<Integer>] position An integer array of length 2 denoting the</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="13"> <code class="ruby"> # location of the piece on the board.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="14"> <span class="hits">1</span> <code class="ruby"> def initialize(color, position)</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="15"> <span class="hits">247</span> <code class="ruby"> @move_tree_template = build_rook_move_tree</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="16"> <span class="hits">247</span> <code class="ruby"> super(color == 'white' ? '♜'.white : '♖', color, position, 5)</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="17"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="18"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="19"> <span class="hits">1</span> <code class="ruby"> protected</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="20"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="21"> <code class="ruby"> ##</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="22"> <code class="ruby"> # Builds the Rook's move tree. The Rook can move horizontally and vertically</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="23"> <code class="ruby"> # as far as the board permits.</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="24"> <code class="ruby"> #</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="25"> <code class="ruby"> # @return [MoveTree] move_tree_template A move tree template for the rook.</code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="26"> <span class="hits">1</span> <code class="ruby"> def build_rook_move_tree</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="27"> <span class="hits">247</span> <code class="ruby"> move_tree = MoveTree.new([0, 0])</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="28"> <code class="ruby"></code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="29"> <code class="ruby"> # Build in each of the four directions the rook can go.</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="30"> <span class="hits">247</span> <code class="ruby"> move_tree.root.add_child(build_directional_tree_nodes([1, 0]))</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="31"> <span class="hits">247</span> <code class="ruby"> move_tree.root.add_child(build_directional_tree_nodes([-1, 0]))</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="32"> <span class="hits">247</span> <code class="ruby"> move_tree.root.add_child(build_directional_tree_nodes([0, 1]))</code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="33"> <span class="hits">247</span> <code class="ruby"> move_tree.root.add_child(build_directional_tree_nodes([0, -1]))</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="34"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="247" data-linenumber="35"> <span class="hits">247</span> <code class="ruby"> move_tree</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="36"> <code class="ruby"> end</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="37"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
<div class="source_table" id="5d87e27a4b21f1f4beee25d74eac8997394978df"> <div class="header"> <h3>lib/invalid_move_error.rb</h3> <h4> <span class="green"> 100.0%
</span>
lines covered </h4> <div class="t-line-summary"> <b>1</b> relevant lines. <span class="green"><b>1</b> lines covered</span> and <span class="red"><b>0</b> lines missed.</span> </div> </div> <pre> <ol> <div> <li class="never" data-hits="" data-linenumber="1"> <code class="ruby"># frozen_string_literal: true</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="2"> <code class="ruby"></code> </li> </div> <div> <li class="covered" data-hits="1" data-linenumber="3"> <span class="hits">1</span> <code class="ruby">class InvalidMoveError < ArgumentError</code> </li> </div> <div> <li class="never" data-hits="" data-linenumber="4"> <code class="ruby">end</code> </li> </div> </ol> </pre>
</div>
</div> </div> </body>
</html>