Minesweeper(simple) in c# [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
so I'm working on some small thing and I'm kind of lost. This is what I have so far.
static void izris()
{
Random bombe = new Random();
int[,] polje = new int[7, 7];
string stolpci = " ABCDEFG";
int vrstice=1;
foreach (char c in stolpci)
{
Console.Write(c);
Console.Write(" ");
}
Console.WriteLine();
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 7; j++)
{
polje[i, j] = bombe.Next(0, 2);
}
}
//izris polja
for(int i=0;i<7;i++)
{
Console.Write(vrstice);
vrstice++;
Console.Write(" ");
for (int j = 0; j < 7; j++)
{
Console.Write(polje[i,j]);
Console.Write(" ");
}
Console.WriteLine();
}
}
So what this does is, it prints a field of 7x7 that contains random numbers from 0 to 1. Now 1 means it is a mine, and 0 means it's not a mine. Now if you look, there are characters marking the columns(ABCDEFG) and numbers from 1-7 marking the rows. Now what I want to do is, for example the user would enter a string and the string would be B4. Then the program would check that and see if the field that the user selected is a mine(0) or a bomb(1). If it is a bomb it would also say how many bombs(1's) are nearby. I have no idea how to do this.
I was thinking of transforming the A-F characters into 0,6 numbers so I could index easier, but I don't know.
So I made this to check if the input is correct.
static void vnospolja()
{
string lokacija;
string nekaj = "A";
int nekaj2 = nekaj[0] - 'A';
lokacija = Convert.ToString(Console.ReadLine());
while (lokacija.Length < 2)
{
string pravilnalokacija=lokacija.Substring(0,1);
int pravilnalokacijaint = pravilnalokacija[0];
if(pravilnalokacijaint>65 && pravilnalokacijaint<72)
{
Console.Write("input ok");
}
string drugiznak = lokacija.Substring(1, 1);
int drugiznakint = drugiznak[0];
if(drugiznakint>0 && drugiznakint<8)
{
Console.Write("input ok");
}
}
}
Now I need some ideas on how I would do this, for instance user enters A4, so the input is correct. So how do I actually move accros my 7,7 field and check for A4? I don't understand this, my friend told me something about a second indexer in my multidimensional field but I have no clue.

to just convert the users input into 0 based coordinates you could use this.
static int[] GetInput()
{
string input = Console.ReadLine();
//validate input here..
int x = input[0] - 'A'; //converts char to int
int y = int.Parse(input.Substring(1)) - 1;
return new int[]{ x, y };
}
You could use this method by doing...
var selected = GetInput();
if(polje[selected[0]][selected[1]] == 1)
{
//its a bomb
}

What about using a Dictionary instead of using an Array?
Dictionary<string, bool> p = new Dictionary<string, bool>();
if (p.ContainsKey("a1"))
{
//do something
}
else { } // not a bomb/mine
So you can easily check wether the field is a bomb.

If you want to translate a user input, such as B4 into row and column, here is a simple way you could do it. Since you already have a collection of column names stolpci, you can use string.IndexOf, which will find the position of a character in a string. For example, B is found in place 2 (using 0-based indexing)
01234567
" ABCDEFG"
Since you would want B to map to column number 1, rather than 2 in the minesweeper array, you would need to subtract one.
As far as the number part goes, you can use int.Parse to read the number. Once again, the number is going to be off by one, because row number 4 actually corresponds to row number 3 in the 0-based indexing for the minesweeper array. So your final result might look something like this:
var input = "B4"; // this would come from the user, hard-coding for example
var column = stolpci.IndexOf(entry.Substring(0, 1)); // 2
var row = int.Parse(entry.Substring(1, 1)); // 4
var isBomb = polje[row - 1, col - 1] == 1; // offset by 1 for 0-based indexing
// do something with this

Related

