-
Stuck with Structs...
I've got one line (so far) in my program that doesn't want to play ball...
Code:
system[mapLocation[random, random2]].AdjSystem[planetAdderLoop] = subSystemNumber;
these come from:
Code:
struct SystemStruct
{
...
private int[] adjSystems;
public int[] AdjSystems;
{
get
{
return adjSystems;
}
set
{
adjSystems = value;
}
}
...
}
Code:
SystemStruct[] system = new SystemStruct[650];
and
Code:
int subSystemNumber = new int();
Now, I've seen this at http://www.c-sharpcorner.com/UploadF...turesInCS.aspx
Code:
//C#: Property
// Author: [email protected]
using System;
class MyStruct
private int x;
public int X
{
get
{
return x;
}
set
{
x = value;
}
}
}
class MyClient
public static void Main()
{
MyStruct ms = new MyStruct();
ms.X = 10;
int xVal = ms.X;
Console.WriteLine(xVal);//Displays 10
}
}
Is it the fact I'm arraying the variable I'm trying to use here? What do I do to change that system[x].AdjSystems[y] so that 'Object reference not set to an instance of an object.' stops screaming at me?
-
You didn't define how many adjSystems there for each of your 650 systems.
private int[] adjSystems;
Writing to any index in this array will throw an exception until you "new" something.
Maybe you should use a container class like ArrayList if you don't know how many subsystems each system has.
-
oops, forgot to say i call this at start:
Code:
public void SpacePlan_Load(object sender, EventArgs e)
{
SystemStruct[] system = new SystemStruct[651];
for (int loop1 = 0; loop1 <= 650; loop1++)
{
system[loop1].AdjSystem = new int[7];
}
}
um, ignore the 650 number, i changed the previous posts 650 to 651 (still same problem though).
-
I'm still stuck on this :(
there are 650 (or so) 'system', and for each system there can be up to 7 adjsystem variables, unfortunately, the code does require that i have the ability to cycle through the the adjsystem variables, reading, writing etc.
help!
Edit: There may be up to 7, but there must always be 7 available. So there may only be one adjacent system, but at any point it must be possible to add more, up to a total of seven. The system struct actually has another property that counts the number of adjsystem for that particluar system, so that cycling through and other actions can be carried out easily.
-
You'd probably get better answers if you actually showed some code. There's no way for us to test what you've got.
Nevertheless, I can still blindly ask questions. Why are you using structs? What reason do you have for wanting value semantics over reference semantics? Note this wonderful little side effect of value semantics:
Code:
struct A
{
int[] _ints;
public int[] Ints
{
get { return _ints; }
set { _ints = value; }
}
}
static void AddInts(A a)
{
a.Ints = new int[7];
}
static void Main(string[] args)
{
A a = new A();
AddInts(a);
if (a.Ints == null)
Console.WriteLine("Why?");
}
Personally, I default to classes unless I have a compelling reason to want value semantics.
Why assign the integer arrays later instead of passing in a parameter on construction? Do you really want AdjSystems to be settable any time or only during construction?
-
I wonder how many characters each post can hold? Let's find out!
Here's my struct:
Code:
struct SystemStruct
{
public int SystemType;
public int SubSystems;
public int AdjSystems;
public int Pop;
public int Ind;
public bool NetLinked;
public bool NetHome;
public int NetLinkedTo;
public int Production;
public int Owner;
public int Carriers;
public int Escorts;
public int Riders;
public int Marines;
public int Cruisers;
public int Fighters;
public int Militia;
public int DefenceMode;// (0 = Retreat, 1 = Defend, 2 = Ambush)
public int RetreatTo;
public int DefendTowards;
public int AmbushAgainst;
public int[] AdjSystem
{
get
{
return adjSystem;
}
set
{
adjSystem = value;
}
}
public int[] adjSystem;
public int Income;
public int ProdCost;
public int Merchanters;
public int FleetSupply;
public int IndSupply;
public int PopSupply;
public int FO;
public int HC;
public int IS;
public int MI;
public int PopLimit;
public int EcoDamage;
public bool Visible;// (o = False, 1 = True);
public bool Stuck;
public bool Station;
}
From what I've read on the net, apparently this might be a good idea. Doesn't throw an error at compile or runtime.
Code:
public void SpacePlan_Load(object sender, EventArgs e)
{
SystemStruct[] system = new SystemStruct[651];
for (int loop1 = 0; loop1 <= 650; loop1++)
{
system[loop1].AdjSystem = new int[7];
}
}
After a few button clicks, we get to this:
Code:
MapCreationRoutine();
Which by code gets through to this, note that there are several uses of the struct 'system', no code errors, and breakpoint use confirms that the values are set to what they should be.
Code:
public void CreateStartPlaces()
{
Stack numberCheck = new Stack();
Stack subsystemCheck = new Stack();
int[] array1 = new int[13];
for (startPlaceLoop = 1; startPlaceLoop <= 12; startPlaceLoop++)
{
// finds a suitable system
do
{
StartPlaces1();
}
while (mapLocation[random, random2] == 0);
// Now let's assign a random empire to the star system
do
{
array1[startPlaceLoop] = rnd.Next(1, 13);
}
while (numberCheck.Contains(array1[startPlaceLoop]) == true);
numberCheck.Push(array1[startPlaceLoop]);
system[mapLocation[random, random2]].Owner = array1[startPlaceLoop];
// sets the number of subsystems of the star system to 4
system[mapLocation[random, random2]].SubSystems = 4;
// also sets the number of adjacent systems to 4 as well
system[mapLocation[random, random2]].AdjSystems = 4;
subsystemCheck.Clear();
for (int planetAdderLoop = 0; planetAdderLoop <= 3; planetAdderLoop++)// loop to add planets/asteroids
{
int subSystemNumber = new int();
bool exists = true;
// Now to assign the subsystems number, and add it to the
// parent systems adjacent systems list
while (exists == true)
{
subSystemNumber = rnd4.Next(100, 600);
system[mapLocation[random, random2]].AdjSystem[planetAdderLoop] = subSystemNumber;
exists = mapLocCount.Contains(subSystemNumber);
}
//add the number to the 'list'
mapLocCount.Push(subSystemNumber);
// Can only be linked to its parent star, so adjacent systems = 1
system[subSystemNumber].AdjSystems = 1;
// here we add the parent system number to the first adjacent system slot
system[subSystemNumber].AdjSystem[0] = mapLocation[random, random2];
if (planetAdderLoop == 0) // if its the first subsystem, its a terran planet
{
assignSysType = 13;
system[subSystemNumber].Owner = array1[startPlaceLoop];
countAsteroids = 0;
}
else // if its not the first subsystem, lets randomise !
{
int AsteroidChance = 0;
if (countAsteroids > 1)
{
AsteroidChance = 18;
}
else
{
AsteroidChance = 21;
}
do
{
assignSysType = rnd2.Next(16, AsteroidChance);
}
while (subsystemCheck.Contains(assignSysType) == true);
if (assignSysType > 19)
{
assignSysType = 19;
}
if (planetAdderLoop == 21 && countAsteroids == 0)
{
assignSysType = 19;
}
}
if (assignSysType == 19)
{
countAsteroids++;
}
if (assignSysType != 19)
{
subsystemCheck.Push(assignSysType);
}
system[subSystemNumber].SystemType = assignSysType;
}
}
}
Code:
public void MoreSubSystems()
{
for (mapy = 1; mapy <= 19; mapy++) //starts the standard map loop
{
for (mapx = 1; mapx <= 19; mapx++)
{
if (mapLocation[mapy, mapx] > 0) // is there a system here? if no - break
{
if (system[mapLocation[mapy, mapx]].SubSystems == 0 // does it have any subsystems? if yes - break
&& system[mapLocation[mapy, mapx]].SystemType != 12 // Is it a planetoid? if yes, break
&& system[mapLocation[mapy, mapx]].SystemType != 11) // Is it a black hole? if yes, break
{
int subTypeCountRandomiser = rnd.Next(1, 101);//randomise for adding subsystems
if (subTypeCountRandomiser < 71)
{
system[mapLocation[mapy, mapx]].SubSystems = 0;
}
if (subTypeCountRandomiser > 70 && subTypeCountRandomiser < 92)
{
system[mapLocation[mapy, mapx]].SubSystems = 1;
}
if (subTypeCountRandomiser > 91 && subTypeCountRandomiser < 97)
{
system[mapLocation[mapy, mapx]].SubSystems = 2;
}
if (subTypeCountRandomiser > 96 && subTypeCountRandomiser < 100)
{
system[mapLocation[mapy, mapx]].SubSystems = 3;
}
if (subTypeCountRandomiser > 99)
{
system[mapLocation[mapy, mapx]].SubSystems = 4;
}
system[mapLocation[mapy, mapx]].AdjSystems = system[mapLocation[mapy, mapx]].SubSystems;
if (system[mapLocation[mapy, mapx]].SubSystems > 0)
{
for (loop1 = 0;
loop1 < system[mapLocation[mapy, mapx]].SubSystems; loop1++)
{
int subSystemNumber = 0;
bool exists = true;
// Now to assign the subsystems number, and add it to the
// parent systems adjacent systems list
while (exists == true)
{
subSystemNumber = rnd4.Next(100, 600);
system[mapLocation[mapy, mapx]].adjSystem[loop1] = subSystemNumber;
exists = mapLocCount.Contains(subSystemNumber);
}
//add the number to the 'list'
mapLocCount.Push(subSystemNumber);
// Can only be linked to its parent star, so adjacent systems = 1
system[subSystemNumber].AdjSystems = 1;
// here we add the parent system number to the first adjacent system slot
system[subSystemNumber].AdjSystem[0] = mapLocation[mapy, mapx];
assignSysType = rnd2.Next(13, 21);
if (assignSysType > 20)
{
assignSysType = 19;
}
system[subSystemNumber].SystemType = assignSysType;
}
}
}
}
}
}
}
Now, as you can see, the struct is mainly used for the fact it's nice and clear to read. All the values in it, apart from AdjSystem[x] work correctly, all assigned and readable etc. What I am wanting to do is to be able to have a value that i can cycle through very easily in loops etc for the adjsystem. There is more code to show, but there's so much it'd never fit in a whole thread.
-
Here's a stab in the dark.
Code:
public void SpacePlan_Load(object sender, EventArgs e)
{
SystemStruct[] system = new SystemStruct[651];
for (int loop1 = 0; loop1 <= 650; loop1++)
{
system[loop1].AdjSystem = new int[7];
}
}
...
public void CreateStartPlaces()
{
...
system[mapLocation[random, random2]].Owner = array1[startPlaceLoop];
Note that CreateStartPlaces doesn't define any variable called 'system'. I'm guessing you've got some class member called 'system' since, as you say, it compiles for you.
However, SpacePlan_Load defines a variable called 'system'. The initialization that you'd wanted done to your class member is actually being done to a local variable that's being lost at the end of scope. Where are you defining the 'system' that CreateStartPlaces is using?
-
Code:
namespace SpacePlanII
{
public partial class SpacePlan : Form
{
...
SystemStruct[] system = new SystemStruct[650];
...
}
}
No idea why I put that second one in SpacePlan_Load(...).
-
Ok, I removed the new Struct in SpacePlan_Load and modified the code to something similar, everything seems ok... The for loop is still there though.
I just have to work through every use of this new system of using the values to correct it all...