Im making a hangman game, at the start of the game the word that the player must guess is printed as stars. I have just started making it again after attempting to write it once and just having messy code that i couldn't bug fix. So I decided it best to write it again. The only problem is, when i try to get my array to print out by using array.ToString(); it just returns System.char[]. See below.
code:
class Program
{
static void Main(string[] args)
{
string PlayerOneWord;
string PlayerTwoGuess;
int lives = 5;
Console.WriteLine("Welcome to hangman!\n PLayer one, Please enter the word which player Two needs to guess!");
PlayerOneWord = Console.ReadLine().ToLower();
var stars = new char[PlayerOneWord.Length];
for (int i = 0; i < stars.Length ; i++)
{
stars[i] = '*';
}
string StarString = stars.ToString();
Console.Write("Word to Guess: {0}" , StarString);
Console.ReadLine();
}
}
output:
The output should say Word to guess: Hello.
Please will someone explain why this is happening as its not the first time I have run into this problem.
Calling ToString on a simple array only returns "T[]" regardless what the type T is. It doesn't have any special handling for char[].
To convert a char[] to string you can use:
string s = new string(charArray);
But for your concrete problem there is an even simpler solution:
string stars = new string('*', PlayerOneWord.Length);
The constructor public String(char c, int count) repeats c count times.
The variable stars is an array of chars. This is the reason you get this error. As it is stated in MSDN
Returns a string that represents the current object.
In order you get a string from the characters in this array, you could use this:
Console.Write("Word to Guess: {0}" , new String(stars));
The correct way to do this would be:
string StarString = new string(stars);
ToString() calls the standard implementation of the Array-class's ToString-method which is the same for all Arrays and similarily to object only returns the fully qualified class name.
Try this code:
static string ConvertCharArr2Str(char[] chs)
{
var s = "";
foreach (var c in chs)
{
s += c;
}
return s;
}
Related
I have to write a program were the user inputs the names (Aryah Stark, etc) and the otuput some to be Stark, Aryah. I cant seem to figure out why my code isn't coming out that way though. I know the Reverse. Array method but I don't know if I placing it right or not. Can someone help me?
class Program
{
static void Main(string[] args)
{
Console.WriteLine("How many names do you want to enter? ");
string name = Console.ReadLine();
int arraySize = Convert.ToInt32(name);
string[] LaName = new string[arraySize];
Array.Reverse(LaName);
for (int i = 0; i < LaName.Length; i++)
{
Console.WriteLine("Enter last name");
LaName[i] = Console.ReadLine();
}
foreach (string val in LaName)
{
Console.WriteLine(val + "\t");
}
Console.ReadKey();
}
}
Array.Reverse reverses a sequence of elements.
Based on example, what you need is reversing of a words in a string, so Split the string to words and then use Array.Reverse to reverse the array.
You could try using either of these solutions, place this logic inside your for loop (after reading user input).
string[] words = LaName[i].Split(' ');
Array.Reverse(words);
LaName[i] = String.Join(" ", words);
or simply (.Net 3.5 and aboeve)
LaName[i] =String.Join(" ", LaName[i].Split(' ').Reverse());
Check this Example
Okay, so I'm creating a hang-man game (Lame, I know, but I gotta' start somewhere). I have successfully pulled ~30 random words from a text file into a variable and can properly display the word in a random order onto the screen (just to test and make sure the variable is obtaining a whole word in random order).
But I need to take that string and break it into single characters in order to 'blank' out the letters to be 'guessed' by the user. I assume an array is the best way to do this - coupled with a while loop that will run while the character != null.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hangman
{
class Program
{
static void Main(string[] args)
{
String[] myWordArrays = File.ReadAllLines("WordList.txt");
Random randomWord = new Random();
int lineCount = File.ReadLines("WordList.txt").Count();
int activeWord = randomWord.Next(0, lineCount);
/*CharEnumerator activeWordChar = activeWord; --- I have tried this,
but it says "Cannot implicitly convert type 'int' to 'System.CharEnumerator'
--- while redlining "activeWord." */
/*CharEnumerator activeWordChar = activeWord.ToString
-- I have tried this but it says "Cannot convert method group 'ToString' to
non-delegate type 'System.CharEnumerator'. Did you intend to invoke the method?
I also tried moving the declaration of activeWordChar below the 'writeline'
that displays the word properly to the console.
I have even tried to create a Char[] activeWordChar = activeWord.toCharArray; But this doesn't work either.
*/
//I'm using this writeline "the word for this game is: " ONLY to test that the
//system is choosing random word **end comment
Console.WriteLine("The Word for this game is: " + myWordArrays[activeWord]);
//Console.WriteLine("The Characters are like this: " + activeWordChar[]);
//my attempt at printing something, but it doesn't work. :(
Console.ReadLine();
}
}
}
I'm open to references in order to figure it out myself, but I'm kinda' stuck here.
Also, how do I close the file that I've opened so that it can be accessed later on in the program if need be? I've only learned the StreamReader("filename") way of 'variable.Close();' - but that isn't working here.
Edit
And why someone would vote this question down is beyond me. lol
A couple of points here (first of all, you are off to a great start):
You are needlessly re-reading your file to get the line count. You can use myWordArrays.Length to set your lineCount variable
Regarding your question about closing the file, per MSDN File.ReadAllLines() closes the file after it is done reading it, so you are fine there with what you already have.
A string itself can be treated like an array in terms of accessing by index and accessing its Length property. There's also the ability to iterate over it implicitly like so:
foreach (char letter in myWordArrays[activeWord])
{
// provide a blanked-out letter for each char
}
You can access any character in the string by its index, so you can think of string as array of chars:
For example, like this snippet:
string word = "word";
char w1 = word[0];
Console.WriteLine(w1);
You can simplify your code a bit as follows. Previously your activeWord variable was an integer and therefore cannot be converted to a character array.
static void Main(string[] args)
{
String[] myWordArrays = File.ReadAllLines("WordList.txt");
Random random = new Random();
string activeWord = myWordArrays[random.next(myWordArrays.Length)];
char[] chars = activeWord.ToCharArray();
}
However a string in C# can be treated as an enumerable object and therefore you should only be using a character array if you need to mutate parts of the string.
Thanks to Sven, I was able to figure it out and I was able to add some things onto it as well!! I'm posting this for other newbs to understand from a newb's perspective:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hangman
{
class Program
{
static void Main(string[] args)
{
printWord();
}
/*I created a method to perform this, so that I can have the program stay open for
either 1) a new game or 2) just to see if I could do it. It works!*/
private static void printWord()
{
String[] myWordArrays = File.ReadAllLines("WordList.txt");
Random randomWord = new Random();
//int lineCount = File.ReadLines("WordList.txt").Count();
//The line below fixed my previous issue of double-reading file
int activeWord = randomWord.Next(0, myWordArrays.Length);
string userSelection = "";
Console.WriteLine("Are you Ready to play Hangman? yes/no: ");
userSelection = Console.ReadLine();
if(userSelection == "yes")
{
/*This runs through the randomly chosen word and prints an underscore in
place of each letter - it does work and this is what fixed my
previous issue - thank you Sven*/
foreach(char letter in myWordArrays[activeWord])
{
Console.Write("_ ");
}
//This prints to the console "Can you guess what this 'varyingLength' letter word is?" - it does work.
Console.WriteLine("Can you guess what this "+ myWordArrays[activeWord].Length +" letter word is?");
Console.ReadLine();
}
//else if(userSelection=="no") -- will add more later
}
}
}
Okay, so I'm creating a hangman game and everything functions so far, including what I'm TRYING to do in the question.
But it feels like there is a much more efficient method of obtaining the char that is also easier to manipulate the index.
protected static void alphabetSelector(string activeWordAlphabet)
{
char[] activeWord = activeWordAlphabet.ToCharArray();
string activeWordString = new string(activeWord);
Console.WriteLine("If you'd like to guess a letter, enter the letter. \n
If you'd like to guess the word, please type in the word. --- testing answer{0}",
activeWordString);
//Console.WriteLine("For Testing Purposes ONLY");
String chosenLetter = Console.ReadLine();
//Char[] letterFinder = Array.FindAll(activeWord, s => s.Equals(chosenLetter));
//string activeWordString = new string(activeWord);
foreach (char letter in activeWord);
{
if(activeWordString.Contains(chosenLetter))
{
Console.WriteLine("{0}", activeWordString);
Console.ReadLine();
}
else
{
Console.WriteLine("errrr...wrong!");
Console.ReadLine();
}
}
}
I have broken up the code in some areas to prevent the reader from having to scroll sideways. If this is bothersome, please let me know and I'll leave it in the future.
So this code will successfully print out the 'word' whenever I select the correct letter from the random word (I have the console print the actual word so that I can test it successfully each time). It will also print 'wrong' when I choose a letter NOT in the string.
But I feel like I should be able to use the
Array.FindAll(activeWord, ...)
functionality or some other way. But every time I try and reorder the arguments, it gives me all kinds of different errors and tells me to redo my arguments.
So, if you can look at this and find an easier method of searching the actual array for the user-selected 'letter', please help!! Even if it's not using the Array.FindAll method!!
Edit
Okay, it seems like there's some confusion with what I've done and why I've done it.
I'm ONLY printing the word inside that 'if' statement to test and make sure that the foreach{if{}} will actually work to find the char inside the string. But I ultimately need to be able to provide a placeholder for a char that is successfully found, as well as being able to 'cross out' the letter (from the alphabet list not shown here).
It's hangman - surely you guys know what I'm needing it to do. It has to keep track of which letters are left in the word, which letters have been chosen, as well as which letters are left in the entire alphabet.
I'm a 4-day old newb when it comes to programming, so please. . . I'm only doing what I know to do and when I get errors, I comment things out and write more until I find something that works.
Take a look at this demo I put together for you: https://dotnetfiddle.net/eP9TQM
I'd suggest creating a second string for the display string. Use a StringBuilder, and you can replace the characters in it at specific indices while creating the fewest number of stringobjects in the process.
string word = "your word or phrase here";
//Initialize a new StringBuilder that will display the word with placeholders.
StringBuilder display = new StringBuilder(word.Length); //You know the display word is the same length as the original word
display.Append('-', word.Length); //Fill it with placeholders.
So now you have your phrase/word, and a string builder full of characters that need to be discovered.
Go ahead and convert the display StringBuilder to a string that you can check on each pass to see if it equals your word:
var displayString = display.ToString();
//Loop until the display string is equal to the word
while (!displayString.Equals(word))
{
//Inside here your logic will follow.
}
So you are basically looping until the person answers here. You could of course go back and add logic to limit the number of attempts, or whatever you desire as an alternate exit strategy.
Inside this logic, you will check if they guessed a letter or a word based on how many characters they entered.
If they guessed a word, the logic is simple. Check if the guessed word is the same as the hidden word. If it is, then you break the loop and they are done. Otherwise, guessing loops back around.
If they guessed a letter, the logic is pretty straightforward, but more involved.
First get the character they guessed, just because it may be easier to work with this way.
char guess = input[0];
Now, look over the word for instances of that character:
//Look for instances of the character in the word.
for (int i = 0; i < word.Length; ++i)
{
//If the current index in the word matches their guess, then update the display.
if (char.ToUpperInvariant(word[i]) == char.ToUpperInvariant(guess))
display[i] = word[i];
}
The comments above should explain the idea here.
Update your displayString at the bottom of the loop so that it will check against the hidden word again:
displayString = display.ToString();
That's really all you need to do here. No fancy Linq needed.
Ok your code is really confusing, even with your edit.
First, why these 2 lines of code since activeWordAlphabet is a string :
char[] activeWord = activeWordAlphabet.ToCharArray();
string activeWordString = new string(activeWord);
Then you do your foreach.
For the word "FooBar", if the player types 'F', you will print
FooBar
FooBar
FooBar
FooBar
FooBar
FooBar
How does this help you in anything?
I think you have to review your algorithm. The string type have the function you need
int chosenLetterPosition = activeWord.IndexOf(chosenLetter, alreadyFoundPosition)
alreadyFoundPosition is an int from where the function will search the letter
IndexOf() returns -1 if the letter is not find or a positive number.
You can save this position with your letter in a dictionary to use it again as your new 'alreadyFoundPosition' if the chosenLetter is already in the dictionary
This is my answer. Because I don't have a lot of tasks today :)
class Letter
{
public bool ischosen { get; set; }
public char value { get; set; }
}
class LetterList
{
public LetterList(string word)
{
_lst = new List<Letter>();
word.ToList().ForEach(x => _lst.Add(new Letter() { value = x }));
}
public bool FindLetter(char letter)
{
var search = _lst.Where(x => x.value == letter).ToList();
search.ForEach(x=>x.ischosen=true);
return search.Count > 0 ? true : false;
}
public string NotChosen()
{
var res = "";
_lst.Where(x => !x.ischosen).ToList().ForEach(x => { res += x.value; });
return res;
}
List<Letter> _lst;
}
How to use
var abc = new LetterList("abcdefghijklmnopqrstuvwxyz");
var answer = new LetterList("myanswer");
Console.WriteLine("This my question. Why? write your answer please");
char x = Console.ReadLine()[0];
if (answer.FindLetter(x))
{
Console.WriteLine("you are right!");
}
else
{
Console.WriteLine("fail");
}
abc.FindLetter(x);
Console.WriteLine("not chosen abc:{0} answer:{1}", abc.NotChosen(), answer.NotChosen());
At least we used to play this game like that when i was a child.
I am still a beginner in C# and I know there is a method that can be used to do this but I can't seem to find it online.
I have a function that permutates a word
static void Main(string[] args)
{
string[] list = "a b c d".Split();
foreach (string[] permutation in Permutations<string>.AllFor(list))
{
System.Console.WriteLine(string.Join(" ", permutation));
}
}
However it only works with words that are broken up. (eg. "a b c d" ) Since that is not really a practical way to ask a user for input, I want to find a way to take a word from the user (an unbroken word like "hello" ) and break it up for the function to understand. Eg. form the input word of the use "happy" to a spaced word for the program to understand = "h a p p y"
I tried this code:
//splits the word into an array
string[] arr = name.Split();
//splits the array with spaces to enter into the program
name = string.Join(" ",arr);
arr = name.Split();
But it just ends up coming out unbroken anyway. Can someone tell me the easiest way to do this?
Just to mention I am still a beginner in C# and programming in total I might not understand some of the higher level concepts. I have been through some answers on this website and I have seen some answers that I don't understand at all.
You can loop over the string to convert it to an array, and then use Join.
using System.Text.RegularExpressions;
using System;
public class Program{
public static void Main(string[] args) {
string v = "hello";
// Convert into the a string array, the old-fashioned way.
string[] name = new string[v.Length];
for (int i = 0; i < v.Length; i++)
name[i] = v[i] + "";
string feedToPermutationFunction = string.Join(" ",name));
// Feed the above string into your permutation code.
}
}
You just need to separate each character and then concatenate them with a space:
This is the simplest way:
var userInput = Console.ReadLine();
var output = string.Join<char>(" ", userInput);
Console.WriteLine(output);
char[] array=input.ToArray();
string val="";
for(int i=0;i<array.Length;i++)
{
val+=array[i]+" ";
}
this will give you a string with spaces like you wanted Val
create an array with the string length
string[] strarray=new string[val.Length];
for(int i=0;i<strarray.Length;i++)
{
strarray[i]=val.Substring(i,len); //**i** is for string index,,,**len** string length in each index
}
Is there any method that I can use that returns a fixed length array after spliting a string with some delimiter and fill the rest with a default string.
Eg.
string fullName = "Jhon Doe";
string[] names = fullName.SpecialSplit(some parameters); //This should always return string array of length 3 with the second elememnt set to empty if there is no middle name.
Next time specify the language you're asking about. We're no guessers.
In Java:
fullName.split(" ");
And anyway, no method will "return string array of length 3 with the second elememnt set to empty if there is no middle name". For the method, there are just two elements. You have to write that method yourself wrapping the standard split() method.
You should read over Jon Skeet's Writing the perfect question. It will be beneficial to you in the future when posting questions of StackOverflow.
There is no method in C# to do what you are asking, but you can easily write an extension method to do what I think you are asking.
here is a quick example:
public static class AbreviatorExtention
{
public static string[] GetInitials(this String str, char splitChar)
{
string[] initialArray = new string[3];
var nameArray = str.Split(new char[] { splitChar },
StringSplitOptions.RemoveEmptyEntries);
if (nameArray.Length == 2)
{
var charArrayFirstName = nameArray[0].ToCharArray();
var charArrayLastName = nameArray[1].ToCharArray();
initialArray[0] = charArrayFirstName[0].ToString().ToUpper();
initialArray[1] = string.Empty;
initialArray[2] = charArrayLastName[0].ToString().ToUpper();
}
else
{
for (int i = 0; i < nameArray.Length; i++)
{
initialArray[i] = (nameArray[i].ToCharArray())[1]
.ToString().ToUpper();
}
}
return initialArray;
}
}
class Program
{
static void Main(string[] args)
{
string FullName = "john doe";
//Extension method in use
string[] names = FullName.GetInitials(' ');
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
Output:
J
D
I would set it up to split the string separate from the fixed array. If you still want a fixed array, then you set up the array to a size of three an populate. This is not the best method, however, as it has no meaning. Better, set up a person or user class and then populate, via rules, from the split string.