Существует лабиринт со стенами разного цвета, и игрок может пройти только через стену того же цвета, что и «он сам». Мне нужен BFS, чтобы найти кратчайший маршрут. Этот метод работает, однако он приводит к ошибке: если есть две стены одинакового цвета в одном направлении, игрок перемещается 4 раза без обновления допустимого цвета (labyrinthPlayer.updateNextWallColor()) вместо перемещения 2 раза (как только внутри стены , затем в пустое поле за стеной).
Вот полное описание проблемы:
Наша задача заключается в перемещении по лабиринту, показанному на картинке. Чтобы войти
в лабиринт, вы должны пройти через красную стену, отмеченную нижней
стрелкой, а чтобы выйти, вы должны пройти через синюю стену, отмеченную
верхней стрелкой. На каждом этапе вы можете перейти к соседней ячейке, только
пройдя через стену указанного цвета. Вначале вы должны пройти
через красную стену. Пройдя через красную стену, вы можете пройти
через белую стену. Пройдя через белую стену, вы можете пройти
через синюю стену, а пройдя через синюю стену, вы должны
снова пройти через красную стену.
Изображение, упомянутое выше
Класс LabyrinthPlayer:
import java.util.Objects;
/**
* Represents the player, and its requirement to cycle legal colors
*/
public class LabyrinthPlayer implements Cloneable {
/**
* Represents the 3 possible wall colors
*/
public enum WallColor {
RED, WHITE, BLUE
}
private WallColor nextWallColor;
/**
* Creates a {@code LabyrinthPlayer} object with the starting legal color as RED.
*/
public LabyrinthPlayer() {
this(WallColor.RED);
}
/**
* Creates a {@code LabyrinthPlayer} object with the given legal wall color.
*/
public LabyrinthPlayer(WallColor nextWallColor) {
this.nextWallColor = nextWallColor;
}
/**
* Cycles the legal color and stores it in nextWallColor
*/
public void updateNextWallColor() {
switch (nextWallColor) {
case RED:
nextWallColor = WallColor.WHITE;
break;
case WHITE:
nextWallColor = WallColor.BLUE;
break;
case BLUE:
nextWallColor = WallColor.RED;
break;
}
}
public WallColor getNextWallColor() {
return nextWallColor;
}
@Override
public LabyrinthPlayer clone() {
try {
return (LabyrinthPlayer) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LabyrinthPlayer that = (LabyrinthPlayer) o;
return nextWallColor == that.nextWallColor;
}
@Override
public int hashCode() {
return Objects.hash(nextWallColor);
}
@Override
public String toString() {
return String.format("LabyrinthPlayer[nextLegalWallColor: %s]" ,getNextWallColor()) ;
}
}
Класс LabyrinthState:
import javafx.geometry.Pos;
import puzzle.State;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
/**
* Represents the states of the labyrinth.
*/
public class LabyrinthState implements State {
/**
* Represents the labyrinth itself.
* X means non-traversable field
* F stands for Black, also a non-traversable field
* P is Red, W is white, K is Blue
* ' ' means empty, traversable field
*/
public static final char[][] BOARD = {
{' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' '},
{' ', 'X', 'F', 'X', 'F', 'X', 'K', 'X', 'F', 'X', ' '},
{' ', 'F', ' ', 'P', ' ', 'P', ' ', 'W', ' ', 'F', ' '},
{' ', 'X', 'K', 'X', 'W', 'X', 'K', 'X', 'P', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'P', ' ', 'K', ' ', 'F', ' '},
{' ', 'X', 'W', 'X', 'K', 'X', 'W', 'X', 'P', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'P', ' ', 'K', ' ', 'F', ' '},
{' ', 'X', 'P', 'X', 'W', 'X', 'K', 'X', 'W', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'K', ' ', 'P', ' ', 'F', ' '},
{' ', 'X', 'F', 'X', 'P', 'X', 'F', 'X', 'F', 'X', ' '},
{' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' '}
};
/**
* The size of the game board.
*/
public static final int BOARD_SIZE = 11;
private LabyrinthPlayer labyrinthPlayer;
public static final Position STARTPOS = new Position(10, 4);
public static final Position ENDPOS = new Position(0, 6);
private Position playerPosition;
/**
* Creates a {@code LabyrinthState} object that represents the initial
* state of the puzzle specified in the assignment.
*/
public LabyrinthState() {
this(new LabyrinthPlayer(LabyrinthPlayer.WallColor.RED), new Position(STARTPOS.row(), STARTPOS.col()));
}
/**
* Creates a {@code LabyrinthState} object with the player legal color and
* position specified.
*
* @param labyrinthPlayer represents the legal color of the player
* @param playerPosition the position of the player on the game board
*/
public LabyrinthState(LabyrinthPlayer labyrinthPlayer, Position playerPosition) {
checkPosition(playerPosition);
this.labyrinthPlayer = labyrinthPlayer.clone();
this.playerPosition = playerPosition;
}
private void checkPosition(Position playerPosition) {
if (!isOnBoard(playerPosition)) {
throw new IllegalArgumentException();
}
}
/**
* A copy is returned that does not allow the
* outside world to change the internal state of the object.
*
* @return a copy of the player
*/
public LabyrinthPlayer getLabyrinthPlayer() {
return labyrinthPlayer.clone();
}
/**
* @return the position of the player
*/
public Position getPlayerPosition() {
return playerPosition;
}
/**
* Updates the player's position to the given position
*
* @param playerPosition the given position
*/
public void setPlayerPosition(final Position playerPosition) {
this.playerPosition = playerPosition;
}
/**
* @param position the given position
* @return whether the given position is on the board
*/
private boolean isOnBoard(final Position position) {
return position.row() >= 0 && position.row() < BOARD_SIZE
&& position.col() >= 0 && position.col() < BOARD_SIZE;
}
/**
*
* @return whether the labyrinth is solved
*/
public boolean isSolved() {
return getPlayerPosition().equals(ENDPOS);
}
/**
*
* @param position the given current position of the player
* @return whether the position the player intends to move to is matching the legal color of the player
*/
private boolean isMatching(final Position position) {
if (!isOnBoard(position)) {
return false;
}
var state = BOARD[position.row()][position.col()];
if(state == 'P' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.RED)) {
return true;
} else if (state == 'W' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.WHITE)) {
return true;
} else if (state == 'K' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.BLUE)) {
return true;
} else if (state == ' ') {
return true;
} else return false;
}
/**
* Moves the player in the given direction, and sets its new position
* @param direction the specified direction in which the player is moved
*/
private void movePlayer(final Direction direction) {
Position currentPosition = getPlayerPosition();
while (true) {
Position tempPosition = currentPosition.move(direction);
Position newPosition = tempPosition.move(direction);
if (isMatching(tempPosition)){
currentPosition = newPosition;
} else {
break;
}
}
labyrinthPlayer.updateNextWallColor();
setPlayerPosition(currentPosition);
}
/**
* @param direction the direction in which the player is moved
* @return whether it is possible to move the player in the given direction
*/
@Override
public boolean isLegalMove(Direction direction) {
return isMatching(getPlayerPosition().move(direction)) && isOnBoard(getPlayerPosition().move(direction));
}
/**
* Calls upon the movePlayer method to actually commit the movement
* @see #movePlayer(Direction)
* @param move the direction in which the player is moved
*/
@Override
public void makeMove(final Direction move) {
switch (move) {
case UP:
if (isLegalMove(Direction.UP)) {
movePlayer(Direction.UP);
}
break;
case RIGHT:
if (isLegalMove(Direction.RIGHT)) {
movePlayer(Direction.RIGHT);
}
break;
case DOWN:
if (isLegalMove(Direction.DOWN)) {
movePlayer(Direction.DOWN);
}
break;
case LEFT:
if (isLegalMove(Direction.LEFT)) {
movePlayer(Direction.LEFT);
}
break;
default:
System.out.println("Invalid move");
break;
}
}
/**
* @return the set of all moves that can be made in the current state
*/
public Set getLegalMoves() {
var legalMoves = EnumSet.noneOf(Direction.class);
for (var direction : Direction.values()) {
if (isLegalMove(direction)) {
legalMoves.add(direction);
}
}
return legalMoves;
}
@Override
public LabyrinthState clone() {
try {
LabyrinthState copy = (LabyrinthState) super.clone();
return copy;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
@Override
public int hashCode() {
return Objects.hash(playerPosition);
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LabyrinthState that = (LabyrinthState) o;
return playerPosition.equals(that.playerPosition);
}
@Override
public String toString() {
return String.format("LabyrinthState[playerPosition=%s, legal moves=%s]",playerPosition, getLegalMoves());
}
};
Класс позиции:
/**
* Represents a Two-Dimensional position.
*/
public record Position(int row, int col) {
/**
* Moves this position by the coordinate changes specified by the given direction.
*
* @param direction a direction that specifies a change in the coordinates
* @return a new position whose vertical and horizontal distances from this
* position are equal to the coordinate changes of the given direction
*/
public Position move(Direction direction) {
return new Position(row + direction.getRowChange(), col + direction.getColChange());
}
@Override
public String toString() {
return String.format("(%d,%d)", row, col);
}
}
Класс направления:
package labyrinth.model;
/**
* Represents the four main directions.
*/
public enum Direction {
UP(-1, 0),
RIGHT(0, 1),
DOWN(1, 0),
LEFT(0, -1);
private final int rowChange;
private final int colChange;
Direction(int rowChange, int colChange) {
this.rowChange = rowChange;
this.colChange = colChange;
}
/**
* @return the change in the row coordinate when moving to the direction
*/
public int getRowChange() {
return rowChange;
}
/**
* @return the change in the column coordinate when moving to the
* direction
*/
public int getColChange() {
return colChange;
}
/**
* @return the direction that corresponds to the coordinate changes
* specified
*
* @param rowChange the change in the row's coordinate
* @param colChange the change in the column's coordinate
*/
public static Direction of(int rowChange, int colChange) {
for (var direction : values()) {
if (direction.rowChange == rowChange && direction.colChange == colChange) {
return direction;
}
}
throw new IllegalArgumentException();
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... eem-to-fix
Моя функция Java для перемещения игрока вызывает ошибку, которую я не могу исправить. ⇐ JAVA
Программисты JAVA общаются здесь
1719084493
Anonymous
Существует лабиринт со стенами разного цвета, и игрок может пройти только через стену того же цвета, что и «он сам». Мне нужен BFS, чтобы найти кратчайший маршрут. Этот метод работает, однако он приводит к ошибке: если есть две стены одинакового цвета в одном направлении, игрок перемещается 4 раза без обновления допустимого цвета (labyrinthPlayer.updateNextWallColor()) вместо перемещения 2 раза (как только внутри стены , затем в пустое поле за стеной).
Вот полное описание проблемы:
Наша задача заключается в перемещении по лабиринту, показанному на картинке. Чтобы войти
в лабиринт, вы должны пройти через красную стену, отмеченную нижней
стрелкой, а чтобы выйти, вы должны пройти через синюю стену, отмеченную
верхней стрелкой. На каждом этапе вы можете перейти к соседней ячейке, только
пройдя через стену указанного цвета. Вначале вы должны пройти
через красную стену. Пройдя через красную стену, вы можете пройти
через белую стену. Пройдя через белую стену, вы можете пройти
через синюю стену, а пройдя через синюю стену, вы должны
снова пройти через красную стену.
Изображение, упомянутое выше
Класс LabyrinthPlayer:
import java.util.Objects;
/**
* Represents the player, and its requirement to cycle legal colors
*/
public class LabyrinthPlayer implements Cloneable {
/**
* Represents the 3 possible wall colors
*/
public enum WallColor {
RED, WHITE, BLUE
}
private WallColor nextWallColor;
/**
* Creates a {@code LabyrinthPlayer} object with the starting legal color as RED.
*/
public LabyrinthPlayer() {
this(WallColor.RED);
}
/**
* Creates a {@code LabyrinthPlayer} object with the given legal wall color.
*/
public LabyrinthPlayer(WallColor nextWallColor) {
this.nextWallColor = nextWallColor;
}
/**
* Cycles the legal color and stores it in nextWallColor
*/
public void updateNextWallColor() {
switch (nextWallColor) {
case RED:
nextWallColor = WallColor.WHITE;
break;
case WHITE:
nextWallColor = WallColor.BLUE;
break;
case BLUE:
nextWallColor = WallColor.RED;
break;
}
}
public WallColor getNextWallColor() {
return nextWallColor;
}
@Override
public LabyrinthPlayer clone() {
try {
return (LabyrinthPlayer) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LabyrinthPlayer that = (LabyrinthPlayer) o;
return nextWallColor == that.nextWallColor;
}
@Override
public int hashCode() {
return Objects.hash(nextWallColor);
}
@Override
public String toString() {
return String.format("LabyrinthPlayer[nextLegalWallColor: %s]" ,getNextWallColor()) ;
}
}
Класс LabyrinthState:
import javafx.geometry.Pos;
import puzzle.State;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
/**
* Represents the states of the labyrinth.
*/
public class LabyrinthState implements State {
/**
* Represents the labyrinth itself.
* X means non-traversable field
* F stands for Black, also a non-traversable field
* P is Red, W is white, K is Blue
* ' ' means empty, traversable field
*/
public static final char[][] BOARD = {
{' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' '},
{' ', 'X', 'F', 'X', 'F', 'X', 'K', 'X', 'F', 'X', ' '},
{' ', 'F', ' ', 'P', ' ', 'P', ' ', 'W', ' ', 'F', ' '},
{' ', 'X', 'K', 'X', 'W', 'X', 'K', 'X', 'P', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'P', ' ', 'K', ' ', 'F', ' '},
{' ', 'X', 'W', 'X', 'K', 'X', 'W', 'X', 'P', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'P', ' ', 'K', ' ', 'F', ' '},
{' ', 'X', 'P', 'X', 'W', 'X', 'K', 'X', 'W', 'X', ' '},
{' ', 'F', ' ', 'K', ' ', 'K', ' ', 'P', ' ', 'F', ' '},
{' ', 'X', 'F', 'X', 'P', 'X', 'F', 'X', 'F', 'X', ' '},
{' ', ' ', ' ', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' '}
};
/**
* The size of the game board.
*/
public static final int BOARD_SIZE = 11;
private LabyrinthPlayer labyrinthPlayer;
public static final Position STARTPOS = new Position(10, 4);
public static final Position ENDPOS = new Position(0, 6);
private Position playerPosition;
/**
* Creates a {@code LabyrinthState} object that represents the initial
* state of the puzzle specified in the assignment.
*/
public LabyrinthState() {
this(new LabyrinthPlayer(LabyrinthPlayer.WallColor.RED), new Position(STARTPOS.row(), STARTPOS.col()));
}
/**
* Creates a {@code LabyrinthState} object with the player legal color and
* position specified.
*
* @param labyrinthPlayer represents the legal color of the player
* @param playerPosition the position of the player on the game board
*/
public LabyrinthState(LabyrinthPlayer labyrinthPlayer, Position playerPosition) {
checkPosition(playerPosition);
this.labyrinthPlayer = labyrinthPlayer.clone();
this.playerPosition = playerPosition;
}
private void checkPosition(Position playerPosition) {
if (!isOnBoard(playerPosition)) {
throw new IllegalArgumentException();
}
}
/**
* A copy is returned that does not allow the
* outside world to change the internal state of the object.
*
* @return a copy of the player
*/
public LabyrinthPlayer getLabyrinthPlayer() {
return labyrinthPlayer.clone();
}
/**
* @return the position of the player
*/
public Position getPlayerPosition() {
return playerPosition;
}
/**
* Updates the player's position to the given position
*
* @param playerPosition the given position
*/
public void setPlayerPosition(final Position playerPosition) {
this.playerPosition = playerPosition;
}
/**
* @param position the given position
* @return whether the given position is on the board
*/
private boolean isOnBoard(final Position position) {
return position.row() >= 0 && position.row() < BOARD_SIZE
&& position.col() >= 0 && position.col() < BOARD_SIZE;
}
/**
*
* @return whether the labyrinth is solved
*/
public boolean isSolved() {
return getPlayerPosition().equals(ENDPOS);
}
/**
*
* @param position the given current position of the player
* @return whether the position the player intends to move to is matching the legal color of the player
*/
private boolean isMatching(final Position position) {
if (!isOnBoard(position)) {
return false;
}
var state = BOARD[position.row()][position.col()];
if(state == 'P' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.RED)) {
return true;
} else if (state == 'W' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.WHITE)) {
return true;
} else if (state == 'K' && labyrinthPlayer.getNextWallColor().equals(LabyrinthPlayer.WallColor.BLUE)) {
return true;
} else if (state == ' ') {
return true;
} else return false;
}
/**
* Moves the player in the given direction, and sets its new position
* @param direction the specified direction in which the player is moved
*/
private void movePlayer(final Direction direction) {
Position currentPosition = getPlayerPosition();
while (true) {
Position tempPosition = currentPosition.move(direction);
Position newPosition = tempPosition.move(direction);
if (isMatching(tempPosition)){
currentPosition = newPosition;
} else {
break;
}
}
labyrinthPlayer.updateNextWallColor();
setPlayerPosition(currentPosition);
}
/**
* @param direction the direction in which the player is moved
* @return whether it is possible to move the player in the given direction
*/
@Override
public boolean isLegalMove(Direction direction) {
return isMatching(getPlayerPosition().move(direction)) && isOnBoard(getPlayerPosition().move(direction));
}
/**
* Calls upon the movePlayer method to actually commit the movement
* @see #movePlayer(Direction)
* @param move the direction in which the player is moved
*/
@Override
public void makeMove(final Direction move) {
switch (move) {
case UP:
if (isLegalMove(Direction.UP)) {
movePlayer(Direction.UP);
}
break;
case RIGHT:
if (isLegalMove(Direction.RIGHT)) {
movePlayer(Direction.RIGHT);
}
break;
case DOWN:
if (isLegalMove(Direction.DOWN)) {
movePlayer(Direction.DOWN);
}
break;
case LEFT:
if (isLegalMove(Direction.LEFT)) {
movePlayer(Direction.LEFT);
}
break;
default:
System.out.println("Invalid move");
break;
}
}
/**
* @return the set of all moves that can be made in the current state
*/
public Set getLegalMoves() {
var legalMoves = EnumSet.noneOf(Direction.class);
for (var direction : Direction.values()) {
if (isLegalMove(direction)) {
legalMoves.add(direction);
}
}
return legalMoves;
}
@Override
public LabyrinthState clone() {
try {
LabyrinthState copy = (LabyrinthState) super.clone();
return copy;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
@Override
public int hashCode() {
return Objects.hash(playerPosition);
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LabyrinthState that = (LabyrinthState) o;
return playerPosition.equals(that.playerPosition);
}
@Override
public String toString() {
return String.format("LabyrinthState[playerPosition=%s, legal moves=%s]",playerPosition, getLegalMoves());
}
};
Класс позиции:
/**
* Represents a Two-Dimensional position.
*/
public record Position(int row, int col) {
/**
* Moves this position by the coordinate changes specified by the given direction.
*
* @param direction a direction that specifies a change in the coordinates
* @return a new position whose vertical and horizontal distances from this
* position are equal to the coordinate changes of the given direction
*/
public Position move(Direction direction) {
return new Position(row + direction.getRowChange(), col + direction.getColChange());
}
@Override
public String toString() {
return String.format("(%d,%d)", row, col);
}
}
Класс направления:
package labyrinth.model;
/**
* Represents the four main directions.
*/
public enum Direction {
UP(-1, 0),
RIGHT(0, 1),
DOWN(1, 0),
LEFT(0, -1);
private final int rowChange;
private final int colChange;
Direction(int rowChange, int colChange) {
this.rowChange = rowChange;
this.colChange = colChange;
}
/**
* @return the change in the row coordinate when moving to the direction
*/
public int getRowChange() {
return rowChange;
}
/**
* @return the change in the column coordinate when moving to the
* direction
*/
public int getColChange() {
return colChange;
}
/**
* @return the direction that corresponds to the coordinate changes
* specified
*
* @param rowChange the change in the row's coordinate
* @param colChange the change in the column's coordinate
*/
public static Direction of(int rowChange, int colChange) {
for (var direction : values()) {
if (direction.rowChange == rowChange && direction.colChange == colChange) {
return direction;
}
}
throw new IllegalArgumentException();
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78656813/my-java-function-to-move-the-player-produces-a-bug-i-cant-seem-to-fix[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия