Guest User

Untitled

a guest
Aug 3rd, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.98 KB | None | 0 0
  1. let time_limit = 100;;
  2. let max_rating = 20;;
  3. let mem_size = 10;; (* четное число! *)
  4.  
  5. class weapon (r0:int) (d0:int) =
  6.   object
  7.     val rng = r0
  8.     val dmg = d0
  9.     method get_dmg (r:int) = max ((Random.int dmg) + (Random.int dmg)-abs(r-rng)) 0
  10.       (*let rec base_dmg x a =
  11.         if x = 0 then a
  12.                  else base_dmg (x-1) (a +(Random.int 2)) in
  13.       base_dmg (2*d0 - abs(rng-r)) 0*)
  14.     method get_rng = rng
  15.   end;;
  16.  
  17. type act = StepF | StepB | Wait | Hit of weapon;;
  18. type t_ai = (act*(float list)) list * int;;
  19.  
  20. let mutation l rt=
  21.   let deep = min ((1.1 -. (float_of_int rt)/.(float_of_int max_rating))/.2.) 1.0 in
  22.   List.map (fun (act,w) -> act,
  23.       (List.map (fun f->f*.(1.-.deep+.Random.float deep)) w)
  24.   ) l;;
  25.  
  26. class hero nm xp0 tactics0=
  27.   object(s)
  28.     val name:string = nm
  29.     val max_xp = xp0
  30.     val mutable xp = xp0
  31.     val mutable wps = []
  32.     val mutable tactics = Array.make mem_size (tactics0,0)
  33.     val mutable act_tack = 0
  34.     method respawn = xp<-max_xp
  35.     method get_name = name
  36.     method get_xp = xp
  37.     method add_wp wp tack = wps <- wp::wps;
  38.       tactics<-Array.map (fun (ai_lt,rt)-> (Hit wp,tack)::ai_lt,rt) tactics
  39.     method drop_all = wps <- []
  40.     method beaten r d  = xp <- xp-d +(r*0)
  41.     method renew_tactics =
  42.       Array.sort (fun (_,r1) (_,r2) -> r2-r1) tactics;
  43.       for i=0 to mem_size/2 - 1 do
  44.         let ai,rt = tactics.(i) in
  45.         tactics.(i) <- ai,0;
  46.         (* мутации! мутации! *)
  47.         tactics.(i+mem_size/2) <- (mutation ai rt,0)
  48.       done
  49.     method rate i =
  50.       let (ai,rt) = tactics.(act_tack) in
  51.       tactics.(act_tack) <- (ai,rt+i);
  52.       act_tack <- (act_tack+1) mod mem_size;
  53.       if abs(rt+i) > max_rating then s#renew_tactics
  54.     method choose env =
  55.       let mult (act,w) =
  56.         List.fold_left2
  57.         (fun (name,accum) f i -> name,(accum +. f *. (float_of_int i)))
  58.         (act,0.) w env in
  59.       let results = List.map mult (fst tactics.(act_tack)) in
  60.       let decreasing = List.fast_sort (fun (_,f1) (_,f2) -> if f1>f2 then -1 else 1) results in
  61.       fst(List.split decreasing)
  62.     method get_wp_rng = (List.hd wps)#get_rng
  63.     method print_tactics =
  64.       for i =0 to mem_size-1 do
  65.         let (ai,rt) = tactics.(i) in
  66.         Printf.printf "\nTactics #1, rating %i:" rt;
  67.         List.iter (fun (act,l)-> begin match act with
  68.         |StepF -> Printf.printf "\n\tF ->\t"
  69.         |StepB -> Printf.printf "\n\tB ->\t"
  70.         |Wait  -> Printf.printf "\n\tW ->\t"
  71.         |Hit _ -> Printf.printf "\n\tH ->\t"end;
  72.         List.iter (fun f->Printf.printf "%2.3f\t" f) l)
  73.         ai
  74.       done
  75.     initializer
  76.       for i=0 to mem_size - 1 do
  77.         let ai,_ = tactics.(i) in
  78.         (* мутации! мутации! *)
  79.         tactics.(i) <- (mutation ai (max_rating/2),0)
  80.       done
  81.   end;;
  82.  
  83. (*  env: xp, dist, self range, opp range *)
  84. let print_fight (hero0:hero) (hero1:hero) dist act sente =
  85.   let h0,h1 =  if sente then hero0,hero1
  86.                         else hero1,hero0 in
  87.   print_string "@/";
  88.   for i=0 to dist-2 do print_char '_' done;
  89.   print_endline "\@";
  90.   Printf.printf "%2i" h0#get_xp;
  91.   for i=0 to dist-2 do print_char '_' done;
  92.   Printf.printf "%2i" h1#get_xp; print_newline ();
  93.   match act with
  94.     |StepF -> Printf.printf "Hero \"%s\" steps forward.\n" hero0#get_name
  95.     |StepB -> Printf.printf "Hero \"%s\" steps backward.\n" hero0#get_name
  96.     |Wait  -> Printf.printf "Hero \"%s\" is waiting.\n" hero0#get_name
  97.     |Hit _ -> Printf.printf "Hero \"%s\" hits hero \"%s\".\n" hero0#get_name hero1#get_name
  98.     |_     -> Printf.printf "Wrong action!!!\n";;
  99.  
  100. let rec fight (hero0:hero) (hero1:hero) pos0 pos1 sente t draw =
  101.   if hero0#get_xp <= 0 then begin hero0#rate (-1); hero1#rate 1; end
  102.   else
  103.     begin
  104.     if t > time_limit then begin hero0#rate (-1); hero1#rate (-1); end
  105.     else
  106.       begin
  107.       let dist = abs(pos1-pos0) in
  108.       let actions = hero0#choose
  109.         [hero0#get_xp;dist;hero0#get_wp_rng;hero1#get_wp_rng] in
  110.       let rec pr = function
  111.         | StepF::tl -> print_string "F "; pr tl
  112.         | StepB::tl -> print_string "B "; pr tl
  113.         | Wait ::tl -> print_string "W "; pr tl
  114.         | (Hit _)::tl -> print_string "H "; pr tl
  115.         | _ -> print_newline (); in
  116.       (*pr actions;*)
  117.       let rec get_av_act = function
  118.         | StepF::tl -> if dist>2 then StepF else get_av_act tl
  119.         | hd::tl    -> hd in
  120.       let action = get_av_act actions in
  121.       if draw then print_fight hero0 hero1 dist action sente else ();
  122.       match action with
  123.       | StepF -> fight hero1 hero0 pos1 (pos0+2*(pos1-pos0)/dist) (not sente) (t+1) draw
  124.       | StepB -> fight hero1 hero0 pos1 (pos0-1*(pos1-pos0)/dist) (not sente) (t+1) draw
  125.       | Wait  -> fight hero1 hero0 pos1  pos0    (not sente) (t+1) draw
  126.       | Hit w -> begin hero1#beaten dist (w#get_dmg dist);
  127.                  fight hero1 hero0 pos1  pos0    (not sente) (t+1) draw end
  128.       end
  129.     end;;
  130.  
  131. let main =
  132.   Random.self_init ();
  133.   let wp0 = new weapon ((Random.int 3)+2) (Random.int 15) in
  134.   let wp1 = new weapon ((Random.int 3)+2) (Random.int 15) in
  135.   let wp_tack0 =  [0.1;0.1;0.1;0.1] in
  136.   let wp_tack1 =  List.map (fun f->0.1+.(Random.float f)) [1.;1.;1.;1.] in
  137.   (* болванчик *)
  138.   let ai0 =    (StepF, [0.1;0.1;0.1;0.1])
  139.             :: (StepB, [0.1;0.1;0.1;0.1])
  140.             :: (Wait, [1.;0.1;0.1;0.1]):: [] in
  141.   let ai1 =    (StepF, List.map (fun f->0.1+.Random.float f) [1.;1.;1.;1.])
  142.             :: (StepB, List.map (fun f->Random.float f) [1.;1.;1.;1.])
  143.             :: (Wait,  List.map (fun f->Random.float f) [1.;1.;1.;1.])
  144.             :: [] in
  145.   let sparrer = new hero "Sparrer" 20 ai0 in
  146.   sparrer#add_wp wp0 wp_tack0;
  147.   let the_one = new hero "The One" 20 ai1 in
  148.   the_one#add_wp wp1 wp_tack1;
  149.   for it = 0 to 3524 do
  150.     fight the_one sparrer 0 20 true 0 false;
  151.     the_one#respawn;
  152.     sparrer#respawn;
  153.   done;
  154.   fight the_one sparrer 0 20 true 0 true;
  155.   the_one#print_tactics;
  156.   exit (0);;
  157. let _ = main ()
Add Comment
Please, Sign In to add comment