与矩阵的生命游戏Ocaml

时间:2016-12-11 00:59:56

标签: arrays matrix random ocaml

我已经为我的生命游戏生成了一个矩阵,我试图让它循环并连续打印出下一代,我使用的是我在网上找到的代码,它没有&# 39;似乎工作。这是我的代码

let generation = ref 1
let get g x y =
  try g.(x).(y)
  with _ -> 0
 ;;
let neighbourhood g x y =
  (get g (x-1) (y-1)) +
  (get g (x-1) (y  )) +
  (get g (x-1) (y+1)) +
  (get g (x  ) (y-1)) +
  (get g (x  ) (y+1)) +
  (get g (x+1) (y-1)) +
  (get g (x+1) (y  )) +
  (get g (x+1) (y+1)) 

let next_cell g x y =
  let n = neighbourhood g x y in
  match g.(x).(y), n with
  | 1, 0 | 1, 1                      -> 0  (* lonely *)
  | 1, 4 | 1, 5 | 1, 6 | 1, 7 | 1, 8 -> 0  (* overcrowded *)
  | 1, 2 | 1, 3                      -> 1  (* lives *)
  | 0, 3                             -> 1  (* get birth *)
  | _ -> 0

let copy g = Array.map Array.copy g

let rec next g =
  let width = Array.length g
  and height = Array.length g.(0)
  and new_g = copy g in
  for x = 0 to pred width do
    for y = 0 to pred height do
      new_g.(x).(y) <- (next_cell g x y)
    done
  done;
  next new_g

let print g =
  let width = Array.length g
  and height = Array.length g.(0) in
  for x = 0 to pred width do
    for y = 0 to pred height do
      if g.(x).(y) = 0
      then print_char '.'
      else print_char 'o'
    done;
    print_newline()
  done
;;

print_string "Width ";
let num = read_int () in
 print_string "Height";
 let num2 = read_int () in
      while !generation < 100 do 
        let myArray = Array.init num (fun _ -> Array.init num2 (fun _ -> Random.int 2)) in 
        print_string "Generation: "; print_int !generation; print_string "\n";
        print (next myArray);
        generation := !generation +1;
        print_newline();
      done;;

它只打印出初始的和后一代而不是新的一代。既然参数是原始数组,那么,当我把print(下一个new_g)给它一个未绑定的值时,有没有办法可以连续打印出后续几代?当我不能覆盖现有的new_g时那样做?

1 个答案:

答案 0 :(得分:0)

只看while while循环,它每次循环时都会分配并初始化一个随机数组。看起来这似乎不对。

我也不知道函数next如何工作,因为它永远不会返回。它的最后一步是无条件地再次召唤自己。

<强>更新

如果您将next的最后一行更改为:

new_g

每次调用它时都会返回下一代。

这是一种以功能(而非命令)风格驱动代码的方法:

let rec generation n array =
    if n < 100 then
        begin
        (* Print the array *);
        generation (n + 1) (next array)
        end

最外面的代码可能如下所示:

let myArray =
    Array.init num
        (fun _ -> Array.init num2 (fun _ -> Random.int 2))
in
generation 0 myArray