#　ダイスロール関連

require 'darkhall/const'
require 'darkhall/util/common'
require 'darkhall/roll_table'
require 'darkhall/action'


module DarkHall
	class CheckDiceBase
		attr_reader :border
	
		def initialize(border, log_title = nil, log_indent_level = 0)
			@border = border.to_i
			@log_title = log_title
			@log_indent_level = log_indent_level
		end

		
		def failure_rate
			1.00 - success_rate
		end
		
		def failure_percentage
			100 - success_percentage
		end
		
		def log_indent
			"\t" * @log_indent_level
		end

	end

	class CheckDice < CheckDiceBase
		def self.roll(*args)
			self.new(*args).roll
		end
		
		def border_on_calculation
			if @border <= 20 then
				20
			elsif @border >= 80 then
				80
			else
				@border
			end
			
		end
	
		def roll
			re = Util.diceroll('3d33', border_on_calculation)
			if @log_title then
				LOGGER.puts("#{log_indent}[3d33判定] #{@log_title} (目標値#{@border} - #{success_percentage}%) => #{re ? '成功' : '失敗'}")
			end
			
			re
		end
		
		alias check roll
		
		def success_rate
			ROLL_TABLE[border_on_calculation] * 0.01
		end
		
		def success_percentage
			(success_rate * 100).round
		end
	end
	
	class CheckDice100 < CheckDiceBase
		def self.roll(*args)
			self.new(*args).roll
		end
	
		def roll
			re = (rand(100) < @border)
			if @log_title then
				LOGGER.puts("#{log_indent}[d100判定] #{@log_title} (目標値#{@border} - #{success_percentage}%) => #{re ? '成功' : '失敗'}")
			end
			
			re
		end
		
		alias check roll
		
		def success_rate
			success_percentage * 0.01
		end

		
		def success_percentage
			if @border < 0 then
				0
			elsif @border > 100 then
				100
			else
				@border
			end
		end
	end
	
	class DoubleDice
		attr_reader :base, :reducing, :balance
	
		def initialize(base, red, balance = 0.5)
			@base = base.to_i
			if @base < 0 then
				@base = 0
			end
			
			@reducing = red.to_i
			if @reducing < 0 then
				@reducing = 0
			end
			
			@balance = balance
			if @balance < 0.0 then
				@balance = 0.0
			end
			
			if @balance > 1.0 then
				@balance = 1.0
			end
		end
		
		def imbalance
			1.0 - @balance
		end
		
		def roll
			random_minus_max = (@base * imbalance).to_i
			if random_minus_max >= 1 then
				b = @base - rand(random_minus_max)
			else
				b = @base
			end
			
			random_minus_max = (@reducing * imbalance).to_i
			if random_minus_max >= 1 then
				r = @reducing - rand(random_minus_max)
			else
				r = @reducing
			end
			
			return fold_in_range(b - r)
		end
		
		def expectation_min
			fold_in_range((@base * @balance).to_i - (@reducing * @balance).to_i)
		end
		
		def expectation_max
			fold_in_range(@base - @reducing)
		end
		
		def min
			fold_in_range((@base * @balance).to_i - @reducing)
		end
		
		def max
			fold_in_range(@base - (@reducing * @balance).to_i)
		end
		
		def center
			((expectation_min + expectation_max) / 2.0).round
		end
		
		def to_s
			sprintf("%d - %d - %d - %d - %d", min, expectation_min, center, expectation_max, max)
		end
		
		def expected_range_caption
			range_caption
		end
		
		def range_caption
			sprintf("%d - %d - %d - %d", min, expectation_min, expectation_max, max)
		end
		
		private
		def fold_in_range(num)
			if num < 1 then
				return 1
			else
				return num
			end
		end
		
	end

	
	
end
