(************************************************* main.ml Main entrance for ataxx Copyright (C) 2001 Brock Wilcox [awwaiid@deathonastick.org] Released under the terms of the GNU GPL See www.gnu.org for more information HISTORY / NOTES 2001.01.29.04.38 - Full Lambda-style HOF and recursion works great. Factorial function, for example *************************************************) let print_gameover board = print_string "FINAL BOARD:\n"; Board.print board; let x_score = Game.score_for Piece.X board in let o_score = Game.score_for Piece.O board in print_string "Game over.\nX's score: "; print_int x_score; print_string "\nO's score: "; print_int o_score; if x_score > o_score then print_string "\n\nX wins!" else if o_score > x_score then print_string "\n\nO wins!" else print_string "Tie!"; print_string "\n\n" let human_player player board = Board.print board; Human.get_move player board let randcomp_lambda = "let rr = \\\\(primpair (rand 49) (rand 49)); rr;" let comp_firstgood = " let true = \\\\#1; let false = \\\\#0; ' If conditional let if = \\b.\\x.\\y.b x y; ' Fixpoint operator for recursion let fix = \\f. (\\x.f (x x)) (\\x.f (x x)); ' Find a piece of _player_, starting at _pos_, using the ' _board_at_ algorithm for reading the board let find_piece = fix (\\self.\\pos.\\player.\\board_at. if (equ (board_at pos) player) (pos) (self (add pos 1) player board_at) ); ' Find the first piece for _player_ let firstgood = \\player.\\board_at. ((\\a.primpair a (sub a 1)) (find_piece 0 player board_at)); let int_to_x = \\n. mod n 7; let int_to_y = \\n. div n 7; ' Find the distance between a and b let dist = \\a.\\b.abs (sub a b); let distance = \\a.\\b. let x = (dist (int_to_x a) (int_to_x b)) in let y = (dist (int_to_y a) (int_to_y b)) in if (gt x y) (x) (y); ' and let and = \\a.\\b. if a (if b b false) false; ' Do a random (legal) move let rand_move = let a = rand 49 in let b = rand 49 in fix (\\self.\\player.\\board_at. if (and (equ player (board_at a)) (equ 0 (board_at b))) (primpair a b) (self player board_at) ); ' find first legal move from pos let findlegal = fix (\\self.\\pos.\\cur.\\board_at. ' if (lt cur 49) if (lt cur (add pos 16)) ( if (and (lt (distance pos cur) 3) (equ (board_at cur) 0)) (cur) (self pos (add cur 1) board_at) ) (50) ); let get_first_legal_move = fix (\\self.\\player.\\pos.\\board_at. let me = (find_piece pos player board_at) in let tospot = (findlegal me 0 board_at) in if (lt tospot 50) (primpair me tospot) (self player (find_piece (add me 1) player board_at) board_at) ); let getfirstlegal_wrapper = \\player.\\board_at. get_first_legal_move player 0 board_at; ' Run the firstgood 'firstgood; ' Run the random move 'rand_move; ' Run the firstlegalmove algo getfirstlegal_wrapper; " let rec randcomp_player player board = let loc1 = Game.int_to_loc (Random.int 49) in let loc2 = Game.int_to_loc (Random.int 49) in try (* print_string "CMove: "; Game.print_move (loc1,loc2); print_newline(); *) Game.do_move player board (loc1,loc2) with _ -> randcomp_player player board let rec randcomp2_player player board = (*let genome = List.hd (Io.from_string randcomp_lambda) in*) let genome = List.hd (Io.from_string comp_firstgood) in (* let exp = Lambda.to_genome genome in *) let exp = Lambda.bruijnize (Lambda.expand genome) in let bexp = Lambda.Apply ( Lambda.Apply ( exp, Lambda.Num (Piece.to_int player) ), Primitives.make_board_at board ) in (*let bexp = Lambda.to_genome exp in *) (*print_string "GENOME: "; Lambda.print bexp; print_newline(); *) (*let ans = Lambda.timed_reduce bexp 3000 in*) let ans = Lambda.reduce bexp in let pans = Lambda.get_pair ans in print_string "ANS: ("; (*Lambda.print ans; *) print_int (Primitives.to_int (fst pans)); print_string ", "; print_int (Primitives.to_int (snd pans)); print_string ")"; print_newline(); let loc1 = Game.int_to_loc (Primitives.to_int (fst pans)) in let loc2 = Game.int_to_loc (Primitives.to_int (snd pans)) in try print_string "CMove: "; Game.print_move (loc1,loc2); print_newline(); Game.do_move player board (loc1,loc2) (*with _ -> randcomp2_player player board*) with _ as x -> raise x (* let randcomp_player player board = let env = {vars=[] ; curboard = board; curplayer = player} in let m = (interp lambda_randcomp env) in match m with | MOVE(move) -> do_move player board move; print_string "randcomp: "; print_move move; print_string "\n"; print_board board; print_newline() | _ -> raise (Error "Not a move!!") let smartcomp_player player board = let env = {vars=[] ; curboard = board; curplayer = player} in let m = (interp smartcomp env) in match m with | MOVE(move) -> do_move player board move; print_string "smartcomp: "; print_move move; print_string "\n"; print_board board; print_newline() | _ -> raise (Error "Not a move!!") *) let gameloop p1 p2 = let board = ref Board.create in let player = ref Piece.X in board := Game.init_board !board; while Game.is_legal_move_on_for !player !board do board := (if !player = Piece.X then p1 !player !board else p2 !player !board ); player := Piece.opposite !player; Board.print !board done; print_gameover !board let _ = Random.self_init(); Primitives.install(); if ((Array.length Sys.argv) > 1) then begin match Sys.argv.(1) with | "2" -> gameloop human_player human_player | "rand" -> gameloop human_player randcomp2_player | "2rand" -> gameloop randcomp2_player randcomp2_player (* | "smart" -> gameloop human_player smartcomp_player | "s_vs_r" -> gameloop randcomp_player smartcomp_player | "s_vs_s" -> gameloop smartcomp_player smartcomp_player | "test" -> test() | _ -> gameloop human_player randcomp_player *) | _ -> print_string "Error. Bad option.\n" end else begin print_string "Ataxx GP Simulation Program\n\n"; print_string "Usage:\n"; print_string " ataxx option\n\n"; print_string "Options:\n"; print_string " 2 - human vs human\n"; print_string " 2rand - randcomp vs randcomp\n"; print_string " smart - human vs smartcomp\n"; print_string " s_vs_r - smartcomp vs randcomp\n"; print_string " s_vs_s - smartcomp vs smartcomp\n"; print_string " test - Do some random test\n"; print_newline(); end (* End of main.ml *)