C# 随机发生器代码?

C# 随机发生器代码?,c#,random,xna,C#,Random,Xna,我试图用这段代码生成一个数组,其中包含唯一的随机音符。它将根据给定的参数做一个注释,并为其指定一个意外符号,可能显示为平面或尖锐的对应物。例如,如果随机生成器说音符“A”是平坦的,那么它有可能显示为A或A♭ 或G♯. 现在,我还没有处理半步笔记(例如C♭ 变成了B♯, 等等),但这主要是因为第一部分不起作用。我现在面临的问题是,我使用的代码似乎无法持续工作。它有时会正确地翻译笔记,有时会把笔记弄乱。也没有系统性的错误模式,至少,不是我试图破译的 我使用XNA在屏幕上显示注释,但真正的问题是数据。

我试图用这段代码生成一个数组,其中包含唯一的随机音符。它将根据给定的参数做一个注释,并为其指定一个意外符号,可能显示为平面或尖锐的对应物。例如,如果随机生成器说音符“A”是平坦的,那么它有可能显示为A或A♭ 或G♯.

现在,我还没有处理半步笔记(例如C♭ 变成了B♯, 等等),但这主要是因为第一部分不起作用。我现在面临的问题是,我使用的代码似乎无法持续工作。它有时会正确地翻译笔记,有时会把笔记弄乱。也没有系统性的错误模式,至少,不是我试图破译的

我使用XNA在屏幕上显示注释,但真正的问题是数据。我在用我做的
笔记
上课

以下是我使用的代码:

首先是
注释
类:

 public class Note
    {
        public enum Notes
        {
            A = 0,
            B = 1,
            C = 2,
            D = 3,
            E = 4,
            F = 5,
            G = 6
        }
        public Notes noteLetter { get; private set; }
        public Notes translatedLetter { get; private set; }
        public bool isFlat { get; private set; }
        public bool showSharp { get; private set; }

        private const int NOTE_COUNT = 7;

        /// <summary>
        /// Creates a Note
        /// </summary>
        /// <param name="note">The basic note</param>
        /// <param name="flat">Is the note flat?</param>
        /// <param name="sharp">Will be shown as it's sharp counterpart?</param>
        public Note(Notes note, bool flat, bool sharp)
        {
            noteLetter = note;
            isFlat = flat;
            showSharp = sharp;

            if (isFlat && showSharp)
            {
                int hashCode = (int)noteLetter;
                translatedLetter = (Notes)((hashCode + NOTE_COUNT - 1) % NOTE_COUNT);
            }
            else
            {
                translatedLetter = noteLetter;
                showSharp = isFlat;
            }

        }
    }
