Veamos cómo diseñar un juego de serpiente básico que proporcione las siguientes funcionalidades:
• La serpiente puede moverse en una dirección determinada y cuando se come la comida, la longitud de la serpiente aumenta.
• Cuando la serpiente se cruce, el juego terminará.
• La comida se generará en un intervalo dado.
Preguntado en : Amazon, Microsoft y muchas más entrevistas
Esta pregunta se hace en entrevistas para juzgar la habilidad de diseño orientado a objetos de un candidato. Entonces, antes que nada, debemos pensar en las clases.
Las clases principales serán:
1. Serpiente
2. Célula
3. Tablero
4. Juego
La clase Juego representa el cuerpo de nuestro programa. Almacena información sobre la serpiente y el tablero.
La clase Cell representa el único punto de visualización/tablero. Contiene el número de fila, el número de columna y la información al respecto, es decir, está vacío o tiene comida o es parte del cuerpo de una serpiente.
Java
// To represent a cell of display board. public class Cell { private final int row, col; private CellType cellType; public Cell(int row, int col) { this.row = row; this.col = col; } public CellType getCellType() { return cellType; } public void setCellType(CellType cellType) { this.cellType = cellType; } public int getRow() { return row; } public int getCol() { return col; } }
Java
// Enum for different cell types public enum CellType { EMPTY, FOOD, SNAKE_NODE; }
Ahora, la clase Snake, que contiene el cuerpo y la cabeza.
Hemos usado Lista enlazada para almacenar el cuerpo porque podemos agregar una celda en O(1).
El método de crecimiento se llamará cuando coma la comida. Otros métodos se explican por sí mismos.
Java
// To represent a snake import java.util.LinkedList; public class Snake { private LinkedList<Cell> snakePartList = new LinkedList<>(); private Cell head; public Snake(Cell initPos) { head = initPos; snakePartList.add(head); head.setCellType(CellType.SNAKE_NODE); } public void grow() { snakePartList.add(head); } public void move(Cell nextCell) { System.out.println("Snake is moving to " + nextCell.getRow() + " " + nextCell.getCol()); Cell tail = snakePartList.removeLast(); tail.setCellType(CellType.EMPTY); head = nextCell; head.setCellType(CellType.SNAKE_NODE); snakePartList.addFirst(head); } public boolean checkCrash(Cell nextCell) { System.out.println("Going to check for Crash"); for (Cell cell : snakePartList) { if (cell == nextCell) { return true; } } return false; } public LinkedList<Cell> getSnakePartList() { return snakePartList; } public void setSnakePartList(LinkedList<Cell> snakePartList) { this.snakePartList = snakePartList; } public Cell getHead() { return head; } public void setHead(Cell head) { this.head = head; } }
Java
public class Board { final int ROW_COUNT, COL_COUNT; private Cell[][] cells; public Board(int rowCount, int columnCount) { ROW_COUNT = rowCount; COL_COUNT = columnCount; cells = new Cell[ROW_COUNT][COL_COUNT]; for (int row = 0; row < ROW_COUNT; row++) { for (int column = 0; column < COL_COUNT; column++) { cells[row][column] = new Cell(row, column); } } } public Cell[][] getCells() { return cells; } public void setCells(Cell[][] cells) { this.cells = cells; } public void generateFood() { System.out.println("Going to generate food"); while(true){ int row = (int)(Math.random() * ROW_COUNT); int column = (int)(Math.random() * COL_COUNT); if(cells[row][column].getCellType()!=CellType.SNAKE_NODE) break; } cells[row][column].setCellType(CellType.FOOD); System.out.println("Food is generated at: " + row + " " + column); } }
Java
// To represent Snake Game public class Game { public static final int DIRECTION_NONE = 0, DIRECTION_RIGHT = 1, DIRECTION_LEFT = -1, DIRECTION_UP = 2, DIRECTION_DOWN = -2; private Snake snake; private Board board; private int direction; private boolean gameOver; public Game(Snake snake, Board board) { this.snake = snake; this.board = board; } public Snake getSnake() { return snake; } public void setSnake(Snake snake) { this.snake = snake; } public Board getBoard() { return board; } public void setBoard(Board board) { this.board = board; } public boolean isGameOver() { return gameOver; } public void setGameOver(boolean gameOver) { this.gameOver = gameOver; } public int getDirection() { return direction; } public void setDirection(int direction) { this.direction = direction; } // We need to update the game at regular intervals, // and accept user input from the Keyboard. public void update() { System.out.println("Going to update the game"); if (!gameOver) { if (direction != DIRECTION_NONE) { Cell nextCell = getNextCell(snake.getHead()); if (snake.checkCrash(nextCell)) { setDirection(DIRECTION_NONE); gameOver = true; } else { snake.move(nextCell); if (nextCell.getCellType() == CellType.FOOD) { snake.grow(); board.generateFood(); } } } } } private Cell getNextCell(Cell currentPosition) { System.out.println("Going to find next cell"); int row = currentPosition.getRow(); int col = currentPosition.getCol(); if (direction == DIRECTION_RIGHT) { col++; } else if (direction == DIRECTION_LEFT) { col--; } else if (direction == DIRECTION_UP) { row--; } else if (direction == DIRECTION_DOWN) { row++; } Cell nextCell = board.getCells()[row][col]; return nextCell; } public static void main(String[] args) { System.out.println("Going to start game"); Cell initPos = new Cell(0, 0); Snake initSnake = new Snake(initPos); Board board = new Board(10, 10); Game newGame = new Game(initSnake, board); newGame.gameOver = false; newGame.direction = DIRECTION_RIGHT; // We need to update the game at regular intervals, // and accept user input from the Keyboard. // here I have just called the different methods // to show the functionality for (int i = 0; i < 5; i++) { if (i == 2) newGame.board.generateFood(); newGame.update(); if (i == 3) newGame.direction = DIRECTION_RIGHT; if (newGame.gameOver == true) break; } } }
Publicación traducida automáticamente
Artículo escrito por shashipk11 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA