Игры на Java-основе жизни


Я недавно в программировании Конвея Игра жизни моделирования в Java, и я был интересно, если кто мог бы представить некоторую информацию о том, как это может быть улучшено. Я в основном озабочены тем, как улучшить "чистоту" и читаемости кода, а не его алгоритмическую сложность. Это моя первая попытка с использованием Java (хотя я пользовалась другими языками ООП) так что если я не использую каких-либо очевидных функциональность в Java, пожалуйста, дайте мне знать!

В Game Класс:

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) {
        return (numberOfAliveNeighbours == 2) || (numberOfAliveNeighbours == 3);
    }

    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);
    }
}

В Cell Класс:

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) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cell cell = (Cell) o;
        return ((x == cell.x) && (y == cell.y));
    }

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


196
3
задан 25 февраля 2018 в 01:02 Источник Поделиться
Комментарии
1 ответ

В equals бросок к Cellтребуется. Перед тем, как делать бросок, тип аргумента должен быть проверен instanceof оператору избежать ClassCastException. Как instanceof возвращает false если первый oerand это null проверка может быть упрощенной:

@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));
}

-1
ответ дан 25 февраля 2018 в 08:02 Источник Поделиться