Jamie Walker Jamie Walker - 1 year ago 55
C# Question

Random Name Generator providing same name to multiple objects

I'm working on a hobby project creating a 'World Generator.' I am trying to populate my world with lots of 'Human' objects which each get a randomly generated name. I have a class NameGenerator that has a function generateName which each time it is called should generate a random name. In my world, I am running a 'day' function every second that adds 100 people to the person list. For some reason when this is run, a lot of the human objects get the same name generated although they should have different names.




Here is my code:

mainGui.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JamiesWorldGenerator
{
public partial class WorldGeneratorForm : Form
{
World world = null;

public WorldGeneratorForm()
{
InitializeComponent();
}

private void runButton_Click(object sender, EventArgs e)
{
if (runButton.Text == "Run")
{
if (world == null) world = new World(this, 1000);
world.run();

runButton.Text = "Stop";
statusLabel.Text = "Status: Active";
}
else if (runButton.Text == "Stop")
{
world.pause();

runButton.Text = "Run";
statusLabel.Text = "Status: Inactive";
}
}

public void updateTimeElapsed(int i)
{
this.daysElapsedLabel.Text = "Days Elapsed: " + i;
}

public void updatePersonList(List<Human> list)
{
foreach (Human h in list) this.peopleList.Items.Add(h);
peopleList.DisplayMember = "FullName";
}
}
}


mainGui.designer.cs

namespace JamiesWorldGenerator
{
partial class WorldGeneratorForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.populationLabel = new System.Windows.Forms.Label();
this.runButton = new System.Windows.Forms.Button();
this.statusLabel = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.countriesList = new System.Windows.Forms.ListBox();
this.panel2 = new System.Windows.Forms.Panel();
this.peopleList = new System.Windows.Forms.ListBox();
this.panel3 = new System.Windows.Forms.Panel();
this.worldNews = new System.Windows.Forms.ListBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.daysElapsedLabel = new System.Windows.Forms.Label();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.panel3.SuspendLayout();
this.SuspendLayout();
//
// populationLabel
//
this.populationLabel.AutoSize = true;
this.populationLabel.Location = new System.Drawing.Point(9, 9);
this.populationLabel.Name = "populationLabel";
this.populationLabel.Size = new System.Drawing.Size(94, 13);
this.populationLabel.TabIndex = 0;
this.populationLabel.Text = "World Population: ";
//
// runButton
//
this.runButton.Location = new System.Drawing.Point(8, 320);
this.runButton.Name = "runButton";
this.runButton.Size = new System.Drawing.Size(75, 23);
this.runButton.TabIndex = 1;
this.runButton.Text = "Run";
this.runButton.UseVisualStyleBackColor = true;
this.runButton.Click += new System.EventHandler(this.runButton_Click);
//
// statusLabel
//
this.statusLabel.AutoSize = true;
this.statusLabel.Location = new System.Drawing.Point(89, 325);
this.statusLabel.Name = "statusLabel";
this.statusLabel.Size = new System.Drawing.Size(81, 13);
this.statusLabel.TabIndex = 2;
this.statusLabel.Text = "Status: Inactive";
//
// panel1
//
this.panel1.Controls.Add(this.countriesList);
this.panel1.Location = new System.Drawing.Point(12, 25);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(197, 187);
this.panel1.TabIndex = 3;
//
// countriesList
//
this.countriesList.Dock = System.Windows.Forms.DockStyle.Fill;
this.countriesList.FormattingEnabled = true;
this.countriesList.Location = new System.Drawing.Point(0, 0);
this.countriesList.Name = "countriesList";
this.countriesList.Size = new System.Drawing.Size(197, 187);
this.countriesList.TabIndex = 1;
//
// panel2
//
this.panel2.Controls.Add(this.peopleList);
this.panel2.Location = new System.Drawing.Point(215, 25);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(197, 187);
this.panel2.TabIndex = 4;
//
// peopleList
//
this.peopleList.Dock = System.Windows.Forms.DockStyle.Fill;
this.peopleList.FormattingEnabled = true;
this.peopleList.Location = new System.Drawing.Point(0, 0);
this.peopleList.Name = "peopleList";
this.peopleList.Size = new System.Drawing.Size(197, 187);
this.peopleList.TabIndex = 0;
//
// panel3
//
this.panel3.Controls.Add(this.worldNews);
this.panel3.Location = new System.Drawing.Point(12, 219);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(400, 95);
this.panel3.TabIndex = 5;
//
// worldNews
//
this.worldNews.Dock = System.Windows.Forms.DockStyle.Fill;
this.worldNews.FormattingEnabled = true;
this.worldNews.Location = new System.Drawing.Point(0, 0);
this.worldNews.Name = "worldNews";
this.worldNews.Size = new System.Drawing.Size(400, 95);
this.worldNews.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(336, 320);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 6;
this.button1.Text = "Load World";
this.button1.UseVisualStyleBackColor = true;
//
// button2
//
this.button2.Location = new System.Drawing.Point(255, 320);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 7;
this.button2.Text = "Save World";
this.button2.UseVisualStyleBackColor = true;
//
// daysElapsedLabel
//
this.daysElapsedLabel.AutoSize = true;
this.daysElapsedLabel.Location = new System.Drawing.Point(212, 9);
this.daysElapsedLabel.Name = "daysElapsedLabel";
this.daysElapsedLabel.Size = new System.Drawing.Size(84, 13);
this.daysElapsedLabel.TabIndex = 8;
this.daysElapsedLabel.Text = "Days Elapsed: 0";
//
// WorldGeneratorForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(423, 351);
this.Controls.Add(this.daysElapsedLabel);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel3);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
this.Controls.Add(this.statusLabel);
this.Controls.Add(this.runButton);
this.Controls.Add(this.populationLabel);
this.Name = "WorldGeneratorForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Jamie\'s World Generator";
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel3.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Label populationLabel;
private System.Windows.Forms.Button runButton;
private System.Windows.Forms.Label statusLabel;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.ListBox countriesList;
private System.Windows.Forms.ListBox peopleList;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.ListBox worldNews;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Label daysElapsedLabel;
}
}


World.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JamiesWorldGenerator
{
public class World
{
private delegate void updateForm();

WorldGeneratorForm gui = null;

List<Country> worldCountries = new List<Country>();
List<Human> worldHumans = new List<Human>();

List<Human> newWorldHumans;

System.Timers.Timer timer = new System.Timers.Timer();
int daysElapsed = 0;

public World(WorldGeneratorForm mainGui, int dayDelay)
{
gui = mainGui;

timer.Interval = dayDelay;
timer.Elapsed += day;
}

private void day(object sender, EventArgs e)
{
newWorldHumans = new List<Human>();

for (int i = 0; i < 100; i++)
{
NameGenerator nameGen = new NameGenerator();
Human h = new Human(nameGen.generateName(4, 8), nameGen.generateName(4, 12));
worldHumans.Add(h);
newWorldHumans.Add(h);

}

daysElapsed++;
Delegate updateDays = new updateForm(updateDayElapsed);
Delegate updatePersonList = new updateForm(updateWorldPopulationList);
gui.Invoke(updateDays);
gui.Invoke(updatePersonList);
}

public void run()
{
timer.Enabled = true;
}

public void pause()
{
timer.Enabled = false;
}

private void updateDayElapsed()
{
gui.updateTimeElapsed(daysElapsed);
}

private void updateWorldPopulationList()
{
gui.updatePersonList(newWorldHumans);
}
}
}


Human.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;

namespace JamiesWorldGenerator
{
public class Human
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }

public Human(string fname, string lname)
{
FirstName = capitaliseFirst(fname);
LastName = capitaliseFirst(lname);
FullName = FirstName + " " + LastName;
}

string capitaliseFirst(string s)
{
if (s.Length == 0) return "";
char[] chars = s.ToCharArray();
chars[0] = Char.ToUpperInvariant(chars[0]);
return new string(chars);
}
}
}


Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JamiesWorldGenerator
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WorldGeneratorForm());
}
}
}


EDIT - NameGenerator.cs sorry I thought I posted it too (silly me)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JamiesWorldGenerator
{
class NameGenerator
{
Random random = new Random();

public string generateName(int minLength, int maxLength)
{
string chars = "abcdefghijklmnopqrstuvwxyz";
string consonants = "bcdfghjklmnpqrstvxzw";
string vowels = "aeiouy";

int length = random.Next(minLength, maxLength);
string name = "";

for (int i = 0; i < length; i++)
{
if (name != "")
{
if (endsWithTwoConsonants(name)) name = name + vowels[random.Next(vowels.Length)];
else if (endsWithTwoVowels(name)) name = name + consonants[random.Next(consonants.Length)];
else name = name + chars[random.Next(chars.Length)];
}
else name = name + chars[random.Next(chars.Length)];
}

return name;
}

bool endsWithTwoConsonants(string s)
{
if (s.Length < 2) return false;
string substring = s.Substring(s.Length - 2);
for(int i = 0; i < substring.Length; i++)
{
if (isVowel(substring[i])) return false;
}
return true;
}

bool endsWithTwoVowels(string s)
{
string[] suffixes = {"aa", "ae", "ai", "ao", "au", "ea", "ee", "ei", "eo", "eu", "ia", "ie", "ii", "io", "iu"
,"oa", "oe", "oi", "oo", "ou", "ua", "ue", "ui", "uo", "uu"};
for(int i = 0; i < suffixes.Length; i++)
{
if (s.EndsWith(suffixes[i])) return true;
}
return false;
}

bool isVowel(char c)
{
string vowels = "aeiouy";
if (vowels.Contains(c))
{
return true;
}
else
{
return false;
}
}

bool isConsonant(char c)
{
string consonants = "bcdfghjklmnpqrstvxzw";
if (consonants.Contains(c))
{
return true;
}
else
{
return false;
}
}
}
}





Any help would be greatly appreaciated

Answer Source

I'll supose placing the NameGenerator nameGen = new NameGenerator(); statement in the day function of World outsite the for loop will solve you're problem.

NameGenerator nameGen = new NameGenerator();
for (int i = 0; i < 100; i++)
{
   Human h = new Human(nameGen.generateName(4, 8), nameGen.generateName(4, 12));
   worldHumans.Add(h);
   newWorldHumans.Add(h);
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download