【问题标题】:Java - 2D Array Index Manipulation in a Complex ProgramJava - 复杂程序中的二维数组索引操作
【发布时间】:2015-10-03 23:10:49
【问题描述】:

在问我的问题之前,我想澄清一些事情。首先,我是 Java 和一般编程的新手。其次,这是我的第二个帖子,所以如果我做错了什么,请放轻松。最后,我想解释一下为什么我做错了,而不仅仅是在对这篇文章的任何回复中粘贴的解决方案。为了更好地理解这个问题,我将编写分配信息,然后是给出的 Driver 类,然后是 Driver 类访问的类代码。

我的问题:

如何使我的“建筑物”的左下角在我的二维数组上为 [0][0]? Here's 一个 for 循环的示例,用于将 2D 数组的左下角更改为 [0][0],但我尝试将其实现到我的 searchRoom 方法(其中玩家角色设置为 myHidingPlaces 索引),我不能让 myHidingPlaces[0][0] 成为我的二维数组的左下角。我相信我需要用 for 循环以某种方式编辑 toString 方法,但我不知道该怎么做。

以下是作业:

你要设计一个类“LostPuppy.java”,它代表一只小狗迷失在多层建筑中, 每层包含相同数量的房间。在此类对象的实例化(或创建)期间, 每个楼层的每个房间都将被初始化为空(您实际上将为此使用空格''字符 目的),并且将选择一个随机房间来放置小狗丢失的地方。为此,字符“P”将 被放置在这个随机位置。下面列出了有关构造函数的更多详细信息。

这个类的一个对象被用作两个玩家轮流寻找小狗的游戏,一个房间在一个 直到找到不幸的小犬。将执行此对象的实例化和搜索 通过提供给您的“驱动程序”程序,您只需专注于开发 类(驱动程序在“PuppyPlay.java”文件中)

字段(当然,所有字段都是私有的):

  • 名为 myHidingPlaces 的字符 (char) 数组。这表示行是楼层的建筑物 柱子是每一层的房间(这座建筑有一个不寻常的编号系统;楼层和 房间都从零开始)。

  • 两个整数将存放小狗丢失的地板和房间,名为 myFloorLocation 和 我的房间位置。

  • 一个名为 myWinner 的字符,当玩家找到小狗时,该字符将分配给玩家的角色 (驱动程序使用数字“1”和“2”来更清楚地区分玩家和小狗)。

  • 一个名为 myFound 的布尔值,在找到小狗时设置为 true。

构造函数:

  • 接收两个整数参数作为用户输入的建筑物的楼层数和房间数 小狗迷路了。

  • 构造函数将二维数组“myHidingPlaces”实例化为带有第一个参数的字符数组 用于行 (theFloors) 和第二个参数作为列 (theRooms)。

  • 初始化 myHidingPlaces 单元格,每个单元格都包含一个空格“”(用单引号完成)

  • 使用第一个参数随机设置 myFloorLocation(地板小狗开启)
  • 使用第二个参数随机设置 myRoomLocation(小狗所在的房间)
  • 将 myHidingPlaces[myFloorLocation][myRoomLocation] 设置为字符“P”
  • 将 myWinner 设置为单个空格
  • 将 myFound 设置为 false

方法:

  • roomSearchedAlready 接收要搜索的楼层和房间,如果房间有,则返回 true 已经被搜索过,否则为假。

  • puppyLocation 接收要搜索的楼层和房间,如果楼层和房间是则返回 true 小狗丢失的地方,否则为假。此方法不应更改任何字段。

  • indicesOK 接收要搜索的楼层和房间,如果楼层和房间的值是 在数组索引范围内,否则为 false(用于检查这些索引是否不会导致错误 应用于数组时)。

  • numberOfFloors 返回建筑物的楼层数(一楼从零开始)。

  • numberOfRooms 返回建筑物每层的房间数(第一个房间从 零且所有楼层的房间数相同)。

  • searchRoom 接收要搜索的楼层和房间以及当前玩家(作为字符类型) 如果找到小狗,则返回 true,否则返回 false。如果没有找到小狗 searchRoom 也 将接收到的楼层和房间位置的 myHidingPlaces 数组设置为接收到的玩家值(“1” 或“2”)或者,当找到时,将 myWinner 字段设置为当前玩家并将 myFound 设置为 true。

  • toString 显示当前的hidingPlaces 数组及其内容,除了小狗的位置 在找到他/她之前一直隐藏,此时(由驱动程序)将调用 toString 并且两者 找到小狗的玩家和一个“P”将显示在同一个单元格中……

  • 现在,也许是 toString 输出的尴尬部分。通常,在显示二维数组时, [0][0] 单元格与矩阵一样显示在左上角。然而,因为小狗 决定迷失在建筑物而不是矩阵中,拥有一楼会更具视觉意义 (第 0 行)显示在底部,在它上面的二楼……最后是顶层,嗯……在顶部!到 保存文字,请仔细查看下一页提供的示例运行。你的输出应该看起来 与在示例运行的下一页上看到的相同。

