OSDN Git Service

Refactored methods: League#find_rival and Game::decide_turns.
authordaigo <beatles@users.sourceforge.jp>
Sat, 4 Sep 2010 07:10:35 +0000 (16:10 +0900)
committerDaigo Moriwaki <daigo@debian.org>
Sat, 4 Sep 2010 07:10:35 +0000 (16:10 +0900)
shogi_server/command.rb
shogi_server/game.rb
shogi_server/league.rb
test/TC_game.rb

index 4ecb676..ba4fe1d 100644 (file)
@@ -490,14 +490,6 @@ module ShogiServer
       end
 
       rival = nil
-      if (Buoy.game_name?(@game_name))
-        if (@my_sente_str != "*")
-          @player.write_safe(sprintf("##[ERROR] You are not allowed to specify TEBAN %s for the game %s\n", @my_sente_str, @game_name))
-          return :continue
-        end
-        @player.sente = nil
-      end # really end
-
       if (League::Floodgate.game_name?(@game_name))
         if (@my_sente_str != "*")
           @player.write_safe(sprintf("##[ERROR] You are not allowed to specify TEBAN %s for the game %s\n", @my_sente_str, @game_name))
@@ -505,42 +497,18 @@ module ShogiServer
         end
         @player.sente = nil
       else
-        if (@my_sente_str == "*") && !Login.handicapped_game_name?(@game_name)
-          rival = $league.get_player("game_waiting", @game_name, nil, @player) # no preference
-        elsif (@my_sente_str == "+")
-          rival = $league.get_player("game_waiting", @game_name, false, @player) # rival must be gote
-        elsif (@my_sente_str == "-")
-          rival = $league.get_player("game_waiting", @game_name, true, @player) # rival must be sente
-        else
-          @player.write_safe(sprintf("##[ERROR] bad game option\n"))
-          return :continue
+        rival = $league.find_rival(@player, @my_sente_str, @game_name)
+        if rival.instance_of?(Symbol)  
+          # An error happened. rival is not a player instance, but an error
+          # symobl that must be returned to the main routine immediately.
+          return rival
         end
       end
 
       if (rival)
         @player.game_name = @game_name
-        
-        if ((@my_sente_str == "*") && (rival.sente == nil))
-          if (rand(2) == 0)
-            @player.sente = true
-            rival.sente = false
-          else
-            @player.sente = false
-            rival.sente = true
-          end
-        elsif (rival.sente == true) # rival has higher priority
-          @player.sente = false
-        elsif (rival.sente == false)
-          @player.sente = true
-        elsif (@my_sente_str == "+")
-          @player.sente = true
-          rival.sente = false
-        elsif (@my_sente_str == "-")
-          @player.sente = false
-          rival.sente = true
-        else
-          ## never reached
-        end
+        Game::decide_turns(@player, @my_sente_str, rival)
+
         if (Buoy.game_name?(@game_name))
           buoy = Buoy.new # TODO config
           if buoy.is_new_game?(@game_name)
index 5f7cd0e..5e46e12 100644 (file)
@@ -31,6 +31,36 @@ class Game
 
   @@mutex = Mutex.new
   @@time  = 0
+
+  # Decide turns of players according to their turn preferences.
+  # p2 is a rival player of the p1 player.
+  # p1_sente_string must be "*", "+" or "-".
+  #
+  def Game.decide_turns(p1, p1_sente_string, p2)
+    if ((p1_sente_string == "*") && (p2.sente == nil))
+      if (rand(2) == 0)
+        p1.sente = true
+        p2.sente = false
+      else
+        p1.sente = false
+        p2.sente = true
+      end
+    elsif (p2.sente == true) # rival has higher priority
+      p1.sente = false
+    elsif (p2.sente == false)
+      p1.sente = true
+    elsif (p1_sente_string == "+")
+      p1.sente = true
+      p2.sente = false
+    elsif (p1_sente_string == "-")
+      p1.sente = false
+      p2.sente = true
+    else
+      ## never reached
+    end
+  end
+
+
   def initialize(game_name, player0, player1, board)
     @monitors = Array::new # array of MonitorHandler*
     @game_name = game_name
index 9f7a5f3..5936e79 100644 (file)
@@ -98,6 +98,31 @@ class League
   def rated_players
     return @persistent.get_players
   end
+
+  # Find a rival for a player.
+  # Return,
+  #   1. symbol :continue for an error case
+  #   2. a rival player instance found
+  #   3. nil if rival not found 
+  #
+  def find_rival(player, my_sente_string, game_name)
+    case my_sente_string
+    when "*" # no preference
+      if Login.handicapped_game_name?(game_name)
+        player.write_safe("##[ERROR] Random turn preference is not allowed for handicapped games\n")
+        return :continue
+      end
+      return get_player("game_waiting", game_name, nil, player)
+    when "+" # rival must be gote
+      return get_player("game_waiting", game_name, false, player) 
+    when "-" # rival must be sente 
+      return get_player("game_waiting", game_name, true, player) 
+    else
+      write_safe("##[ERROR] bad game option: %s\n" % [my_sente_string])
+      return :continue
+    end
+  end
+
 end # class League
 
 end # ShogiServer
index a2b8366..8d7d493 100644 (file)
@@ -368,5 +368,41 @@ EOF
     game.monitoroff(handler2)
     assert_equal(0, game.monitors.size)
   end
+
+  def test_decide_turns
+    p1 = MockPlayer.new
+    p1.name = "p1"
+    p2 = MockPlayer.new
+    p2.name = "p2"
+
+    p1.sente=nil; p2.sente=false
+    ShogiServer::Game::decide_turns(p1, "+", p2)
+    assert_equal true, p1.sente
+
+    p1.sente=nil; p2.sente=nil
+    ShogiServer::Game::decide_turns(p1, "+", p2)
+    assert_equal true, p1.sente
+
+    p1.sente=nil; p2.sente=true
+    ShogiServer::Game::decide_turns(p1, "-", p2)
+    assert_equal false, p1.sente
+
+    p1.sente=nil; p2.sente=nil
+    ShogiServer::Game::decide_turns(p1, "-", p2)
+    assert_equal false, p1.sente
+
+    p1.sente=nil; p2.sente=false
+    ShogiServer::Game::decide_turns(p1, "*", p2)
+    assert_equal true, p1.sente
+
+    p1.sente=nil; p2.sente=true
+    ShogiServer::Game::decide_turns(p1, "*", p2)
+    assert_equal false, p1.sente
+
+    p1.sente=nil; p2.sente=nil
+    ShogiServer::Game::decide_turns(p1, "*", p2)
+    assert (p1.sente == true  && p2.sente == false) ||
+           (p1.sente == false && p2.sente == true)
+  end
 end