Battleship game C# - c#

I am stuck upon a problem about namimng the colums and the lines, differently than 0 to 10. something like this picture, the lines starting from the bottom 1 to 10 and colums from A to J.
I've created a program that tells me if the ship is destroyed or not, after using 14 moves( in this image using move 5 c, in my program 5 2, counts as a hit, if all the blue squares are hit the program returns destroyed).
My problem is that i don't know why i can't user input a move like "4 a" (Input string was not in a correct format.' - after debugging). I wrote the following code:
char[,] board = new char[10, 10];
int table = 10;
int hits = 2;
int totalHits = 14;
int neededHits = 8;
for (int i = 9; i >= 0; i--)
{
string line = Console.ReadLine();
string[] boardCharacters = line.Split(' ');
for (int j = 0; j < table; j++)
{
board[i, j] = Convert.ToChar(boardCharacters[j]);
}
}
int countHits = 0;
for (int z = 0; z < totalHits; z++)
{
var ac = Console.ReadLine().Split(' ');
var c1 = int.Parse(ac[0]) - 1;
var c2 = (ac[1].ToLower()[0] - 'a');
int[] attack = new int[2];
for (int i = 0; i < hits; i++)
{
attack[i] = int.Parse(ac[i]);
}
if (board[attack[0], attack[1]] == 'x')
{
countHits++;
}
}
Console.WriteLine(countHits == neededHits ? "destroyed" : "not destroyed");
Console.ReadLine();

Your problem is in this section:
var ac = Console.ReadLine().Split(' ');
var c1 = int.Parse(ac[0]) - 1;
var c2 = (ac[1].ToLower()[0] - 'a');
int[] attack = new int[2];
// You've already parsed the two parts of the input into 'c1' and 'c2'.
// This loop is redundant, and is the cause of the problem.
for (int i = 0; i < hits; i++)
{
// When 'i' = 1, this is looking at the second part of the input ("a")
// and trying to parse it as a number. This is what causes the exception.
attack[i] = int.Parse(ac[i]);
}
I would suggest removing that loop, and populate the 'attack' array when you create it:
int[] attack = new int[] { c1, c2 };

Related

I'm generating a list of 100 random "names", now I need to follow it up with 100 more names and 100 random numbers. C#

I'm making a program that generates the "names" (random lines of text from the ASCII) that are the names of movies in this instance. I should follow them up with a "name" of a director for each (can also be generated from the ASCII), and after that the random year that is the year the "movie" was made (from 1896 to 2021).
I have two separate functions that randomize the names of the movies and directors, but I'm confused with the supposed placement of the Console.Writeline which the intelligence only allows inside their own loops. Otherwise it doesn't seem to be able to use the values "directorname" and "moviename".
I need it to write the names in a single line, ai. (KHGTJ, KGHTJF).
Also I need a way to generate a random year from 1896 to 2021 that is printed after the names of the movie, and director, ai. (KFJU, MDDOS, 1922).
private static void GenerateRandomNames()
{
Random random = new Random();
char y = (char)65;
for (int p = 0; p < 100; p++)
{
string directorname = "";
for (int m = 0; m < 5; m++)
{
int b = random.Next(65, 90);
y = (char)b;
directorname += y;
}
Console.WriteLine(directorname);
}
Random rnd = new Random();
char x = (char)65;
for (int j = 0; j < 100; j++)
{
string moviename = "";
for (int i = 0; i < 5; i++)
{
int a = rnd.Next(65, 90);
x = (char)a;
moviename += x;
}
Console.WriteLine(moviename);
}
Console.WriteLine();
I need to fix the plecement of the Console.Writeline() so it can print both names in the same line, and be able to print the year after them.
I've tried placing the Console.Writeline() outside the loops, but of course it can't then use the name. But this way it prints them the wrong way.
If you want to have minimal changes in your code, you can use the following code:
private static void GenerateRandomNames()
{
//a separate thing for the names of the directors (ASCII)
// then for the years they were made (1896-2021)
//they should all be printed in the end ie. (KGMFK, JDBDJ, 1922)
Random rnd = new Random();
char x = (char)65;
for (int j = 0; j < 100; j++)
{
string directors = "";
string moviename = "";
for (int i = 0; i < 5; i++)
{
int a = rnd.Next(65, 90);
x = (char)a;
moviename += x;
}
for (int i = 0; i < 5; i++)
{
int a = rnd.Next(65, 90);
x = (char)a;
directors += x;
}
Console.WriteLine("( "+directors +", "+ moviename + ", " +rnd.Next(1896, 2021).ToString()+" )");
}
Console.WriteLine();
}
and result:
Not sure if it is good to answer this type of question, but answering it anyway.
Since you only want other 5-letter words and 4-digit numbers ranging from 1896 - 2021,
Just get another variable 'b' and do the same as you did for 'a', like :
int b = rnd.Next(65,90) ;
y = char(b) ;
director name += y ;
and to get the year value, you can use this :
year = rnd.Next(1896,2021)
So, by combining all of the above, you have the code like this :
internal class Program
{
private static void GenerateRandomNames()
{
Random rnd = new Random();
char x = (char)65;
char y = (char) 65 ;
for (int j = 0; j < 100; j++)
{
string moviename = "";
string directorName = "";
int year = rnd.Next(1896,2021);
for (int i = 0; i < 5; i++)
{
int a = rnd.Next(65, 90);
int b = rnd.Next(65, 90);
x = (char)a;
moviename += x;
y = (char)a;
directorName += x;
}
Console.WriteLine(moviename);
Console.WriteLine(directorName);
Console.WriteLine(year);
}
Console.WriteLine();
}
static void Main(string[] args)
{
GenerateRandomNames();
}
}
The task becomes easier if you extract the creation of a random name to a new method. This allows you to call it twice easily. I moved the random object to the class (making it a class field), so that it can be reused in different places.
internal class Program
{
private static readonly Random _rnd = new Random();
private static string CreateRandomName(int minLength, int maxLength)
{
string name = "";
for (int i = 0; i < _rnd.Next(minLength, maxLength + 1); i++)
{
char c = (char)_rnd.Next((int)'A', (int)'Z' + 1);
name += c;
}
return name;
}
private static void WriteRandomNames()
{
for (int i = 0; i < 100; i++)
{
string movie = CreateRandomName(4, 40);
string director = CreateRandomName(3, 30);
int year = _rnd.Next(1896, 2022);
Console.WriteLine($"{movie}, {director}, {year}");
}
Console.WriteLine();
}
static void Main(string[] args)
{
WriteRandomNames();
}
}
Note that the second parameter of the Next(Int32, Int32) method is the exclusive upper bound. Therefore I added 1.
output:
HATRHKYAHQTGS, NCPQ, 1999
QVJAYOTTISN, LJTGJDMB, 2018
JEXJDICLRMZFRV, GJPZHFBHOTR, 1932
SKFINIGVYUIIVBD, DIZSKOS, 1958
LWWGSEIZT, AMDW, 1950
OAVZVQVFPPBY, SPEZZE, 2008
YLNTZZIXOCNENGYUL, URNJMK, 1962
ONIN, WUITIL, 1987
RJUXGORWDVQRILDWWKSDWF, MOEYPZQPV, 1946
YUQSSOPZTCTRM, UEPPXIVGERG, 1994
KILWEYC, QJZOTLKFMVPHUE, 1915
Wow, in the time it took me to write an answer, three or more others appeared. They all seem like pretty good answers to me, but since I went to the trouble of writing this code, here you go. :)
I focused on using the same Random in different ways, because I think that's what you were asking about.
using System;
using System.Collections.Generic;
using System.Linq;
Random rnd = new Random(1950);
GenerateRandomNames();
void GenerateRandomNames()
{
for (int j = 0; j < 100; j++)
{
// here's one way to get a random string
string name = Guid.NewGuid().ToString().Substring(0, 5);
string description = new string(GetRandomCharacters(rnd.Next(5,16)).ToArray());
string cleaner = new string(GetCleanerCharacters(rnd.Next(5, 16)).ToArray());
string preferred = new string(GetPreferredRandomCharacters(rnd.Next(5, 16)).ToArray());
int year = rnd.Next(1896, DateTime.Now.Year + 1);
Console.WriteLine($"{year}\t{preferred}");
Console.WriteLine($"{year}\t{cleaner}");
Console.WriteLine($"{year}\t{name}\t{description}");
Console.WriteLine();
}
Console.WriteLine();
}
// Not readable
IEnumerable<char> GetRandomCharacters(int length = 5)
{
for (int i = 0; i < length; i++)
{
yield return Convert.ToChar(rnd.Next(0, 255));
}
}
// gives you lots of spaces
IEnumerable<char> GetCleanerCharacters(int length = 5)
{
for (int i = 0; i < length; i++)
{
char c = Convert.ToChar(rnd.Next(0, 255));
if (char.IsLetter(c))
{
yield return c;
}
else
{
yield return ' ';
}
}
}
// Most readable (in my opinion), but still nonsense.
IEnumerable<char> GetPreferredRandomCharacters(int length = 5)
{
for (int i = 0; i < length; i++)
{
bool randomSpace = rnd.Next(0, 6) == 3;
if (i > 0 && randomSpace) // prevent it from starting with a space
{
yield return ' ';
continue;
}
var c = Convert.ToChar(rnd.Next(65, 91)); // uppercase letters
if (rnd.Next(0, 2) == 1)
{
c = char.ToLower(c);
}
yield return c;
}
}

Putting values of an array into text boxes using C#

I've created a dimensional array using two for loops, and as each inner loop completes, I'd like those values to go into textboxes on a windows form. (I realize that the values will be overwritten each time, with just the values from the final outer loop showing at the end.)
The comments in the code show what I've been trying to get to work.
Thanks!
if (IsValidData())
{
int Columns = 5;
int Rows = Convert.ToInt32(txtNumbDrawings.Text);
int[,] ball = new int[Columns, Rows];
for (int i = 0; i < Rows; i++)
{
List<int> ballsList = new List<int>();
int[] txtBall = new int[Columns];
for (int j = 0; j < Columns; j++)
{
Random number = new Random();
ball[i, j] = number.Next(1, 70);
// prevent duplicate numbers
while (ballsList.Contains(ball[i, j] ))
{
ball[i, j] = number.Next(1, 70);
}
ballsList.Add(ball[i, j]);
/*************************************************
* how do I get the current ball value
* into a textbox on a form?
*
* textboxes are named txtBall1, txtBall2, etc...
*
* I was trying something like:
*
* TextBox[] txtBall = new TextBox[5];
* for (int i = 0; i < 5; i++)
* {
* txtBall[i + 1].Text = ball[i, j].ToString();
* }
*************************************************/
}
ballsList = null;
}
}
Windows Form Image: https://1drv.ms/u/s!Ak6hxvO3Ye6Oj5I9NQy834Yk4TRLyw?e=DniwK8
If I understand what you're trying to do, and that seems to be assigning a shuffled list of integers to one of 5 list boxes, then this should do it:
if (IsValidData())
{
Random rnd = new Random();
// (1, 69) because rnd.Next(1, 70) only produces the numbers 1 to 69
int[] shuffled_balls = Enumerable.Range(1, 69).OrderBy(x => rnd.Next()).ToArray();
ListBox[] list_boxes = new [] { lstBall1, lstBall2, lstBall3, lstBall4, lstBall5 };
for (int i = 0; i < shuffled_balls.Length; i++)
{
list_boxes[i % list_boxes.Length].Items.Add(shuffled_balls[i]);
}
}

C# Using a random number gen with a key to solve an encrypted message but I cannot get the message to keep within the string

For my problem I am experiencing today comes in the form of a string array. The goal of this assignment is to use Random with a seed value of 243 as a key to access a hidden message from 22 lines. Within these 22 lines are 5 letters that form a word. Here is 22 lines containing 60 characters in each line and the goal is to use the key to pick the 5 letters from each line.
String[] line = { "<?JRrP*h^vtVc^ppOZI#PCAa{ (n1>&VSf~59eI7Tn5We^77O/CEvgdq}gU0",
"G;t#o=#|^ZWV01`a-h{=Js>!z`_j!&7PB9nCgtfHZ:WtWk4e&#k5i7uV{$E/",
"]7zXf&4uA=n8!Sa08IIoKyc~:#d*T8FcOWjB?~QQ =Ch(S37UT>RYobbSz>#",
"w*A)v5gHh>p9vvVeUzvfmMT~tr)8s(nC`11Lz:qhjjN6c$Z ^T,W$VQqUB/#",
"+NSrOLhed*2;)$z#}=;t7FY?z6?e^?cX+nf;6me6Kt|TBpN ZNr7&9j t4c8",
"-N&E2X/:<_k0W$HpH${*f?M0K_Qp##F!)M){nVAu`4bzab_too;m8YPm!tyR",
"s=69 j&*yLRpb2IR[RNg~O!ZfUhr{czx]mbB}Hau]T(CtI-%0}1NFeRV<ZRb",
"!U-]QY4sN&S2pW+JGaenHc?|)KQJ:,&Cu}s'GIp:59U)J~]n&(/^s6:=htS ",
"'iXi 0;qbk#|kn&/-5Q*mbC2|FN_bVp6tk3K_3):bj+#%1 I/+0 ]I6CEFDX",
" [/,2k( 7ZNy,7GlV#,kk$PVEpXKTn&8mPX&[~o9)q2S]6rs!3k$:i$]*WeA",
"3[KGT5+Z^#FWPt aq{y/|2I##!}5Kzz$9M&LFieF*8f_l4RGuBie]UD!2+Dh",
"7u.qDs=#k5:' S$dKiRmMU>)1lFb)%:;EL/4)#:Juu[_'a1)Q_TGWUe`V%QW",
"zZxtz~aOCoZGN(vny]#N[=1IOqbnGN]iQbN;Vtc' od`$-xN^&ex##z]HO )",
"<q(t2VukYZf%yyNzWODBw40wgc!Nfpr&]Yj- oNM6-t#^`h(R %o+s0'af-N",
"Ut$gg#F?/#Bg!v+j>,aedrzekyzhebJpb wo(-:>:hw1]<v3hEgU%&h]J=zm",
"D]uLuP$ ~;b1pBk% usN#f #ytk[6:Di1Lx[hK;,7u4mbVca:b[` bk]]qQ ",
"dHicvw De/<SM{7+QR#n0iAR^bUe_;}uy;Fr,PUiV?8*F(37a`++Q.nZ&6%3",
"Bcc-1EY1UG} {a on6,UN=P~/rDjKkguKBG<[*xsM#akb+/zA}gn*Nc$hc}>",
" ndhw'TX-O4f=* LZc<#cHIL#xk|]BSv+Z!^<s-ZUUlpi!Q~F7IimyZVD7de",
":Vzi{=[b)HEaV`M-[Wb#FlVFxNN0 I9. G?}Z#tKDmu|'gM LLzlT->M TpL",
"mKb^.+i/#NRXa7]XuX>1!gbR LOQ(q}%1H]x+.mz:=D}xB*<$eWDj_J%g/0a",
"[{&NOLF9YcL^iCvcBcY+A2LB:UoQ|V1{s,?>7krK{pb#8w]pgfa#U$tHNbay" };
For the chunk of code that I am working on comes here.
String[] decrypted = new String[22];
var randNum = new Random(243);
int i, k;
for (i = 0; i < 22; i++)
{
String currentLine = line[i];
for (k = 0; k < 5; k++)
{
decrypted[i] = Convert.ToString(currentLine[randNum.Next(0, 60)]);
}
}
printIt(decrypted);
Console.ReadLine();
}
static void printIt(string[] decrypted)
{
var build = new StringBuilder();
for (int h = 0; h < 22; h++)
{
build.Append(Convert.ToString(decrypted[h]));
}
Console.WriteLine(build);
The help I am looking for is to understand how I can store the 5 characters from each line successfully within the decrypted array.
I can gain the correct answer if I insert directly in my nested for loop the Console.WriteLine(decrypted[i]);
However, if I try to pull the same line anywhere after the for loop containing random, I only am able to pull the first letter of each line.
Change your loop to:
String[] decrypted = new String[110];
for (i = 0; i < 22; i++)
{
String currentLine = line[i];
for (k = 0; k < 5; k++)
{
decrypted[k + i * 5] = Convert.ToString(currentLine[randNum.Next(0, 60)]);
}
}
And Print:
static void printIt(string[] decrypted)
{
var build = new StringBuilder();
for (int h = 0; h < decrypted.Length; h++)
{
build.Append(Convert.ToString(decrypted[h]));
}
Console.WriteLine(build);
}
I was able to solve my own problem after doing a bit more research and deduction of what I could possibly be missing. Here is the solution.
for (i = 0; i < 22; i++)
{
String currentLine = line[i];
for (k = 0; k < 5; k++)
{
decrypted[i] = decrypted[i] + Convert.ToString(currentLine[randNum.Next(0, 60)]);
//Adding the previous character to the new character to help build up the string.
}
It was after I realized I wasn't building up the characters properly I chose to add the previous character and it solved my problem.

C# program that returns morse code for numbers not working

I'm trying to make a program that: When given a 4 digit number (for example, 1001) it sums the digits of that number, for 1001 this is 1 + 0 + 0 + 1 = 2, than it finds all sequences of 6 numbers from 1 to 6 (including permutations, i.e. 1*1*1*1*1*2 is different than 2*1*1*1*1*1) whose product is that number.
The result should be printed on the console in the following format: each sequence of 6 numbers, with their Morse representation, separated with a single pipe: 1 is .---- , 2 is ..---: .----|.----|.----|.----|..---|, on a new row the next permutation: .----|.----|.----|..---|.----| and so on.
The problem is, my solution doesn't show the correct answers, not even the correct number of them.
Here's my code (and please, if possible, tell me where my mistake is, and not some one line hack solutions to the problem with LINQ and regex and God knows what):
string n = Console.ReadLine();
string[] digitsChar = new string[n.Length];
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
int morseProduct = digits.Sum();
Console.WriteLine(morseProduct);
List<int> morseCodeNumbers = new List<int>();
for (int i = 1; i < 6; i++)
{
for (int j = 1; i < 6; i++)
{
for (int k = 1; i < 6; i++)
{
for (int l = 1; i < 6; i++)
{
for (int m = 1; i < 6; i++)
{
for (int o = 1; o < 6; o++)
{
int product = i * j * k * l * m * o;
if (product == morseProduct)
{
morseCodeNumbers.Add(i);
morseCodeNumbers.Add(j);
morseCodeNumbers.Add(k);
morseCodeNumbers.Add(l);
morseCodeNumbers.Add(m);
morseCodeNumbers.Add(o);
}
}
}
}
}
}
}
int numberOfNumbers = morseCodeNumbers.Count;
string[] morseCodes = new string[] { "-----", ".----", "..---", "...--", "....-", "....." };
for (int i = 0; i < numberOfNumbers; i++)
{
int counter = 0;
if (i % 5 == 0)
{
Console.WriteLine();
counter = 0;
}
if (counter < 5)
{
int index = morseCodeNumbers[i];
Console.Write(morseCodes[index] + "|");
counter++;
}
A lot of your for-loop conditions refer to i instead of j,k,l and m. The same for the increment part. For example:
for (int j = 1; i < 6; i++)
should be
for (int j = 1; j < 6; j++)
Furthermore if the range is from 1 to 6 you need to change < to <=, see:
for (int i = 1; i <= 6; i++)
You don't need to convert the string to a string array to get the int array of digits btw, so while this is correct:
for (int i = 0; i < 4; i++)
{
digitsChar[i] = n[i].ToString();
}
int[] digits = new int[digitsChar.Length];
for (int i = 0; i < 4; i++)
{
digits[i] = Convert.ToInt32(digitsChar[i]);
}
you could it do like that (sry for LINQ):
var digits = n.Select(c=>(int)char.GetNumericValue(c) ).ToArray();

How do I get my code to work?

I have a one assignment
I have to make one dimension array with 20 numbers - first 10 numbers are from 1 do 10. others 10 numbers I have to get in method called Dopolni - where I have to sum together array with one another like - p11 = p0+p1, p12 = p1+p2, p14 = p2+p3 and so on - I dont know how to arrange it to get those other 10 numbers - help please
my code till now is
static void Dopolni(int[] p)
{
for (int i = 11; i < 20; i++)
{
p[i] = p[i] + 1;
}
}
static void Main(string[] args)
{
int[] p = new int[20];
for (int i = 1; i < 20; i++)
{
if (i <= 10)
{
p[i] += i;
}
Console.WriteLine("{0}", p[i]);
}
Dopolni(p);
Console.WriteLine(p);
Console.ReadKey(true);
}
All numbers I have to write out in main window. Hope someone can help out
The indices of the first 10 numbers range from 0 to 9, the others from 10 to 19. But since you always sum two consecutive numbers, you will only get 9 sums! In order to get 10 sums, you could start by summing 0 with p[0]:
int previous = 0;
for (int i = 0; i < 10; i++) {
p[i + 10] = previous + p[i];
previous = p[i];
}
public static void Main()
{
int[] p = new int[20];
for (int i = 0; i < 10; i++)
{
p[i] = i + 1;
ยจ
Console.WriteLine(p[i]);
}
Dopolni(p);
}
static void Dopolni(int[] p)
{
for (int i = 10; i < 20; i++)
{
p[i] = p[i - 10] + p[i - 9];
Console.WriteLine(p[i]);
}
}
This looks like trouble:
int[] p = new int[20];
Console.WriteLine(p);
What you want is to loop through p and print each element, not rely on the array implementation of ToString().
Try:
foreach (var n in p)
Console.WriteLine(n);
Do you need to have it in a function? Its really quite simple...
Notice I use 'out int[]', thats what your missing in your code. Out specifies you want in/out param, not just in ;)
static void Main()
{
int[] p = new int[20];
// First 10 numbers
for (int i = 0; i < 10; i++)
p[i] = i + 1;
Dolpini(out p);
foreach (int m in p)
Console.WriteLine(m);
}
static void Dolpini(out int[] numbers)
{
// Next 10 numbers
for (int k = 10; k < 20; k++)
p[k] = p[k-10] + p[k-9];
}

Categories

Resources