2017-08-16 79 views
-1

我正在開發一個創建「世界生成器」的業餘愛好項目。我試圖用很多'人類'對象來填充我的世界,每個對象都有一個隨機生成的名字。我有一個NameGenerator類,它有一個函數generateName,每次調用時都會生成一個隨機名。在我的世界裏,我每秒鐘都會運行一個「日」功能,將100人添加到人員列表中。出於某種原因,當它運行時,很多人類對象會得到相同的名稱,儘管它們應該有不同的名稱。爲多個對象提供相同名稱的隨機名稱生成器


這裏是我的代碼:

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()); 
     } 
    } 
} 

編輯 - NameGenerator.cs抱歉,我想我張貼太(我傻)

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; 
      } 
     } 
    } 
} 

任何幫助將大大appreaciated

+1

我想問題是隨機發生器的種子。 – Wollmich

+10

問題幾乎肯定存在於'NameGenerator'中 - 您選擇不與我們分享的一段代碼。 –

+1

請提供'NameGenerator'類或至少'generateName(int x,int y)'方法' – Smartis

回答

4

我supose放置NameGenerator nameGen =新NameGenerator();在世界outsite的for函數中使用for循環將解決您的問題。

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); 
} 
+0

是這個工作。爲什麼將它放在循環外面會有所作爲? –

+4

@JamieWalker - 因爲當你在不提供種子的情況下調用'new Random()'時,它會根據當前的日期時間值進行播種 - 從現代CPU的角度來看,需要*年齡*來改變。 –

0

充分利用NameGenerator有單隨機初始種子,所以每次你實例NameGenerator和生成的名稱,這將永遠是不同的。

class NameGenerator 
{ 
    private static readonly Random staticRandom = new Random(); 
    private Random random {get;set;} 

    public NameGenerator() 
    { 
     random = staticRandom; 
    } 

... 
相關問題