公共课堂笔记
{
公共枚举注释
{
A=0,
B=1,
C=2,
D=3,
E=4,
F=5,
G=6
}
公共注释注释字母{get;private set;}
公共注释翻译字母{get;private set;}
公共布尔是平坦的{get;私有集;}
公共bool showSharp{get;private set;}
私有常量int NOTE_COUNT=7;
/// 
///创建注释
/// 
///基调
///这张纸条是平的吗?
///是否会显示为锐利的对应物?
公共注释(注释注释、布尔平坦、布尔锐利)
{
noteLetter=注释;
isFlat=平坦;
showSharp=夏普;
如果(isFlat和showSharp)
{
int hashCode=(int)noteLetter;
翻译字母=(注释)((hashCode+注释计数-1)%NOTE计数);
}
其他的
{
翻译字母=注释字母;
showSharp=isFlat;
}
}
}
然后是Game1.cs文件:

 public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        KeyboardState KeyBState, prevKeybState;

        Texture2D sprite;

        Rectangle noteSource;
        Rectangle accSource;

        const int ACCIDENTAL_START_X = 840;

        const int BORDER_OFFSET = 12;

        Vector2 notePosition;

        SpriteFont font;

        /// <summary>
        /// The array of notes, row/column format
        /// </summary>
        Note[,] box;

        const int ROW_SIZE = 3, COLUMN_SIZE = 4;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            box = new Note[ROW_SIZE, COLUMN_SIZE];
            noteSource = new Rectangle(0, 0, 120, 120);
            accSource = new Rectangle(ACCIDENTAL_START_X, 0, 50, 50);

            notePosition = Vector2.Zero;
        }


        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            MakeTable();

            base.Initialize();
        }


        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            sprite = Content.Load<Texture2D>("Note Pieces2");
            font = Content.Load<SpriteFont>("font");
            // TODO: use this.Content to load your game content here
        }


        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }


        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            KeyBState = Keyboard.GetState();

            if (KeyBState.IsKeyDown(Keys.Escape))
                this.Exit();

            if (KeyBState.IsKeyDown(Keys.Space) && prevKeybState.IsKeyUp(Keys.Space))
                MakeTable();

            // TODO: Add your update logic here
            prevKeybState = KeyBState;
            base.Update(gameTime);
        }


        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            for (int r = 0; r < ROW_SIZE; r++)
            {
                for (int c = 0; c < COLUMN_SIZE; c++)
                {
                    Note temp = box[r, c];
                    notePosition.Y = r * noteSource.Width + (r * BORDER_OFFSET);
                    notePosition.X = c * noteSource.Height + (c * BORDER_OFFSET);
                    noteSource.X = temp.translatedLetter.GetHashCode() * noteSource.Width;

                    spriteBatch.Draw(sprite, notePosition, noteSource, Color.White);

                    notePosition.X += noteSource.Width / 2;
                    notePosition.Y += 7;

                    spriteBatch.DrawString(font,
                        temp.noteLetter.ToString() +
                        (temp.isFlat ? "b " : "  ") +
                        temp.translatedLetter +
                        (temp.showSharp ? "#" : ""), notePosition, Color.Black);

                    notePosition.X -= noteSource.Width / 2;
                    notePosition.Y -= 7;

                    if (temp.isFlat)
                    {
                        notePosition.X += 63;
                        notePosition.Y += 63;

                        accSource.X = ACCIDENTAL_START_X;
                        accSource.Y = 0;
                        if (temp.showSharp)
                        {
                            accSource.X += (temp.translatedLetter.GetHashCode() % 2) * (accSource.Width * 2);
                            accSource.Y += ((int)(temp.translatedLetter.GetHashCode() / 2)) * accSource.Height;
                            spriteBatch.Draw(sprite, notePosition, accSource, Color.White);
                        }
                        /*
                    else
                    {
                        accSource.X += (temp.translatedLetter.GetHashCode() % 2) * (accSource.Width * 2) + accSource.Width;
                        accSource.Y += ((int)(temp.translatedLetter.GetHashCode() / 2)) * accSource.Height;
                        spriteBatch.Draw(sprite, notePosition, accSource, Color.White);
                    }
                    */
                    }

                }
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }

        /// <summary>
        /// Makes a new random table of notes
        /// </summary>
        private void MakeTable()
        {
            //make everything null
            for (int r = 0; r < ROW_SIZE; r++)
            {
                for (int c = 0; c < COLUMN_SIZE; c++)
                {
                    box[r, c] = null;
                }
            }

            //then start
            Random rand = new Random();
            for (int i = 0; i < 12; i++)
            {
                bool isUnique;
                bool noteEntered;

                do
                {
                    Note newNote = new Note((Note.Notes)rand.Next(0, 7),
                                rand.Next(0, 2) == 0 ? true : false,
                                rand.Next(0, 2) == 0 ? true : false);

                    isUnique = true;
                    noteEntered = false;
                    //Check to see if there exists a note like this
                    for (int r = 0; r < ROW_SIZE; r++)
                    {
                        for (int c = 0; c < COLUMN_SIZE; c++)
                        {
                            Note temp = box[r, c];
                            if (noteEntered || !isUnique)
                                continue;
                            else if (temp != null &&
                                temp.noteLetter == newNote.noteLetter &&
                                temp.isFlat == newNote.isFlat)
                            {
                                isUnique = false;
                            }
                            else if (temp == null)
                            {
                                box[r, c] = newNote;
                                noteEntered = true;
                            }

                        }
                    }
                } while (!isUnique);
            }
        }
    }
公共类游戏1:Microsoft.Xna.Framework.Game
{
图形管理器图形;
SpriteBatch SpriteBatch;
键盘状态KeyBState,prevKeybState;
纹理2D雪碧;
矩形信源;
矩形源;
const int意外启动=840;
const int BORDER_OFFSET=12;
矢量2位置;
SpriteFont字体;
/// 
///注释数组,行/列格式
/// 
注[,]框;
常量int行大小=3,列大小=4;
公共游戏1()
{
graphics=新的GraphicsDeviceManager(此);
Content.RootDirectory=“Content”;
框=新注释[行大小、列大小];
noteSource=新矩形(0,0,120,120);
accSource=新矩形(意外开始X,0,50,50);
notePosition=Vector2.0;
}
受保护的覆盖无效初始化()
{
//TODO:在此处添加初始化逻辑
MakeTable();
base.Initialize();
}
受保护的覆盖void LoadContent()
{
//创建一个新的SpriteBatch,可用于绘制纹理。
spriteBatch=新spriteBatch(图形设备);
sprite=内容加载(“注释片段2”);
font=内容加载(“font”);
//TODO:使用此.Content在此处加载游戏内容
}
受保护的覆盖无效UnloadContent()
{
//TODO:在此卸载任何非ContentManager内容
}
受保护覆盖无效更新(游戏时间游戏时间)
{
//允许游戏退出
KeyBState=Keyboard.GetState();
if(KeyBState.IsKeyDown(Keys.Escape))
这是Exit();
if(KeyBState.IsKeyDown(Keys.Space)和&prevKeybState.iskeydup(Keys.Space))
MakeTable();
//TODO:在此处添加更新逻辑
prevKeybState=KeyBState;
更新(游戏时间);
}
受保护覆盖无效绘制(游戏时间游戏时间)
{
图形设备。清晰(颜色:矢车菊蓝);
//TODO:在此处添加图形代码
spriteBatch.Begin();
对于(int r=0;r    /// <summary>
    /// A musical note
    /// </summary>
    public class Note
    {
        public enum Notes
        {
            Ab = 10,
            A = 0,
            Bb = 11,
            B = 1,
            C = 2,
            Db = 13,
            D = 3,
            Eb = 14,
            E = 4,
            F = 5,
            Gb = 16,
            G = 6
        }
        /// <summary>
        /// This holds the notes with accidentals
        /// </summary>
        public Notes noteLetter { get; private set; }
        /// <summary>
        /// this holds the note without any accidentals
        /// </summary>
        public Notes naturalLetter { get; private set; }
        /// <summary>
        /// Holds the value of the note if showsharp is true
        /// </summary>
        public Notes translatedLetter { get; private set; }
        /// <summary>
        /// Denotes whether or not the note will represented
        /// as its sharp counterpart, its prerequisite being
        /// that it was flat in the first place
        /// </summary>
        public bool showSharp { get; private set; }

        /// <summary>
        /// Creates a Note
        /// </summary>
        /// <param name="note">The basic note</param>
        /// <param name="sharp">Will be shown as it's sharp counterpart?</param>
        public Note(Notes note, bool sharp)
        {
            noteLetter = note;
            switch(noteLetter)
            {
                case Notes.Ab:
                    naturalLetter = Notes.A;
                    translatedLetter = Notes.G;
                    break;
                case Notes.Bb:
                    naturalLetter = Notes.B;
                    translatedLetter = Notes.A;
                    break;
                case Notes.Db:
                    naturalLetter = Notes.D;
                    translatedLetter = Notes.C;
                    break;
                case Notes.Eb:
                    naturalLetter = Notes.E;
                    translatedLetter = Notes.D;
                    break;
                case Notes.Gb:
                    naturalLetter = Notes.G;
                    translatedLetter = Notes.F;
                    break;
                default:
                    naturalLetter = noteLetter;
                    break;
            }
            showSharp = sharp;

            if (showSharp)
            {
                switch (noteLetter)
                {
                    case Notes.A:
                    case Notes.B:
                    case Notes.C:
                    case Notes.D:
                    case Notes.E:
                    case Notes.F:
                    case Notes.G:
                        showSharp = false;
                        break;
                }
            }

        }

        /// <summary>
        /// Will make a random table of Note objects
        /// </summary>
        /// <param name="table">the array in which to place the Note objects</param>
        public static void MakeTable(out Note[,] table)
        {
            Note[,] temp = new Note[3, 4];

            Random rand = new Random();

            temp[0, 0] = new Note(Notes.Ab, (rand.Next(0, 2) == 0 ? true : false));
            temp[0, 1] = new Note(Notes.A, (rand.Next(0, 2) == 0 ? true : false));
            temp[0, 2] = new Note(Notes.Bb, (rand.Next(0, 2) == 0 ? true : false));
            temp[0, 3] = new Note(Notes.B, (rand.Next(0, 2) == 0 ? true : false));
            temp[1, 0] = new Note(Notes.C, (rand.Next(0, 2) == 0 ? true : false));
            temp[1, 1] = new Note(Notes.Db, (rand.Next(0, 2) == 0 ? true : false));
            temp[1, 2] = new Note(Notes.D, (rand.Next(0, 2) == 0 ? true : false));
            temp[1, 3] = new Note(Notes.Eb, (rand.Next(0, 2) == 0 ? true : false));
            temp[2, 0] = new Note(Notes.E, (rand.Next(0, 2) == 0 ? true : false));
            temp[2, 1] = new Note(Notes.F, (rand.Next(0, 2) == 0 ? true : false));
            temp[2, 2] = new Note(Notes.Gb, (rand.Next(0, 2) == 0 ? true : false));
            temp[2, 3] = new Note(Notes.G, (rand.Next(0, 2) == 0 ? true : false));

            table = new Note[3, 4];

            for (int i = 0; i < 12; i++)
            {
                int row;
                int col;

                row = rand.Next(0, 3);
                col = rand.Next(0, 4);

                while (table[row, col] != null)
                {
                    //Randomly choose if either the row or column will be incremented
                    bool useRow = (rand.Next(0, 2) == 0 ? true : false);

                    //then increment one of them
                    if (useRow)
                    {
                        row = (row + 1) % 3;
                    }
                    else
                    {
                        col = (col + 1) % 4;
                    }
                }

                //Place notes in the empty registers
                if (table[row, col] == null)
                {
                    table[row, col] = temp[(int)(i / 4), i % 4];
                }
            }
        }
    }
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    KeyboardState KeyBState, prevKeybState;

    Texture2D sprite;

    Rectangle noteSource;
    Rectangle accSource;

    const int ACCIDENTAL_START_X = 840;

    const int BORDER_OFFSET = 12;

    Vector2 notePosition;

    SpriteFont font;

    /// <summary>
    /// The array of notes, row/column format
    /// </summary>
    Note[,] box;

    const int ROW_SIZE = 3, COLUMN_SIZE = 4;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        box = new Note[ROW_SIZE, COLUMN_SIZE];
        noteSource = new Rectangle(0, 0, 120, 120);
        accSource = new Rectangle(ACCIDENTAL_START_X, 0, 50, 50);

        notePosition = Vector2.Zero;
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        Note.MakeTable(out box);

        base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        sprite = Content.Load<Texture2D>("Note Pieces2");
        font = Content.Load<SpriteFont>("font");
        // TODO: use this.Content to load your game content here
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        KeyBState = Keyboard.GetState();

        if (KeyBState.IsKeyDown(Keys.Escape))
            this.Exit();

        if (KeyBState.IsKeyDown(Keys.Space) && prevKeybState.IsKeyUp(Keys.Space))
            Note.MakeTable(out box);

        // TODO: Add your update logic here
        prevKeybState = KeyBState;
        base.Update(gameTime);
    }

    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        // TODO: Add your drawing code here
        spriteBatch.Begin();
        for (int r = 0; r < ROW_SIZE; r++)
        {
            for (int c = 0; c < COLUMN_SIZE; c++)
            {
                Note temp = box[r, c];
                notePosition.Y = r * noteSource.Width + ((r + 1) * BORDER_OFFSET);
                notePosition.X = c * noteSource.Height + ((c + 1) * BORDER_OFFSET);
                noteSource.X = (temp.showSharp ? (int)temp.translatedLetter : (int)temp.naturalLetter) * noteSource.Width;

                spriteBatch.Draw(sprite, notePosition, noteSource, Color.White);

                notePosition.X += noteSource.Width / 2;
                notePosition.Y += 7;

                spriteBatch.DrawString(font,
                    temp.noteLetter.ToString() + " " +
                    (temp.showSharp ? "#" : ""), notePosition, Color.Black);

                notePosition.X -= noteSource.Width / 2;
                notePosition.Y -= 7;

                switch (temp.noteLetter)
                {
                    case Note.Notes.Ab:
                    case Note.Notes.Bb:
                    case Note.Notes.Db:
                    case Note.Notes.Eb:
                    case Note.Notes.Gb:
                        notePosition.X += 63;
                        notePosition.Y += 63;

                        int accOffset = 0;
                        if (temp.showSharp)
                        {
                            accSource.X = (int)temp.translatedLetter * noteSource.Width;
                        }
                        else
                        {
                            accSource.X = (int)temp.naturalLetter * noteSource.Width;
                            accOffset = accSource.Width;
                        }

                        accSource.X += accOffset;
                        accSource.Y = noteSource.Height;
                        spriteBatch.Draw(sprite, notePosition, accSource, Color.White);
                        break;
                }

            }
        }
        spriteBatch.End();
        base.Draw(gameTime);
      }
    }