Check adjacent values in a 2d array - c#

I'm making a treasure hunt game - I allow a user to input a coordinate - and if it contains 't' for treasure, then they win. But I want to add something so that it'll check what they enter and if t is within a 1 element radius of their guess - it'll say "You are hot". Or "You are cold" if 't' is > 1 element away.
I can't figure out the best way I could do this. I've tried things such as
if (Board[Row+1,Column] == 't' || Board[Row+1,Column+1] == 't' etc etc etc)
{
Console.WriteLine("You are hot.");
}
else
{
Console.Writeline("You are cold.");
}
But this doesn't seem to be working for me, I can't use Lists yet so I'd like to get around this without using them.
This is the part of the code that should figure it out.
string HotOrCold = "";
if (Board[Row, Column] != 'x')
{
Board[Row, Column] = 'm';
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Clear();
if () // Here Is Where It Should Figure It Out
Console.WriteLine("Uh-oh! You haven't found the treasure, try again!");
Console.WriteLine("You are {0}.", HotOrCold);
Console.ForegroundColor = ConsoleColor.Gray;
wonGame = false;
PrintBoard(Board);
SaveGame(username, ref Board);
}
I've also tried a nested for loop - but maybe I haven't used that correctly.

Not really a code question.
What you can do though is get the absolute value (i.e. ignore negative sign) of the difference between T and their guess for X and Y.
If either the absolute difference between T and the guess X or Y is 1 then you can say they are warm or whatever.
Partial example for you (prefer X/Y but have used row/col to match your work):
var rowDiff = Math.Abs(guessRow - tRow);
var columnDiff = Math.Abs(guessColumn - tColumn);
if (rowDiff == 0 && columnDiff == 0)
{
Console.WriteLine("You got it...");
}
else if (rowDiff <= 1 && columnDiff <= 1)
{
Console.WriteLine("You are hot...");
}
else
{
Console.WriteLine("You are cold...");
}
Thanks for the tip off Wiz.

The array can be seen as a subset of a Cartesian space. And how to position the elements in the array lends itself well to distance calculations in a Cartesian coordinate system. This means that the corresponding mathematical function can be implemented and used with confidence.
So that's what I would advice you to do for example:
static double distanceToTreasure(int x, int y)
{
double dX = x * 1.0D;
double dY = y * 1.0D;
double dWinX = winningX * 1.0D;
double dWinY = winningY * 1.0D;
double deltaX = Math.Abs(dWinX - dX);
double deltaY = Math.Abs(dWinY - dY);
return Math.Sqrt(Math.Pow(deltaX, 2.0D) + Math.Pow(deltaY, 2.0D));
}
Now I can easily check for any radius wether or not the player is in the vicinity of the treasure
static Boolean isInTheViccinityOfTreasure(double radius, int x, int y)
{
return distanceToTreasure(x,y) <= radius;
}
I can also just as easily see if our player has tumbled on the treasure:
static Boolean hasGotTheTreasure(int x, int y)
{
return distanceToTreasure(x, y) == 0.0D;
}
I can now get inputs from the user and use the methods above to output the right result. I am looping in order to test various cases.
public static void Main(string[] args)
{
while (true)
{
// datas setting
initDatas();
// Random treasure position selection
setupWinningPosition();
// This is cheating: some kind of debugging so you can test the results
Console.WriteLine("Don' t tell tx=" + winningX + " and tY = " + winningY);
Console.WriteLine("Enter x");
int x = Int32.Parse(Console.ReadLine());
Console.WriteLine("Enter y");
int y = Int32.Parse(Console.ReadLine());
if (hasGotTheTreasure(x, y))
{
Console.WriteLine("You got the treasure dude!!!");
}
// A radius of 1 is used here
else if (isInTheViccinityOfTreasure(1, x, y))
{
Console.WriteLine("That's getting hot: keep going boy...");
}
else
{
Console.WriteLine("Oops it's getting very cold");
}
// This is the way out of the loop by hitting 'q'
ConsoleKeyInfo key = Console.ReadKey();
if (key.KeyChar == 'q')
{
break;
}
}
}
This is what my output looks like:

Ben is on the Right Path but code needs to be more like.
public static void FoundTreasure(int guessColumn, int guessRow )
{
if (Math.Abs(guessRow - TRow) == 0 && Math.Abs(guessColumn - TColumn) == 0)
{
Console.WriteLine("You got it...");
return;
}
if (Math.Abs(guessRow - TRow) <= 1 && Math.Abs(guessColumn - TColumn) <= 1)
{
Console.WriteLine("You are hot...");
return;
}
Console.WriteLine("You are cold...");
}
This assumes that TRow and Tcolumn (the Tresure location) is set in the parent class.

Related

How do I detect an infinite loop occuring in my code?

So my code is to check if a given number is a 'happy number'. It squares each digit of the number, adds them and continues to do so until either the result of the addition is 1 (which means it is a happy number) or until it results in a 4 (which means it is not a happy number).
What's happening is that there are many numbers which cause an infinite loop (therefore meaning they are not a happy number) and I'm wondering how I would construct my code so that it will detect when there's an infinite loop occuring? I have some ideas but all flawed.
My code is as follows:
using System;
namespace Happy_numbers_problem
{
class Program
{
static int HappyNumbers(string Number)
{
string Output = Number;
while ((Convert.ToInt32(Output) != 1) && (Convert.ToInt32(Output) != 4))
{
string Result2 = "0";
for (int Index = 0; Index < Output.Length; Index++)
{
string Character = Output.Substring(Index, 1);
int Calc = Convert.ToInt32(Character);
int Result = Calc * Calc;
//Adding Result2 and Result, then turning it into a string.
Result2 = Convert.ToString(Convert.ToInt32(Result2) + Result);
if (Index == (Output.Length) - 1)
{
Output = Result2;
}
}
}
return Convert.ToInt32(Output);
}
static void Main(string[] args)
{
Console.WriteLine("Please enter a number");
string Number = Console.ReadLine();
int Output = HappyNumbers(Number);
if (Output == 1)
{
Console.WriteLine(Number + " is a happy number");
}
else if (Output == 4)
{
Console.WriteLine(Number + " is not a happy number");
}
else
{
Console.WriteLine(Number + " is not a happy number");
}
}
}
}
The problem resides in your while condition. If your output needs to be 1 or 4 to break out of the loop and deliver the output to latter be analysed, you have to use the operator or || instead of the operator and &&.

How to allow only a certain range of numbers to be inputted into a string in C#

