Java-based Game Of Life

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
1












I've recently had a go at programming a Conway's Game of Life simulation in Java, and I was wondering if anyone could provide some input on how it could be improved. I'm mainly concerned with how to improve the "cleanliness" and readability of the code, rather than it's algorithmic complexity. This is my first attempt at using Java (although I used other OOP languages) so if I'm not using any obvious Java functionality please let me know!



The Game Class:



package com.company;

import java.util.HashSet;
import java.util.Set;

public class Game
private Set<Cell> cells = new HashSet<>();

public Game()

public void addCell(Cell cell)
cells.add(cell);


public boolean hasAliveCellAt(Cell cell)
return cells.contains(cell);


public int getNumberOfAliveCells()
return cells.size();


public void tick()
Set<Cell> nextTicksCells = new HashSet<>();

nextTicksCells.addAll(getCellsThatSurviveTick());
nextTicksCells.addAll(getCellsThatAreBornFromTick());

cells = nextTicksCells;


private Set<Cell> getCellsThatSurviveTick()
Set<Cell> survivingCells = new HashSet<>();

for (Cell cell : cells)
if (cellCanSurvive(cell))
survivingCells.add(cell);



return survivingCells;


private boolean cellCanSurvive(Cell cell)
int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);
return cellHasCorrectAmountOfNeighboursToSurvive(numberOfAliveNeighbours);


private int getNumberOfAliveNeighbours(Cell cell)
int numberOfAliveNeighbours = 0;

for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
for (int y = (cell.y - 1); y <= (cell.y + 1); y++)

Cell neighbouringCell = new Cell(x, y);

if (cell.equals(neighbouringCell))
continue;


if (hasAliveCellAt(neighbouringCell))
numberOfAliveNeighbours++;




return numberOfAliveNeighbours;


private boolean cellHasCorrectAmountOfNeighboursToSurvive(int numberOfAliveNeighbours)

private Set<Cell> getCellsThatAreBornFromTick()
Set<Cell> deadNeighbouringCells = getGamesDeadNeighbouringCells();

Set<Cell> cellsToBeBorn = new HashSet<>();

for (Cell cell : deadNeighbouringCells)
if (cellCanBeBorn(cell))
cellsToBeBorn.add(cell);



return cellsToBeBorn;


private Set<Cell> getGamesDeadNeighbouringCells()
Set<Cell> deadNeighbouringCells = new HashSet<>();

for (Cell cell : cells)
deadNeighbouringCells.addAll(getCellsDeadNeighbouringCells(cell));


return deadNeighbouringCells;


private Set<Cell> getCellsDeadNeighbouringCells(Cell cell)
Set<Cell> deadNeighbouringCells = new HashSet<>();

for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
for (int y = (cell.y - 1); y <= (cell.y + 1); y++)
Cell neighbouringCells = new Cell(x, y);

if (cell.equals(neighbouringCells))
continue;


if (!hasAliveCellAt(neighbouringCells))
deadNeighbouringCells.add(neighbouringCells);




return deadNeighbouringCells;


private boolean cellCanBeBorn(Cell cell)
int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);

return cellHasCorrectAmountOfNeighboursToBeBorn(numberOfAliveNeighbours);


private boolean cellHasCorrectAmountOfNeighboursToBeBorn(int numberOfAliveNeighbours)
return (numberOfAliveNeighbours == 3);




The Cell Class:



package com.company;

import java.util.Objects;

public class Cell
public final int x;
public final int y;

public Cell(int x, int y)
this.x = x;
this.y = y;


@Override
public boolean equals(Object o)

@Override
public int hashCode()
return Objects.hash(x, y);