这里是驱动程序:

import java.util.Random;
import java.util.Scanner;

/**
 * This program is used as a driver program to play the game from the
 * class LostPuppy.  Not to be used for grading!
 *
 * A puppy is lost in a multi-floor building represented in the class 
 * LostPuppy.class.  Two players will take turns searching the building
 * by selecting a floor and a room where the puppy might be.
 *
 * @author David Schuessler
 * @version Spring 2015
 */

public class PuppyPlay
{
  /**
   * Driver program to play LostPuppy.
   *
   * @param theArgs may contain file names in an array of type String
   */
  public static void main(String[] theArgs)
  {
    Scanner s = new Scanner(System.in);
    LostPuppy game; 
    int totalFloors;
    int totalRooms;
    int floor;
    int room;
    char[] players = {'1', '2'};
    int playerIndex;
    boolean found = false;
    Random rand = new Random();

    do 
    {
      System.out.print("To find the puppy, we need to know:\n"
                       + "\tHow many floors are in the building\n"
                       + "\tHow many rooms are on the floors\n\n"
                       + "             Please enter the number of floors: ");
      totalFloors = s.nextInt();
      System.out.print("Please enter the number of rooms on the floors: ");
      totalRooms = s.nextInt();
      s.nextLine();    // Consume previous newline character    

      // Start the game: Create a LostPuppy object:
      game = new LostPuppy(totalFloors, totalRooms);

      // Pick starting player
      playerIndex = rand.nextInt(2);

      System.out.println("\nFloor and room numbers start at zero '0'");

      do 
      {

        do 
        {
          System.out.println("\nPlayer " + players[playerIndex]
                             + ", enter floor and room to search separated by a space: ");
          floor = s.nextInt();
          room = s.nextInt();

          //for testing, use random generation of floor and room
          //floor = rand.nextInt(totalFloors);
          //room = rand.nextInt(totalRooms);
        } while (!game.indicesOK(floor, room) 
                 || game.roomSearchedAlready(floor, room));


        found = game.searchRoom(floor, room, players[playerIndex]);
        playerIndex = (playerIndex + 1) % 2;
        System.out.println("\n[" + floor + "], [" + room + "]");
        System.out.println(game.toString());
        s.nextLine();
      } while (!found);

      playerIndex = (playerIndex + 1) % 2;
      System.out.println("Great job player " + players[playerIndex] +"!");
      System.out.println("Would you like to find another puppy [Y/N]? ");
    } 
    while (s.nextLine().equalsIgnoreCase("Y"));
  }
}

最后,这是我的测试代码:

import java.util.Random;
import java.util.Scanner;

public class LostPuppy
{
   int value;
   char[][] myHidingPlaces;
   int myFloorLocation;
   int myRoomLocation;
   char myWinner;
   boolean myFound;
   Random random = new Random();

   public LostPuppy(int theFloors, int theRooms)
   {
      myHidingPlaces = new char[theFloors][theRooms];

      for (int i = theFloors - 1; i >= 0; i--)
      {
         for (int j = 0; j <= theRooms - 1; j++)
         {
            myHidingPlaces[i][j] = ' ';
         }
      }

      myFloorLocation = random.nextInt(theFloors);
      myRoomLocation = random.nextInt(theRooms);
      myHidingPlaces[myFloorLocation][myRoomLocation] = 'P';
      myWinner = ' ';
      myFound = false;  
   }
   public boolean roomSearchedAlready(int floor, int room)
   {
      return (myHidingPlaces[floor][room] == '1' || 
              myHidingPlaces[floor][room] == '2');
   }

   public boolean puppyLocation(int floor, int room)
   {
      return (myHidingPlaces[floor][room] == 'P');
   }

   public boolean indicesOK(int floor, int room)
   {
      return (floor <= myHidingPlaces.length && room <= myHidingPlaces[0].length);
   }