Reverse String, Array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
C# code for reversing a string
I couldn't understand this part
arr[name.Length - i] = name[i - 1];
Let us have a name of 5 characters. so the value of the arr will be 4, right?
Then in the loop, the looping variable is also taking the same length, so its initial value will be 4, too.
In the first iteration, the value of arr[4 - 4] will be arr[0] and name[4 - 1] will be name[3], so the first index of arr is copied with the fourth index of name.
How is the original name stored in reversed order in arr?
static void Main(string[] args)
{
Console.Write("What is your name: ");
var name = Console.ReadLine();
var arr = new char[name.Length];
for (var i = name.Length; i > 0; i--)
arr[name.Length - i] = name[i - 1];
var reversed = new string(arr);
Console.WriteLine(reversed);
}
I've reproduced the image of original code here.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("What is your name? ");
string name = Console.ReadLine();
var arr = new char[name.Length];
for (var i = name.Length; i > 0; i--){
arr[name.Length -1] = name[i-1];
}
var reversed = new string(arr);
Console.WriteLine(reversed);
}
}
It looks like the indexing is just off a little. You want to take the length of the name that you've entered (the end of it) and take the characters starting from the end back to the beginning of the word. Below I've changed a few variable names to add a little more meaning to the code.
public static void CorrectedMain()
{
Console.WriteLine("What is your name? ");
string name = Console.ReadLine();
char[] reversedLetters = new char[name.Length];
for (var i = name.Length; i > 0; i--){
reversedLetters[i-1] = name[name.Length -i ];
}
var reversed = new string(reversedLetters);
Console.WriteLine(reversed);
}
If you enter Thomas in the first block you get back T, if you run the code in the second block you will get back samohT.
Here is a fiddle of it.
https://dotnetfiddle.net/txwyd1
In answer to your question: Strings and arrays are zero-indexed. I.e. the first element is at index 0. The last is at Length - 1.
The code in your example is not very well-written. It breaks a couple of basic coding principles.
Iterate forwards, unless there is a very specific need to go backwards. In this case, there is not.
Use zero-based variables when doing any code involving strings and arrays.
The example breaks both these, and I think that's part of what it makes it hard to read, but let's try.
Looking at the iteration, if Length is 5 as you suggested then i starts at 5 and goes down to 1. When i is 5: (name.Length - i) = 0, and i - 1 = 4, so the array index 0 (the first in the array) gets the character at position 4 (which is the 5th character).
On the next iteration, i is 4: (name.Length - i) = 1, and i - 1 = 3, so the array index 1 (the second in the array) gets the character at position 3 (which is the 4th character).
And so on.
Here's a slightly nicer version of the same algorithm. Hopefully, it is a bit easier to read.
public static void Main()
{
Console.Write("What is your name: ");
string name = Console.ReadLine();
int n = name.Length;
char[] arr = new char[n];
for (int i = 0; i < n; i++)
arr[i] = name[n - 1 - i];
string reversed = new String(arr);
Console.WriteLine(reversed);
}

How would I add to an integer based on characters in a string?

Basically, I'm creating a game and I have gotten to the stage where I need to add a score to an integer.
Lets say that the integer is called totalScore.
I currently have a string named spacedLetters which contains 7 letters randomly picked from a 26 letter array (the alphabet). I have created a simple:
Console.WriteLine("Please Enter A Word:");
userInput = Console.ReadLine();
Section that allows the user to input a word. All I want to do is to check through this string that they input (userInput) and add a value to totalScore based on what letters are in the word they inputted.
This should work a bit like scrabble as if they input room, it would value the r, then the o, then the other o, then the m and add a value that is assigned to these letters to the total score. I understand that I will need a reference table as well but I simply don't know how to do this.
TL;DR, I need a reference table for letters in the alphabet to correspond to a certain number (Like scrabble) and I need some code that checks through each letter in the users input and adds a value to a number based on if their word contains that letter. It also needs to account for duplicate letters, such as in the word room.
Thank you.
EDIT:
I ended up using the code:
for (i = 0; i < 10; i++)
{
if (userInput.Contains(valueOf1[i]))
{
length1 = length1 + 1;
totalScore = totalScore + 1;
}
}
People provided solutions but they were not what I was looking for, especially concerning my code, therefore no answer chosen.
The following skeleton of an algorithm should do the trick (sorry for posting F# code, I tend to think faster in it than in C#; translating it should be quite straightforward, though):
let createRandomScores (n : int) =
let r = System.Random ()
let rec loop acc score =
if score > n then dict acc else
let x = char (r.Next (97, 123)), score
loop (x :: acc) (score + 1)
loop [] 1
let scoreDict = createRandomScores 6
let scoreWord (word : string) =
let matchChar c =
match scoreDict.TryGetValue c with
| true, s -> s | _ -> 0
word |> Seq.map matchChar
|> Seq.sum
let addWordToScore score word =
score + scoreWord word
EDIT: This might look as follows in C#:
static Dictionary<char, int> CreateRandomScores(int n)
{
var r = new Random();
var scores = new Dictionary<char, int>();
for (var score = 1; score <= n; score++)
scores[(char)r.Next(97, 123)] = score;
return scores;
}
Dictionary<char, int> ScoreDict = CreateRandomScores(6);
static int ScoreWord(string word)
{
var wordScore = 0;
foreach (var c in word)
if (ScoreDict.TryGetValue(c, out s))
wordScore += s;
return wordScore;
}
static int AddWordToScore(int score, string word)
{
return score + ScoreWord(word);
}
for (i = 0; i < 10; i++)
{
if (userInput.Contains(valueOf1[i]))
{
length1 = length1 + 1;
totalScore = totalScore + 1;
}
}

Why won't this c# string-wrapping algorithm work? [closed]

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 6 years ago.
Improve this question
Alright, so, in my C# Cosmos operating system, I'm working on a system that lets me input a string, and a desired width, and wrap the string into lines based on the width.
It works sorta like this: Input string is "Hello beautiful world". Width is 6. The algorithm will iterate through the string, and if the char index is that of the width, and the current char is a Space, it'll take everything from the beginning of the string up until that point, add it to a List, and remove it from the string itself, and reset the char index to 0, and start over. It does this until the string is either empty or smaller than the width. If it's smaller than the width, it's added to the List, and the for loop is terminated. In laymen, our output string should come out like this:
Hello
beautiful
world.
This is my code.
public static List<string> split_string(int width, string text)
{
List<string> text_lines = new List<string>();
//Separate lines of text.
for (int i = 0; i < text.Length; i++)
{
if (text.Length <= width)
{
text_lines.Add(text);
i = text.Length + 5;
}
else
{
if (i >= width)
{
if (text[i] == ' ')
{
text_lines.Add(text.Substring(0, i + 1));
text = text.Remove(0, i + 1);
i = 0;
}
}
}
}
return text_lines;
}
The thing is, sometimes, if I end up having to deal with the string being smaller than the width, we get issues. It seems to skip that part of the string. Yikes!
For example, here's a piece of my OS that uses this. It's supposed to take a title and a message, and display it in a messagebox with an OK button.
public static void ShowMessagebox(string title, string text)
{
int splitWidth = 25;
if(text.Length < splitWidth)
{
splitWidth = text.Length;
}
if(title.Length > splitWidth)
{
splitWidth = title.Length;
}
var lines = new List<string>();
if(splitWidth > text.Length)
{
lines.Add(text);
}
else
{
lines = TUI.Utils.split_string(splitWidth, text);
}
foreach(var line in lines)
{
if(text.Contains(line))
{
text = text.Replace(line, "");
}
}
if(text.Length > 0)
{
lines.Add(text);
}
int h = lines.Count + 4;
int w = 0;
foreach(var line in lines)
{
if(line.Length + 4 > w)
{
w = line.Length + 4;
}
}
int x = (Console.WindowWidth - w) / 2;
int y = (Console.WindowHeight - h) / 2;
TUI.Utils.ClearArea(x, y, w, h, ConsoleColor.Green);
TUI.Utils.ClearArea(x, y, w, 1, ConsoleColor.White);
TUI.Utils.Write(x + 1, y, title, ConsoleColor.White, ConsoleColor.Black);
for(int i = 0; i < lines.Count - 1; i++)
{
TUI.Utils.Write(x + 2, (y + 2) + i, lines[i], ConsoleColor.Green, ConsoleColor.White);
}
int xw = x + w;
int yh = y + h;
TUI.Utils.Write(xw - 6, yh - 2, "<OK>", TUI.Utils.COL_BUTTON_SELECTED, TUI.Utils.COL_BUTTON_TEXT);
bool stuck = true;
while (stuck)
{
var kinf = Console.ReadKey();
if (kinf.Key == ConsoleKey.Enter)
{
stuck = false;
Console.Clear();
}
else
{
}
}
}
Pretty simple. Starts with a default width of 25 chars, and if the title is bigger, it sets it to title length. If text length is smaller than the width it sets the width to compensate. Then it makes the call to the splitter algorithm from above, found in 'TUI.Utils', and then does some stuff to print to the screen.
Here's a piece of my OS's "ConfigurationManager", an application that takes in user input and uses it to generate a config file. Very work-in-progress right now.
Curse.ShowMessagebox("Memphis can't run properly this system.", "Memphis needs at least one FAT partition on a Master Boot Record to be able to store it's configuration and other files on. Please use a partition utility like GParted to partition your hard drive properly.");
But have a look at what comes out onto my screen...
The messagebox coming out of the above method call
As you can see, not really the thing I want. It's missing some of the string!
You don't need to change text, as we can just store the offset of our original substring. The fewer string manipulations we do, the better.
public static List<string> split_string(int width, string text)
{
width = width - 1; //So we're not constantly comparing to width - 1
var returnSet = new List<string>();
var currLength = 0;
var oldOffset = 0;
for (var i = 0; i < text.Length; i++)
{
if (currLength >= width && text[i] == ' ')
{
returnSet.Add(text.Substring(oldOffset, i - oldOffset));
oldOffset = i + 1;
currLength = 0;
continue;
}
currLength++;
}
if (oldOffset < text.Length)
returnSet.Add(text.Substring(oldOffset));
return returnSet;
}
Testing:
split_string(25, "Memphis needs at least one FAT partition on a Master Boot Record to be able to store it's configuration and other files on. Please use a partition utility like GParted to partition your hard drive properly.");
Gives:
Memphis needs at least one
FAT partition on a Master
Boot Record to be able to
store it's configuration
and other files on. Please
use a partition utility like
GParted to partition your
hard drive properly.
split_string(6, "Hello beautiful world.")
Gives
Hello
beautiful
world.

Why can't I correctly assign variables to an Array? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
So I'm writing a program that inputs a number (binary) then assigns each digit of that input into an array.
static void Main(string[] args)
{
Console.Write("Please enter a binary number: ");
String input = Console.ReadLine();
int inputLength = input.Length;
int nInput = Convert.ToInt32(input);
int[] digits;
digits = new int[inputLength];
int remain = 10;
int divider = 1;
for (int i = 0; i > inputLength; i++)
{
digits[i] = (nInput % remain) / divider;
remain = remain * 10;
divider = divider * 10;
}
Console.WriteLine("Demo number " + digits[0]);
}
However, it seems like all my arrays have a value of 0, whenever I run the code. Why is that?
So if my input is 11010,
digit[0] should be 0.
digit[1] should be 1.
digit[2] should be 0.
digit[3] should be 1.
digit[4] should be 1.
The Loop is not executing since its condition always false; So you are getting its default value, change the condition as i < inputLength;
If you do so and give the input as "123"
The output on the console will be : Demo number 3; And the array Will be
digit[0]=3
digit[1]=2
digit[2]=1
Few suggestions to improve your code:
use int.TryParse(); instead for Convert.ToInt32(); for avoid throwing conversion exceptions. you can see a comparison here
Since the numbers are in an array you can reverse them using Array.Reverse()
That is ..
String input =Console.ReadLine();
int nInput;
int inputLength = input.Length;
if (int.TryParse(input, out nInput))
{
int[] digits = new int[inputLength];
Array.Reverse(digits);
Console.WriteLine("Reversed Number is:{0}",String.Join( "",digits));
}
else { Console.WriteLine("Wrong input"); }
Try this code!
static void Main(string[] args)
{
string input = Console.ReadLine();
int[] vec = new int[input.Length];
int i = 0;
foreach (char ch in input) {
vec[i] = Convert.ToInt32(ch.ToString());
i++;
}
foreach (int numaux in vec) {
Console.WriteLine(numaux);
}
Console.Read();
}
Just iterate over the input string using foreach statement (Will save you from the error that was already pointed out) and convert each char into an int that will be stored inside of the array.
Cheers!

Taking certain string characters and returning the string

I asked this question yesterday but it wasn't well received mainly due to how I asked it so ill try do better this time.
I have a string variable called message. lets say message equals "ABCDABCDABCDABCD"
now I need to do some processing on the characters in the string but not all at the same time, I want to access characters [0][4][8][12] on the first pass of the function, put each of these characters in a string and return it which is easy done if I pass an integer to my function lets say 4 and with in a for loop do
if(i % int == 0)
{
string += message[i];
}
this should return "AAAA"
the next time I call the function ill need elements [0][1], [4][5], [8][9], [12][13] and the time after that ill need [0][1][2], [4][5][6], [8][9][10], [12][13][14].
I need the characters returned in a string in the order they were taken, I could do this by changing my int I pass the function but then id need to call the function several times and do work on the returned strings to get them into the order they were taken, which I have already tried and it slowed my program down when dealing with large messages > 10k characters.
Please don't delete or put my question on hold, im quite happy to give more information on my problem if its not clear, ill seldom post to this site and usually try and find a solution myself, there are too many acceptance junkies on here for my liking. but I would appreciate some help from some of them regarding this.Thanks
Edit
I understand its not easy to figure it out and I have to say im not the best at describing it, its a vigenere cracker in WPF, I have done the kasiski examination on a piece of text and graphed out all the data, it finds the key length 90% of the time or gives me the best clue to what the key might be, now im calculating the frequency of bi,tri and quad grams of the message based on the data from the kasiski exam, lets say the key is 5 and the message is "ABCDABCDABCDABCD" im calculating probability on only the characters of the key Im changing so when I try key AAAAA im only wanting to calculate monograms on elements [0][4][9][14] of the message, ill run through 26 characters up to ZAAAA and take the most probable then I move onto element [1] of the key, lets say FAAAA gave the best score on the first element of the key. now I need elements [0][1],[5][6],[9][10][13][14] as im calculating probability on 2 pieces on the key FCAAA, so the length of the key and what key character im working on will determine what elements of the message ill be taking.
One-liner with LINQ (I use Batch extension from MoreLINQ, but you can use your own) which selects all required chars from input string:
string message = "ABCDABCDABCDABCD";
int size = 4;
int charsToTake = 2;
var characters = message.Batch(size).SelectMany(b => b.Take(charsToTake));
If you need result as string, you can easily create one:
var result = new String(characters.ToArray());
// ABABABAB
More efficient way - create your own method which will split string by substrings of required length:
public static IEnumerable<string> ToSubstrings(this string s, int length)
{
int index = 0;
while (index + length < s.Length)
{
yield return s.Substring(index, length);
index += length;
}
if (index < s.Length)
yield return s.Substring(index);
}
I would also create method for safe getting substring from start of string (to avoid annoying string length check and passing zero as start index):
public static string SubstringFromStart(this string s, int length)
{
return s.Substring(0, Math.Min(s.Length, length));
}
Now its very clear what you are doing:
var substrings = message.ToSubstrings(size)
.Select(s => s.SubstringFromStart(charsToTake));
var result = String.Concat(substrings);
Here is a simple program which does what you want, if I understand correctly:
static void Main(string[] args)
{
string data = "ABCDABCDABCDABCD";
Console.WriteLine(StrangeSubstring(data,4, 1));
// "AAAA"
Console.WriteLine(StrangeSubstring(data,4, 2));
// "ABABABAB"
Console.WriteLine(StrangeSubstring(data,4, 3));
// "ABCABCABCABC"
}
static string StrangeSubstring(string input, int modulo, int length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; ++i)
{
if (i % modulo == 0)
{
for (int j = 0; j<length; ++j)
{
if (i+j < input.Length)
sb.Append(input[i+j]);
}
}
}
return sb.ToString();
}
My solution will be like this
static string MethodName(int range){
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < str.Length ; i++){
if(i % 4 == 0){
sb.Append(str[i]);
for(int j = i + 1 ; j <= i + range ; j ++){
if(j >= str.Length)
break;
sb.Append(str[j]);
}
}
}
return sb.ToString();
}
you can parse your string to a char array :
string message="ABCDABCDABCDABCD";
char[] myCharArray = message.ToCharArray();
string result="";
for(int i=0, i<myCharArray.Length -1 ; i++)
{
if(i%4 ==0)
result+=myCharArray[i];
}
EDIT 1 :
public string[] myfunction(char[] charArray)
{
List<string> result = new List<string>();
for(int i=0, i<charArray.length -1; i=i+4)
{
result.add(charArray[i]+charArray[i+1])
}
return result.toArray();
}
This is a recursive solution. In YourFunction, PatternLength is the length of the character pattern which is repeated (so, 4 for "ABCD"), Offset is where you start in the pattern (e.g. 0 if you start with "A") and SubstringLength is the number of characters.
The function call in Main will give you all "A". If you change SubstringLength to 2, it gives you all "AB". There is no error handling, make sure then PatternLength<=Offest+SubstringLength
namespace Foo
{
class Bar
{
static void Main(string[] args)
{
Console.WriteLine(YourFunction("ABCABCABCABCABCABCABC", 3, 0,1));
Console.ReadKey();
}
static string YourFunction(string SubString, int PatternLength, int Offset, int SubstringLength)
{
string result;
if (SubString.Length <= PatternLength)
{
result = SubString.Substring(Offset, SubstringLength);
}
else
{
result = YourFunction(SubString.Substring(PatternLength, (SubString.Length - PatternLength)), PatternLength, Offset, SubstringLength) + SubString.Substring(Offset, SubstringLength);
}
return result;
}
}
}

Categories

Resources