I have this code where it will not allow multiple periods, and has to be passed into a double using valueIsGood to check if it is compatible. As well as not allow a empty string.
The method ReadNumberForHeight() does not allow a user to input any letters or special characters. Only numbers and the period(.) are allowed for input through this method.
I want to have a range for height since logically nobody can be .01 inches tall.
I want a range of only 3'0 and 12'5(3.0 and 12.5) as compatible input.
If it is not compatible go to the "So I am going to ask again..." if statement, and then go back to ask the user again for their height.
An example input would be: 5.6, 5.11, 6.1
I have looked everywhere for a solution and have not found anything that has worked, or that I have tried that did work.
Any errors get caught by this loop but I still want a range of numbers from 3.0 to 12.5 as valid input to be accepted into this code.
string height1;
bool valueIsGood;
double parsedValue;
do
{
Console.Write("What is your height?:");
height1 = ReadNumberForHeight();
valueIsGood = string.IsNullOrEmpty(height1) == false && double.TryParse(height1, out parsedValue);
if (!valueIsGood)
{
Console.WriteLine("So I am going to ask again...\n");
}
}
while (!valueIsGood);
Here is the ReadNumberForHeight() method underneath.
private static string ReadNumberForHeight()
{
string input = "";
do
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
if (char.IsNumber(keyInfo.KeyChar) || keyInfo.KeyChar == '.')
{
input = input + keyInfo.KeyChar;
Console.Write(keyInfo.KeyChar);
}
if (keyInfo.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
if (keyInfo.Key == ConsoleKey.Backspace)
{
input = input.Substring(0, input.Length - 1);
Console.Write("\b \b");
}
} while (true);
return input;
Do you really need to read key by key?
You can just call Console.ReadLine() and then process the user input:
bool valueIsGood = false;
do {
Console.Write("What is your height?:");
string userInput = Console.ReadLine();
if (!string.IsNullOrEmpty(userInput) && double.TryParse(userInput, out double parsedValue)) {
Console.WriteLine($"Good value! => {parsedValue}");
valueIsGood = true;
}
else {
Console.WriteLine("So I am going to ask again...\n");
}
} while (!valueIsGood);
Console.ReadKey();
This works as I understood you expected:
What is your height?:5d3
So I am going to ask again...
What is your height?:32.3
Good value! => 32.3
To accept only a range you can change the if condition to something like:
if (!string.IsNullOrEmpty(userInput) && double.TryParse(userInput, out double parsedValue) && parsedValue >= XXX && parsedValue <= YYYY)

If an user does not input a local variable how do i define it using other variables? C#

Let me explain.
I am a high school student with not a lot of expirience programming in C#, we have an asigment to make a geometry calculator i got a triangular pyramid, but thats beside the point. The calculator is suposed to get an imput from the user and then with that given data calculate the surface and the volume.
double a = Convert.ToDouble(Console.ReadLine());
double h = Convert.ToDouble(Console.ReadLine());
double H = Convert.ToDouble(Console.ReadLine());
double area = Math.Pow(a, 2) * Math.Sqrt(3) / 4 + 3 * a * h / 2;
double volume = Math.Pow(a, 2) * Math.Sqrt(3) * H / 12;
Console.WriteLine(volume);
Console.WriteLine(area);
Console.ReadLine();
Now thats easy for me , but a problem arises when the user does not know the value of one of the variables for example the hight.In such a instance the calculator is suposed to calculate it using the other two local variables.
double h = Convert.ToDouble(Console.ReadLine());
double h = Math.Sqrt(Math.Pow(a * Math.Sqrt(3) / 3, 2) + Math.Pow(H));
I know i know you cant do this but i coudn't find anything on the internet, so i beg you for help since this is 20% of my grade.
And if this can't be done do you have any other sugestions.
P.s. Sorry if my english is bad.
This is fairly simple to accomplish. Not having a variable means that you'll have a different formula/calculation depending on the missing variable, you can do this with if conditionals.
//Read them in as strings if you want to check if they're "_blank_", convert them
later.
string a = Console.ReadLine();
string h = Console.ReadLine();
string H = Console.ReadLine();
double area = 0;
double volume = 0;
if(a == "") //If it's blank, no entry do this code.
{
//This is how I'd convert it, just a little less pretty for the sake
//of understanding for you. You'd need to do this in every if block.
double returnedDoubleh = ConvertToDouble(h);
double returnedDoubleH = ConvertToDouble(H);
//Have your formula if `a` is blank.
}
else if (h == "")
{
double returnedDoubleA = ConvertToDouble(a);
double returnedDoubleH = ConvertToDouble(H);
//Have your formula if `h` is blank.
}
else if (H == "")
{
double returnedDoubleA = ConvertToDouble(a);
double returnedDoubleh = ConvertToDouble(h);
//Have your formula if `H` is blank.
}
else //This is if none are blank OR More than one is blank which would crash if
more than one is blank..
{
area = Math.Pow(a, 2) * Math.Sqrt(3) / 4 + 3 * a * h / 2;
volume = Math.Pow(a, 2) * Math.Sqrt(3) * H / 12;
}
Console.WriteLine(volume);
Console.WriteLine(area);
Console.ReadLine();
Example Function to convert your string values.
public static double ConvertToDouble(string nonConverted)
{
double converted;
while (!double.TryParse(nonConverted, out converted) || String.IsNullOrWhiteSpace(nonConverted))
{
Console.Clear();
Console.WriteLine($"INVALID RESPONSE\n\r" +
$"\n\rTry Again");
nonConverted = Console.ReadLine();
}
return converted;
}
In your conditionals you can also use a "Variable" so instead of saying if(a == "") you could do something like if(a == "x")

How do I make a statement follow the same "if" rules as before

I am trying to write a mini-quiz and I want the "try again" button to follow the same rules as the "if" statement as before the "else"
using System;
public class Program
{
public static void Main()
{
int x;
x = int.Parse(Console.ReadLine());
Console.WriteLine("Find a number that can be divided by both 7 and 12");
if ((x % 7 == 0) && (x % 12 == 0))
{
Console.WriteLine("well done, " +x+ " can be divided by 7 and 12");
}
else
{
Console.WriteLine("Wrong, try again.");
Console.ReadLine();
}
}
}
I want the ReadLine after the else statement to follow the same rules as the "if" statement before it but it needs a whole new statement to follow and copy-pasting the statement seems like an inefficient solution.
Normally this kind of processing is done in a while loop, which continues to loop until the user answers correctly. So the key is then to create a condition that will become false when there's a correct answer.
Notice that we also have the x variable re-assigned to the Console.ReadLine() method in the else block, otherwise we're always comparing the old value of x and the loop will never end.
For example:
bool answeredCorrectly = false;
while (!answeredCorrectly)
{
if ((x % 7 == 0) && (x % 12 == 0))
{
Console.WriteLine("well done, " + x + " can be divided by 7 and 12");
answeredCorrectly = true; // This will have us exit the while loop
}
else
{
Console.WriteLine("Wrong, try again.");
x = int.Parse(Console.ReadLine());
}
}
If you want to be really tricky about it, you could write a method that will get an integer from the user, and which takes function that can be used to validate that the input is correct (any method that takes in an int and returns a bool).
This way, you can create a validation method and pass that (along with the prompt for the user) to the method that gets an integer from the user.
Note that we're using the int.TryParse method to try to get an integer from the string input. This method is really handy because it does two things: First, it returns true if the parsing succeeds, and second, it returns the int value in an out parameter. This way we can use the return value to ensure they entered a number, and we can use the output parameter to see if the number meets our conditions:
private static int GetIntFromUser(string prompt, Func<int, bool> validator = null)
{
int result = 0;
bool answeredCorrectly = false;
while (!answeredCorrectly)
{
// Show message to user
Console.Write(prompt);
// Set to true only if int.TryParse succeeds and the validator returns true
answeredCorrectly = int.TryParse(Console.ReadLine(), out result) &&
(validator == null || validator.Invoke(result));
if (!answeredCorrectly) Console.WriteLine("Incorrect, please try again");
}
return result;
}
With this method in place, we can now call it from our main method as often as we like, with whatever validation we like, and we don't need to re-write all the looping code each time:
int x = GetIntFromUser("Enter a number that can be divided by both 7 and 12: ",
i => i % 7 == 0 && i % 12 == 0);
x = GetIntFromUser("Enter a negative number: ", i => i < 0);
x = GetIntFromUser("Enter a number between 10 and 20: ", i => i > 10 && i < 20);
You could even use it to create a number guessing game with just a few lines of code!
int randomNumber = new Random().Next(1, 101);
int x = GetIntFromUser("I'm thinking of a number from 1 to 100. Try to guess it: ", i =>
{
Console.WriteLine(i < randomNumber
? $"{i} is too low - guess a larger number."
: i > randomNumber ? $"{i} is too high - guess a smaller number." : "Correct!");
return i == randomNumber;
});
Have you considered using a while block and break; on the successful condition?
using System;
public class Program
{
public static void Main()
{
int x;
Console.WriteLine("Find a number that can be divided by both 7 and 12");
while (true)
{ //Loop the code until it is broken out of
x = int.Parse(Console.ReadLine());
if ((x % 7 == 0) && (x % 12 == 0))
{
Console.WriteLine("well done, " + x + " can be divided by 7 and 12");
Console.ReadKey(); //Pause the program so it doesnt break out immediately
break; //Break out of the while loop
}
else
{
Console.WriteLine("Wrong, try again.");
}
}
}
}

C# code issue - Code not working properly

I wrote a basic number guessing game from C#. It seems to return the 3rd option ("Wrong choice! Please try again.") every time no matter what var c is chosen by the user. I was trying with characters (s instead of 1 and w instead of 2 etc with c as a string) but it gave the same results. Not sure where it's going bad.
using System;
namespace Challanges
{
class Program
{
static int guess = 500;
static int low = 1;
static int high = 1000;
static bool cont = false;
static void Guess() //guesses and adjusts variables according to input.
{
int c;
Console.WriteLine("Is your number greater or less than: " + guess + Environment.NewLine + "If it is less than, press 1; if it is greater, press 2." + Environment.NewLine + "If it is your number, press 3.");
c = Convert.ToInt32(Console.Read());
if (c == 1)
{
high = 500;
guess = low + high / 2;
}
else if (c == 2)
{
low = 500;
guess = low + high / 2;
}
else if (c == 3)
{
Console.WriteLine("Congratulations!! We found your number!");
cont = true;
}
else
{
Console.WriteLine("Wrong choice! Please try again.");
Console.ReadKey();
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!" + Environment.NewLine + "Let's play a guessing game. Think of a number between 1 and 1000." + Environment.NewLine + "Type your number :)");
int x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your number is: " + x + Environment.NewLine + "Too easy?");
Console.ReadKey();
Console.WriteLine("Think of a number");
if(cont == false)
{
Guess();
} else
{
Console.ReadKey();
}
}
}
}
As mentioned in the comments before, Console.Read() returns a character code. The character code for the number 1 is 49, thus your conditions fail and the else block is executed.
What you wanted to do was use Console.ReadLine()which returns a string instead of character codes. If you cast that string into an Int32 you should be able to evaluate your conditions correctly.

Categories

Resources