索引超出范围...。但是它似乎没有超出范围,所以怎么回事?

时间:2018-10-16 12:27:12

标签: c# indexoutofrangeexception

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

namespace CardDealer
{
    class Deck
    {

        string[] deck = new string[52];

        string[] name = new string[13];

        string[] suits = new string[4];

        public Deck()
        {
            name[0] = "Ace ";
            name[1] = "Two ";
            name[2] = "Three ";
            name[3] = "Four ";
            name[4] = "Five ";
            name[5] = "Six ";
            name[6] = "Seven ";
            name[7] = "Eight ";
            name[8] = "Nine ";
            name[9] = "Ten ";
            name[10] = "Unterknave ";
            name[11] = "Oberknave ";
            name[12] = "King ";

            suits[0] = "of Hearts";
            suits[1] = "of Bells";
            suits[2] = "of Acorns";
            suits[4] = "of Leaves";

            for (int i = 0; i < 13; i++)
            {
                deck[i] = name[i] + suits[0];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 13] = name[i] + suits[1];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 26] = name[i] + suits[2];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 39] = name[i] + suits[3];
            }
        }

        Random rnd = new Random();
        int cardsLeft = 52;

        public void Shuffle()
        {
            string[] deck = new string[52];

            for (int i = 0; i < 13; i++)
            {
                deck[i] = name[i] + suits[0];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 13] = name[i] + suits[1];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 26] = name[i] + suits[2];
            }

            for (int i = 0; i < 13; i++)
            {
                deck[i + 39] = name[i] + suits[3];
            }


            string[] myrandomarray = deck.OrderBy(x => rnd.Next()).ToArray();

            deck = myrandomarray;

            cardsLeft = 52;
        }



        public string Deal()
        {

            string deltCard = deck[0];

            cardsLeft--;

            string[] newDeck = new string[cardsLeft];

            for (int i = 0; i < cardsLeft + 1; i++)
            {
                if (deck[i] != deltCard)
                {
                    newDeck[0] = deck[i];
                }
            }

            deck = newDeck;

            return deltCard;





        }


    }

    class play
    {
        static void Main()
        {

            Deck mydeck = new Deck();

            Console.WriteLine(mydeck.Deal());


        }
    }



}

大家好,我的代码在这里遇到了麻烦。有两节课,一堂课制作一个套牌,另一堂课玩。当我执行此代码时,它将引发错误(超出索引范围),但我只是没有看到它,就像我不知道它如何超出范围一样,它向我显示了超出范围的位置,但它似乎没有超出范围,怎么回事?

4 个答案:

答案 0 :(得分:3)

您缺少索引3,而是有4:

suits[0] = "of Hearts";
suits[1] = "of Bells";
suits[2] = "of Acorns";
suits[4] = "of Leaves";

将最后一行更改为:

suits[3] = "of Leaves";

答案 1 :(得分:3)

请勿明确地放置索引:

        string[] suits = new string[4];

        ...

        suits[0] = "of Hearts";
        suits[1] = "of Bells";
        suits[2] = "of Acorns";
        suits[4] = "of Leaves";  // <- it must be "3", not "4"

但是请使用初始化器

        // create array with items mentioned
        string[] suits = new string[] {
          "of Hearts", 
          "of Bells", 
          "of Acorns", 
          "of Leaves"
        };

编译器为您完成常规工作。与namedeck相同:

// Let's get rid of trailing spaces
string[] name = new string[] {
  "Ace", 
  "Two",
  "Three",
  "Four",
  "Five",
  "Six",
  "Seven",
  "Eight",
  "Nine",
  "Ten",
  "Unterknave",
  "Oberknave",
  "King",
};

// as well as pesky "of": suit "Acorns" or "Clubs", not "of Acorns"
string[] suits = new string[] {
  "Hearts",
  "Bells",
  "Acorns",
  "Leaves",
};

string[] deck;

public Deck() {
  // All combinations of name and suits (cartesian join)
  // Avoid magic numbers like 13 (some games like preference has 8 cards in a suit)
  deck = name
    .SelectMany(n => suits.Select(s => $"{n} of {s}")) // <- space and "of" here
    .ToArray();

答案 2 :(得分:1)

  

suits [4] =“叶子”;

应该是

suits[3] = "of Leaves";

答案 3 :(得分:1)

虽然您已经直接回答了问题,但我可以提供一些代码改进,使您的生活更加轻松。

  • 每当使用for循环迭代数组时,将i < array.Length优先于i < SomeHardCodedValue

  • 要填充卡片组,请不要使用4个不同的循环,请使用嵌套循环。

  • 在改组时不要填充新的纸牌,而是创建现有纸牌的副本并对其进行混洗,或者只是对现有纸牌进行混洗。

  • 当对值进行硬编码时,
  • 更喜欢在循环中使用数组初始化程序。

将所有这些要点组合到代码中,一个更好的版本将如下所示:

class Deck
{
    // The next two arrays are static since they are always the same,
    // no point of making multiple copies of them for each instance of the class
    private static string[] name = new string[] 
    {
        "Ace", "Two", "Three", "Four" /* more of the same here*/
    };

    private static string[] suits = new string[]
    {
        "Hearts", "Bells", "Acorns", "Leaves"
    };

    // all the fields used in this class
    private string[] deck = new string[suits.Length * name.Length];
    private int lastDelt = 0;
    private Random rnd = new Random();

    public Deck()
    {
        // see how simple the constructor is now
        for(var i = 0 ; i < suits.Length; i++)
        {
            for(var j = 0; j < name.Length; j++)
            {
                // Calculate deck index using i and j
                deck[(i+1) * j] = name[j] +" of "+ suits[i];
            }
        }
    }

    public void Shuffle()
    {
        // You might want to look into the Fisher-Yates shuffle instead, link below.
        deck = deck.OrderBy(x => rnd.Next()).ToArray();

        cardsLeft = deck.Length;
    }

    public string Deal()
    {
        if(lastDelt >= deck.Length)
        {
            throw new Exception("No cards left in the deck");
        }
        string deltCard = deck[lastDelt];
        lastDelt++;
        return deltCard;
    }

}

当然,您可以将整个卡片组放在一个硬编码的静态数组中,然后在每个构造函数中使用它的一个副本。

A link to a c# implementation of the Fisher-Yates shuffle algorithm,如所承诺的。