Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I get an index out of range when I make a empty guess, I also have problem with updating my score label. Currently it will go through the update but not perform it on the form. I’d also like to make sure the user can’t keep entering a valid letter to get more points, please help just got back to learning c# and projects like this help me learn
namespace Guess_The_Word
{
public partial class Form1 : Form
{
private int wrongGuesses = 0;
private int userGuesses;
private int score = 0;
private string secretWord = String.Empty;
private string[] words;
private string currentWord = string.Empty;
private string userGuess = string.Empty;
private string userInput = string.Empty;
private string randomInput = string.Empty;
public Form1()
{
InitializeComponent();
}
private void guessBtn_Click(object sender, EventArgs e)
{
string guess = userInputBox.Text.ToString();
char[] randomCharArray = currentWord.ToLowerInvariant().ToCharArray();
char[] userInputArray = guess.ToLowerInvariant().ToCharArray();
//Assume that userInput would never be superior than randomCharArray
//And contain only one char
for (int i = 0; i < randomCharArray.Length; i++)
{
if (userInputArray[0].Equals(randomCharArray[i])) // Here is where the error happens
{
UpdateScore();
}
}
// Clean userInput in form
userInputBox.Text = string.Empty;
}
private void resetGamebtn_Click(object sender, EventArgs e)
{
SetUpWords();
}
private void SetUpWords()
{
string path = (#"C:\commonwords.txt"); // Save the variable path with the path to the txt file
words = File.ReadAllLines(path);
int guessIndex = (new Random()).Next(words.Length);
currentWord = words[guessIndex];
wordlbl.Text = string.Empty;
for (int i = 0; i < currentWord.Length; i++)
{
wordlbl.Text += "*";
}
}
private void UpdateScore()
{
scorelbl.Text = Convert.ToString(score);
}
}
}
Make sure you check the length of the array before attempting to access specific indices whether known or not. The example below is kind of overkill on the logic, but it demonstrates the previous statement thoroughly.
if (userInputArray.Length > 0 && userInputArray.Length > i)
if (randomCharArray.Length > 0 && randomCharArray.Length > i)
if (userInputArray[0].Equals(randomCharArray[i]))
UpdateScore();
private void UpdateScore() {
score++;
scorelbl.Text = Convert.ToString(score);
}
I went over to .NET Fiddle and did a basic run through without all of the extra complexity of using arrays and I'm returning some pretty good results. The logic in the example below is pretty basic and will currently only handle the current word having only one of each letter. You'll have to expand on it from here to allow handling of multiple letters in words such as "banana" or "apple".
Hopefully this will get you headed in the right direction with your project, and I hope my answer above taught you what you needed to know about checking the length of arrays before attempting to access their indices.
using System;
using System.Collections.Generic;
public class Program
{
private static int score = 0;
private static string currentWord = string.Empty;
private static char userGuess = '`';
private static List<char> correctLetters = new List<char>();
public static void Main()
{
currentWord = "are";
do {
Console.WriteLine("Enter a letter: ");
userGuess = Console.ReadLine()[0];
} while (TestInput());
Console.WriteLine("The word was: " + currentWord);
Console.ReadLine();
}
private static bool TestInput() {
if (currentWord.ToLowerInvariant().Contains(userGuess.ToString().ToLowerInvariant())) {
correctLetters.Add(userGuess);
score++;
Console.WriteLine("Current Score: " + score);
}
if (correctLetters.Count == currentWord.Length)
return false;
return true;
}
}
Related
I'm still a noob at working with data so I don't know where to look for more advanced algorithms. Where can I find the info about a string searching algorithm that doesn't require exact input?
I want to make a little programm that works pretty much like this: there are quotes and tags asociated with them, a random tag appears and the user has to input a quote that might be compatible with it, my lil programm searches if it has the quote, returns true or false and shows you the number of mistakes.
Here's what i've done so far
public readonly struct Quote
{
public readonly string[] Tags;
public readonly string TheQuote;
public Quote(string theQuote, params string[] tags)
{
Tags = tags;
TheQuote = theQuote;
}
}
static void MatchTag()
{
Console.WriteLine("Input a quote that might fit the tag");
var input = Console.ReadLine();
var inpL = input.Length;
var allowedMistakes = 5;
var possibleQuotes = quotes.Where(q => q.Tags.Contains(currTag) && inpL.IsInRange(q.TheQuote.Length, q.TheQuote.Length < 10 ? 2 : q.TheQuote.Length / 10));
foreach (var quote in possibleQuotes)
{
var quoteTxt = quote.TheQuote;
int diff = quoteStr.Length - inpL, length, mistakesNum=0;
if (diff < 0)//go through the smallest string to not throw an error
{
length = quoteTxt.Length;
mistakesNum += -diff;
}
else
length = inpL;
bool clear = false;
for (int i = 0; i < length; i++)
{
if (input[i] != quoteTxt[i])
mistakesNum++;
if (mistakesNum > allowedMistakes)
{
clear = true;
break;
}
}
if (clear)
continue;
//show that you are right and return;
Console.WriteLine("The quote fits the tag!");
Console.WriteLine("Mistakes: " + mistakesNum);
return;
}
Console.WriteLine("The quote doesn't fit the tag!");
}
This is what the game looks like:
The player has to click on the word in the lower half in the correct order of the upper paragraph.
For example, The upper paragraph starts with "This", the user has to find and touch "This" on the lower half. He gets 3 tries to get it right. If he clicks on the wrong word, he looses a life.
In my code, I have managed to separate the words in the first string by checking for spaces and dots in between them and used a StringBuilder to add individual letters and later transfer that to another string that stores the whole word.
//Proper Working Code
public class Queue2Test : MonoBehaviour {
private string paraString = "This is not the end of the line. This is only the beginning. It cannot get much worse.";
private StringBuilder buffer;
private string finalString;
private int counter;
void Start () {
buffer = new StringBuilder ();
finalString = null;
counter = 0;
dothis ();
}
void dothis () {
for (counter = 0; counter < paraString.Length; counter++) {
buffer = buffer.Append(paraString[counter]);
if (paraString[counter] == ' ' || paraString[counter] == '.') {
//buffer.Remove(counter,1);
finalString = buffer.ToString();
buffer.Length = 0;
print (finalString);
}
}
}
}
Which works. The output of the above code is all the words printed one by one. Now what I want to do is, change this in such a way that each word prints only when I click on the mouse. And to do that I did this:
// This code needs editing:
public class Queue3Test : MonoBehaviour {
private string paraString = "This is not the end of the line. This is only the beginning. It cannot get much worse.";
private StringBuilder buffer;
private string finalString;
private int counter;
private bool flag;
private int tempvalue;
void Start () {
buffer = new StringBuilder ();
finalString = null;
counter = 0;
flag = false;
tempvalue = 0;
}
void Update () {
if (flag) {
dothis ();
}
}
void OnMouseDown () {
flag = true;
//print (flag);
}
void dothis () {
for (counter = tempvalue; counter < paraString.Length; counter++) {
buffer = buffer.Append(paraString[counter]);
if (flag) {
if (paraString[counter] == ' ' || paraString[counter] == '.') {
//buffer.Remove(counter,1);
finalString = buffer.ToString();
buffer.Length = 0;
print (finalString);
tempvalue = counter;
flag = false;
continue;
}
//break;
}
}
}
}
This code's output is this:
This //First Click
is not the end of the line. This is only the beginning. It cannot get much worse. //Second Click
This code prints the first line after the first click and on the second click it prints the remaining line all at once!
I want each word printed separately one after the other on mouse click.
I click on a small collider on the right side of the paragraph to invoke the mouse click function.
I am fairly new to programming using C# and I am making this game for my college project. Any help in this will be useful or just point me towards the right direction. I would definitely mention the answerers name on the game's credits!!!
Thanks. :)
First of all, regarding your first problem.
All you have to do is call
words = paraString
.Split(new[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries)
.ToList();
this will return you an array of words, ignoring all the whitespace and empty ones. From here on out you can do something like this:
void OnMouseDown() {
var wordToShow = words.Skip(currentWord).FirstOrDefault();
if (!String.IsNullOrEmpty(wordToShow)) {
currentWord++;
Debug.Log(wordToShow);
} else {
Debug.Log("Nothing left...");
}
}
Just be sure to store words list as private field of your behaviour script like this:
private IList<string> words;
You can initialize it by splitting your input string in the Start() or Awake() functions. I would use start.
At first, you should avoid this style of naming variables and functions (flag, dothis).
At second, you've chose not appropriate solution to solve the task. It can be resolved much simplier.
using UnityEngine;
using System;
public class Queue3Test : MonoBehaviour {
private string paraString = "This is not the end of the line. This is only the beginning. It cannot get much worse.";
private string[] words;
private int counter = 0;
private void Start()
{
InitializeParaString();
}
private void OnMouseDown()
{
ShowNextWord();
}
private void InitializeParaString()
{
counter = 0;
words = paraString.Split(new[] { '.', ' ' }, StringSplitOptions.RemoveEmptyEntries);
}
private void ShowNextWord()
{
if (counter < words.Length)
{
print(words[counter]);
counter++;
}
}
}
Good Luck!
I got a code for line numbering, it works perfectly fine for numbering lines the regular way but I'm looking for something a little bit different. I want my code to only count line breaks when i press enter(the program receives an return keycode) and not then the textbox automatically cut the lines with word wrapping. This is the code i'm using right now:
//Instructions
int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + "\n");
}
maxLC = linecount;
}
}
How i think i would be done easiest is by saving the line count every time someone presses enter to a list and also everytime someone presses enter it updates the line number texbox with every line number at positions said in list. But i have no idea how to detect when an return is removed. Anybody knows how to solve this?
Extremely basic example that counts the lines in your code you posted:
class Program
{
static void Main(string[] args)
{
string stringFromTextBox =
#" int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + ""\n"");
}
maxLC = linecount;
}
}";
Regex r = new Regex("\r", RegexOptions.Multiline);
int lines = r.Matches(stringFromTextBox).Count;
//You'll need to run this line every time the user presses a key
}
}
i have debugged my code (below) and found out the problem is the Convert() method that converts the text from the textbox. but how i fix this problem?
i have a example of similar problem here.
code:
//METHODS
static string RollDice (int dice)
{
Random roll = new Random();
int rollOutput = roll.Next(1, dice);
//NOTE: VERY IMPORTANT! EVERY TIME THE INPUT GOES INTO THIS
//METHOD REMEMBER TO INCREACE IT BY ONE!
//AND NEVER LET THE USER TO ROLL TO DICE QUICKLY ONE AFTER ANOTHER!
string rollResult = rollOutput.ToString();
return rollResult;
}
static void TwiceD20(int bonus, bool advantage)
{
string firstRollString = RollDice(21) + bonus;
string secondRollString = RollDice(21) + bonus;
int firstRoll = Convert.ToInt32(firstRollString);
int secondRoll = Convert.ToInt32(secondRollString);
switch(advantage)
{
case true:
if (firstRoll >= secondRoll)
{
MessageBox.Show(firstRollString);
}
else
{
MessageBox.Show(secondRollString);
}
break;
case false:
if (firstRoll <= secondRoll)
{
MessageBox.Show(firstRollString);
}
else
{
MessageBox.Show(secondRollString);
}
break;
}
}
//BUTTONS
private void btn1d20_Click(object sender, EventArgs e)
{
MessageBox.Show("Roll Result: " + RollDice(21));
}
private void btnAdv_Click(object sender, EventArgs e)
{
TwiceD20(Convert.ToInt32(textBox1d20.Text), true);
}
private void btnDisAdv_Click(object sender, EventArgs e)
{
TwiceD20(Convert.ToInt32(textBox1d20.Text), false);
}
You have added a non-int into the string. So naturally you cannot convert that to an int because the string is not just an int anymmore.
string firstRollString = RollDice(21) + bonus; // This won't convert back to an int
string secondRollString = RollDice(21) + bonus; // This won't convert back to an int
int firstRoll = Convert.ToInt32(firstRollString);
int secondRoll = Convert.ToInt32(secondRollString);
Adding bonus to the string result of RollDice is simply appending the string "True" or "False" to the result of RollDice. I suspect that you think it is adding a numerical 0 or 1.
I would do as the comments suggest and have RollDice return a number. Then you can turn it into a string and manipulate it later as you see fit.
Or, if you don't want to return anything, just make a quick change to the order of operations.
int firstRoll = Convert.ToInt32(RollDice(21));
int secondRoll = Convert.ToInt32(RollDice(21));
string firstRollString = firstRoll + bonus;
string secondRollString = secondRoll + bonus;
But, not knowing for sure what you intend for your code to do, even that may not work for you.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to convert a column number (eg. 127) into an excel column (eg. AA)
Ok so I am writing a method which accepts a 2d array as a parameter. I want to put this 2d array onto an Excel worksheet but I need to work out the final cell location. I can get the height easily enough like so:
var height = data.GetLength(1); //`data` is the name of my 2d array
This gives me my Y axis but it's not so easy to get my X axis. Obviously I can get the number like so:
var width = data.GetLength(0);
This gives me a number, which I want to convert to a letter. So, for example, 0 is A, 1 is B and so on until we get to 26 which goes back to A again. I am sure that there is a simple way to do this but I have a total mental block.
What would you do?
Thanks
Here's a version that also handles two-letter columns (after column Z):
static string GetColumnName(int index)
{
const string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var value = "";
if (index >= letters.Length)
value += letters[index / letters.Length - 1];
value += letters[index % letters.Length];
return value;
}
Just cast it to a char and do "ToString()".
using System;
using System.Collections.Generic;
public class MyClass
{
public static void RunSnippet()
{
int myNumber = 65;
string myLetter = ((char) myNumber).ToString();
WL(myLetter);
}
#region Helper methods
public static void Main()
{
try
{
RunSnippet();
}
catch (Exception e)
{
string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
Console.WriteLine(error);
}
finally
{
Console.Write("Press any key to continue...");
Console.ReadKey();
}
}
private static void WL(object text, params object[] args)
{
Console.WriteLine(text.ToString(), args);
}
private static void RL()
{
Console.ReadLine();
}
private static void Break()
{
System.Diagnostics.Debugger.Break();
}
#endregion
}