!************************************************************************
! * This file has been written as a sample solution to an exercise in a 
! * course given at the Edinburgh Parallel Computing Centre. It is made
! * freely available with the understanding that every copy of this file
! * must include this header and that EPCC takes no responsibility for
! * the use of the enclosed teaching material.
! *
! * Authors:     Alan Simpson, Harvey Richardson, Alistair Ewing
! *
! * Contact:     epcc-tec@epcc.ed.ac.uk
! *
! * Purpose:	 Exercise 2: Game of Life
! *
! * Contents:    HPF source code.
! *
! ************************************************************************/
      PROGRAM life
      IMPLICIT NONE

! This code performs MAXLOOP iterations of an NxN life board
!
      INTEGER, PARAMETER :: N=20, MAXLOOP=10
      INTEGER loop

! Declare main arrays
!
      INTEGER, DIMENSION(N,N) :: board, neighbours

      CHARACTER*(10) picfile

! Initialise board
!
      board = 0

      board(N/2,:) = 1
      board(:,N/2) = 1

! Print starting config to file life00.pgm
!
      OPEN(UNIT=10, FILE='life.pgm')

      WRITE(10, FMT='(''P2'',/,i3,2x,i3,/,i3)') N, N, 1
      WRITE(10,*) board

! Perform MAXLOOP updates
!
      DO loop = 1, MAXLOOP

! Count number of neighbours
!
        neighbours =
     &    CSHIFT(board, SHIFT= 1, DIM=1) +
     &    CSHIFT(board, SHIFT=-1, DIM=1) +
     &    CSHIFT(board, SHIFT= 1, DIM=2) +
     &    CSHIFT(board, SHIFT=-1, DIM=2) +
     &    CSHIFT(CSHIFT(board, SHIFT= 1, DIM=2), SHIFT= 1, DIM=1) +
     &    CSHIFT(CSHIFT(board, SHIFT= 1, DIM=2), SHIFT=-1, DIM=1) +
     &    CSHIFT(CSHIFT(board, SHIFT=-1, DIM=2), SHIFT= 1, DIM=1) +
     &    CSHIFT(CSHIFT(board, SHIFT=-1, DIM=2), SHIFT=-1, DIM=1)

! Calculate new generation
!
        WHERE (neighbours.lt.2 .or. neighbours.gt.3)
          board = 0
        END WHERE
        WHERE (neighbours.eq.3)
          board = 1
        END WHERE

! Write out new state of board
!
        WRITE(10, FMT='(''P2'',/,i3,2x,i3,/,i3)') N, N, 1
        WRITE(10,*) board

      END DO

      CLOSE(UNIT=10)

      END

      

