(* game.ml Define characteristics of the game itself Copyright (C) 2000 Brock Wilcox Freely distributable under the terms of the GNU General Public License HISTORY 2000.11.02.14.00 - Most rules implemented - Only needs winner routine 2000.10.27.10.35 - Created *) type loc = int * int type piece = | X | O | Blank type whowin = | PlayerX | PlayerO | Tie | Nobody exception Illegal_move exception Illegal_position exception PlayerX_wins exception PlayerO_wins exception Tie exception Error exception Exit let new_board = Array.create_matrix 7 7 Blank (*let init_board b = b.(0).(0) <- X; b.(6).(6) <- X; b.(6).(0) <- O; b.(0).(6) <- O *) let print_piece = function | X -> print_char 'X' | O -> print_char 'O' | Blank -> print_char ' ' let print_board b = print_string " "; for i = 0 to 6 do print_int i; print_string " "; done; print_newline(); for y = 0 to 6 do print_string " +---+---+---+---+---+---+---+\n"; print_int y; for x = 0 to 6 do print_string " | "; print_piece b.(x).(y); done; print_string " |\n"; done; print_string " +---+---+---+---+---+---+---+\n" let distance from_loc to_loc = let x = abs ((fst from_loc) - (fst to_loc)) in let y = abs ((snd from_loc) - (snd to_loc)) in if x > y then x else y let contents_of b l = b.(fst l).(snd l) let set_contents p b l = b.(fst l).(snd l) <- p let is_empty b t = contents_of b t == Blank let is_legal_loc l = let x = fst l in let y = snd l in (x >= 0) && (x < 8) && (y >= 0) && (y < 8) let is_move_legal b from_loc to_loc = (is_legal_loc from_loc) && (is_legal_loc to_loc) && (is_empty b to_loc) && (not ((distance from_loc to_loc) > 2)) let is_move_legal_for p b from_loc to_loc = ((contents_of b from_loc) == p) && (is_move_legal b from_loc to_loc) let list_legal_moves b = print_string "HERE!"; let movelist = ref ([(0,0),(6,6)]) in print_string "HERE!"; for x = 0 to 6 do for y = 0 to 6 do if (b.(x).(y)) != Blank then for i = -2 to 2 do for j = -2 to 2 do if is_move_legal b (x,y) (x+i,y+j) then begin print_piece (contents_of b (x,y)); print_string ": ("; print_int x; print_string ","; print_int y; print_string ") -> ("; print_int (x+i); print_string ","; print_int (y+j); print_string ")\n"; movelist := ((x,y),(x+i,y+j)) :: !movelist; end; done; done; done; done; !movelist let opposite_of = function | X -> O | O -> X | _ -> Blank let change_neighbors_to piece board loc = let x = (fst loc) in let y = (snd loc) in let opp = opposite_of piece in for i = -1 to 1 do for j = -1 to 1 do if (is_legal_loc (x+i,y+j)) && (contents_of board (x+i,y+j) == opp) then set_contents piece board (x+i,y+j); done done let do_move piece board from_loc to_loc = if is_move_legal_for piece board from_loc to_loc then begin set_contents piece board to_loc; if (distance from_loc to_loc) == 2 then set_contents Blank board from_loc; change_neighbors_to piece board to_loc; true end else false let init_board board = set_contents X board (0,0); set_contents X board (6,6); set_contents O board (0,6); set_contents O board (6,0) let print_turn p = print_string "Player "; print_piece p; print_string "'s turn.\n" let check_move = function | 0 | 1 | 2 | 3 | 4 | 5 | 6 as m -> m | -1 -> exit 0; raise Exit | _ -> raise Illegal_move let rec get_move player board = print_turn player; print_string "From X:"; let from_x = check_move (read_int()) in print_string "From Y:"; let from_y = check_move (read_int()) in print_string " To X:"; let to_x = check_move (read_int()) in print_string " To Y:"; let to_y = check_move (read_int()) in if not (do_move player board (from_x,from_y) (to_x,to_y)) then (print_string "Bad move.\n"; print_board board; get_move player board) let gameloop () = let board = new_board in let player = ref O in init_board board; while true do player := opposite_of !player; print_board board; get_move !player board; (* list_legal_moves board; *) done let _ = gameloop () (* End of game.ml *)