2019년 4월 13일 토요일

# Golang으로 셀룰러 오토마타 샘플 코드.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// genCave
package main

import (
 "encoding/json"
 "fmt"
 "math/rand"
 "os"
 "time"
)

// reference links :
// 1) http://gamedevelopment.tutsplus.com/tutorials/generate-random-cave-levels-using-cellular-automata--gamedev-9664

// global variables
// cell Map x size and y size
var mapX = 15
var mapY = 15

func main() {

 var numberOfSteps int = 3

 var cellMap [][]bool = make([][]bool, mapY)
 for i := range cellMap {
  cellMap[i] = make([]bool, mapX)
 }
 InitCellMap(cellMap, mapX, mapY)

 for i := 0; i < numberOfSteps; i++ {
  cellMap = DoSimulationStep(cellMap, mapX, mapY)
 }

 // for i := 0; i < mapX; i++ {
 //  fmt.Println(cellMap[i])
 // }

 SaveMapToJsonFile(cellMap)
}

func SaveMapToJsonFile(_cellMap [][]bool) {

 os.Create("CaveMapData.json")
 file, openErr := os.OpenFile("CaveMapData.json", os.O_RDWR, os.ModeType)
 if openErr != nil {
  fmt.Println(openErr)
 } else {
  marshalData, err := json.MarshalIndent(_cellMap, "", " ")
  if err != nil {
   fmt.Println(err)
  } else {
   file.Write(marshalData)
  }
 
 }
 file.Close()
}

func InitCellMap(_cellMap [][]bool, width int, heigth int) {
 var chanceToStartAlive float32 = 0.45

 rand.Seed(time.Now().UnixNano())
 for x := 0; x < width; x++ {
  for y := 0; y < heigth; y++ {
   if rand.Float32() < chanceToStartAlive {
    _cellMap[x][y] = true
   } else {
    _cellMap[x][y] = false
   }
  }
 }
}

func CountAliveNeighbours(_cellMap [][]bool, posX int, posY int) int {

 var count int = 0
 for i := -1; i < 2; i++ {
  for j := -1; j < 2; j++ {
   var neighbour_x int = posX + i
   var neighbour_y int = posY + j
   if i == 0 && j == 0 {
    // nothing to do
   } else if (neighbour_x < 0) ||
    (neighbour_y < 0) ||
    (neighbour_x >= mapX) ||
    (neighbour_y >= mapY) {
    count = count + 1
   } else if _cellMap[neighbour_x][neighbour_y] {
    count = count + 1
   }
  }
 }
 return count
}

func DoSimulationStep(oldMap [][]bool, width int, height int) [][]bool {
 var deathLimit, birthLimit int = 2, 6
 var newMap [][]bool = make([][]bool, mapY)
 for i := range newMap {
  newMap[i] = make([]bool, mapX)
 }

 for x := 0; x < width; x++ {
  for y := 0; y < height; y++ {
   var nbs int = CountAliveNeighbours(oldMap, x, y)

   if oldMap[x][y] {
    if nbs < deathLimit {
     newMap[x][y] = false
    } else {
     newMap[x][y] = true
    }
   } else {
    if nbs > birthLimit {
     newMap[x][y] = true
    } else {
     newMap[x][y] = false
    }
   }
  }
 }
 return newMap
}

댓글 없음:

댓글 쓰기