I'm working on a Hangman project that requires me to change characters "-" to "a to z". Since I'm learning how to code with C#, I have no clue how to do it.
I obviously need to use position because of the case where the word as duplicated letters (EX.: C oo kies)
Here's the code I developed, it makes my thing crashes and it's obviously incomplete.
private void chkA_Checked(object sender, RoutedEventArgs e)
{
if (motRechercher.Contains("a"))
{
int indexDemotRechercher = motRechercher.IndexOf("a");
int k = indexDemotRechercher;
var StringBuilderOP = new StringBuilder(motRechercher);
StringBuilderOP.Remove(indexDemotRechercher, indexDemotRechercher);
StringBuilderOP.Insert(k, "A");
}}
motRechercher is a STRING that I can use everywhere that I randomly pick from a list of 27 words. If this bother, it's a check-box and where I write the text is a Text-box(called txtMot).
Feel free to use other variables, I'll re-adapt after for my own comprehension. I would just like some explanation/examples to help my learning experience.
Here is the code of the randomiser if you really feel like this can help you understand[It works] :
private void btnDemarrer_Click(object sender, RoutedEventArgs e)
{
Random rdn = new Random();
int nbreAleatoire = rdn.Next(0, 27);
motRechercher = lesMots[nbreAleatoire];
if (motRechercher.Length > 0)
{
String str = new String('-', motRechercher.Length);
txtMot.Text = str;
}
}
QUESTION : How do I make a thing that detects duplicate and that will change the "-" to "a-z"?
Ask questions and I'll try to answer them if you think it's unclear.
Here is a quick sample... I have two strings... one for the hidden word the user does NOT see, and another for the one presented, using "-" or even "_" as place-holders for the actual characters.
I have a simple function "IsThereA" which expects a single letter as to the guess of a letter in the word. I then just call for all the letters including a few random ones. The function returns boolean so you can draw the hangman as each failure occurs.
In the "IsThereA" method, I am looking one character at a time for the guessed letter. If found, I replace it by using substring instead of the "-". So once updated, you can use the "WordUserCanSee" property however you need to.
This version doesn't do case-sensitive, but you can adjust as needed.
public class Hangman
{
string HangmanWord = "cookies";
string WordUserCanSee = "-------";
public Hangman()
{
IsThereA("o");
IsThereA("f");
IsThereA("k");
IsThereA("w");
IsThereA("i");
IsThereA("c");
IsThereA("s");
IsThereA("e");
}
public bool IsThereA(string guessLetter)
{
bool anyMatch = false;
for (int i = 0; i < HangmanWord.Length; i++)
{
if (HangmanWord.Substring(i, 1).Equals(guessLetter))
{
anyMatch = true;
WordUserCanSee = WordUserCanSee.Substring(0, i) + guessLetter + WordUserCanSee.Substring(i + 1);
}
}
return anyMatch;
}
}
motRechercher = motRechercher.Replace("-", "a-z");
Related
I'd like to create a short program to download several pictures from a website.
On a form, I would like to enter a root-link to a website with placeholders.
The placeholders can be defined with Start/End value and asc/desc.
For example: the original link is
google.de/1236-01.jpg
and I'd like to generate all links from
google.de/1236-1.jpg
up to
google.de/9955-12.jpg
So my input would be "google.de/[0]-[1].jpg" and placeholders are set to:
[0] = start 1236|end 9955|asc
[1] = start 1|end 12|asc
Via GetValidCharacters() I get a String-List of valid combinations for each entered placeholder (can be selected via ascending/descending + start&end).
The goal I'm struggling with is to build all combinations of this link, because I need to determine while runtime, how much placeholders I have.
My idea was to loop over an queue and enquueue each new build line, until there is none left with placeholders, but I don't know how to do this.
I need to make sure that all combinations are entered and they are entered only once.
private static void CreateDownloadList()
{
Queue<string> tmpQueue = new Queue<string>(); //temp queue
tmpQueue.Enqueue(DL_path); //DL_Path = google.de/[0]-[1].jpg
string line = "";
while ((line = tmpQueue.Dequeue()) != null) //not empty
{
if (line.Contains("[")) //placeholder
{
string tmpLine = line;
//how to determine, which placeholder is next?? need to know this and replace this with every combination, I get from GetValidCharacters(start, end, DESC)
}
else //done
{
_urlList.Add(line);
}
}
}
how about a simple for loop?
for (int i = 1236; i <= 9955; i++)
{
for (int j = 1; j <= 12; j++)
{
tmpQueue.Enqueue(string.Format("google.de/{0}-{1}.jpg", i, j));
}
}
I'm not going give you the full code but here is some pseudo code that would solve the problem.
given :
todostack -- stack object that holds a list of unresolved items
replace_map -- map object that holds marker string and map of all values
marker_list -- list of all markers
final_list -- list object that holds the results
(note you can probably use marker_list and replace_map in one object -- I have them separate to make my code clearer)
init :
push todostack with your starting string
set marker_list and replace_map to correct values (from parameters I assume)
clear final_list
algorithm :
while (there are any items in todostack)
{
curitem = todostack.pop
if (curitem contains a marker in marker_list)
{
loop for each replacement in replace_map
{
new_item = curitem replaced with replacement
todostack.push(new_item)
}
}
else
add curitem to final_list
}
#Hogan this was the hint to the correct way.
solution is this
private void CreateDownloadList()
{
Queue<string> tmpQueue = new Queue<string>();
tmpQueue.Enqueue(downloadPathWithPlaceHolders);
while(tmpQueue.Count > 0)
{
string currentItem = tmpQueue.Dequeue();
bool test = false;
if(currentItem.Contains("["))
{
foreach(Placeholder p in _placeholders)
{
if(currentItem.Contains(p.PlaceHolder))
{
foreach(string s in p.Replacements)
{
tmpQueue.Enqueue(currentItem.Replace(p.PlaceHolder, s));
}
test = true;
}
if(test)
break;
}
}
else
{
_downloadLinkList.Add(currentItem);
}
}
}
I am working o a project that turns message into ascii decimal values... this side is not important, the problem is it needs to read it back so the translation is basically like this:
if (textBox1.Text.Contains("a"))
{
textBox3.Text = textBox3.Text.Replace("a", "97");
}
if (textBox1.Text.Contains("b"))
{
textBox3.Text = textBox3.Text.Replace("b", "98");
}
.
.
.
if (textBox1.Text.Contains("Ğ"))
{
textBox3.Text = textBox3.Text.Replace("Ğ", "286");
}
if (textBox1.Text.Contains("ş"))
{
textBox3.Text = textBox3.Text.Replace("ş", "351");
}
this translation works perfect.
but translating back the output is the problem.
my translating back method in a nutshell:
if (sonmesajBinary.Text.Contains("97"))
{
okunanMesaj.Text = okunanMesaj.Text.Replace("97", "a");
}
if (sonmesajBinary.Text.Contains("98"))
{
okunanMesaj.Text = okunanMesaj.Text.Replace("98", "b");
}
if (sonmesajBinary.Text.Contains("99"))
{
okunanMesaj.Text = okunanMesaj.Text.Replace("99", "c");
}
and the problem is lets say the output is 140
but it also includes "40"
so pc gets it wrong. That's my problem, and i require your kind help:).
i am kinda noob so sorry for my mistakes and i am 17 also english is not my native language.
note: ascii values might not be the real ones, these are just for example.
There are many problems with your code there. Checking Contains will return true for any number of occurrences of a character at any location. You're checking in textBox1 and replacing in textBox3. You're checking each character known to you but it is possible there are more! There are easier ways of getting the byte/int/number equivalent of your character based on the encoding of your input.
Here's a rudimentary solution based on comments following the question. You however need to read more about code pages and then encodings. This is only part of the Encrypt operation. I'm sure you can figure out how to replace the contents and later also Decrypt to usable format. Cheers! Happy coding.
static void Main(string[] args)
{
string fileContents = "";
int encryptKey = 3; // Consider getting this from args[0], etc.
using (FileStream fs = File.OpenRead(#"C:\Users\My\Desktop\testfile.txt"))
using (TextReader tr = new StreamReader(fs))
{
fileContents = tr.ReadToEnd();
}
byte[] asciiBytesOfFile = Encoding.ASCII.GetBytes(fileContents);
int[] encryptedContents = Encrypt(encryptKey, asciiBytesOfFile);
}
private static int[] Encrypt(int encryptKey, byte[] asciiBytesOfFile)
{
int[] encryptedChars = new int[asciiBytesOfFile.Length];
for (int i = 0; i < asciiBytesOfFile.Length; i++)
{
encryptedChars[i] = encryptKey ^ asciiBytesOfFile[i];
}
return encryptedChars;
}
It was fixed thanks to Tom Blodget, all I needed to do was delimit. So I added 0 to beginning of every 2 digit values:D
if (textBox1.Text.Contains("a"))
{
textBox3.Text = textBox3.Text.Replace("a", "097");
}
I am quite new the C# and I have googled the answer. The closest answer I have found was this one. But it doesn't help me.
I am trying to write a function that finds the biggest number in a string using loops and splicing only. For some reason, when the condition is met, the local variable big won't mutate in the if statements. I have tried to debug it by setting big = 34 when I hit a space, but even then it won't mutate the local variable.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace parser
{
class Sub_parser
{
// function to find the greatest number in a string
public int Greatest(string uinput)
{
int len = uinput.Length;
string con1 = "";
int big = 0;
int m = 0;
// looping through the string
for (int i = 0; i < len; i++)
{
// find all the numbers
if (char.IsDigit(uinput[i]))
{
con1 = con1 + uinput[i];
}
// if we hit a space then we check the number value
else if (uinput[i].Equals(" "))
{
if (con1 != "")
{
m = int.Parse(con1);
Console.WriteLine(m);
if (m > big)
{
big = m;
}
}
con1 = "";
}
}
return big;
}
public static void Main(string[] args)
{
while (true)
{
string u_input = Console.ReadLine();
Sub_parser sp = new Sub_parser();
Console.WriteLine(sp.Greatest(u_input));
}
}
}
}
The problem comes from your check in this statement :
else if (uinput[i].Equals(" "))
uinput[i] is a char, while " " is a string : see this example
if you replace the double quotes by single quotes, it works fine...
else if (uinput[i].Equals(' '))
And, as stated by the comments, the last number will never be checked, unless your input string ends by a space. This leaves you with two options :
recheck again the value of con1 after the loop (which is not very good-looking)
Rewrite your method because you're a bit overdoing things, don't reinvent the wheel. You can do something like (using System.Linq):
public int BiggestNumberInString(string input)
{
return input.Split(null).Max(x => int.Parse(x));
}
only if you are sure of your input
When you give a number and a space in the keyboard you only read the number, no space.
So you have uinput="34".
Inside the loop, you check if the m > big only if uinput[i].Equals(" "). Which is never.
In general if you read a line, with numbers followed by space, it would ignore the last number.
One solution would be to append a " " into uinput, but i recommend splicing.
string[] numbers = uinput.Split(null);
Then iterate over the array.
Also, as said in another answer compare uinput[i].Equals(' ') because " "represents a string, and you were comparing a char with a string.
As Martin Verjans mentioned, in order to make your code work you have to edit it like in his example.
Although there is still a Problem if you input a single number. The output would then be 0.
I would go for this Method:
public static int Greatest(string uinput)
{
List<int> numbers = new List<int>();
foreach(string str in uinput.Split(' '))
{
numbers.Add(int.Parse(str));
}
return numbers.Max();
}
So I am so fresh into the world of programming, starting new, I decided to start messing around in C# to create simple apps from ideas that come to mind, with this little app, I'm trying to have multiple TextBoxes named d1,d2,d3,d4,etc... the user inserts numbers into the textboxes then clicks button1, which begins the process in the code below creating a new list which contains all of the values of the textboxes and then the list is converted to an array and the array is then converted into an int array, etc....
BUT, when starting the application and I add values to the textboxes and then click button1, it shows 2 error like shows in the //gray code line below
Please help.
private void button1_Click(object sender, EventArgs e)
{
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
foreach(string numb in dodo)
{
if (numb == "")
numb = "0"; //numb word has a red underline
}
string[] terms = dodo.ToArray();
int[] valv = {};
int x = 0;
for(int i=0;i<=19;i++)
{
valv[i] = int.Parse(terms[i]); //the ; in the end has a red underline and shows "FormatException was unhandled" error
i++;
x = x + valv[i];
}
string myString;
myString = x.ToString();
Result1.Text = myString;
}
you can't change the iteration variable which is numb in your case. Please change in the List container instead
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
int k = 0;
foreach (string numb in dodo)
{
if (numb == "")
{
//numb = "0"; //numb word has a red underline
dodo[k] = "0";
}
k++;
}
Now your code on parsing into integer won't give any runtime error.
The first line "tells" you that you are not able to assign a new value to the variable which is used as a foreach iteration variable.
The second line, "tells" you that you have string value which is not able to be parsed correctly (e.g. user put string which is not a number). To avoid this you can use Int32.TryParse method instead, which will safely try to parse the given string.
The best and easiest way to achieve what you need is using LINQ methods, here is the example based on few things/assumptions:
Since you are converting empty strings into zeros, you could simply skip those entries from counting
To avoid FormatException, you should use TryParse method instead. Since TryParse method will safely parse the given string, you don't even have to filter empty strings at all (they will be skipped). However, I deliberately left filtering part, to get you a better overview of a solution.
You can use list initializer to make list initialization more readable
Solution:
List<string> dodo = new List<string>()
{
d1.Text, d2.Text //...others
};
int sum = dodo
.Where(item => !String.IsNullOrEmpty(item))
.Sum(item =>
{
if (Int32.TryParse(item, out int parsedItem))
{
return parsedItem;
}
return 0;
});
You can get more familiar with LINQ and used methods on following link
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;
}