2048: Difference between revisions

Content added Content deleted
(Update Seed7 example)
(→‎{{header|OCaml}}: added OCaml WIP)
Line 5,877: Line 5,877:
eraseLine()
eraseLine()
cursorUp()</lang>
cursorUp()</lang>


=={{header|OCaml}}==

<lang ocaml>
let list_make x v =
let rec aux acc i =
if i <= 0 then acc else aux (v::acc) (i-1)
in
aux [] x


let pad_right n line =
let len = List.length line in
let x = n - len in
line @ (list_make x 0)


let _move_left line =
let n = List.length line in
let line = List.filter ((<>) 0) line in
let rec aux acc = function
| x::y::tl ->
if x = y
then aux (x+y::acc) tl
else aux (x::acc) (y::tl)
| x::[] ->
aux (x::acc) []
| [] ->
List.rev acc
in
pad_right n (aux [] line)


let move_left grid =
List.map _move_left grid


let move_right grid =
grid
|> List.map List.rev
|> List.map _move_left
|> List.map List.rev


let rec replace g n v =
match g with
| x::xs -> if n = 0 then v::xs else x::(replace xs (n-1) v)
| [] -> raise (Invalid_argument "replace")


(* add a new value in a random cell containing zero *)
let rec new_value grid =
(* tricky functional version to get the cells with zeros
let _, zeros =
List.fold_left (fun (y, acc) line ->
let _, acc =
List.fold_left (fun (x, acc) v ->
if v = 0 then (x+1, (x,y)::acc) else (x+1, acc)
) (0, acc) line
in
(y+1), acc
) (0, []) grid
in
*)
(* the imperative version is more KISS *)
let zeros = ref [] in
List.iteri (fun y line ->
List.iteri (fun x v ->
if v = 0 then zeros := (x, y) :: !zeros
) line;
) grid;
let n = List.length !zeros in
if n = 0 then raise Exit;
let x, y = List.nth !zeros (Random.int n) in
let v = if Random.int 10 = 0 then 4 else 2 in
let line = List.nth grid y in
let new_line = replace line x v in
replace grid y new_line


(* turn counterclockwise *)
let turn_ccw grid =
let y = List.length grid in
let x = List.length (List.nth grid 0) in
List.init x (fun i ->
List.init y (fun j ->
List.nth (List.nth grid j) (x-i-1)
)
)


(* turn clockwise *)
let turn_cw grid =
let y = List.length grid in
let x = List.length (List.nth grid 0) in
let arr =
Array.init x (fun i ->
Array.init y (fun j ->
List.nth (List.nth grid (y-j-1)) (i)
)
)
in
List.map Array.to_list (Array.to_list arr)


let move_up grid =
grid
|> turn_ccw
|> move_left
|> turn_cw


let move_down grid =
grid
|> turn_cw
|> move_left
|> turn_ccw


let display grid =
List.iter (fun line ->
print_string " [";
line
|> List.map (Printf.sprintf "%4d")
|> String.concat "; "
|> print_string;
print_endline "]"
) grid


let () =
Random.self_init ();
let width =
try int_of_string Sys.argv.(1)
with _ -> 4
in
let line = list_make width 0 in
let grid = list_make width line in

let grid = new_value grid in
let grid = new_value grid in

print_endline {|
s -> left
f -> right
e -> up
d -> down
q -> quit
|};
let rec loop grid =
display grid;
let grid =
match read_line () with
| "s" -> move_left grid
| "f" -> move_right grid
| "e" -> move_up grid
| "d" -> move_down grid
| "q" -> exit 0
| _ -> grid
in
let grid =
try new_value grid
with Exit ->
print_endline "Game Over";
exit 0
in
loop grid
in
loop grid</lang>


=={{header|Perl 6}}==
=={{header|Perl 6}}==