2014-12-28 2 views
0

이 코드는 고유 한 무작위 음표로 구성된 배열을 생성하려고합니다. 주어진 매개 변수에 따라 메모를 작성하고 우발적 인 기호를 지정하여 평평하거나 날카로운 부분으로 표시 할 수 있습니다. 예를 들어 임의 생성기가 음표 "A"가 평평하다고 말하면 A ♭ 또는 G # 중 하나로 표시 될 수 있습니다.임의 생성기 코드?

이제는 절반 단계 음표 (예 : C ♭가 B # 등으로 바뀌 었음)를 처리하지 않았지만 주로 첫 부분이 작동하지 않기 때문입니다. 지금 가지고있는 문제는 내가 사용하고있는 코드가 일관되게 작동하지 않는 것입니다. 메모를 올바르게 번역하고 다른 사람을 망칠 것입니다. 체계적인 오류 패턴도 없습니다. 최소한 해독하려 한 것이 아닙니다.

화면에 메모를 표시하기 위해 XNA를 사용하고 있지만 실제로 문제가 있습니다. 내가 만든 Note 클래스를 사용하고 있습니다.

먼저 Note 클래스 : 다음

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

     } 
    } 

은 Game1.cs 파일 : 메인 코드 실행 모든 것이 MakeTable()

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

입니다

다음

내가 사용하고 코드입니다 방법,하지만 다른 곳에 문제가있는 경우를 대비하여 모든 것을 넣었습니다. 내가 아는 한, 그래픽 라이브러리 이외에, XNA Framework와 관련된 라이브러리를 사용하고 있지 않습니다. 그러면이 라이브러리가 잘못 될 수 있습니다. CodePlex에서 만든 XNA를 다시 사용하고 있습니다. 나는 그들이 아직 몇 가지 일을하고 있다는 것을 알고 있지만 이것은 문제가되어서는 안된다. 누군가 이걸로 나를 도울 수 있습니까?

+0

이 왜 열거 정수 값을 지정하지 않습니다? 캐스팅이 문제 일 수 있습니다. – zaitsman

+2

메모 클래스의 오류 : GetHashCode를 호출하면 임의의 숫자가 생길 수 있습니다. 그러지 마십시오. 또 다른 오류 : 당신은 너무 메모 클래스와 그 생성자에 bool을 가지고 있지만, 현재 논리와 함께, 그들은 항상 같은 값을 가질 것입니다 (그들이 동일하지 않으면 showSharp = isFlat 할당은 동일하게 만듭니다). 그리고이 질문에 가장 문제가되는 부분은 실제 결과와 예상 결과를 말해줘야한다는 것입니다. 나는 여기서 무엇을 이루려고하는지 전혀 모르며, 음표도 이해하지 못합니다. – fejesjoco

+0

한 번에 하나씩. 나는 GetHashCode()가 문제가되는지 몰랐다. 나는 전에 그것을 사용했고, 나는 지금까지이 문제가 없었습니다. 그러나, 나는 그것을 사용하는 것을 멈출 용의가있다. showSharp 및 isFlat에 관해서 : 나는 둘 다에 대한 이유가 있습니다.다만 당신이 모르는 경우에, 예리하고 편평한 것이 긍정 부정 같이 작동하지 않는다; 샤프, 자연 (날카롭지 않거나 평평하지 않음), 플랫 한 세 가지 값이 있습니다. 각각의 음표는 자연스런 키를 제외하고는이 값 중 하나 일 가능성이 있습니다. 이 경우, 상대 샤프 (sharps)와 플랫 (flat)은 서로 이어지게됩니다. TBC –

답변

0

지금 알아 냈습니다. 나는 Lee Daniel Crocker의 충고를 받아 내 프로그램을 수정했다. 12 값 열거 형을 만들고 MakeTable() 메서드를 편집하여 별개 세트의 각 노트를 가져 와서 다른 배열로 임의로 공급합니다. 또한, 나는 쉽게 그림을 그릴 수 있도록 그림을 수정했습니다. 뒤늦은 시각에서 심지어 은 왜 내가 원래 한 짓을했는지 모른다.

덧붙여서 MakeTable()을 쓰기 쉽도록 MakeTable()Note 클래스로 옮겼습니다.

여기 내 코드입니다 :

첫째, Note :

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

그리고 Game1 :

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