【问题标题】:C# Hangman Game ErrorC# 刽子手游戏错误
【发布时间】:2013-12-31 19:02:47
【问题描述】:

我一直有这个错误。

ArgumentOutOfRangeException 未处理。 指数超出范围。必须是非负数且小于集合的大小。 参数名称:索引

下面是有问题的表单的完整代码,这里是 Hangman 游戏发生的地方。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Hangman_APPD_Assignment
{
public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

列表标签 = new List();是 makeLabels() 方法将使用它的标签。

    String w = "";
    List<Label> labels = new List<Label>();
    int score = 0, missed = 0, correctCount = 0, gameCount = 1;

下面的代码是当用户点击QUIT按钮时,应用程序将关闭。

    private void btnQuit_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

下面的代码是当表单加载或显示时,使用 makeLabels() 方法。

    private void Form2_Load(object sender, EventArgs e)
    {
        makeLabels();
    }

下面的代码是使用随机单词并转换为字符串,用符号“_”替换每个字母。转换后的字符串将被放入一个名为 Labels 的标签内。

    private void makeLabels()
    {
        w = getRandomWord().ToLower();
        w.Replace(" ", "");

        char[] letters = w.ToCharArray();
        int space = 569 / letters.Length - 1;

        for (int i = 0; i < letters.Length; i++)
        {
            labels.Add(new Label());
            labels[i].Location = new Point((i * space) + 10, 109);
            labels[i].Parent = groupBox2;
            labels[i].Text = "_" + i;
            labels[i].BringToFront();
            labels[i].CreateControl();
        }


        lblLength.Text = letters.Length.ToString();
    }

下面的代码是一种在 1) 用户完全猜出单词或 2) 用户猜不出来的情况下创建新游戏的方法。

    private void newGame()
    {
        gameCount++;

        if (gameCount == 15)
        {
            this.Hide();
            if (score >= 7)
            {
                Form4 f4 = new Form4();
                f4.ShowDialog();
            }
            else
            {
                Form6 f6 = new Form6();
                f6.ShowDialog();
            }
        }
        else
        {
            getRandomWord();
            makeLabels();
            enableLetterButtons();
            lblMissed.Text = "";
            hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part0;
        }
    }

下面的代码从字符串数组中获取一个随机词,作为游戏中的神秘词。

    public string getRandomWord()
    {
        Random randomNum = new Random();

        String[] words = {"virus", "network", "syntax", "router", "switch", "worms", "trojan", "email", "bios",
                             "cmos", "ram", "cipher", "malware", "botnet", "cookies", "patches", "cryptograph",
                             "metamorphic", "polymorphic", "rootkit", "logicbomb", "spam", "spyware", "keyloggers",
                             "adware", "software", "hardware", "botherder", "phishing", "whaling", "pharming", 
                             "vishing", "spim", "topology", "tailgating", "loop", "java", "motherboard", "unique",
                             "parameter"};
        int randomNumber = randomNum.Next(0, (words.Length - 1));

        return words[randomNumber];
    }

下面的代码是每次用户猜错时更换图片。

    private void setPicture(int wrongTry)
    {
        switch(wrongTry)
        {
            case 0: 
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part0;
                break;
            case 1: 
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part1;
                break;
            case 2:
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part2;
                break;
            case 3:
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part3;
                break;
            case 4:
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part4;
                break;
            case 5:
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part5;
                break;
            case 6:
                hangPic.Image = Hangman_APPD_Assignment.Properties.Resources.part6;
                break;
        }
    }

下面的代码是当用户点击一个字母按钮时调用一个方法。

    private void checkGuessedLetter(string wordToGuess, string guessedLetter, Button buttonName)
    {
        int strLength = wordToGuess.Length;

        char letter = guessedLetter.ToCharArray()[0];
        buttonName.Enabled = false;

        if (w.Contains(guessedLetter))
        {
            char[] LS = w.ToCharArray();
            for (int i = 0; i < LS.Length; i++)
            {
                if (LS[i] == letter)
                {
                    MessageBox.Show("The value of w is " + w + " AND " + i);
                    labels[i].Text = letter.ToString();
                    conditionPic.Image = Hangman_APPD_Assignment.Properties.Resources.correctpic;
                    correctCount++;
                    MessageBox.Show("You got correct " + correctCount + " time(s).");
                    if (correctCount == strLength)
                    {
                        MessageBox.Show("Good job! Keep it up, matey!", "Victory!", MessageBoxButtons.OK, MessageBoxIcon.None);
                        score++;
                        lblScore.Text = score.ToString();
                        newGame();
                        missed = 0;
                        correctCount = 0;
                        labels.Clear();
                    }
                }

                foreach (Label l in labels)
                    if (l.Text == "__") return;
            }
        }
        else
        {
            conditionPic.Image = Hangman_APPD_Assignment.Properties.Resources.wrong;
            lblMissed.Text += " " + letter.ToString() + " |";
            missed++;
            MessageBox.Show("You missed " + missed + " time(s).");
            setPicture(missed);

            if (missed == 6)
            {
                MessageBox.Show("Unfortunately, you lost this round... Make sure you won't let this happen again, "
                + "or else you will end up in Davy Jones' Locker.", "Defeat!", MessageBoxButtons.OK, 
                MessageBoxIcon.Error);
                newGame();
                missed = 0;
                correctCount = 0;
                labels.Clear();
            }
        }
    }

