0

So I've created a 2d Array of objects of Type "Champion" that represent avatars on a 2D 10x10 grid, where null spaces indicate "open" spots and not null spaces are obviously occupied with Champions.

private static void createCharacter() 
{       
    System.out.println("New Character Name");
    String name = sc.next();
    System.out.println("Character x coord");
    int xc = sc.nextInt();
    System.out.println("Character y coord");
    int yc =sc.nextInt();   
    Champion tempchamp = new Champion(name,xc,yc);
    if(grid[xc][yc]!= null)
    {
        System.out.println("Error, Space Already Occuped");
    }//End If 
    else
    {
        grid[xc][yc] = tempchamp;
    }//End Else

My character constructor allows for name, x and y coordinates but the coordinates are also represented on the grid, obviously. The output looking something like this Output My issue now is finding a way to allow user to select the Character they want to move. Is there a way of iterating through a 2D array to compare if any index's name attribute contains the same value as that of a user input String or would I be looking at an entirely different solution. Any and all help much appreciated. Also apologies if formatting is off. First post.

Currently Move method targets actual coordinates of Champions on Grid

private static void moveCharacter() 
    {
        System.out.println("Enter Co-ords of Champ to Move");
        int posx = sc.nextInt();
        int posy = sc.nextInt();
        if(grid[posx][posy]!=null)
        {
            String moving = grid[posx][posy].getName();
            System.out.println("Enter Target Coordinates");
            int tarx = sc.nextInt();
            int tary = sc.nextInt();
            if(grid[tarx][tary]==null)
            {
                grid[posx][posy]=null;
                Champion champ = new Champion(moving, tarx, tary);
                grid[tarx][tary]=champ;
                printgrid();
                double distance = calculateDistance(posx, posy, tarx, tary);
                System.out.println("Distace Travelled " + distance);
            }//End if
        }//End If Pos Null
        else
            System.out.println("Target Position is Empty");
            {
            moveCharacter();
            }//End Else
    }//End Move Character

Was toying around with something like

String ChampToMove = "Brian";
for(int i = 0; i<grid.length; i++)
    {
        for(int j = 0; j<grid[i].length;j++)
        {
            if(grid[i][j].getName.equals(ChampToMove))
            {
             moveCharacter(ChampToMove );
            }
        }//End Nested For

The last piece isn't currently what I'm using but more what I was playing around with earlier, its just a general gist of what I was thinking would work, however I feel it's not efficient whatsoever.

Ian Mc
  • 5,656
  • 4
  • 18
  • 25
Timmyctc
  • 1
  • 2
  • Well checking if a string matches a champion object doesn't make sense. Do you mean checking if one champion object matches another? –  Mar 07 '18 at 17:00
  • 1
    Yeah sorry I wasn't particularly clear. Too much caffeine. I mean the String matches the name property of a champion object in a 2D Champion array. At the minute I'm working around by prompting user for the ccoords of an existing Champion in the 2D array. The end goal is to move them and calculate distance moved. Rather than move them im passing their name to a temp String. Changing their old Position to null and updating the new position with a new Champion with same name as the Old. I realise I've somwhat coded myself into a corner with my approach, alas. Such is life – Timmyctc Mar 07 '18 at 17:09
  • oh, so only if any of the champions share the same name? Also, you do have getters for all your attributes right? –  Mar 07 '18 at 17:13
  • 1
    Yeah I have getters. Basically what I'm doing is inputting coords `grid[6][6]`and getting the Champion at the coord and moving him randomly however I wanted to alter it so the user inputs the name of the Champion and regardless of their coords in the 2D array, they are moved. I assume I could iterate through the entire 2D array and get the name value at each index until one matches with a user Input String but I was wondering is there a more efficient method – Timmyctc Mar 07 '18 at 17:24
  • Could you add what you've tried so far, if you're looking for a more efficient method? –  Mar 07 '18 at 17:25
  • 2
    Have you considered keeping a List of active Champions? The Champion class stores the grid position. It would be more efficient to iterate this list, rather than the grid. Other collections like Map and Set will also offer better lookup performance (i.e. to find if a champion name is currently on the grid) – Ian Mc Mar 07 '18 at 17:48
  • Given that it's a 10X10 grid, i don't feel like the efficiency will improve much. However, one thing you could do is add a break after you call the move method. Look here to see how to break out of nested loops https://stackoverflow.com/questions/886955/breaking-out-of-nested-loops-in-java –  Mar 07 '18 at 17:51
  • @Timmyctc did you receive an answer? –  Mar 07 '18 at 18:27

1 Answers1

0

I would recommend using a binarySearch, it has a runtime of O(nlog(n)), compared to your current algorithm, which has a runtime of O(n^2).

A possible way to implement is :

for(int i = 0; i<grid.length; i++)
    {
            if(binarySearch(grid[i], ChampToMove))
            {
             moveCharacter(ChampToMove );
             break;
            }
        }//End Nested For

and the binarySearch algorithm :

public static boolean binarySearch(String[] a, String x) {
int low = 0;
int high = a.length - 1;
int mid;

while (low <= high) {
    mid = (low + high) / 2;
    System.out.println(a[mid]);
    if (a[mid].compareTo(x) < 0) {
        low = mid + 1;
    } else if (a[mid].compareTo(x) > 0) {
        high = mid - 1;
    } else {
        return true;
    }
}

return false;
}

if you have any questions about how any of this works, just ask.