   public int numberOfFloors()
   {
      return myHidingPlaces.length - 1;
   }
   public int numberOfRooms()
   {
      return myHidingPlaces[0].length - 1;
   }

   public boolean searchRoom(int floor, int room, char player)
   {
      if (puppyLocation(floor, room))
      {
         myFound = true;
         myWinner = player;
         return true;
      }
      else
      {
         myHidingPlaces[floor][room] = player;
         return false;
      }
   }

   public String toString()
   {
      int rooms = myHidingPlaces[0].length;
      int floors = myHidingPlaces.length;

      System.out.print(" ");
      for (int x = 0; x < rooms; x++)
      {
         System.out.print("___");
      }

      for (int y = 0; y < rooms - 1; y++)
      {
         System.out.print("_");
      }
      System.out.print("\n");

      for (int r = 0; r < floors; r++)
      {
         System.out.print("| ");
         for (int c = 0; c < rooms; c++)
         {

            if (myHidingPlaces[r][c] == 'P' && myFound)
            {
               System.out.print("" + myWinner + "" + myHidingPlaces[r][c] + "| ");
            }
            else if (myHidingPlaces[r][c] == 'P' && !myFound)
            {
               System.out.print("  | ");
            }
            else
            {
               System.out.print(myHidingPlaces[r][c] + " | ");
            }

            //System.out.print(myHidingPlaces[r][c] + " | ");

         }
         System.out.print("\n");
         for (int i = 0; i < rooms; i++)
         {
            System.out.print("|___");
         }
         System.out.print("|\n");
      }
      return "";

   }

}

【问题讨论】:

  • 请考虑缩短您的问题并仅编写必要的最少文本+代码。
  • 你能只把你面临的问题而不是你的应用程序的整个文档?只需专注于这三件事,什么不正常,你期望它做什么和它做了什么。
  • @alfasin 谢谢你的建议。尽管对于一项复杂的计划任务,我认为提供尽可能多的信息对我来说至关重要,这样答案才不会混淆。
  • @Codebender 感谢您的意见,我编辑了我的问题,以便更清楚地说明我的问题以及我认为问题的根源。
  • @Trafton 我研究了你的整个代码和信息。好的,我明白了你想要什么。当您尝试在搜索室方法中实现链接中提供的代码时遇到什么问题。

标签: java arrays indexing


【解决方案1】:

您无法在 Java 中创建反转数组,但您不需要它。您需要考虑建筑物并对其进行操作,就像您对矩阵进行操作一样。但是,您需要将其颠倒打印。您提供的链接也没有改变数组中的位置,它只是从最后一个索引到第一个索引的数组遍历。

所以您需要将数组倒置打印,这很容易。您需要在toString 方法中更改一行,更改

for (int r = 0; r < floors; r++)

到

for (int r = floors - 1; r >= 0; r--)

你会得到正确的结果!

同样在这种情况下,你不需要像你一样从最后一个填充数组(至少因为你用相同的值填充它)

for (int i = theFloors - 1; i >= 0; i--) {
    for (int j = 0; j <= theRooms - 1; j++) {
        ...
    }
}

如果你这样做会更好(只是更好地阅读你的代码)

for (int i = 0; i < theFloors; i++) {
    for (int j = 0; j < theRooms; j++) {
        ...
    }
}

正如@Dante 所说,您还需要更正indicesOK 方法,因为数组的最后一个索引是它的length - 1,所以当您访问myHidingPlaces.length 或myHidingPlaces[i].length 元素时,将抛出异常ArrayIndexOutOfBoundsException。

public boolean indicesOK(int floor, int room) {
    return (floor < myHidingPlaces.length && room < myHidingPlaces[0].length);
}

【讨论】:

  • 这如何解决 OP 的问题。 OP的问题到底是什么?他说,当他尝试在搜索室方法中实现这一点时,他遇到了问题,但搜索室方法对我来说似乎很好。
  • @Dante 我相信我需要用 for 循环以某种方式编辑 toString 方法,但我不知道该怎么做。 OP 是对的,问题出在toString 方法中,我的回答显示了如何纠正它。我猜searchRoom 方法的问题是 OP 试图颠倒存储 myHidingPlaces 的所有值,因此以错误的顺序访问了此方法中的元素。
  • @NikolayKondratyev 我不敢相信事情就这么简单。我是如此接近,我正在改变这些价值观。非常感谢你救了我的命!
  • @NikolayKondratyev 你觉得我的解决方案怎么样。
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 2015-06-21
  • 2023-01-24
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多