Task: Conway's Game of Life




Go: package main

import (
	"bytes"
	"fmt"
	"math/rand"
	"time"
)

type Field struct {
	s    [][]bool
	w, h int
}

func NewField(w, h int) Field {
	s := make([][]bool, h)
	for i := range s {
		s[i] = make([]bool, w)
	}
	return Field{s: s, w: w, h: h}
}

func (f Field) Set(x, y int, b bool) {
	f.s[y][x] = b
}

func (f Field) Next(x, y int) bool {
	on := 0
	for i := -1; i <= 1; i++ {
		for j := -1; j <= 1; j++ {
			if f.State(x+i, y+j) && !(j == 0 && i == 0) {
				on++
			}
		}
	}
	return on == 3 || on == 2 && f.State(x, y)
}

func (f Field) State(x, y int) bool {
	for y < 0 {
		y += f.h
	}
	for x < 0 {
		x += f.w
	}
	return f.s[y%f.h][x%f.w]
}

type Life struct {
	w, h int
	a, b Field
}

func NewLife(w, h int) *Life {
	a := NewField(w, h)
	for i := 0; i < (w * h / 2); i++ {
		a.Set(rand.Intn(w), rand.Intn(h), true)
	}
	return &Life{
		a: a,
		b: NewField(w, h),
		w: w, h: h,
	}
}

func (l *Life) Step() {
	for y := 0; y < l.h; y++ {
		for x := 0; x < l.w; x++ {
			l.b.Set(x, y, l.a.Next(x, y))
		}
	}
	l.a, l.b = l.b, l.a
}

func (l *Life) String() string {
	var buf bytes.Buffer
	for y := 0; y < l.h; y++ {
		for x := 0; x < l.w; x++ {
			b := byte(' ')
			if l.a.State(x, y) {
				b = '*'
			}
			buf.WriteByte(b)
		}
		buf.WriteByte('\n')
	}
	return buf.String()
}

func main() {
	l := NewLife(80, 15)
	for i := 0; i < 300; i++ {
		l.Step()
		fmt.Print("\x0c")
		fmt.Println(l)
		time.Sleep(time.Second / 30)
	}
}







Fortran:  PROGRAM LIFE_2D
   IMPLICIT NONE
 
   INTEGER, PARAMETER :: gridsize = 10
   LOGICAL :: cells(0:gridsize+1,0:gridsize+1) = .FALSE.
   INTEGER :: i, j, generation=0
   REAL :: rnums(gridsize,gridsize)
 
 
 
 
 
 
    cells(3:5,3:5) = .TRUE. ; cells(6:8,6:8) = .TRUE.                      
 
 
 
   
   CALL Drawgen(cells(1:gridsize, 1:gridsize), generation)
   DO generation = 1, 8
      CALL NextgenV2(cells)
      CALL Drawgen(cells(1:gridsize, 1:gridsize), generation)
   END DO
 
 CONTAINS
 
   SUBROUTINE Drawgen(cells, gen)
     LOGICAL, INTENT(IN OUT) :: cells(:,:)
     INTEGER, INTENT(IN) :: gen
 
     WRITE(*, "(A,I0)") "Generation ", gen 
     DO i = 1, SIZE(cells,1)
        DO j = 1, SIZE(cells,2)
           IF (cells(i,j)) THEN
              WRITE(*, "(A)", ADVANCE = "NO") "#"
           ELSE
              WRITE(*, "(A)", ADVANCE = "NO") " "
           END IF
        END DO
        WRITE(*,*)
     END DO
     WRITE(*,*)
   END SUBROUTINE Drawgen
 
  SUBROUTINE Nextgen(cells)
     LOGICAL, INTENT(IN OUT) :: cells(0:,0:)
     LOGICAL :: buffer(0:SIZE(cells, 1)-1, 0:SIZE(cells, 2)-1)
     INTEGER :: neighbours, i, j
   
     buffer = cells   
     DO j = 1, SIZE(cells, 2)-2
        DO i = 1, SIZE(cells, 1)-2
          if(buffer(i, j)) then
            neighbours = sum(count(buffer(i-1:i+1, j-1:j+1), 1)) - 1
          else
            neighbours = sum(count(buffer(i-1:i+1, j-1:j+1), 1))
          end if
  
          SELECT CASE(neighbours)
            CASE (0:1, 4:8)
               cells(i,j) = .FALSE.
  
            CASE (2)
               
  
            CASE (3)
               cells(i,j) = .TRUE.
          END SELECT
          
        END DO
     END DO
  END SUBROUTINE Nextgen








  PURE SUBROUTINE NextgenV2(cells)
     LOGICAL, INTENT(IN OUT) :: cells(:,:)
     INTEGER(KIND=1) :: buffer(1:SIZE(cells, 1)-2,1:SIZE(cells, 2)-2)
     INTEGER :: gridsize, i, j
     
     gridsize=SIZE(cells, 1)
     buffer=0
     
     DO j=-1, 1
        DO i=-1,1
           IF(i==0 .AND. j==0) CYCLE
           WHERE(cells(i+2:gridsize-i-1,j+2:gridsize-j-1)) buffer=buffer+1
        END DO
     END DO

     WHERE(buffer<2 .or. buffer>3) cells(2:gridsize-1,2:gridsize-1) = .FALSE.
     WHERE(buffer==3) cells(2:gridsize-1,2:gridsize-1) = .TRUE.
  END SUBROUTINE NextgenV2

 END PROGRAM LIFE_2D