(** * LikeEternalAndRealNeurons (L.E.A.R.N) * * Copyright (c) 2006 Gilles Bizet * * This file is part of LikeEternalAndRealNeurons (L.E.A.R.N) * * LikeEternalAndRealNeurons (L.E.A.R.N) * is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * LikeEternalAndRealNeurons (L.E.A.R.N) * is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with Foobar; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA **)


(*********************************************************************)

(*definitions, implementations, functions, notations, sets, directions*)


module PaireOrd = 
struct type t = int*int let compare = compare end;; (*compare a affiner*)
  (*module Simple = 
struct type t = char let compare = compare end;;*)

module Ensemble = Set.Make(PaireOrd);; (*Set: cf. Library Ocaml*)
(*module Ensemble1 = Set.Make(Simple);;*)

open Ensemble;;

(*conventions*)

(****************

*(0,7)------(7,7) (i,j) * - ------ - * - ------ - ->:Est(i+1,j) <-:Ouest(i-1,j) * - ------ - * - ------ - ^:Nord(i,j+1) v:Sud(i,j-1) * - ------ - * - ------ - *(0,0)------(7,0) (0,0) = a1 (7,7) = h8

*****************)




let e = empty
let (+!) r s = union r s
let (//) r s = inter r s
let (+$)r s = add r s
let (-->) r s = mem r s
let (-/->) r s = not (mem r s)
let (-/) r s = remove r s

let rec h e i j = if i+1=0 then e else h ((i,j) +$ e) (i-1) j
let rec v e i j = if j+1=0 then e else v ((i,j) +$ e) i (j-1)
let dNS i j  = (h e 7 j) +! (v e i 7)
let echiquier = (h e 7 0) +! (h e 7 1) +! (h e 7 2) +! (h e 7 3)
+! (h e 7 4) +! (h e 7 5) +! (h e 7 6) +! (h e 7 7)

let rec dNE e i j = if (i,j) -/-> echiquier then e else dNE ((i,j) +$ e) (i+1) (j+1)
let rec dSO e i j = if (i,j) -/-> echiquier then e else dSO ((i,j) +$ e) (i-1) (j-1)
let rec dSE e i j = if (i,j) -/-> echiquier then e else dSE ((i,j) +$ e) (i+1) (j-1)
let rec dNO e i j = if (i,j) -/-> echiquier then e else dNO ((i,j) +$ e) (i-1) (j+1)
let rec dO e i j = if (i,j) -/-> echiquier then e else dO ((i,j) +$ e) (i-1) (j)
let rec dS e i j = if (i,j) -/-> echiquier then e else dS ((i,j) +$ e) (i) (j-1)
let rec dN e i j = if (i,j) -/-> echiquier then e else dN ((i,j) +$ e) (i) (j+1)
let rec dE e i j = if (i,j) -/-> echiquier then e else dE ((i,j) +$ e) (i+1) (j)
let diag i j = (dNE e i j) +! (dSO e i j) +! (dSE e i j) +! (dNO e i j)
let dir i j = (dNS i j) +! (dNE e i j) +! (dSO e i j) +! (dSE e i j) +! (dNO e i j);;



let f0 x = match x with                                 (*data sructure *)(*definition utile ?*)
  | (0,0)->('r','w')| (1,0)->('p','w')                 (*filter and function*)
  | (0,1)->('n','w')| (1,1)->('p','w')
  | (0,2)->('b','w')| (1,2)->('p','w')
  | (0,3)->('q','w')| (1,3)->('p','w')
  | (0,4)->('k','w')| (1,4)->('p','w')
  | (0,5)->('b','w')| (1,5)->('p','w')
  | (0,6)->('n','w')| (1,6)->('p','w')
  | (0,7)->('r','w')| (1,7)->('p','w')
  | (7,0)->('r','b')| (6,0)->('p','b')
  | (7,1)->('n','b')| (6,1)->('p','b')
  | (7,2)->('b','b')| (6,2)->('p','b')
  | (7,3)->('q','b')| (6,3)->('p','b')
  | (7,4)->('k','b')| (6,4)->('p','b')
  | (7,5)->('b','b')| (6,5)->('p','b')
  | (7,6)->('n','b')| (6,6)->('p','b')
  | (7,7)->('r','b')| (6,7)->('p','b')
  | (_,_)->('-','-')
let f=f0
(*segment ferme [x,y]*)
let segmentF x y =  let i=fst x and j=snd x and k=fst y and l=snd y in
  if y-->(dN e i j) then inter (dN e i j) (dS e k l) else
    if y-->(dS e i j) then inter (dS e i j) (dN e k l) else
      if y-->(dO e i j) then inter (dO e i j) (dE e k l) else
        if y-->(dE e i j) then inter (dE e i j) (dO e k l) else
          if y-->(dNE e i j) then inter (dNE e i j) (dSO e k l) else
            if y-->(dSO e i j) then inter (dSO e i j) (dNE e k l) else
              if y-->(dSE e i j) then inter (dSE e i j) (dNO e k l) else 
                inter (dNO e i j) (dSE e k l)

(*segment ouvert ]x,y[*)
let segO x y = let temp = segmentF x y in 
  remove y (remove x temp)

(*segment vide de piece - funtion boolean*)
let segV x y = let p z = (snd (f x)='-'in for_all p (segO x y)

(*fonctions utiles*)
let ( ++ ) x y = (fst x + fst y, snd x + snd y)
let ( -- ) x y = (fst x - fst y, snd x - snd y)
let (/*) k x = (k*fst x,k*snd x)

let y = (0,0) and x = (0,0)
let s w = (y -- x = w)
let q k x y = (s (k /* x)) or (s (k /* y))
let ss f x y = (snd (f x) <> snd (f y))   (*cases dont les pieces sont de couleurs opposees, incluant les cases vides*)
let rr f x y = (f y = ('-','-'))||(ss f x y) (*utile pour definir les regles*)

(*distance*)
let  dist x y = max (abs (fst y - fst x)) (abs (snd y - snd x));;

(*matrix 8x8 -> vector 64: (0,0)~0;(7,0)~7;(0,1)~8 ...(0,7)~56;(7,7)~63*)
let vect64 mat = let temp = Array.create 64 0 in
for i=0 to 7 do
  for j=0 to 7 do
temp.(i+j*8)<- mat.(i).(j)
done;done;temp;;

(*String_of_char*)
let string_of_char c = String.make 1 c

(*reverse array**inutile ?*)
let reverse arr = let lg = Array.length arr in
  for k = lg-1 downto 0 do
    arr.(k) <- arr.(lg-1-k)
  done

(*String_of_IntArray*ordonné!*)
let rec string_of_IntArray arr (n:int) =
if n=0 then string_of_int arr.(0) else (string_of_IntArray arr (n-1))^(string_of_int arr.(n))