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}}== |