将ASCII地图字符串转二维int数组及K角色移动逻辑实现求助
问题:ASCII地图转二维int数组及角色移动逻辑实现
需求说明
需要将给定的ASCII地图字符串转换为二维int数组,按规则为每个字符分配ID:K=1、P=2、*=3、D=4,同时实现角色K的朝向管理与移动逻辑——初始朝向向上,仅当朝向方向无障碍物(*)时才可移动。
原始地图字符串
String samplemap = "-------------------\n" + "|K * P * D|\n" + "| * * |\n" + "| * ****** |\n" + "| * |\n" + "-------------------";
已实现部分
- 地图行列数计算:
int maxRow = samplemap.split("\n").length - 2; int maxCol = samplemap.split("\n")[0].length() - 2;
- 识别
*并设置障碍物的逻辑及输出:
//Find "*" in the samplemap to pass to the constructor in floor class // * - wall - 4(注:此处ID与需求不符,需修正为3) for(int i = 1; i < maxRow; i++) { for(int j = 1; j < maxCol; j++) { if(samplemap.split("\n")[i].charAt(j) == '*') { floorMap.setWallLocation(i, j); } } }
输出:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 4 4 4 4 4 4 0 0
解决方案
1. 优化地图解析逻辑
避免重复调用split("\n")(每次调用都会生成新数组,影响性能),先将所有行存入数组复用,同时一次性解析所有字符并设置对应ID:
String[] mapLines = samplemap.split("\n"); int maxRow = mapLines.length - 2; int maxCol = mapLines[0].length() - 2; FloorMap floorMap = new FloorMap(maxRow, maxCol); // 初始化全0二维数组 Player player = null; // 用于存储K角色实例 // 遍历地图内容行(跳过首尾横线) for (int lineIdx = 1; lineIdx <= maxRow; lineIdx++) { String currentLine = mapLines[lineIdx]; // 遍历当前行字符(跳过首尾|) for (int charIdx = 1; charIdx <= maxCol; charIdx++) { char c = currentLine.charAt(charIdx); // 转换为二维数组坐标:行=lineIdx-1,列=charIdx-1 int row = lineIdx - 1; int col = charIdx - 1; switch(c) { case 'K': floorMap.setCellValue(row, col, 1); player = new Player(row, col); // 创建K角色实例 break; case 'P': floorMap.setCellValue(row, col, 2); break; case '*': floorMap.setCellValue(row, col, 3); // 修正ID为3 break; case 'D': floorMap.setCellValue(row, col, 4); break; // 空格保持0,无需处理 } } }
2. 实现K角色的朝向与移动逻辑
定义朝向枚举管理角色方向,添加转向、移动判断方法:
// 朝向枚举 enum Direction { UP, RIGHT, DOWN, LEFT } // K角色类 class Player { int x; // 行坐标 int y; // 列坐标 Direction facing; // 当前朝向 public Player(int x, int y) { this.x = x; this.y = y; this.facing = Direction.UP; // 初始朝向向上 } // 右转切换朝向 public void turnRight() { switch(facing) { case UP: facing = Direction.RIGHT; break; case RIGHT: facing = Direction.DOWN; break; case DOWN: facing = Direction.LEFT; break; case LEFT: facing = Direction.UP; break; } } // 尝试移动:返回是否移动成功 public boolean tryMove(FloorMap floorMap) { int newX = x; int newY = y; // 根据朝向计算新坐标 switch(facing) { case UP: newX -= 1; break; case RIGHT: newY += 1; break; case DOWN: newX += 1; break; case LEFT: newY -= 1; break; } // 检查新坐标是否在地图范围内,且不是障碍物(ID=3) if (newX >= 0 && newX < floorMap.getMaxRow() && newY >= 0 && newY < floorMap.getMaxCol() && floorMap.getCellValue(newX, newY) != 3) { // 更新坐标 x = newX; y = newY; // 同步更新地图中的角色位置(若需要) floorMap.updatePlayerLocation(x, y); return true; } return false; // 移动失败 } }
3. 关键注意事项
- 坐标转换一致性:确保字符串索引与二维数组坐标的转换逻辑和你预期的坐标(如
K(0,4))匹配,可根据实际需求调整row和col的计算方式。 - ID映射统一:全程保持
K=1、P=2、*=3、D=4的对应关系,避免混淆。 - 性能优化:一次性拆分地图字符串并复用行数组,避免循环中重复调用
split。
内容的提问来源于stack exchange,提问作者Mostin
相关产品推荐
相关产品推荐

