我想使用fisher-yates shuffle洗牌列表中的元素。但是,除非我在它應該洗牌的地方設置斷點,否則這些元素似乎不會洗牌。我嘗試異步執行洗牌,但我沒有運氣(也許我做錯了)。IEnumerable不會洗牌,除非我把一個斷點
洗牌算法如下:
// Uses Fisher-Yates shuffle to swap elements
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
Random rng = new Random();
T[] elements = source.ToArray();
for (int i = elements.Length - 1; i >= 0; i--)
{
int j = rng.Next(i + 1);
yield return elements[j];
elements[j] = elements[i];
}
}
我洗牌是這樣的:
imageDataList= imageDataList.Shuffle().ToList();
我異步洗牌是這樣的:
imageDataList = await Task.Run(() => imageDataList.Shuffle().ToList());
這裏是我的代碼片段:
GameData gameData = null;
ImageData imageData = null;
ToneData toneData = null;
ImageToneData imageToneData = null;
LevelData levelData = null;
List<ImageData> imageDataList = new List<ImageData>();
List<ToneData> toneDataList = new List<ToneData>();
List<ImageToneData> imageToneDataList = new List<ImageToneData>();
List<LevelData> levelDataList = new List<LevelData>();
// Add images to a list of ImageData contracts
foreach (GameImage gameImage in game.GameImages)
{
imageData = new ImageData()
{
ImageId = gameImage.Image.ImageId,
ImageFileName = gameImage.Image.ImageFileName
};
imageDataList.Add(imageData);
}
// Add tones to a list of ToneData contracts
foreach (GameTone gameTone in game.GameTones)
{
toneData = new ToneData()
{
ToneId = gameTone.Tone.ToneId,
ToneFileName = gameTone.Tone.ToneFileName
};
toneDataList.Add(toneData);
}
//Randomize image and tone association
imageDataList = imageDataList.Shuffle().ToList();
toneDataList = toneDataList.Shuffle().ToList();
// Combine imageData and toneData and assign a position
for (int i = 0; i < game.NumLevels; i++)
{
imageToneData = new ImageToneData()
{
Image = imageDataList.ElementAt(i),
Tone = toneDataList.ElementAt(i),
Position = (i + 1)
};
imageToneDataList.Add(imageToneData);
}
foreach (GameLevel level in game.GameLevels)
{
//Randomize image/tone (already fixed association)
imageToneDataList = imageToneDataList.Shuffle().ToList();
levelData = new LevelData()
{
GameLevelId = level.GameLevelId,
Level = level.Level,
UniqueRounds = level.UniqueRounds,
Rounds = level.Rounds,
NumImages = level.NumImages,
ImageTones = imageToneDataList.Take(level.NumImages)
};
levelDataList.Add(levelData);
}
gameData = new GameData()
{
NumLevels = game.NumLevels,
SelectionTime = game.SelectionTime,
Levels = levelDataList
};
個
我的數據合同如下:
[DataContract]
public class GameData
{
[DataMember]
public int NumLevels { get; set; }
[DataMember]
public int? SelectionTime { get; set; }
[DataMember]
public IEnumerable<LevelData> Levels { get; set; }
}
[DataContract]
public class LevelData
{
[DataMember]
public int GameLevelId { get; set; }
[DataMember]
public int Level { get; set; }
[DataMember]
public bool UniqueRounds { get; set; }
[DataMember]
public int Rounds { get; set; }
[DataMember]
public int NumImages { get; set; }
[DataMember]
public IEnumerable<ImageToneData> ImageTones { get; set; }
}
[DataContract]
public class ImageToneData
{
[DataMember]
public ImageData Image { get; set; }
[DataMember]
public ToneData Tone { get; set; }
[DataMember]
public int? Position { get; set; }
}
[DataContract]
public class ImageData
{
[DataMember]
public int ImageId { get; set; }
[DataMember]
public string ImageFileName { get; set; }
}
[DataContract]
public class ToneData
{
[DataMember]
public int ToneId { get; set; }
[DataMember]
public string ToneFileName { get; set; }
}
任何幫助,非常感謝!
將代碼放置在一個空的控制檯項目中。問題仍然存在嗎?它不會。 – usr
嘗試將'elements'列爲一個列表,並在每次產生列表時刪除它們。 –
@usr我有一個單獨的項目中的代碼在一個單獨的項目 –