下面的代码是获取在lblScore标签处累积的分数,以显示在下一个表格中。

    public int getScore()
    {
        int score = int.Parse(lblScore.Text);
        return score;
    }

下面的代码是当用户点击一个包含字母的按钮时调用一个方法来猜测刽子手游戏中的单词。

    private void Abtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "a", Abtn);
    }

    private void Bbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "b", Bbtn);
    }

    private void Cbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "c", Cbtn);
    }

    private void Dbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "d", Dbtn);
    }

    private void Ebtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "e", Ebtn);
    }

    private void Fbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "f", Fbtn);
    }

    private void Gbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "g", Gbtn);
    }

    private void Hbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "h", Hbtn);
    }

    private void Ibtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "i", Ibtn);
    }

    private void Jbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "j", Jbtn);
    }

    private void Kbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "k", Kbtn);
    }

    private void Lbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "l", Lbtn);
    }

    private void Mbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "m", Mbtn);
    }

    private void Nbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "n", Nbtn);
    }

    private void Obtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "o", Obtn);
    }

    private void Pbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "p", Pbtn);
    }

    private void Qbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "q", Qbtn);
    }

    private void Rbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "r", Rbtn);
    }

    private void Sbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "s", Sbtn);
    }

    private void Tbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "t", Tbtn);
    }

    private void Ubtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "u", Ubtn);
    }

    private void Vbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "v", Vbtn);
    }

    private void Wbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "w", Wbtn);
    }

    private void Xbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "x", Xbtn);
    }

    private void Ybtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "y", Ybtn);
    }

    private void Zbtn_Click(object sender, EventArgs e)
    {
        checkGuessedLetter(w, "z", Zbtn);
    }

下面的代码是启用返回上一个游戏中点击过的所有按钮。

    private void enableLetterButtons()
    {
        Abtn.Enabled = true;
        Bbtn.Enabled = true;
        Cbtn.Enabled = true;
        Dbtn.Enabled = true;
        Ebtn.Enabled = true;
        Fbtn.Enabled = true;
        Gbtn.Enabled = true;
        Hbtn.Enabled = true;
        Ibtn.Enabled = true;
        Jbtn.Enabled = true;
        Kbtn.Enabled = true;
        Lbtn.Enabled = true;
        Mbtn.Enabled = true;
        Nbtn.Enabled = true;
        Obtn.Enabled = true;
        Pbtn.Enabled = true;
        Qbtn.Enabled = true;
        Rbtn.Enabled = true;
        Sbtn.Enabled = true;
        Tbtn.Enabled = true;
        Ubtn.Enabled = true;
        Vbtn.Enabled = true;
        Wbtn.Enabled = true;
        Xbtn.Enabled = true;
        Ybtn.Enabled = true;
        Zbtn.Enabled = true;
    }

下面的代码是当用户点击应用右上角的X按钮时关闭应用。

    private void btnOut_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }
}

}

附:对不起,我忘了输入错误的来源。 所以错误在

labels[i].Text = letter.ToString();

在 checkGuessedLetter(string wordToGuess, string guessedLetter, Button buttonName) 方法中。

【问题讨论】:

  • 异常有一个叫做堆栈跟踪的东西,它可以准确地告诉你错误发生在哪一行。另外,您应该了解调试代码:youtube.com/watch?v=C0vDKXIq_9A(我没有看到所有视频)
  • 如果你注释了你的代码,你就不需要继续添加“下面的代码......”这将是一个很长的代码块。
  • 你能在错误行下一个断点,看看标签包含多少对象吗?您的标签似乎没有正确创建。
  • 标签包含 6 个对象?这与单词的长度与单词所具有的字母数量相同
  • ..和LS.Length的值=?当您收到该错误时,i 的值 = ?

标签: c#


【解决方案1】:

问题出在以下几行:

newGame();
missed = 0;
correctCount = 0;
labels.Clear();

关键是停下来想想newGame做了什么,然后想想你后来做了什么?因为这是家庭作业(我从一些名字中推测),所以请好好想想。

完成了吗?好的。所以希望你意识到你的newGame 方法调用MakeLabels 来生成标签,然后你在几行之后清除了labels。这意味着对于后续游戏,您的labels 列表将始终为空。

对此的正确解决方法是,我引用的最后三行都是创建新游戏的一部分,因此应该采用该方法。实际上,您只需要在制作新的时清除labels,因此也将其作为该方法的一部分。这样做,你的程序会更清晰,希望也能工作! :)

【讨论】:

  • 谢谢!耶!你是救生员。太感谢了! :) 好工作!现在很开心。
  • 我希望你很高兴,因为你学到了一些关于调试和良好代码结构的知识,而不仅仅是因为你得到了答案。 ;-)
猜你喜欢
  • 2014-10-19
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 2016-02-13
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
相关资源
最近更新 更多