Last active
October 29, 2019 16:25
-
-
Save jordanrobinson/10d365e0df999b0ee1bdc72fbe3e97af to your computer and use it in GitHub Desktop.
Clojure Game of Life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns clojure-katas.game-of-life) | |
(defn contains-live? | |
[board] | |
(.contains (apply concat board) 1)) | |
(defn create-grid | |
[size] | |
(repeat size (repeat size 0))) | |
(defn random-grid | |
[size] | |
(partition size (take (* size size) (repeatedly #(rand-int 2))))) | |
(defn generate-coordinate-map | |
[board] | |
(for [x (vec (take (count board) (range))) | |
y (vec (take (count board) (range)))] | |
[x y])) | |
(defn get-at-position | |
[board pos-x pos-y] | |
(nth (nth board pos-y ()) pos-x 0)) | |
(defn get-left-neighbour | |
[board pos-x pos-y] | |
(get-at-position board (dec pos-x) pos-y)) | |
(defn get-right-neighbour | |
[board pos-x pos-y] | |
(get-at-position board (inc pos-x) pos-y)) | |
(defn get-top-neighbour | |
[board pos-x pos-y] | |
(get-at-position board pos-x (dec pos-y))) | |
(defn get-bottom-neighbour | |
[board pos-x pos-y] | |
(get-at-position board pos-x (inc pos-y))) | |
(defn count-neighbours | |
[board pos-x pos-y] | |
(+ | |
(get-left-neighbour board pos-x pos-y) | |
(get-right-neighbour board pos-x pos-y) | |
(get-top-neighbour board pos-x pos-y) | |
(get-bottom-neighbour board pos-x pos-y))) | |
(defn should-live-or-die? [val] | |
(cond (< val 2) 0 | |
(or (= 2 val) (= 3 val)) 1 | |
(> val 3) 0)) | |
(defn get-all-neighbours | |
[board] | |
(map #(let [[first second] %1] | |
(count-neighbours board first second)) | |
(generate-coordinate-map board))) | |
(defn next-generation | |
[board] | |
(partition (count board) (map should-live-or-die? (get-all-neighbours board)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns clojure-katas.game-of-life-test | |
(:require [clojure.test :refer :all] | |
[clojure-katas.game-of-life :refer :all])) | |
; Any live cell with fewer than two live neighbours dies, as if caused by under-population. | |
; Any live cell with two or three live neighbours lives on to the next generation. | |
; Any live cell with more than three live neighbours dies, as if by overcrowding. | |
; Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. | |
(def example-empty-3x3-grid | |
[[0 0 0] | |
[0 0 0] | |
[0 0 0]]) | |
(def example-1-live-cell-3x3-grid | |
[[0 0 0] | |
[0 1 0] | |
[0 0 0]]) | |
(def example-2-live-cell-3x3-grid | |
[[0 0 0] | |
[1 0 1] | |
[0 0 0]]) | |
(def example-3-live-cell-3x3-grid | |
[[0 1 0] | |
[1 0 1] | |
[0 0 0]]) | |
(def example-4-live-cell-3x3-grid | |
[[0 1 0] | |
[1 0 1] | |
[0 1 0]]) | |
(deftest create-grid_whenGivenDimensions_createsGridOfThoseDimensions | |
(is (= (create-grid 3) example-empty-3x3-grid))) | |
(deftest next-generation_whenGivenEmptyBoard_returnsEmptyBoard | |
(is (= (next-generation example-empty-3x3-grid) example-empty-3x3-grid))) | |
(deftest next-generation_whenGivenBoardWithOneLiveCell_returnsEmptyBoard | |
(is (= (next-generation example-1-live-cell-3x3-grid) example-empty-3x3-grid))) | |
(deftest contains-live_whenGivenBoardWithOneLiveCell_returnsTrue | |
(is (= (contains-live? example-1-live-cell-3x3-grid) true))) | |
(deftest count-neighbours_whenGivenTwoNeighbours_returnsTwo | |
(is (= (count-neighbours example-2-live-cell-3x3-grid 1 1) 2))) | |
(deftest count-neighbours_returnsZero_whenEdgesOfGrid | |
(is (= (count-neighbours example-empty-3x3-grid 0 0) 0))) | |
(deftest next-generation_whenGivenBoardWithTwoLiveNeighbours_CellLives | |
(is (= (contains-live? (next-generation example-2-live-cell-3x3-grid)) true))) | |
(deftest next-generation_whenGivenBoardWithThreeLiveNeighbours_CellLives | |
(is (= (contains-live? (next-generation example-3-live-cell-3x3-grid)) true))) | |
(deftest next-generation_whenGivenBoardWithFourLiveNeighbours_CellDies | |
(is (= (get-at-position (next-generation example-4-live-cell-3x3-grid) 1 1) 0))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment