//maybe here is some way to optimise dodge checks
        private static void hit()
        {
            if (attacker.waiting < defender.waiting &&
                attacker.waiting < attacker.time_til_damage)
            {   //attacker acts
                timer                    += attacker.waiting;
                defender.waiting         -= attacker.waiting;
                attacker.time_til_damage -= attacker.waiting;

                //console.WriteLine("Defender get hit");
                if (defender.take_damage())
                {
                    throw new Exception("1"); //attacker wins
                }
                if (dodge_all_quick_moves &&
                    !attacker.dodged &&
                    !defender.next_attack_is_charged &&
                    defender.waiting <= defender.start_dodge_q &&
                    defender.waiting > defender.end_dodge_q &&
                    attacker.incoming_damage > 0)
                {
                    //console.WriteLine("Dodge");
                    if (write_battle_log)
                    {
                        Battle_logger.LogAttackerAction("Dodge", attacker, defender, timer);
                    }

                    attacker.dodged          = true;
                    defender.incoming_damage = 0;
                    attacker.waiting         = 1;
                    attacker.incoming_damage = (int)Math.Floor(attacker.incoming_damage / 4F);
                    return;
                }
                else
                if (dodge_all_charge_moves &&
                    !attacker.dodged &&
                    defender.next_attack_is_charged &&
                    defender.waiting <= defender.start_dodge_c &&
                    defender.waiting > defender.end_dodge_c &&
                    attacker.incoming_damage > 0)
                {
                    //console.WriteLine("Dodge");
                    if (write_battle_log)
                    {
                        Battle_logger.LogAttackerAction("Dodge", attacker, defender, timer);
                    }

                    attacker.dodged          = true;
                    defender.incoming_damage = 0;
                    attacker.waiting         = 1;
                    attacker.incoming_damage = (int)Math.Floor(attacker.incoming_damage / 4F);
                    return;
                }

                if (attacker.enrg_cost <= attacker.current_en &&
                    defender.current_hp > defender.overkill_hp_point)
                { //c move
                    //console.WriteLine("Attacker use charge move");
                    if (write_battle_log)
                    {
                        Battle_logger.LogAttackerAction("Charge move", attacker, defender, timer);
                    }

                    defender.incoming_damage = attacker.c_damage;
                    attacker.waiting         = attacker.c_cd;
                    attacker.current_en     -= attacker.enrg_cost;
                }
                else
                { //q move
                    //console.WriteLine("Attacker use quick move");
                    if (write_battle_log)
                    {
                        Battle_logger.LogAttackerAction("Quick move", attacker, defender, timer);
                    }

                    defender.incoming_damage = attacker.q_damage;
                    attacker.waiting         = attacker.q_cd;
                    attacker.current_en     += attacker.enrg_gain;
                    if (attacker.current_en > 100)
                    {
                        attacker.current_en = 100;
                    }
                }
            }
            else if (defender.waiting < attacker.time_til_damage)
            {   //defender acts
                timer                    += defender.waiting;
                attacker.waiting         -= defender.waiting;
                attacker.time_til_damage -= defender.waiting;

                if (defender.enrg_cost <= defender.current_en &&
                    delayed_charge)
                { //c move
                    //console.WriteLine("Defender use charge move");
                    if (write_battle_log)
                    {
                        Battle_logger.LogDefenderAction("Charge move !", attacker, defender, timer);
                    }

                    delayed_charge = false;

                    attacker.incoming_damage        = defender.c_damage;
                    attacker.time_til_damage        = defender.c_cd - defender.end_dodge_c;
                    defender.waiting                = defender.c_cd;
                    defender.current_en            -= defender.enrg_cost;
                    defender.next_attack_is_charged = true;
                }
                else
                { //q move
                    //console.WriteLine("Defender use quick move");
                    if (write_battle_log)
                    {
                        Battle_logger.LogDefenderAction("Quick move", attacker, defender, timer);
                    }

                    if (defender.enrg_cost <= defender.current_en)
                    {
                        delayed_charge = true; //1 move delay for charged attacks
                    }
                    attacker.incoming_damage = defender.q_damage;
                    attacker.time_til_damage = defender.q_cd - defender.end_dodge_q;
                    defender.waiting         = defender.q_cd;
                    defender.current_en     += defender.enrg_gain;
                    if (defender.current_en > 200)
                    {
                        defender.current_en = 200;
                    }
                    defender.next_attack_is_charged = false;

                    defender.attacked = true;
                }
            }
            else
            {   //damage reached attacker
                //console.WriteLine("Attacker get hit");
                timer            += attacker.time_til_damage;
                attacker.waiting -= attacker.time_til_damage;
                defender.waiting -= attacker.time_til_damage;

                if (write_battle_log && attacker.incoming_damage != 0)
                {
                    Battle_logger.LogIncomingDamage(attacker, defender, timer);
                }

                if (attacker.take_damage())
                {
                    throw new Exception("2"); //defender wins
                }
                attacker.time_til_damage = 100F;
            }
        }
        private static Battle_Result Simulate_battles()
        {
            if (write_battle_log)
            {
                Battle_logger.SetFileHeader(attacker, defender);
            }


            Battle_Result battle_result = new Battle_Result();
            Tuple <bool, float, int, int> br;

            //Console.WriteLine("Don't dodge");
            if (write_battle_log)
            {
                Battle_logger.AddTableHeader("no dodge");
            }

            dodge_all_quick_moves  = false;
            dodge_all_charge_moves = false;
            br = battle();
            battle_result.no_dodge_result   = br.Item1;
            battle_result.no_dodge_time     = br.Item2;
            battle_result.no_dodge_hp       = br.Item3;
            battle_result.no_dodge_enemy_hp = br.Item4;

            if (write_battle_log)
            {
                Battle_logger.AddTableSummary(br.Item1, br.Item2, br.Item3, br.Item4);
            }

            ////console.WriteLine("------------");
            ////console.WriteLine();

            //Console.WriteLine("Dodge charged moves");
            if (write_battle_log)
            {
                Battle_logger.AddTableHeader("charge dodge");
            }

            dodge_all_charge_moves = true;
            br = battle();
            battle_result.ch_dodge_result   = br.Item1;
            battle_result.ch_dodge_time     = br.Item2;
            battle_result.ch_dodge_hp       = br.Item3;
            battle_result.ch_dodge_enemy_hp = br.Item4;

            if (write_battle_log)
            {
                Battle_logger.AddTableSummary(br.Item1, br.Item2, br.Item3, br.Item4);
            }

            ////console.WriteLine("------------");
            ////console.WriteLine();

            //Console.WriteLine("Dodge all moves");
            if (write_battle_log)
            {
                Battle_logger.AddTableHeader("full dodge");
            }
            dodge_all_quick_moves = true;
            br = battle();
            battle_result.full_dodge_result   = br.Item1;
            battle_result.full_dodge_time     = br.Item2;
            battle_result.full_dodge_hp       = br.Item3;
            battle_result.full_dodge_enemy_hp = br.Item4;

            if (write_battle_log)
            {
                Battle_logger.AddTableSummary(br.Item1, br.Item2, br.Item3, br.Item4);
            }

            battle_result.use_charges = attacker.use_charges;
            return(battle_result);
        }