share|improve this question



























    up vote
    3
    down vote

    favorite
    1












    I've recently had a go at programming a Conway's Game of Life simulation in Java, and I was wondering if anyone could provide some input on how it could be improved. I'm mainly concerned with how to improve the "cleanliness" and readability of the code, rather than it's algorithmic complexity. This is my first attempt at using Java (although I used other OOP languages) so if I'm not using any obvious Java functionality please let me know!



    The Game Class:



    package com.company;

    import java.util.HashSet;
    import java.util.Set;

    public class Game
    private Set<Cell> cells = new HashSet<>();

    public Game()

    public void addCell(Cell cell)
    cells.add(cell);


    public boolean hasAliveCellAt(Cell cell)
    return cells.contains(cell);


    public int getNumberOfAliveCells()
    return cells.size();


    public void tick()
    Set<Cell> nextTicksCells = new HashSet<>();

    nextTicksCells.addAll(getCellsThatSurviveTick());
    nextTicksCells.addAll(getCellsThatAreBornFromTick());

    cells = nextTicksCells;


    private Set<Cell> getCellsThatSurviveTick()
    Set<Cell> survivingCells = new HashSet<>();

    for (Cell cell : cells)
    if (cellCanSurvive(cell))
    survivingCells.add(cell);



    return survivingCells;


    private boolean cellCanSurvive(Cell cell)
    int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);
    return cellHasCorrectAmountOfNeighboursToSurvive(numberOfAliveNeighbours);


    private int getNumberOfAliveNeighbours(Cell cell)
    int numberOfAliveNeighbours = 0;

    for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
    for (int y = (cell.y - 1); y <= (cell.y + 1); y++)

    Cell neighbouringCell = new Cell(x, y);

    if (cell.equals(neighbouringCell))
    continue;


    if (hasAliveCellAt(neighbouringCell))
    numberOfAliveNeighbours++;




    return numberOfAliveNeighbours;


    private boolean cellHasCorrectAmountOfNeighboursToSurvive(int numberOfAliveNeighbours)

    private Set<Cell> getCellsThatAreBornFromTick()
    Set<Cell> deadNeighbouringCells = getGamesDeadNeighbouringCells();

    Set<Cell> cellsToBeBorn = new HashSet<>();

    for (Cell cell : deadNeighbouringCells)
    if (cellCanBeBorn(cell))
    cellsToBeBorn.add(cell);



    return cellsToBeBorn;


    private Set<Cell> getGamesDeadNeighbouringCells()
    Set<Cell> deadNeighbouringCells = new HashSet<>();

    for (Cell cell : cells)
    deadNeighbouringCells.addAll(getCellsDeadNeighbouringCells(cell));


    return deadNeighbouringCells;


    private Set<Cell> getCellsDeadNeighbouringCells(Cell cell)
    Set<Cell> deadNeighbouringCells = new HashSet<>();

    for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
    for (int y = (cell.y - 1); y <= (cell.y + 1); y++)
    Cell neighbouringCells = new Cell(x, y);

    if (cell.equals(neighbouringCells))
    continue;


    if (!hasAliveCellAt(neighbouringCells))
    deadNeighbouringCells.add(neighbouringCells);




    return deadNeighbouringCells;


    private boolean cellCanBeBorn(Cell cell)
    int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);

    return cellHasCorrectAmountOfNeighboursToBeBorn(numberOfAliveNeighbours);


    private boolean cellHasCorrectAmountOfNeighboursToBeBorn(int numberOfAliveNeighbours)
    return (numberOfAliveNeighbours == 3);




    The Cell Class:



    package com.company;

    import java.util.Objects;

    public class Cell
    public final int x;
    public final int y;

    public Cell(int x, int y)
    this.x = x;
    this.y = y;


    @Override
    public boolean equals(Object o)

    @Override
    public int hashCode()
    return Objects.hash(x, y);








    share|improve this question























      up vote
      3
      down vote

      favorite
      1









      up vote
      3
      down vote

      favorite
      1






      1





      I've recently had a go at programming a Conway's Game of Life simulation in Java, and I was wondering if anyone could provide some input on how it could be improved. I'm mainly concerned with how to improve the "cleanliness" and readability of the code, rather than it's algorithmic complexity. This is my first attempt at using Java (although I used other OOP languages) so if I'm not using any obvious Java functionality please let me know!



      The Game Class:



      package com.company;

      import java.util.HashSet;
      import java.util.Set;

      public class Game
      private Set<Cell> cells = new HashSet<>();

      public Game()

      public void addCell(Cell cell)
      cells.add(cell);


      public boolean hasAliveCellAt(Cell cell)
      return cells.contains(cell);


      public int getNumberOfAliveCells()
      return cells.size();


      public void tick()
      Set<Cell> nextTicksCells = new HashSet<>();

      nextTicksCells.addAll(getCellsThatSurviveTick());
      nextTicksCells.addAll(getCellsThatAreBornFromTick());

      cells = nextTicksCells;


      private Set<Cell> getCellsThatSurviveTick()
      Set<Cell> survivingCells = new HashSet<>();

      for (Cell cell : cells)
      if (cellCanSurvive(cell))
      survivingCells.add(cell);



      return survivingCells;


      private boolean cellCanSurvive(Cell cell)
      int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);
      return cellHasCorrectAmountOfNeighboursToSurvive(numberOfAliveNeighbours);


      private int getNumberOfAliveNeighbours(Cell cell)
      int numberOfAliveNeighbours = 0;

      for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
      for (int y = (cell.y - 1); y <= (cell.y + 1); y++)

      Cell neighbouringCell = new Cell(x, y);

      if (cell.equals(neighbouringCell))
      continue;


      if (hasAliveCellAt(neighbouringCell))
      numberOfAliveNeighbours++;




      return numberOfAliveNeighbours;


      private boolean cellHasCorrectAmountOfNeighboursToSurvive(int numberOfAliveNeighbours)

      private Set<Cell> getCellsThatAreBornFromTick()
      Set<Cell> deadNeighbouringCells = getGamesDeadNeighbouringCells();

      Set<Cell> cellsToBeBorn = new HashSet<>();

      for (Cell cell : deadNeighbouringCells)
      if (cellCanBeBorn(cell))
      cellsToBeBorn.add(cell);



      return cellsToBeBorn;


      private Set<Cell> getGamesDeadNeighbouringCells()
      Set<Cell> deadNeighbouringCells = new HashSet<>();

      for (Cell cell : cells)
      deadNeighbouringCells.addAll(getCellsDeadNeighbouringCells(cell));


      return deadNeighbouringCells;


      private Set<Cell> getCellsDeadNeighbouringCells(Cell cell)
      Set<Cell> deadNeighbouringCells = new HashSet<>();

      for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
      for (int y = (cell.y - 1); y <= (cell.y + 1); y++)
      Cell neighbouringCells = new Cell(x, y);

      if (cell.equals(neighbouringCells))
      continue;


      if (!hasAliveCellAt(neighbouringCells))
      deadNeighbouringCells.add(neighbouringCells);




      return deadNeighbouringCells;


      private boolean cellCanBeBorn(Cell cell)
      int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);

      return cellHasCorrectAmountOfNeighboursToBeBorn(numberOfAliveNeighbours);


      private boolean cellHasCorrectAmountOfNeighboursToBeBorn(int numberOfAliveNeighbours)
      return (numberOfAliveNeighbours == 3);




      The Cell Class:



      package com.company;

      import java.util.Objects;

      public class Cell
      public final int x;
      public final int y;

      public Cell(int x, int y)
      this.x = x;
      this.y = y;


      @Override
      public boolean equals(Object o)

      @Override
      public int hashCode()
      return Objects.hash(x, y);








      share|improve this question













      I've recently had a go at programming a Conway's Game of Life simulation in Java, and I was wondering if anyone could provide some input on how it could be improved. I'm mainly concerned with how to improve the "cleanliness" and readability of the code, rather than it's algorithmic complexity. This is my first attempt at using Java (although I used other OOP languages) so if I'm not using any obvious Java functionality please let me know!



      The Game Class:



      package com.company;

      import java.util.HashSet;
      import java.util.Set;

      public class Game
      private Set<Cell> cells = new HashSet<>();

      public Game()

      public void addCell(Cell cell)
      cells.add(cell);


      public boolean hasAliveCellAt(Cell cell)
      return cells.contains(cell);


      public int getNumberOfAliveCells()
      return cells.size();


      public void tick()
      Set<Cell> nextTicksCells = new HashSet<>();

      nextTicksCells.addAll(getCellsThatSurviveTick());
      nextTicksCells.addAll(getCellsThatAreBornFromTick());

      cells = nextTicksCells;


      private Set<Cell> getCellsThatSurviveTick()
      Set<Cell> survivingCells = new HashSet<>();

      for (Cell cell : cells)
      if (cellCanSurvive(cell))
      survivingCells.add(cell);



      return survivingCells;


      private boolean cellCanSurvive(Cell cell)
      int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);
      return cellHasCorrectAmountOfNeighboursToSurvive(numberOfAliveNeighbours);


      private int getNumberOfAliveNeighbours(Cell cell)
      int numberOfAliveNeighbours = 0;

      for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
      for (int y = (cell.y - 1); y <= (cell.y + 1); y++)

      Cell neighbouringCell = new Cell(x, y);

      if (cell.equals(neighbouringCell))
      continue;


      if (hasAliveCellAt(neighbouringCell))
      numberOfAliveNeighbours++;




      return numberOfAliveNeighbours;


      private boolean cellHasCorrectAmountOfNeighboursToSurvive(int numberOfAliveNeighbours)

      private Set<Cell> getCellsThatAreBornFromTick()
      Set<Cell> deadNeighbouringCells = getGamesDeadNeighbouringCells();

      Set<Cell> cellsToBeBorn = new HashSet<>();

      for (Cell cell : deadNeighbouringCells)
      if (cellCanBeBorn(cell))
      cellsToBeBorn.add(cell);



      return cellsToBeBorn;


      private Set<Cell> getGamesDeadNeighbouringCells()
      Set<Cell> deadNeighbouringCells = new HashSet<>();

      for (Cell cell : cells)
      deadNeighbouringCells.addAll(getCellsDeadNeighbouringCells(cell));


      return deadNeighbouringCells;


      private Set<Cell> getCellsDeadNeighbouringCells(Cell cell)
      Set<Cell> deadNeighbouringCells = new HashSet<>();

      for (int x = (cell.x - 1); x <= (cell.x + 1); x++)
      for (int y = (cell.y - 1); y <= (cell.y + 1); y++)
      Cell neighbouringCells = new Cell(x, y);

      if (cell.equals(neighbouringCells))
      continue;


      if (!hasAliveCellAt(neighbouringCells))
      deadNeighbouringCells.add(neighbouringCells);




      return deadNeighbouringCells;


      private boolean cellCanBeBorn(Cell cell)
      int numberOfAliveNeighbours = getNumberOfAliveNeighbours(cell);

      return cellHasCorrectAmountOfNeighboursToBeBorn(numberOfAliveNeighbours);


      private boolean cellHasCorrectAmountOfNeighboursToBeBorn(int numberOfAliveNeighbours)
      return (numberOfAliveNeighbours == 3);




      The Cell Class:



      package com.company;

      import java.util.Objects;

      public class Cell
      public final int x;
      public final int y;

      public Cell(int x, int y)
      this.x = x;
      this.y = y;


      @Override
      public boolean equals(Object o)

      @Override
      public int hashCode()
      return Objects.hash(x, y);










      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 25 at 19:45









      200_success

      123k14142399




      123k14142399









      asked Feb 25 at 13:22









      tbre

      162




      162




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          -1
          down vote













          In equals a cast to Cellis required. Before doing the cast, the type of the argument needs to be checked by the instanceof Operator to avoid a ClassCastException. As instanceof returns false if the first oerand is null the check can be simplfied:



          @Override public boolean equals(Object o) 
          if (this == o) return true;
          if (!(o instanceof Cell)) return false;
          Cell cell = (Cell) o;
          return ((x == cell.x) && (y == cell.y));






          share|improve this answer



















          • 1




            Did you mean if (not o instanceof Cell) return false;?
            – Solomon Ucko
            Feb 25 at 23:06










          • His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
            – Imus
            Feb 26 at 8:00






          • 1




            Don't you need the not?
            – Solomon Ucko
            Feb 26 at 13:01










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188319%2fjava-based-game-of-life%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          -1
          down vote













          In equals a cast to Cellis required. Before doing the cast, the type of the argument needs to be checked by the instanceof Operator to avoid a ClassCastException. As instanceof returns false if the first oerand is null the check can be simplfied:



          @Override public boolean equals(Object o) 
          if (this == o) return true;
          if (!(o instanceof Cell)) return false;
          Cell cell = (Cell) o;
          return ((x == cell.x) && (y == cell.y));






          share|improve this answer



















          • 1




            Did you mean if (not o instanceof Cell) return false;?
            – Solomon Ucko
            Feb 25 at 23:06










          • His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
            – Imus
            Feb 26 at 8:00






          • 1




            Don't you need the not?
            – Solomon Ucko
            Feb 26 at 13:01














          up vote
          -1
          down vote













          In equals a cast to Cellis required. Before doing the cast, the type of the argument needs to be checked by the instanceof Operator to avoid a ClassCastException. As instanceof returns false if the first oerand is null the check can be simplfied:



          @Override public boolean equals(Object o) 
          if (this == o) return true;
          if (!(o instanceof Cell)) return false;
          Cell cell = (Cell) o;
          return ((x == cell.x) && (y == cell.y));






          share|improve this answer



















          • 1




            Did you mean if (not o instanceof Cell) return false;?
            – Solomon Ucko
            Feb 25 at 23:06










          • His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
            – Imus
            Feb 26 at 8:00






          • 1




            Don't you need the not?
            – Solomon Ucko
            Feb 26 at 13:01












          up vote
          -1
          down vote










          up vote
          -1
          down vote









          In equals a cast to Cellis required. Before doing the cast, the type of the argument needs to be checked by the instanceof Operator to avoid a ClassCastException. As instanceof returns false if the first oerand is null the check can be simplfied:



          @Override public boolean equals(Object o) 
          if (this == o) return true;
          if (!(o instanceof Cell)) return false;
          Cell cell = (Cell) o;
          return ((x == cell.x) && (y == cell.y));






          share|improve this answer















          In equals a cast to Cellis required. Before doing the cast, the type of the argument needs to be checked by the instanceof Operator to avoid a ClassCastException. As instanceof returns false if the first oerand is null the check can be simplfied:



          @Override public boolean equals(Object o) 
          if (this == o) return true;
          if (!(o instanceof Cell)) return false;
          Cell cell = (Cell) o;
          return ((x == cell.x) && (y == cell.y));







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Feb 26 at 13:16


























          answered Feb 25 at 20:27









          milbrandt

          34715




          34715







          • 1




            Did you mean if (not o instanceof Cell) return false;?
            – Solomon Ucko
            Feb 25 at 23:06










          • His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
            – Imus
            Feb 26 at 8:00






          • 1




            Don't you need the not?
            – Solomon Ucko
            Feb 26 at 13:01












          • 1




            Did you mean if (not o instanceof Cell) return false;?
            – Solomon Ucko
            Feb 25 at 23:06










          • His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
            – Imus
            Feb 26 at 8:00






          • 1




            Don't you need the not?
            – Solomon Ucko
            Feb 26 at 13:01







          1




          1




          Did you mean if (not o instanceof Cell) return false;?
          – Solomon Ucko
          Feb 25 at 23:06




          Did you mean if (not o instanceof Cell) return false;?
          – Solomon Ucko
          Feb 25 at 23:06












          His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
          – Imus
          Feb 26 at 8:00




          His current implementation is better in case Cell can also have subclasses that don't really need to override the equals method. Seeing that it's also the only method where he's not using after the if statement I'm assuming he let his IDE generate the equals (and hashcode) which is often a better idea than to try to implement it yourself.
          – Imus
          Feb 26 at 8:00




          1




          1




          Don't you need the not?
          – Solomon Ucko
          Feb 26 at 13:01




          Don't you need the not?
          – Solomon Ucko
          Feb 26 at 13:01












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188319%2fjava-based-game-of-life%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation