Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
twitch
live-coding-fr
Commits
04b65a9f
Commit
04b65a9f
authored
Jan 21, 2021
by
Colin DAMON
Browse files
Game of life implementation
parent
8d58b798
Changes
4
Hide whitespace changes
Inline
Side-by-side
game-of-life/src/main/java/fr/ippon/life/Cell.java
0 → 100644
View file @
04b65a9f
package
fr.ippon.life
;
import
java.util.Set
;
public
class
Cell
{
private
static
final
int
LOW_POPULATION_THRESHOLD
=
2
;
private
static
final
int
HIGH_POPULATION_THRESHOLD
=
3
;
private
static
final
int
BORN_THRESHOLD
=
HIGH_POPULATION_THRESHOLD
;
private
final
int
row
;
private
final
int
column
;
public
Cell
(
int
row
,
int
column
)
{
this
.
row
=
row
;
this
.
column
=
column
;
}
boolean
stayAlive
(
Set
<
Cell
>
aliveCells
)
{
long
neighbourgCount
=
countNeigbours
(
aliveCells
);
return
neighbourgCount
==
LOW_POPULATION_THRESHOLD
||
neighbourgCount
==
HIGH_POPULATION_THRESHOLD
;
}
boolean
born
(
Set
<
Cell
>
aliveCells
)
{
return
countNeigbours
(
aliveCells
)
==
BORN_THRESHOLD
;
}
private
long
countNeigbours
(
Set
<
Cell
>
aliveCells
)
{
return
aliveCells
.
stream
().
filter
(
this
::
isNeighbour
).
count
();
}
private
boolean
isNeighbour
(
Cell
other
)
{
if
(
other
.
equals
(
this
))
{
return
false
;
}
return
delta
(
row
,
other
.
row
)
<=
1
&&
delta
(
column
,
other
.
column
)
<=
1
;
}
private
static
int
delta
(
int
first
,
int
second
)
{
return
Math
.
abs
(
first
-
second
);
}
public
int
getRow
()
{
return
row
;
}
public
int
getColumn
()
{
return
column
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
column
;
result
=
prime
*
result
+
row
;
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
Cell
other
=
(
Cell
)
obj
;
if
(
column
!=
other
.
column
)
return
false
;
if
(
row
!=
other
.
row
)
return
false
;
return
true
;
}
}
game-of-life/src/main/java/fr/ippon/life/Generation.java
0 → 100644
View file @
04b65a9f
package
fr.ippon.life
;
import
java.util.Collection
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
public
class
Generation
{
private
Set
<
Cell
>
aliveCells
;
public
Generation
(
Cell
...
aliveCells
)
{
this
(
Set
.
of
(
aliveCells
));
}
private
Generation
(
Set
<
Cell
>
cells
)
{
aliveCells
=
cells
;
}
public
Generation
next
()
{
Stream
<
Cell
>
stayAlive
=
aliveCells
.
stream
().
filter
(
cell
->
cell
.
stayAlive
(
aliveCells
));
Stream
<
Cell
>
born
=
buildGrid
().
deadCells
().
stream
().
filter
(
cell
->
cell
.
born
(
aliveCells
));
Set
<
Cell
>
cells
=
Stream
.
concat
(
stayAlive
,
born
).
collect
(
Collectors
.
toUnmodifiableSet
());
return
new
Generation
(
cells
);
}
public
Collection
<
Cell
>
getAliveCells
()
{
return
aliveCells
;
}
private
Grid
buildGrid
()
{
return
new
Grid
(
aliveCells
);
}
}
game-of-life/src/main/java/fr/ippon/life/Grid.java
0 → 100644
View file @
04b65a9f
package
fr.ippon.life
;
import
java.util.Collection
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
import
java.util.stream.Stream
;
public
class
Grid
{
private
final
Set
<
Cell
>
deadCells
;
private
final
Box
box
;
Grid
(
Set
<
Cell
>
cells
)
{
box
=
new
Box
(
cells
);
this
.
deadCells
=
buildDeadCells
(
cells
);
}
private
Set
<
Cell
>
buildDeadCells
(
Set
<
Cell
>
cells
)
{
return
IntStream
.
range
(
box
.
getTopRow
(),
box
.
getBottomRow
())
.
mapToObj
(
Integer:
:
valueOf
)
.
flatMap
(
row
->
toDeadCell
(
cells
,
row
))
.
collect
(
Collectors
.
toUnmodifiableSet
());
}
private
Stream
<
Cell
>
toDeadCell
(
Set
<
Cell
>
cells
,
int
row
)
{
return
IntStream
.
range
(
box
.
getLeftColumn
(),
box
.
getRightColumn
())
.
mapToObj
(
column
->
new
Cell
(
row
,
column
))
.
filter
(
cell
->
!
cells
.
contains
(
cell
));
}
public
Collection
<
Cell
>
deadCells
()
{
return
deadCells
;
}
private
static
class
Box
{
private
final
Point
topLeft
;
private
final
Point
bottomRight
;
public
Box
(
Set
<
Cell
>
cells
)
{
topLeft
=
Point
.
topLeft
(
cells
);
bottomRight
=
Point
.
bottomRight
(
cells
);
}
public
int
getTopRow
()
{
return
topLeft
.
getRow
();
}
public
int
getBottomRow
()
{
return
bottomRight
.
getRow
()
+
1
;
}
public
int
getLeftColumn
()
{
return
topLeft
.
getColumn
();
}
public
int
getRightColumn
()
{
return
bottomRight
.
getColumn
()
+
1
;
}
}
private
static
class
Point
{
private
final
int
row
;
private
final
int
column
;
public
Point
(
int
row
,
int
column
)
{
this
.
row
=
row
;
this
.
column
=
column
;
}
private
static
Point
topLeft
(
Set
<
Cell
>
cells
)
{
int
row
=
cells
.
stream
().
mapToInt
(
Cell:
:
getRow
).
min
().
orElse
(
0
);
int
column
=
cells
.
stream
().
mapToInt
(
Cell:
:
getColumn
).
min
().
orElse
(
0
);
return
new
Point
(
row
-
1
,
column
-
1
);
}
private
static
Point
bottomRight
(
Set
<
Cell
>
cells
)
{
int
row
=
cells
.
stream
().
mapToInt
(
Cell:
:
getRow
).
max
().
orElse
(
0
);
int
column
=
cells
.
stream
().
mapToInt
(
Cell:
:
getColumn
).
max
().
orElse
(
0
);
return
new
Point
(
row
+
1
,
column
+
1
);
}
public
int
getRow
()
{
return
row
;
}
public
int
getColumn
()
{
return
column
;
}
}
}
game-of-life/src/test/java/fr/ippon/life/GameOfLifeTest.java
0 → 100644
View file @
04b65a9f
package
fr.ippon.life
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.*;
import
org.junit.jupiter.api.Test
;
class
GameOfLifeTest
{
@Test
void
nextGenerationShouldHaveAllDeadCellsForAllDeadGrid
()
{
Generation
nextGeneration
=
new
Generation
().
next
();
assertThat
(
nextGeneration
.
getAliveCells
()).
isEmpty
();
}
@Test
void
nextGenerationShouldHaveAllDeadCellsFromOneAliveCell
()
{
Generation
nextGeneration
=
new
Generation
(
cell
(
1
,
1
)).
next
();
assertThat
(
nextGeneration
.
getAliveCells
()).
isEmpty
();
}
@Test
void
nextGenerationShouldHaveAllDeadCellsFromTwoContiguousAliveCells
()
{
Generation
nextGeneration
=
new
Generation
(
cell
(
1
,
1
),
cell
(
2
,
1
)).
next
();
assertThat
(
nextGeneration
.
getAliveCells
()).
isEmpty
();
}
@Test
void
nextGenerationShouldHaveFourAliveCellsFromTriangularConfiguration
()
{
Cell
first
=
cell
(
1
,
2
);
Cell
second
=
cell
(
2
,
1
);
Cell
third
=
cell
(
2
,
2
);
Generation
nextGeneration
=
new
Generation
(
first
,
second
,
third
).
next
();
assertThat
(
nextGeneration
.
getAliveCells
()).
containsExactlyInAnyOrder
(
cell
(
1
,
1
),
first
,
second
,
third
);
}
@Test
void
nextGenerationShouldHaveOneColumnFromOneLine
()
{
Generation
nextGeneration
=
new
Generation
(
cell
(
4
,
5
),
cell
(
5
,
5
),
cell
(
6
,
5
)).
next
();
assertThat
(
nextGeneration
.
getAliveCells
()).
containsExactlyInAnyOrder
(
cell
(
5
,
4
),
cell
(
5
,
5
),
cell
(
5
,
6
));
}
@Test
void
shouldAdvanceInGenerations
()
{
Generation
nextGeneration
=
threeCellsColumn
();
assertThat
(
nextGeneration
.
getAliveCells
()).
containsExactlyInAnyOrder
(
cell
(
4
,
5
),
cell
(
5
,
5
),
cell
(
6
,
5
));
}
private
Generation
threeCellsColumn
()
{
return
new
Generation
(
cell
(
4
,
5
),
cell
(
5
,
5
),
cell
(
6
,
5
)).
next
().
next
();
}
private
static
Cell
cell
(
int
row
,
int
column
)
{
return
new
Cell
(
row
,
column
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment