Skip to content

Commit

Permalink
game of life initial
Browse files Browse the repository at this point in the history
  • Loading branch information
jarekratajski committed May 9, 2018
0 parents commit 2b4d722
Show file tree
Hide file tree
Showing 9 changed files with 429 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dist/
target/
*.iml
.idea/
out/
7 changes: 7 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
cd life
etlas install
etlas configure --enable-uberjar-mode
etlas build
cd ../life-java
mvn package
64 changes: 64 additions & 0 deletions life-java/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>pl.setblack</groupId>
<artifactId>eta-life-java</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>life-java</name>


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>pl.setblack.life.GameOfLife</mainClass>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>pl.setblack</groupId>
<artifactId>life-in-eta</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../life/dist/build/life-hs/life-hs.jar</systemPath>
</dependency>
<dependency>
<groupId>javafx</groupId>
<artifactId>jfxrt</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${java.home}/lib/ext/jfxrt.jar</systemPath>
</dependency>
</dependencies>
</project>
114 changes: 114 additions & 0 deletions life-java/src/main/java/pl/setblack/life/GameOfLife.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package pl.setblack.life;


import javafx.application.Application;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.awt.image.BufferedImage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class GameOfLife extends Application {
ExecutorService executorService = Executors.newSingleThreadExecutor();

int lastState = 0;
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
int wi = 100;
int hi = 100;
int cwi= wi*6;
int chi= hi*6;
BufferedImage image = new BufferedImage(wi, hi, BufferedImage.TYPE_3BYTE_BGR);


int state = Life.initEmpty(wi-1, hi-1);

for (int i=0 ; i < wi/2; i++) {
state = Life.setCell(state, i+wi/4, hi/2, java.awt.Color.BLUE);
}

for (int i=0 ; i < wi/2; i++) {
state = Life.setCell(state, i+wi/4, hi/4, java.awt.Color.GREEN);
}

for (int i=0 ; i < wi/2; i++) {
state = Life.setCell(state, i+wi/4, hi/4+hi/2, java.awt.Color.RED);
}

/*for (int i=0 ; i < hi/2; i++) {
state = Life.setCell(state, wi/2, i+ hi/4, java.awt.Color.GREEN);
}*/


lastState = state;
Life.fillImage(lastState, image);

BorderPane border = new BorderPane();

Image fxImage = SwingFXUtils.toFXImage(image, null);

Canvas canvas = new Canvas(cwi, chi);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(fxImage,0,0, cwi, chi);
Button button = new Button("next>>");

Runnable makeStep = () -> {
GraphicsContext gc1 = canvas.getGraphicsContext2D();
lastState = Life.newState(lastState);
System.out.println("new state:"+ lastState);
Life.fillImage(lastState, image);
Image fxImage1 = SwingFXUtils.toFXImage(image, null);


gc1.drawImage(fxImage1,0,0, cwi, chi);

};

button.setOnAction( e -> {
makeStep.run();
});
border.setCenter(canvas);
Button autobutton = new Button("auto");
autobutton.setOnAction( e -> {
ScheduledService<Void> svc = new ScheduledService<Void>() {
protected Task<Void> createTask() {
return new Task<Void>() {
protected Void call() {

makeStep.run();
return null;
}
};
}
};
svc.setPeriod(Duration.millis(20));
svc.start();

});
HBox hbox = new HBox(8);
hbox.getChildren().addAll(button, autobutton);
border.setBottom(hbox);
primaryStage.setScene(new Scene(border));
primaryStage.show();
}


}
2 changes: 2 additions & 0 deletions life/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain
22 changes: 22 additions & 0 deletions life/life-hs.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: life-hs
version: 0.1.0.0
synopsis:
-- description:
-- license:
-- license-file:
homepage:
author: jarekratajski
maintainer: jratajski@gmail.com
category:
-- copyright:
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10

executable life-hs
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >= 4.7 && < 5, array
hs-source-dirs: src
default-language: Haskell2010
126 changes: 126 additions & 0 deletions life/src/Life.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
module Life where

import Data.Array
import Data.Maybe
import Data.Bits
import Debug.Trace


data Color = Color {red :: Int,
green :: Int,
blue :: Int};

data Cell = Dead | Alive {color :: Color}

type Row = Array Int Cell
type Plane = Array Int Row


takeRow:: Plane->Int->Maybe Row
takeRow plane y
| (y>= minBound && y <=maxBound) = Just $ plane!y
| otherwise = Nothing
where
myBounds = bounds plane
minBound = fst myBounds
maxBound = snd myBounds

takeCell:: Row->Int->Maybe Cell
takeCell row x
| (x>= minBound && x <=maxBound) = Just $ row!x
| otherwise = Nothing
where
myBounds = bounds row
minBound = fst myBounds
maxBound = snd myBounds


takeRows::Int->Plane->[Row]
takeRows y plane = catMaybes maybeRows
where
rows = [y-1, y, y+1]
maybeRows = (takeRow plane) <$> rows

takeCells::[Row]->Int->[Cell]
takeCells rows x = catMaybes $ concat allCells
where
columns = [x-1, x, x+1]
allCells = (\row -> takeCell row <$> columns ) <$> rows


neighborhood::Int->Int ->Plane->[Cell]
neighborhood x y plane = takeCells rows x
where rows = takeRows y plane


newCell::[Cell]->Cell->Cell
newCell cells Dead = if alive ==3 then Alive { color = snd vals} else Dead
where
vals = newCellValue cells (0, Color {red = 0,green = 0, blue = 0})
alive = fst vals
newCell cells Alive{color = c} = if alive ==3 || alive==4 then Alive { color = c} else Dead
where
vals = newCellValue cells (0, c)
alive = fst vals



newCellValue::[Cell]->(Int, Color)->(Int, Color)
newCellValue [] (cnt, color) = (cnt, color)
newCellValue (Dead:xs) (cnt, color) = newCellValue xs (cnt, color)
newCellValue (Alive {color = c} :xs) (cnt, color) = newCellValue xs (cnt+1, mixC color c)


calcCell::Cell->Int -> Int -> Plane -> Cell
calcCell cell x y plane = aNew
where
ngh = neighborhood x y plane
aNew = newCell ngh cell

showCell::Cell->String
showCell Dead = "."
showCell _ = "O"

mixC::Color->Color->Color
mixC a b = Color { red = red a .|. red b,
blue = blue a .|. blue b,
green = green a .|. green b}


cellFromColor::Color->Cell
cellFromColor Color { red = 0, green = 0 , blue = 0 } = Dead
cellFromColor col = Alive { color = col}


mix::Int->Int->Int
mix a b = a .|. b


makePlane::Int->Int->Plane
makePlane wi hi = array (0, hi) [ (i, makeRow wi) | i <- [0..hi] ]


makeRow::Int->Row
makeRow wi = array (0,wi) [ (i, Dead) | i<- [0..wi] ]



setCell::Plane->Int->Int->Cell->Plane
setCell plane x y cell = plane // [(y , newRow)]
where
row = plane ! y
newRow = row // [(x, cell)]


-- actuall processing
processRow::Row->Plane->Int->Row
processRow row plane y = row // newElems
where
elements = assocs row
newElems =(\(x,cell) -> (x, calcCell cell x y plane) ) <$> elements

processPlane::Plane->Plane
processPlane plane = plane // newElems
where
elements = assocs plane
newElems =(\(y,row) -> (y, processRow row plane y) ) <$> elements
Loading

0 comments on commit 2b4d722

Please sign in to comment.