C# Test Box Manipulation when reading from a File - c#

I am trying to code a simple game where my program randomly selects a word from a dictionary and stores it in a text box/or label? (Not Sure of this part). Then I have another text box where the user enters his guess.
Now I want to give the user some hint.F or example the word:
'game' would look like '_ a m _' or 'g _ _ e'. I have no preference to how the characters are placed.
I have programmed all of the previous code including the random file handling method, all timers and counter etc. I am just stuck on this part.
The program undergoes the following code :
var lines = File.ReadAllLines(#"LOCATION");
textBox3.Text = lines[new Random().Next(lines.Length)];
to select a random word from the file. However the whole word is being shown in textbox 3 and not parts of it like i wish. I am at a complete loss for ideas on how to proceed. I could not find anything similar on the web.
Cheers,
R

Once you pick a random word from file, based on length of the word, decide on how many characters you'd want to hide and then randomly replace those many characters.
something like this-
public string GetPartialWord(string word)
{
if(string.IsNullOrEmpty(word))
{
return string.Empty;
}
char[] partialWord = word.ToCharArray();
int numberOfCharsToHide = word.Length / 2;
Random randomNumberGenerator = new Random();
HashSet<int> maskedIndices = new HashSet<int>();
for(int i=0;i<numberOfCharsToHide;i++)
{
int rIndex = randomNumberGenerator.Next(0, word.Length);
while(!maskedIndices.Add(rIndex))
{
rIndex = randomNumberGenerator.Next(0, word.Length);
}
partialWord[rIndex] = '_';
}
return new string(partialWord);
}

The code below will replace at least half of the characters with underscores. The code takes a word and keeps generating random numbers until it has replaced at least half of the characters with underscores.
public string ConvertToGuessWord(string word)
{
var guessWord = word;
int lastRandom = 0;
do
{
Random rand = new Random();
int thisRandom = 0;
do
{
thisRandom = rand.Next(0, guessWord.Length);
} while (lastRandom == thisRandom);
guessWord = guessWord.Replace(guessWord[thisRandom], '_');
lastRandom = thisRandom;
} while (guessWord.Count(x => x == '_') < (word.Length / 2));
return guessWord;
}

Related

How to swap huge string

I have huge string e.g (This is just the part, the string looks same it has just a bit different values).
string numbers = "48.7465504247904 9.16364437205161 48.7465666577545 9.16367275419435 48.746927738083 9.16430761814855 48.7471066512883 9.16462219521963 48.7471147950429";
So I have to swap the whole number e.g.
Output should be:
9.16364437205161 48.7465504247904
Also I need to swap the first and second part.
So I've tried to split the string, and then to replace the old one with the new one.
string numbers = "48.7465504247904 9.16364437205161 48.7465666577545 9.16367275419435 48.746927738083 9.16430761814855 48.7471066512883 9.16462219521963 48.7471147950429";
string output = "";
double first = 0;
double second = 0;
for (int i = 0; i < numbers.Length; i++)
{
numbers.Split(' ');
first = numbers[0];
second = numbers[1];
}
output = numbers.Replace(numbers[1], numbers[0]);
Console.WriteLine(output);
But my variable first always after the loop has the value 52.
Right now my output is: 44.7465504247904 9.16364437205161, it changed the first part, also it calculates somehow -4
.
You're not assigning anything to the value coming back from .Split and, if I read this right, you're also iterating each character in the numbers array for unclear reasons.
Using .Split is all you need ... well, and System.Linq
using System.Linq;
// ...
string SwapNumbers(string numbers) {
return numbers.Split(' ').Reverse().Join();
}
The above assumes you want to reverse the whole series of numbers. It absolutely does not swap 1,2 then swap 3,4 etc. If that's what you're looking for, it's a bit more involved and I'll add that in a second for funsies.
string SwapAlternateNumbers(string numbersInput) {
var wholeSeries = numbersInput.Split(' ').ToList();
// odd number of inputs
if (wholeSeries.Count % 2 != 0) {
throw new InvalidOperationException("I'm not handling this use case for you.");
}
var result = new StringBuilder();
for(var i = 0; i < wholeSeries.Count - 1; i += 2) {
// append the _second_ number
result.Append(wholeSeries[i+1]).Append(" ");
// append the _first_ number
result.Append(wholeSeries[i]).Append(" ");
}
// assuming you want the whole thing as a string
return result.ToString();
}
Edit: converted back to input and output string. Sorry about the enumerables; that's a difficult habit to break.
here
public static void Main()
{
string nums = "48.7465504247904 9.16364437205161 48.7465504247904 9.16364437205161";
var numbers = nums.Split(' ');
var swapped = numbers.Reverse();
Console.WriteLine("Hello World {"+string.Join(" ",swapped.ToArray())+"}");
}

Generation of random capital letters in C# while checking to generate only one pair from each

Hi I'm trying to code basic console Pexeso game in C#. And I'm wondering how to generate one and only one pair of capital letters.
So far my code can genereate string with random capital letters but I don't know how to control it to generate only two and only two from each one.
string chars = "AABBCCDDEEFFGGHHIIJJKKLL";
var stringChars = new char[24];
Random random = new Random();
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[random.Next(chars.Length)];
}
string finalString = new String(stringChars);
Console.WriteLine(finalString);
Thank you very much for your help.
You start off well by defining all items you want in your final sequence.
What you want to do next is not take items from that list (in a way that you can take them more than once) as you do now, instead you actually want to shuffle your list.
Imagine your letters are playing cards, and you take two full sets. You shuffle them, and you have a sequence of playing cards, in which every card appears exactly twice.
To shuffle your set of letters, or any given sequence, you can use the Fisher-Yates shuffle.
Something like this should do the trick:
for (int i = chars.Length - 1; i > 0; i--)
{
char j = random.Next(i + 1);
int temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
Now your finalString is no longer needed: the result you want is in your chars array.
One of the trivial solutions for your problem is using LINQ's method OrderBy with a random number:
string chars = "AABBCCDDEEFFGGHHIIJJKKLL";
Random random = new Random();
var shuffled = chars.OrderBy(c => random.Next(chars.Length));
string finalString = new string(shuffled.ToArray());
Console.WriteLine(finalString);
Sometimes you may see people using Guid instead of random numbers:
string chars = "AABBCCDDEEFFGGHHIIJJKKLL";
var shuffled = chars.OrderBy(c => Guid.NewGuid());
string finalString = new string(shuffled.ToArray());
Console.WriteLine(finalString);

Adding 'space' in C# textbox

Hi guys, so I need to add a 'space' between each character in my displayed text box.
I am giving the user a masked word like this He__o for him to guess and I want to convert this to H e _ _ o
I am using the following code to randomly replace characters with '_'
char[] partialWord = word.ToCharArray();
int numberOfCharsToHide = word.Length / 2; //divide word length by 2 to get chars to hide
Random randomNumberGenerator = new Random(); //generate rand number
HashSet<int> maskedIndices = new HashSet<int>(); //This is to make sure that I select unique indices to hide. Hashset helps in achieving this
for (int i = 0; i < numberOfCharsToHide; i++) //counter until it reaches words to hide
{
int rIndex = randomNumberGenerator.Next(0, word.Length); //init rindex
while (!maskedIndices.Add(rIndex))
{
rIndex = randomNumberGenerator.Next(0, word.Length); //This is to make sure that I select unique indices to hide. Hashset helps in achieving this
}
partialWord[rIndex] = '_'; //replace with _
}
return new string(partialWord);
I have tried : partialWord[rIndex] = '_ ';however this brings the error "Too many characters in literal"
I have tried : partialWord[rIndex] = "_ "; however this returns the error " Cannot convert type string to char.
Any idea how I can proceed to achieve a space between each character?
Thanks
The following code should do as you ask. I think the code is pretty self explanatory., but feel free to ask if anything is unclear as to the why or how of the code.
// char[] partialWord is used from question code
char[] result = new char[(partialWord.Length * 2) - 1];
for(int i = 0; i < result.Length; i++)
{
result[i] = i % 2 == 0 ? partialWord[i / 2] : ' ';
}
return new string(result);
Since the resulting string is longer than the original string, you can't use only one char array because its length is constant.
Here's a solution with StringBuilder:
var builder = new StringBuilder(word);
for (int i = 0 ; i < word.Length ; i++) {
builder.Insert(i * 2, " ");
}
return builder.ToString().TrimStart(' '); // TrimStart is called here to remove the leading whitespace. If you want to keep it, delete the call.

Need help finding n amount of Excel Ranges

So I have this situation:
At work I need to make an Excel AddIn which can collect some data from user surveys and show them in a neat little Excel Report. I have the format down however I have trouble figuring out how I find the Excel Ranges needed to showcase the questions that were asked in the survey.
Every question needs to take up three cells each since there are three stats associated with each and that's fine until you reach Z and have to start over with AA, AB, AC, etc. I can't quite wrap my head around it and I feel my current solution is being needlessly complicated. I know that right now there are 13 questions. That's 39 cells I need for the questions total but that could change in the future, or I might have to find smaller reports than all of the 13 questions. I need to make sure my algorithm can take care of both scenarios.
Currently I have this:
const String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphabetCounter = 0;
int alphabetIndex = 1;
for (int i = 0; i < dict["questions"].Length; i++)
{
String start = "";
String end = "";
if ((alphabetIndex + 1) > ALPHABET.Length)
{
alphabetCounter++;
alphabetIndex = 0;
start += ALPHABET[alphabetCounter - 1] + ALPHABET[alphabetIndex];
}
else
{
start += ALPHABET[alphabetIndex];
alphabetIndex++;
}
if ((alphabetIndex + 1) > ALPHABET.Length)
{
alphabetCounter++;
alphabetIndex = 0;
end += ALPHABET[alphabetIndex];
}
else
{
alphabetIndex++;
end += ALPHABET[alphabetIndex];
}
Excel.Range range = sheet.get_Range(start + "7", end + "7");
questionRanges.Add(range);
}
It's not finished because I ran into a wall here. So just to explain:
ALPHABET is just that. The alphabet. I use that to get the cell letters.
AlphabetCounter is how many times I have gone through the alphabet so in the event that I need to add an extra letter in front of my cells letter (Like the A in AB) I can get that from the ALPHABET string
AlphabetIndex is where in the alphabet I currently am.
I hope you can help me.
How would I go about getting all the ranges I need to accompany the n amount of questions I can get details about?
The trivial solution would be to change
const string ALPHABET = "ABC..."
to
const string[] ColumnNames = { "A", "B", "C", ..., "Z", "AA".. }
But this doesn't scale well. Think about what happens when you need to add a column. You'd have to add another item in the array, and eventually you'd have 26^2 array entries. Certainly not ideal.
A better solution would be to treat the column index as a base 26 number and convert it using a function like the following:
string GetColumnName(int index)
{
List<char> chars = new List<char>();
while (index >= 0)
{
int current = index % 26;
chars.Add((char)('A' + current));
index = (int)((index - current) / 26) - 1;
}
chars.Reverse();
return new string(chars.ToArray());
}
The function here converts the base by repeatedly calculating the remainder (also known as modulus or %).
just another idea of implementation, maybe it can be useful:
...
List<char> start = new List<char>();
List<char> end = new List<char>();
start = Increment(end);
Increment(end);
Increment(end);
Excel.Range range = sheet.get_Range(new String(start.ToArray())+ "7",
new String(end.ToArray())+ "7");
}
private List<char> Increment(List<char> listColumn, int position=0)
{
if (listColumn.Count > position)
{
listColumn[position]++;
if (listColumn[position] == '[')
{
listColumn[position] = 'A';
Increment(listColumn, ++position);
}
}
else
{
listColumn.Add('A');
}
return listColumn;
}

I want to use every single letter of a word and randomize it but it doesn't work in C#

Yes I have searched a lot for a solution and yes I am a beginner and this is the first time that I asked a question through this website. I usually ask it to my teacher but I have a holiday and I am spending my free time on learning C#.
I have a task which I made up by myself and the task is a game where you have to put a word into a console application and the console has to randomize every single letter of the word so that the other player has to guess what the word is.
example : the word is "programming" and after that the console will mix up the letters of the word, so it could be "ginamrmgorp" and the player has to guess what the word is.
string woord = Console.ReadLine();
Random random = new Random();
char[] woorden = woord.ToCharArray();
for (int i = 0; i < woorden.Length; i++)
{
kiesgetal = random.Next(0, woorden.Length);
char letter = woorden[kiesgetal];
Console.Write("letter: ");
Console.WriteLine(letter);
}
Console.ReadKey();
The problem is that the console isn't using every letter of the word but the console is using some letters (not all) of the word and it puts it in the length of the word so it isn't "ginamrmgorp" but "gimmmmoopra".
Basically you wanna shuffle the character array. You can do that easily using Fisher-Yates shuffle algorithm, as implemented in this answer. Here is the modified version for arrays:
public static void Shuffle<T>(this T[] list)
{
Random rng = new Random();
int n = list.Length;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Then just use it like this:
char[] woorden = woord.ToCharArray();
woorden.Shuffle();
string shuffledWord = new string(woorden);
Random.Next will not necessarily return a different number each time. It's entirely likely that you will get the same number muptiple times.
What you want to do is shuffle the letters, which can be done by ordering by a random number:
char[] woorden = woord.ToCharArray();
var woordenShuffled = woorden.OrderBy(c => random.Next()).ToArray();
for (int i = 0; i < woordenShuffled.Length; i++)
{
char letter = woordenShuffled[i];
Console.Write("letter: ");
Console.WriteLine(letter);
}
or if you just want to create the whole string:
string woordShuffled = new string(woord.OrderBy(c => random.Next()).ToArray());

Categories

Resources