1 <?xml version="1.0" encoding="iso-8859-1"?>
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
8 <title>apply_move! (Game)</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12 <body class="standalone-code">
13 <pre><span class="ruby-comment cmt"># File lib/libttc.rb, line 379</span>
14 <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">apply_move!</span>(<span class="ruby-identifier">move</span>, <span class="ruby-identifier">player</span> = <span class="ruby-ivar">@current_player</span>)
15 <span class="ruby-comment cmt"># Check the move is a valid one</span>
16 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Piece #{move.piece} does not exist"</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@pieces</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">name</span>)
17 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Player #{player} moving piece #{move.piece}"</span>) <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">colour</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">player</span>
18 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Attempting to move captured piece #{move.piece}"</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">captured</span>
19 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Attempting to move #{move.piece} onto or via base without captured pieces"</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">via_base?</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">contains</span>.<span class="ruby-identifier">empty?</span>
20 <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>.<span class="ruby-identifier">safe?</span>
21 <span class="ruby-keyword kw">if</span> (<span class="ruby-ivar">@pieces</span>.<span class="ruby-identifier">find_all</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>, <span class="ruby-identifier">p</span><span class="ruby-operator">|</span> <span class="ruby-identifier">p</span>.<span class="ruby-identifier">position</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>}).<span class="ruby-identifier">length</span> <span class="ruby-operator">>=</span> <span class="ruby-value">3</span>
22 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Attempting to move #{move.piece} onto safe position #{move.destination} when there are already three or more pieces there"</span>)
23 <span class="ruby-keyword kw">end</span>
24 <span class="ruby-keyword kw">end</span>
25 <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">via_base?</span>
26 <span class="ruby-identifier">moved_distance</span> = <span class="ruby-identifier">board</span>.<span class="ruby-identifier">distance_between</span>[<span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">position</span>.<span class="ruby-identifier">place</span>][<span class="ruby-identifier">player</span>] <span class="ruby-operator">+</span>
27 <span class="ruby-identifier">board</span>.<span class="ruby-identifier">distance_between</span>[<span class="ruby-identifier">player</span>][<span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>.<span class="ruby-identifier">place</span>]
28 <span class="ruby-keyword kw">else</span>
29 <span class="ruby-identifier">moved_distance</span> = <span class="ruby-identifier">board</span>.<span class="ruby-identifier">distance_between</span>[<span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">position</span>.<span class="ruby-identifier">place</span>][<span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>.<span class="ruby-identifier">place</span>]
30 <span class="ruby-keyword kw">end</span>
31 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">InvalidMoveError</span>, <span class="ruby-node">"Attempting to move piece #{move.piece} #{moved_distance} places (from #{move.piece.position} to #{move.destination})"</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">moved_distance</span> <span class="ruby-operator"><</span> <span class="ruby-value">1</span> <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">moved_distance</span> <span class="ruby-operator">></span> <span class="ruby-value">6</span>
33 <span class="ruby-comment cmt"># Apply this move</span>
34 <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">move_to</span>(<span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>)
36 <span class="ruby-comment cmt"># Capture anything already there (unless it's a safe place or a base, </span>
37 <span class="ruby-comment cmt"># or our own colour, or already captured)</span>
38 <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>.<span class="ruby-identifier">safe?</span> <span class="ruby-keyword kw">or</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span>.<span class="ruby-identifier">base?</span>
39 <span class="ruby-ivar">@pieces</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">name</span>, <span class="ruby-identifier">target_piece</span><span class="ruby-operator">|</span>
40 <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">target_piece</span>.<span class="ruby-identifier">position</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">destination</span> <span class="ruby-keyword kw">and</span>
41 <span class="ruby-identifier">target_piece</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span> <span class="ruby-keyword kw">and</span>
42 <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">contains</span>.<span class="ruby-identifier">member?</span>(<span class="ruby-identifier">target_piece</span>) <span class="ruby-keyword kw">and</span>
43 <span class="ruby-identifier">target_piece</span>.<span class="ruby-identifier">colour</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">player</span> <span class="ruby-keyword kw">and</span>
44 <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">target_piece</span>.<span class="ruby-identifier">captured</span>
45 <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">capture</span>(<span class="ruby-identifier">target_piece</span>)
46 <span class="ruby-keyword kw">end</span>
47 <span class="ruby-keyword kw">end</span>
48 <span class="ruby-keyword kw">end</span>
50 <span class="ruby-comment cmt"># If the move was via our base, drop all captured pieces</span>
51 <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">via_base?</span>
52 <span class="ruby-identifier">capturers_base</span> = <span class="ruby-identifier">board</span>.<span class="ruby-identifier">positions</span>[<span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">colour</span>]
53 <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">contains</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">captured_piece</span><span class="ruby-operator">|</span>
54 <span class="ruby-identifier">captured_piece</span>.<span class="ruby-identifier">move_to</span> <span class="ruby-identifier">capturers_base</span>
55 <span class="ruby-identifier">captured_piece</span>.<span class="ruby-identifier">captured</span> = <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">captured_piece</span>.<span class="ruby-identifier">colour</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">colour</span>
56 <span class="ruby-keyword kw">end</span>
57 <span class="ruby-identifier">move</span>.<span class="ruby-identifier">piece</span>.<span class="ruby-identifier">contains</span> = []
58 <span class="ruby-keyword kw">end</span>
60 <span class="ruby-comment cmt"># Record the new stae</span>
61 <span class="ruby-identifier">this_game_state</span> = <span class="ruby-constant">GameState</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">move</span>, <span class="ruby-identifier">player</span>, <span class="ruby-ivar">@pieces</span>)
62 <span class="ruby-ivar">@history</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">this_game_state</span>
64 <span class="ruby-comment cmt"># Retain only players that have uncaptured pieces. </span>
65 <span class="ruby-comment cmt"># If there's only one player with uncaptured pieces, declare a win.</span>
66 <span class="ruby-identifier">potential_players</span> = []
67 <span class="ruby-ivar">@players</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">p</span><span class="ruby-operator">|</span>
68 <span class="ruby-keyword kw">if</span> (<span class="ruby-ivar">@pieces</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">select</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">piece</span><span class="ruby-operator">|</span> <span class="ruby-identifier">piece</span>.<span class="ruby-identifier">colour</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">p</span>}).<span class="ruby-identifier">any?</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">piece</span><span class="ruby-operator">|</span> <span class="ruby-keyword kw">not</span> <span class="ruby-identifier">piece</span>.<span class="ruby-identifier">captured</span>}
69 <span class="ruby-identifier">potential_players</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">p</span>
70 <span class="ruby-keyword kw">end</span>
71 <span class="ruby-comment cmt"># potential_players << p if (@pieces.values.select {|p| p.colour == @current_player}).any? {|p| not p.captured}</span>
72 <span class="ruby-keyword kw">end</span>
73 <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">potential_players</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator"><=</span> <span class="ruby-value">1</span>
74 <span class="ruby-identifier">raise</span>(<span class="ruby-constant">GameWonNotice</span>, <span class="ruby-node">"Game won by #{potential_players[0]}"</span>)
75 <span class="ruby-keyword kw">end</span>
76 <span class="ruby-ivar">@players</span> = <span class="ruby-identifier">potential_players</span>.<span class="ruby-identifier">sort</span>
77 <span class="ruby-keyword kw">end</span></pre>