-1

I apologize if this question is too vague because I haven't actually built out any code yet, but my question is about how to code (perhaps in C# in a Unity3d script, but really just generically) the dynamically changing unit depth/width in total war games.

In TW games, you can click and drag to change a unit from an nx2 formation to 2xn formation and anything in between. Here's a video (watch from 15 seconds in to 30 seconds in):

https://www.youtube.com/watch?v=3aGRzy_PzJQ

I'm curious, generically speaking, about the code that would permit someone to on the fly exchange the elements of an array like that. I'm assuming here that the units in the formation are elements in an array

so, you might start with an array like this:

    int[,] array = new int[2, 20];

and end up with an array like this:

    int[,] array = int[20, 2];

but in between you create the closest approximations, with the last row in some cases being unfilled, and then the elements of that last row would have to center visually until the column width was such that the number of elements in all the rows are equal again.

It kind of reminds me of that common intro to programming problem that requires you to write to the console a pyramid made of *'s all stacked up and adding one element per row with spaces in between, but a lot more complicated.

Most of the lower-tech formation tactics games out there, like Scourge of War just let you choose either Line Formation (2 rows deep) or column formation (2 columns wide), without any in between options, which was perhaps an intentional design choice, but it makes unit movement so awkward that I had to assume they did it out of technical limitations, so maybe this is a hard problem.

  • Have you considered using a list? You can't change arrays in C# like you want. – Chris Sharp Mar 11 '17 at 00:41
  • _"I haven't actually built out any code yet"_ -- yup, that about sums it up. Frankly, I don't think it's a good idea to try to use your _collection_ data structure as some kind of model for the geographic layout of objects. Better to have a simple collection (e.g. array or list) that just _stores_ the objects, and then have each object maintain its own position. When you want to change formations, just run through the existing objects and assign them new positions, i.e. fill in the spaces of the new formation with the objects you have. – Peter Duniho Mar 11 '17 at 00:44
  • But really, your question is way too broad. Lots of different ways to do it, and just as many different opinions about what way you _should_ do it. – Peter Duniho Mar 11 '17 at 00:45
  • I think you are asking how to rotate a two-dimensional array, which is answered [here](http://stackoverflow.com/questions/42519/how-do-you-rotate-a-two-dimensional-array). – John Wu Mar 11 '17 at 01:28

1 Answers1

0

I wrote some code to clarify the question a bit. The method form() takes parameters for the number of units in the formation and the width of the formation, without using an array, and just prints out the formation to the console with any extra men put in the last row and centered:

x = number of men

y = width formation

r = number of rows, or depth (calculated from x and y)

L = leftover men in last row if y does not divide evenly into x

Space = number spaces used to center last row

form() = method called from the class Formation

I figured it should take the depth and number of men because the number of men is set (until some die but that's not being simulated here) and the player would normally spread out the men to the desired width, and so the number of rows, and number of men in those rows, including the last row, and the centering of that last row, should be taken care of by the program. At least that's one way to do that.

namespace ConsoleApplication6
{

    class Formation
    {
        public int x;
        public int y;

        public Formation(int x, int y)
        {
            this.x = x;
            this.y = y;
        }


        public void form()
        {
            int r = x / y;
            int Left = x % y;
            int Space = (y - Left)/2;
            for (int i = 0; i < r;i++)
                {
                for (int j = 0; j < y; j++)
                    {
                    Console.Write("A");
                    }
                Console.WriteLine();
                if (i == r - 1)
                {
                    for (int m = 0; m < Space; m++)
                    {
                        Console.Write(" ");
                    }
                    for (int k = 0; k < Left; k++)
                    {
                        Console.Write("A");
                    }
                }
                }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("enter the number of men: ");
            int a = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("enter the formation width: ");
            int b = Convert.ToInt32(Console.ReadLine());
            Formation testudo = new Formation(a,b);
            testudo.form();
            Console.ReadKey();
        }
    }
}

So, I think what I'm trying to do to improve this is have the above code run repeatedly in real time as the user inputs a different desired width (y changes) and men die (x changes)

But, if it were actually to be implemented in a game I think it would have to be an array, so I guess the array could take the x parameter as its max index number and then i would do a kind of for loop like for(x in array) or whatever print x instead of just console logging the letter A over and over