caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] help with ocaml tic tac toe example
@ 2014-04-26 14:02 recordbot
  0 siblings, 0 replies; only message in thread
From: recordbot @ 2014-04-26 14:02 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 489 bytes --]

Hi to all
I'm new in Ocaml language. 
I tried to develop a simple program to play at tic tac toe against computer.
I developed several functions:
- a function to insert the coins into the grid,
- functions to check win/lose/pair etc...
The only thing that I cannot do is to implement the main function: the I.A 
algorithm!
I want use the minimax algorithm using recursive function, but I'm not able..
Can anyone help me?
Attached to this email there is what I developed till now

Thank you

[-- Attachment #2: filetto.ml --]
[-- Type: application/octet-stream, Size: 7886 bytes --]

  exception ErroreListaVuota;;
  exception ErroreNumeroNegativo;;
  exception ErroreIndiceTroppoPiccolo;;
  exception ErroreIndiceNonValido;;
  exception ErroreGenerico;;
  
  (* qui possiamo stabilire la grandezza della griglia... che come vedremo è rappresentata per mezzo di una lista *)
  (* here we are fixing the dimension of the grid. 3 means that the grid is 3x3, 4 means that is 4x4 etc. The grid is represented by a list *)
  let larghezza_griglia = 3;; 

(* qui definiamo il tipo per i valori della griglia *)
(* here we say the value that each grid's cell can assume. V means Empty (in Italian "Vuoto" *)
  type valori_griglia =
  | O
  | X
  | V;; (* Vuoto *)
  
 
  
 let listaVuota = [V;V;V;V;V;V;V;V;V];;
 
 (*let lista2 = [	O;O;X;
 				V;V;V;
 				V;V;O];;*)
 
 (* lista in cui c'è un filetto diagonale delle O, è stata dichiarata semplicemente per provare le funzioni successive *)
 let lista3 = [
				O;X;O;
				X;O;X;
				O;X;X];;
				
  (*restituisce l'ennesimo elemento della lista, dove n è passato in input*)
  (*return the nth element of the list, where n is the input *)
  let rec return_ennesimo = function _,[]->raise ErroreListaVuota 
  									| n,h::t ->  if(n<0) then 
  													raise ErroreNumeroNegativo 
  												  else 
  												  if (n=0) then 
  												  		h
  												  else 
  												  	return_ennesimo(n-1,t);;
  												  	
  
    			

(* è una funzione ausiliaria... restituisce i primi n elementi della lista fornita in input*)
(* this is an auxiliar function.. It returns the 1..n elements of the list passed in input *)
let rec primi n= function
[] -> []
| h::t -> if n<=0 then [] 
			else h::primi (n-1) t;;
			
(* funzione ausiliaria..  trova l'ennesimo elemento nella lista e lo sostituisce con il nuovo valore fornito in input		*)
(*another auxiliar function.. it replace the nth element of the list with the newest one passed in input *)
let rec trova_e_sostituisci n p= function
[] ->raise ErroreListaVuota
| h::t ->
			if n = 0 then 
				p::t
			else
				trova_e_sostituisci (n-1) p t;;
	
(*la funzione inserisci effettua l'operazione di sostituzione dell'n-esimo elemento all'interno di una lista. n è la posizione in cui va inserito il valore p
ad esempio se sto per inserire la prima mossa, avrò inizialmente la lista che rappresenta la griglia riempita con tutte V
e subito dopo avrò uno di questi elementi sostituiti con la pedina del giocatore--> 
input: 1 X [V;V;V;V;V;V;V;V;V]
output [V;X;V;V;V;V;V;V;V]
*)			
(* if the input is: "1 X [V;V;V;V;V;V;V;V;V]", then the output is: [V;X;V;V;V;V;V;V;V], and so on. the first input is the position, the second input is the symbol to insert and the third input is the grid *)
let inserisci n p = function
	[] -> []
	|l -> primi n l @ trova_e_sostituisci n p l;;
  									 
  									 
(*funzione che si occupa di verificare se la lista è stata riempita tutta, cioè se siamo in una configurazione terminale *)
(*this function check if we have the list full *)
let rec is_riempita = function
							[] -> true
							|h::t -> if (h=V) then
										false
									else
										is_riempita t
										
  (*funzione ausiliaria di "controlla", si occupa di verificare se c'è un filetto nelle righe*)
  (*this is an auxiliar function of "controlla". This function check if we have a "three in a row" in the rows *)
  let rec confronto_righe = function i,plyr,l ->
  										if( return_ennesimo(i,l) =plyr) then
  											if ((i+1) mod (larghezza_griglia) = 0) then
  												true
  											else
  												confronto_righe(i+larghezza_griglia,plyr,l)
  										else
  											false;;
  (*funzione ausiliaria di "controlla", si occupa di verificare se c'è un filetto nella colonne*)
  (*this is an auxiliar function of "controlla". This function check if we have a "three in a row" in the rows *)
  let rec confronto_colonne = function i,plyr,l ->
  										if( return_ennesimo(i,l) =plyr) then
  											if (i >= larghezza_griglia * (larghezza_griglia - 1)) then
  												true
  											else
  												confronto_colonne(i+larghezza_griglia,plyr,l)
  										else
  											false;;
  											
  (*funzione ausiliaria di "controlla", si occupa di verificare se c'è un filetto nella diagonale principale*)	
  (*this is an auxiliar function of "controlla". This function check if we have a "three in a row" in the main diagonal *)
					
  let rec confronto_diagonale_principale = function i,plyr,l ->
  										if( return_ennesimo(i,l) =plyr) then
  											if (i >= (larghezza_griglia * larghezza_griglia) - 1) then
  												true
  											else
  												confronto_diagonale_principale(i + larghezza_griglia + 1, plyr,l)
  										else
  											false;;
  										
  (*funzione ausiliaria di "controlla", si occupa di verificare se c'è un filetto nella diagonale secondaria*)
  (*this is an auxiliar function of "controlla". This function check if we have a "three in a row" in the other diagonal *)
  let rec confronto_diagonale_secondaria = function i,plyr,l ->
  										if( return_ennesimo(i,l) =plyr) then
  											if (i >= (larghezza_griglia * (larghezza_griglia - 1))) then
  												true
  											else
  												confronto_diagonale_secondaria(i + larghezza_griglia - 1, plyr,l)
  										else
  											false;;
  											
  (*funzione che si occupa di verificare se il player con la pedina passata in input ha vinto o no *)
  (*this is the main function that checks if there is a win condition into the grid *)
  let rec controlla = function
  						i,x,l -> if (i >= larghezza_griglia) then
  									false
  								else
  									if ((i = 0) && (confronto_diagonale_principale(i,x,l) = true)) then
  										true
  									else
  									if ((i mod larghezza_griglia = 0) && (confronto_righe(larghezza_griglia * i,x,l) = true)) then
  										true
  									else
  									if (confronto_colonne(i,x,l) = true) then
  										true
  									else
  									if ((i = larghezza_griglia - 1) && (confronto_diagonale_secondaria(larghezza_griglia -1,x,l) = true)) then
  										true
  									else		
  										controlla(i+1,x,l);;
  								  	
 (*funzione che fa uso di "controlla" e di "is_riempita", si occupa di verificare se la griglia occupa una posizione di parita*)
 (*this function check if there is a tie condition *)
  let is_patta = function
  							[] -> raise ErroreListaVuota
  							| l -> if ((is_riempita l = true) && (controlla (0,O,l) = true || (controlla (0,X,l) = true))) then
  										true
  									else
  									  	false;;
  								  	
  	(*questa funzione inverte la pedina. Se la pedin è X ritorna O e viceversa *)
  	let inverti = function 
		m ->	if (m = X) then
					O
				else
				if (m = O) then
					X
				else
					V;;
		
					
  	(* ok.. fino a qui abbiamo le funzioni di contorno al programma.... quelle che si accorgono quando c'è una vittoria all'interno 
  	della griglia o una patta, e quelle che permettono di inserire pedine all'uno o all'altro (computer) giocatore*)
  	
  	
   let listaAppoggio = [0;1;2;3;4;5;6;7;8];;
   

				
				
	(* definire pedina. Dovrà essere una variabile che cambia di inserimento in inserimento da X a O e da O a X *)
   let rec miniMax pos = function
   				[] ->	raise ErroreListaVuota
   				| l ->	let asd = inserisci pos pedina l in
   						let pos = inverti pos in
   						if (is_riempita l = true)
   							if (controlla(0,X,l) = true)
   								return -1
   							else
   							if (controlla(0,O,l) = true)
   								return 1
   							else
   								return 0
   						else
   						
   						
   						
   						
   						

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-04-26 14:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-26 14:02 [Caml-list] help with ocaml tic tac toe example recordbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).