Игра Жизнь на LiveScript в 30 строк

    В продолжение 30-ти строчного мема, выкладываю реализацию известной игры Жизнь на LiveScript (язык, транслируемый в Javascript).

    Игра жизнь — это клеточный автомат с простыми правилами:
    • Имеется поле с клетками, которые могут быть в двух состояниях: живая и мертвая
    • Если у мертвой клетки ровно три живых соседа, то она оживает
    • Если у живой клетки два или три живых соседа, то она продолжает жить, в противном случае она умирает от перенаселенности или одиночества

    Для начала, сам код:
    stopped=true
    
    document.body.onkeyup = (e) -> e.keyCode==13 && stopped := !stopped
    
    change = (div, a) -> 
        div.setAttribute(\class, a  and "cell active" or "cell")
        div.ac=a
        
    window.activate = (div) ->
        div.ac ?= false
        change div, !div.ac
        
    setInterval ->
        unless stopped
            arr=document.getElementById("board").children
            newarr=[[false for _ to arr[0].children.length-1] for _ to arr.length-1]
            c=0
            
            for i in [0 to arr.length-1]
                for j in [0 to arr[i].children.length-1]
                    for sx in [i-1 to i+1]
                        for sy in [j-1 to j+1] when not (sy == j and sx ==i)
                            arr[(sx+newarr.length)%newarr.length].children[(sy+newarr[0].length)%newarr[0].length].ac and ++c
                    (c == 3 or (c == 2 and arr[i].children[j].ac)) and newarr[i][j]=true
                    c=0
                    
            for i in [0 to newarr.length-1]
                for j in [0 to newarr[i].length-1]
                        change arr[i].children[j], newarr[i][j] 
    , 1000/15
    

    Как видно, код простой и лаконичный. Отсутствие фигурных скобок позволяет сократить размер кода.
    И ссылка на jsfiddle. Вначале задайте изначальное состояние поля (которое закольцовано), после чего нажмите enter и игра начнется.

    А вот результат трансляции:
    // Generated by LiveScript 1.2.0
    (function(){
      var stopped, change;
      stopped = true;
      document.body.onkeyup = function(e){
        return e.keyCode === 13 && (stopped = !stopped);
      };
      change = function(div, a){
        div.setAttribute('class', a && "cell active" || "cell");
        return div.ac = a;
      };
      window.activate = function(div){
        div.ac == null && (div.ac = false);
        return change(div, !div.ac);
      };
      setInterval(function(){
        var arr, newarr, res$, i$, to$, _, lresult$, j$, to1$, c, ref$, len$, i, ref1$, len1$, j, k$, ref2$, len2$, sx, l$, ref3$, len3$, sy, lresult1$, results$ = [];
        if (!stopped) {
          arr = document.getElementById("board").children;
          res$ = [];
          for (i$ = 0, to$ = arr.length - 1; i$ <= to$; ++i$) {
            _ = i$;
            lresult$ = [];
            for (j$ = 0, to1$ = arr[0].children.length - 1; j$ <= to1$; ++j$) {
              _ = j$;
              lresult$.push(false);
            }
            res$.push(lresult$);
          }
          newarr = res$;
          c = 0;
          for (i$ = 0, len$ = (ref$ = (fn$())).length; i$ < len$; ++i$) {
            i = ref$[i$];
            for (j$ = 0, len1$ = (ref1$ = (fn1$())).length; j$ < len1$; ++j$) {
              j = ref1$[j$];
              for (k$ = 0, len2$ = (ref2$ = (fn2$())).length; k$ < len2$; ++k$) {
                sx = ref2$[k$];
                for (l$ = 0, len3$ = (ref3$ = (fn3$())).length; l$ < len3$; ++l$) {
                  sy = ref3$[l$];
                  if (!(sy === j && sx === i)) {
                    arr[(sx + newarr.length) % newarr.length].children[(sy + newarr[0].length) % newarr[0].length].ac && ++c;
                  }
                }
              }
              (c === 3 || (c === 2 && arr[i].children[j].ac)) && (newarr[i][j] = true);
              c = 0;
            }
          }
          for (i$ = 0, len$ = (ref$ = (fn4$())).length; i$ < len$; ++i$) {
            i = ref$[i$];
            lresult1$ = [];
            for (j$ = 0, len1$ = (ref1$ = (fn5$())).length; j$ < len1$; ++j$) {
              j = ref1$[j$];
              lresult1$.push(change(arr[i].children[j], newarr[i][j]));
            }
            results$.push(lresult1$);
          }
          return results$;
        }
        function fn$(){
          var i$, to$, results$ = [];
          for (i$ = 0, to$ = arr.length - 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
        function fn1$(){
          var i$, to$, results$ = [];
          for (i$ = 0, to$ = arr[i].children.length - 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
        function fn2$(){
          var i$, to$, results$ = [];
          for (i$ = i - 1, to$ = i + 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
        function fn3$(){
          var i$, to$, results$ = [];
          for (i$ = j - 1, to$ = j + 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
        function fn4$(){
          var i$, to$, results$ = [];
          for (i$ = 0, to$ = newarr.length - 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
        function fn5$(){
          var i$, to$, results$ = [];
          for (i$ = 0, to$ = newarr[i].length - 1; i$ <= to$; ++i$) {
            results$.push(i$);
          }
          return results$;
        }
      }, 1000 / 15);
    }).call(this);
    



    Также проведу небольшой обзор языка, может кто и заинтересуется.
    LiveScript похож на уже ставший известным CoffeeScript, но также имеет элементы функциональных языков, синтаксический сахар для многих конструкций.
    Рассмотрим базовые элементы синтаксиса:

    Определение функции:
    add = (x, y) -> x+y
    

    Вызов функции:
    add 5 6
    add(5, 6)
    add 5, 6
    

    Циклы:
    for i in [0 to 10]
        console.log i
    

    Строки без пробелов можно записывать в таком виде:
    a = \string
    alert \str
    

    Определение класса:
    class Accumulator
      (num) ->
        @acc = num
      sum:8
      add: (n) ->
        @acc+=n
        @acc+@sum  #returns
    
    a = new Accumulator 1
    a.sum # 8
    a.acc  # 1
    a.add 9 # @acc now 10; return 18
    


    На этом всё. Спасибо за внимание.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 9

      +3
      Нда, Вы оказались быстрее меня. Как раз написал свой вариант этой игры на JS в 30 строк.
        +2
        Публикуйте, здесь все-таки читы.
          0
          Статью писать теперь лень, а код и демо вот: jsfiddle.net/LqRuF/21/
      • UFO just landed and posted this here
        • UFO just landed and posted this here
            0
            Обновил игру, добавил правила
            0
            «Жизнь» хоть и называется игрой, но участия там мы не принимаем. Максимум можем начальные значения расставить и всё вроде.
            • UFO just landed and posted this here
            0
            В подтверждение своих слов:

            «Игрок не принимает прямого участия в игре, а лишь расставляет или генерирует начальную конфигурацию «живых» клеток, которые затем взаимодействуют согласно правилам уже без его участия (он является наблюдателем).»

            Источник: ru.wikipedia.org/wiki/%D0%96%D0%B8%D0%B7%D0%BD%D1%8C_%28%D0%B8%D0%B3%D1%80%D0%B0%29

            Only users with full accounts can post comments. Log in, please.