# $Id$

# Classes shared between client and server
module AntGame
  # Basic little animal wandering our world
  class Ant
    attr_accessor :energie, :x, :y, :direction, :has_food
    attr_accessor :friend_pheromone, :foe_pheromone, :home

    def initialize(x=0, y=0)
      @direction = :north
      @has_food = false
      @energie = 1.0
      @x = x; @y = y
      @next_action = Actions::WAIT
    end

    def dead?
      self.energie <= 0
    end
  end

  # Constants for the ants actions
  module Actions
    WAIT = :wait
    TAKE_FOOD = :take_food
    DROP_FOOD = :drop_food
    GO = :go
    TURN_LEFT = :turn_left
    TURN_RIGHT = :turn_right
    ATTACK = :attack
  end

  module Protocoll
    QUIT = 'Q:'
    ANT = 'A:'
    NEXT_ROUND = 'NR:'
    PLAYER_ID = "PN:"

    # Propertys of a ant that can be communicated to the client
    class AntPropertys
      ATTRIBUTES = [:id, :direction, :has_food, :energie, :x, :y]
      CELLS = [:cell, :cell_north, :cell_east, :cell_south, :cell_west]
      attr_accessor *ATTRIBUTES
      attr_accessor *CELLS

      def AntPropertys.from_ant(ant)
        result = AntPropertys.new
        result.load_from_ant(ant)
        result
      end

      def load_from_ant(ant)
        ATTRIBUTES.each do | a | self.send("#{a}=", ant.send(a)) end
        CELLS.each do | c | 
          cell = ant.send c
          self.send("#{c}=", cell ? CellPropertys.from_cell(cell, ant) : nil)
        end
      end

      def update_ant(ant)
        ATTRIBUTES.each do | a | ant.send("#{a}=", self.send(a)) end
        CELLS.each do | c | ant.send("#{c}=", self.send(c)) end
      end
    end
    
    # Propertys of a visible cell can be communicated to the client
    class CellPropertys
      attr_accessor :food, :friend_pheromone, :foe_pheromone, :friend_count, :foe_count, :home

      def CellPropertys.from_cell(cell, ant)
        result = CellPropertys.new
        result.load_from_cell(cell, ant)
        result
      end

      def load_from_cell(cell, ant)
        self.food = cell.food
        self.friend_pheromone = cell.pheromone.inject(0) { | r, (p, v) | r += (p == ant.player) ? v : 0 }
        self.foe_pheromone   = cell.pheromone.inject(0) { | r, (p, v) | r += (p == ant.player) ? 0 : v }
        self.foe_count       = cell.ants.inject(0){|r, a| r + (ant.player == a.player ? 0 : 1)  }
        self.friend_count    = cell.ants.inject(0){|r, a| r + (ant.player == a.player ? 1 : 0)  }
        self.home            = cell.home ? cell.home.id : nil
        self
      end
    end    
  end
end



class String; 
  def hex_encode
    result = ''
    self.each_byte do | b | result << "%02x" % b end
    result
  end

  def hex_decode
    self.scan(/../m).inject('') {|r, b| r << b.to_i(16).chr}
  end
end