How to return a string using methods - c#

I am writing a class called Television that does a few simple controls, but I am running into an issue with my ToString method. "'Television.ToString()': not all code paths return a value". How would I go about returning either message? Any help is appreciated greatly, thank you.
class Television
{
private string manufacturer;
private int screenSize;
private bool powerOn = false; // the power is off by default
private int channel = 2; // channel is default set to 2
private int volume = 20; // volume default set to 20
public Television (string manu, int size) // The purpose of this constructor is to initialize the manufacturer and screen size fields.
{
manufacturer = manu;
screenSize = size;
}
public int GetVolume() // accessor method that returns volume
{
return volume;
}
public int GetChannel() // accessor method that returns channel
{
return channel;
}
public string GetManufacturer() // accessor method that returns manufacturer
{
return manufacturer;
}
public int GetScreenSize() // accessor method that returns screen sizes
{
return screenSize;
}
public void SetChannel(int userChannel) // mutator method that changes the channel
{
Console.WriteLine("What channel would you like to watch?: ");
userChannel = int.Parse(Console.ReadLine());
userChannel = channel;
}
public void power() // mutator method that turns the power on/off
{
powerOn = !powerOn;
}
public void IncreaseVolume() // mutator method that increases volume by 1
{
volume = volume + 1;
}
public void DecreaseVolume() // mutator method that decreases volume by 1
{
volume = volume - 1;
}
**public string ToString()
{
if (powerOn == false) {
Console.WriteLine("A " + screenSize + " inch " + manufacturer + " has been turned off.");
}
else if (powerOn == true)
{
Console.WriteLine("A " + screenSize + " inch " + manufacturer + " has been turned on.");
}**
}
}
}

ToString should override the base method to respect the polymorphism design and it must return a string but you return nothing:
public override string ToString()
{
string str = "A " + screenSize + " inch " + manufacturer + " has been turned ";
return str + ( powerOn ? "on." : "off." );
}
Or:
public override string ToString()
{
return $"A {screenSize} inch {manufacturer} is turned {(powerOn ? "on" : "off")}.";
}
Therefore you can use:
var television = new Television();
Console.WriteLine(television.ToString());
MessageBox.Show(television.ToString());
label.Text = television.ToString();

Related

If/else statement is returning false, even though the condition should be true. (C#)

I'm currently trying to build a tic-tac-toe game in C# as of right now. Now, I've gotten most of the whole game set up. Below is the complete code for my project as of rn:
// Main code.
Game newGame = new();
newGame.RunGame();
// Classes
internal class Game
{
private Player[] Players;
private Updater GameUpdater;
private Board GameBoard;
public Game()
{
Players = new Player[2] { new(PlayerSymbol.X), new(PlayerSymbol.O) };
GameUpdater = new();
GameBoard = new();
}
public void RunGame()
{
while (true)
{
GameBoard.DisplayBoard();
int currentPlayer = GameUpdater.SendPlayerTurnInfo();
int playerInput = Players[currentPlayer].GetUserInput(); // The position the player wants to place their X/O
bool playerInputtedValidNumber = GameUpdater.VerifyUserHasInputValidNumber(playerInput);
if (playerInputtedValidNumber)
{
bool playerInputtedUnusedNumber = GameUpdater.VerifyUserHasInputUnusedSpot(GameBoard.SendBoardPiecesData(--playerInput));
if (playerInputtedUnusedNumber)
{
PlayerSymbol currentPlayerSymbol = Players[currentPlayer].SendPlayerSymbol(); // The symbol of the current player.
GameBoard.UpdateBoardPiecesData(playerInput, currentPlayerSymbol);
}
else
{
Console.WriteLine("This position has already been used!");
continue;
}
}
else
{
Console.WriteLine("Inputted an invalid position!");
continue;
}
}
}
}
internal class Board
{
private string[]? BoardPieces;
private string? BoardDisplay;
public Board()
{
BoardPieces = new string[9] { " ", " ", " ", " ", " ", " ", " ", " ", " " };
BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} ";
}
public void DisplayBoard()
{
Console.WriteLine(BoardDisplay);
}
public string SendBoardPiecesData(int userInput)
{
return BoardPieces[userInput]; // No issue with null since the number will be automatically checked for null beforehand.
}
public void UpdateBoardPiecesData(int userInput, PlayerSymbol playerSymbol)
{
BoardPieces[userInput] = $"{playerSymbol}";
BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} ";
}
}
internal class Updater
{
private int PlayerIndicator;
public Updater()
{
PlayerIndicator = 1;
}
public int SendPlayerTurnInfo()
{
if (PlayerIndicator == 1)
{
PlayerIndicator = 0;
return PlayerIndicator;
} else
{
PlayerIndicator = 1;
return PlayerIndicator;
}
}
public bool VerifyUserHasInputValidNumber(int userInput)
{
Console.WriteLine(userInput);
if (userInput >= 0 || userInput <= 10)
{
return false;
} else
{
return true;
}
}
public bool VerifyUserHasInputUnusedSpot(string userInput)
{
if (userInput == "X" || userInput == "O") return false;
else return true;
}
}
internal class Player
{
private PlayerSymbol PlayerSymbol;
public Player(PlayerSymbol playerSymbol)
{
PlayerSymbol = playerSymbol;
}
public int GetUserInput()
{
Console.Write($"It is currently {PlayerSymbol}'s turn. Which position would you like to play at? ");
string? input = Console.ReadLine();
bool isNumerical = int.TryParse(input, out int _);
while (!isNumerical)
{
Console.Write("Invalid input, please input a number. ");
input = Console.ReadLine();
isNumerical = int.TryParse(input, out int _);
}
return int.Parse(input);
}
public PlayerSymbol SendPlayerSymbol()
{
return PlayerSymbol;
}
}
// Enumerations
enum PlayerSymbol
{
X,
O
}
Right now, the main issue with this code will be inside the Updater class.
I have a VerifyUserHasInputValidNumber(int userInput) method, taking in the number input that the player has taken, and returning a true or false depending on whether it fits a range of being a value between 1-9.
public bool VerifyUserHasInputValidNumber(int userInput)
{
if (userInput >= 0 || userInput <= 10)
{
return false;
} else
{
return true;
}
}
For some reason though, even though I can confirm that the userInput parameter is being inputted correctly (the Console.WriteLine in the 1st line of the method), it will still produce a false and will tell the user that they've inputted an invalid position.
public void RunGame()
{
while (true)
{
GameBoard.DisplayBoard();
int currentPlayer = GameUpdater.SendPlayerTurnInfo();
int playerInput = Players[currentPlayer].GetUserInput(); // THIS IS THE NUMBER THAT'S BEING INPUTTED INTO THE METHOD THAT I'M HAVING AN ISSUE WITH (the VerifyUserHasInputValidNumber(playerInput); method)
bool playerInputtedValidNumber = GameUpdater.VerifyUserHasInputValidNumber(playerInput); // Should be true if I input any number between 1-9.
if (playerInputtedValidNumber)
{
bool playerInputtedUnusedNumber = GameUpdater.VerifyUserHasInputUnusedSpot(GameBoard.SendBoardPiecesData(--playerInput));
if (playerInputtedUnusedNumber)
{
PlayerSymbol currentPlayerSymbol = Players[currentPlayer].SendPlayerSymbol(); // The symbol of the current player.
GameBoard.UpdateBoardPiecesData(playerInput, currentPlayerSymbol);
}
else
{
Console.WriteLine("This position has already been used!");
continue;
}
}
else
{
Console.WriteLine("Inputted an invalid position!"); // THIS, however, is what is being logged into the console.
continue;
}
}
}
I don't know if it may be a memory leak issue, or if I may have some sort of incorrect formatting, but if I could get any help with this issue, I would greatly appreciate it.
this test
if (userInput >= 0 || userInput <= 10)
is always true. What value do you think will be false?
I assume you want
if (userInput >= 0 && userInput <= 10)
return true;
else return false;

Lock Boolean Value though while block

I am creating a card game and I wish to create a god mode to freak out my friends but I need to keep a Boolean value through all runs of the methods i'm using
All Code:
namespace Card_Game_1
{
class Program
{
static void Main(string[] args)
{
while (true)
{
P1Hand();
}
}
#region PosAns
static string PosAns()
{
string posans = "Y";
return posans;
}
#endregion
#region NegAns
static string NegAns()
{
string posans = "N";
return posans;
}
#endregion
#region P1Hand
static int P1Hand()
{
int P1Hand = 0;
if (PlayerInput().Equals(PosAns()))
{
int NewRnd = Rnd();
string StringRnd = NewRnd.ToString();
Console.WriteLine(StringRnd);
P1Hand = P1Hand + NewRnd;
Console.WriteLine("You're Hand Is " + P1Hand);
}
else
{
if (GMActP1() == true)
{
P1Hand = GodModeP1();
Console.WriteLine("You're Hand Is " + P1Hand);
}
if (PlayerInput().Equals(NegAns()))
{
Console.WriteLine("You're Hand Is " +P1Hand);
}
}
return P1Hand;
}
#endregion
#region P2Hand
static int P2Hand()
{
// Not completing till P1 is done
return P2Hand;
}
#endregion
#region NormalMode
static int Rnd()
{
Random Rd = new Random();
int[] Cards = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
int RandomIdex = Rd.Next(1, Cards.Length);
return RandomIdex;
}
#endregion
#region GodMString
static string GodMString()
{
string GmAct = " ChTy";
return GmAct;
}
#endregion
#region GodModeP1
static int GodModeP1()
{
int NewP1Hand = P1Hand();
int WinHand = 21 - NewP1Hand;
return WinHand;
}
#endregion
#region GMActP1
static bool GMActP1()
{
bool Godmode = false;
if (PlayerInput().Equals(PosAns() + GodMString()))
{
Godmode = true;
}
bool NewGodM = Godmode;
return NewGodM;
}
#endregion
#region GodModeP2
static int GodModeP2()
{
int NewP2Hand = P2Hand();
int WinHand = 21 - NewP2Hand;
return WinHand;
}
#endregion
#region PlayerInput
static string PlayerInput()
{
string S = Console.ReadLine();
return S;
}
#endregion
}
}
Now My Problem is this:
1: when the logic turns in the direction of God Mode methods or GM methods it draws a blank then ask for another PlayerInput Method
2: I believe this stems from the Boolean value in GMActP1 Method not staying true through while statements or not returning a value at all so it falls out of the logic in P1Hand Method
the methods are only there till i'm finishing up as it helps me keep track of things so it's easier to edit then when finished I edit it to be a little less crazy. GMString works as the password while GMActP1 is an activator for God Mode for use with Logic in P1Hand.
Here's Where the problem lies:
static bool GMActP1()
{
bool Godmode = false;
Console.WriteLine(Godmode);
if (PlayerInput().Equals(PosAns() + GodMString()))
{
Godmode = true;
Console.WriteLine(Godmode);
}
bool NewGodM = Godmode;
Console.WriteLine(NewGodM);
return NewGodM;
}
I checked the last piece of code and it returns false at all stages.
Here is my question is it possible to lock the bool var as true after the required logic has been met i would rather not have to declare the bool var as false every time it runs because that would mean you would have to write "Y ChTy" every turn you have and if you dont want your friends to know, it wont be very easy to get them to look the other way when you input this "cheat code" when i get this to work i will have it run normally for the first few rounds until the required number to 21 is less than 12 because 12 is the max # card you can receive. This way it looks like a normal game stacked in your favor.

Errors CS0116 and CS0246

I'm building a simple class that allows me to calculate the dimensions of the room for a class and I'm having trouble getting the code to work. When I run it these are the errors I am receiving.
/p1/room.cs(1,7): error CS0116: A namespace cannot directly contain members such as fields or methods
/p1/room.cs(48,19): warning CS0108: 'Room.GetType()' hides inherited member 'object.GetType()'. Use the new keyword if hiding was intended.
/p1/room.cs(1,1): error CS0246: The type or namespace name 'Using' could not be found (are you missing a using directive or an assembly reference?)
I did some research and found that it seems that most of the time the two above errors refer to either unmatched brackets, but after searching through my room.cs file, I was unable to find any. In comparing the headers to my files to other classes I've found I can't find any differences.
Here is my room.cs file
Using System;
namespace p1
{
public class Room
{
private string type;
private double length;
private double width;
private double height;
public Room()
{
type = "Default";
length = 0.0;
width = 0.0;
height = 0.0;
}
public Room(string t, double l, double w, double h)
{
type = t;
length = l;
width = w;
height = h;
}
public void SetType(string t)
{
type = t;
}
public void SetLength(double l)
{
length = l;
}
public void SetWidth(double w)
{
width = w;
}
public void SetHeight(double h)
{
height = h;
}
public string GetType()
{
return type;
}
public double GetLength()
{
return length;
}
public double GetWidth()
{
return width;
}
public double GetHeight()
{
return height;
}
public double GetArea()
{
return length*width;
}
public double GetVolume()
{
return length*width*height;
}
public void Display()
{
Console.WriteLine("Room Type: " + this.GetType());
Console.WriteLine("Room Length: " + this.GetLength());
Console.WriteLine("Room Width: " + this.GetWidth());
Console.WriteLine("Room Height: " + this.GetHeight());
Console.WriteLine("Room Area: " + this.GetArea().ToString("F 2") + " sq ft " );
Console.WriteLine("Room Volume: " + this.GetVolume().ToString("F 2") + " cu ft ");
}
}
}
I can also post the program.cs file if needed, but this was getting quite long and I didn't want it to be unreadable.
Correct syntax to use NameSpace should be using not Using
Replace Using System; with using System;
Use
public new string GetType()
{
return type;
}
in place of to get rid of warning "Use new keyword is hiding was intented"
public string GetType()
{
return type;
}
In addition to what vivek nuna already said, you should get used to C#'s concept of properties. This will make your code less verbose and avoids the specific problem of hiding GetType():
public class Room
{
public string Type { get; set; } = "Default"; // with C#6 property initialization
public double Length { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public Room() {} // no code here, Type is initalized, double is 0 by default
public Room(string t, double l, double w, double h)
{
Type = t;
Length = l;
Width = w;
Height = h;
}
public double GetArea()
{
return Length * Width;
}
public double GetVolume()
{
return Length * Width * Height;
}
public void Display()
{
Console.WriteLine("Room Type: " + Type);
Console.WriteLine("Room Length: " + Length);
Console.WriteLine("Room Width: " + Width);
Console.WriteLine("Room Height: " + Height);
Console.WriteLine("Room Area: " + GetArea().ToString("F 2") + " sq ft " );
Console.WriteLine("Room Volume: " + GetVolume().ToString("F 2") + " cu ft ");
}
}
From outside you can now simply access the properties:
Room r = new Room();
r.Height = 12;
Console.WriteLine(r.Height);
The compiler does all the work you did yourself in your code. It creates backing fields for each property and the getter and setter methods. You don't have to do this and can concentrate on the real work.

Property or indexer cannot be assigned to - it is read only

Hey i just started by C# class 2 weeks ago so i am beginner programmer
and i am having trouble with my code. i have 2 classes, one of them is the test case that runs the program and the other has private variables. my variables color, NumOfWheels, StartingPoint, CurrentSpeed, and Mileage says property or indexer cannot be assigned to - it is read only when i try to build it. how do i fix this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Homework1
{
class Car
{
private string color;
private int numOfWheels;
private int startingPoint;
private int mileage;
private int currentSpeed;
public Car()
{
Color = "";
NumOfWheels = 4;
StartingPoint = 100000;
CurrentSpeed = 0;
Mileage = 0;
}
public Car(string color, int numOfWheels, int startingPoint, int currentSpeed, int mileage)
{
Color = color;
NumOfWheels = numOfWheels;
StartingPoint = startingPoint;
CurrentSpeed = currentSpeed;
Mileage = mileage;
}
public virtual void setcolor(string color)
{
this.color = color;
}
public virtual void setnumOfWheels(int numOfWheels)
{
this.numOfWheels = numOfWheels;
}
public virtual string Color
{
get
{
return color;
}
}
public virtual double NumOfWheels
{
get
{
return numOfWheels;
}
}
public virtual int StartingPoint
{
get
{
return startingPoint;
}
}
public virtual int CurrentSpeed
{
get
{
return currentSpeed;
}
}
public virtual int Mileage
{
get
{
return mileage;
}
}
public override string ToString()
{
return (" color " + color + " numOfWheels" + numOfWheels + "startingPoint " + startingPoint + "mileage" + mileage + "current speed" + currentSpeed);
}
}
}
********************************************************************************
/// this is the test case that runs the program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class CarTest
{
static void Main(string[] args)
{
Car myCar = new Car();
Console.WriteLine("*****************************");
Console.WriteLine("* *");
Console.WriteLine("* WELCOME TO CAR MANAGER *");
Console.WriteLine("* By <<my Name>> *");
Console.WriteLine("* *");
Console.WriteLine("*****************************");
Console.WriteLine("\nEnter the number of wheels of a car");
int numOfWheels = Console.Read();
myCar.setWheels(numOfWheels);
Console.WriteLine("Enter the color of the car");
String color = Console.ReadLine();
Console.WriteLine("Current mileage will be set to zero");
Console.WriteLine("The current starting point will be set to 100000");
Console.Write("The current status of your car \n{0:D} Wheels, \n{1}, \n{2:D} Miles and \nCAR POINT = {3:D}", myCar.getNumOfWheels,
myCar.getColor, myCar.getMileage, myCar.getStartingPoint);
Console.WriteLine("\nEnter the owner's name");
String name = Console.ReadLine();
Console.WriteLine("Enter the miles the car ran in this week");
int milesThisWeek = Console.ReadLine;
myCar.setMileage(Mileage);
Console.WriteLine("This car is owned by n{1}", name);
Console.WriteLine("===>The current status of your car:");
Console.WriteLine("Wheels: " + myCar.getWheels());
Console.WriteLine("Color: " + myCar.getColor());
Console.WriteLine("Current Mileage: " + myCar.getMileage());
Console.WriteLine("Starting Point: " + myCar.getStartingPoint());
Console.WriteLine("************ Thank you for using CAR MANAGER *************");
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine("Press ENTER to close console…….");
}
}
}
You're trying to set a property:
Color = "";
(among other places) But that property doesn't have a setter, only a getter:
public virtual string Color
{
get
{
return color;
}
}
In order to set the value of a property, it needs a setter:
public virtual string Color
{
get
{
return color;
}
set
{
color = value;
}
}
(repeat for your other properties as well)
It looks like you're trying to create Java-like setter methods:
public virtual void setcolor(string color)
{
this.color = color;
}
This works, and you can call those instead of trying to set the properties:
setColor("");
But it's not the expected convention in C#. The properties can manage the backing variables themselves. In fact, you can remove the backing variables entirely and use auto-implemented properties for simple values:
public virtual string Color { get; set; }
If you just need to hold a value, a simple property does that just fine. Methods are more for operations in code, not for getting/setting simple values. (Additionally, you wouldn't want to get into the habit of calling a lot of methods from a constructor. A constructor should really just build the state of the object and nothing else.)

Knights Tour recursive C# Im getting something wrong in my way of doing the stuff

class Knight
{
public static readonly double LegalDistance = Math.Sqrt(5);
public Stack<Field> Steps { get; set; }
private static readonly List<Field> board = Board.GameBoard;
private static List<Field> fields;
private static readonly Random random = new Random();
private static readonly object synLock = new object();
public Knight(Field initial)
{
Steps = new Stack<Field>();
Steps.Push(initial);
}
public void Move()
{
Field destination = Choose();
if (destination == null)
{
return;
}
Console.WriteLine("Moving from " + GetPosition().GetFieldName() + " to " + destination.GetFieldName());
Steps.Push(destination);
}
public Field Back()
{
Field from = Steps.Pop();
Console.WriteLine("Moving back from " + from.GetFieldName() + " to " + GetPosition().GetFieldName());
return from;
}
public Field Choose()
{
List<Field> legalMoves = Behaviour();
legalMoves.RemoveAll(field => Steps.Contains(field, new FieldValueComparer()));
if (legalMoves.Count == 0)
{
return null;
}
Field theChoosenOne;
int index;
lock (synLock)
{
index = random.Next(0, legalMoves.Count);
}
theChoosenOne = legalMoves.ElementAt(index);
return theChoosenOne;
}
private List<Field> Behaviour()
{
fields = new List<Field>();
fields.AddRange(board);
for (int i = fields.Count - 1; i >= 0; i--)
{
double actualDistance = fields[i].GetDistance(GetPosition());
if (!actualDistance.Equals(LegalDistance))
{
fields.Remove(fields[i]);
}
}
return fields;
}
public List<Field> GetSteps()
{
return Steps.ToList();
}
public Field GetPosition()
{
return Steps.Peek();
}
}
So this is how I'd do the stuff. The problem is, I am missing some key functionality, because on low given stepcount it backtracks to the start, on high stepcount, it causes StackOverFlow.
Here are some other functions to let you understand what I want to do:
Calculating distance:
public double GetDistance(Field other)
{
return Math.Sqrt(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2));
}
Finding the path:
class PathFinder
{
public static void FindPath(Knight knight)
{
if (knight.Steps.Count != 20)
{
knight.Move();
FindPath(knight);
knight.Back();
}
}
}
Your path search is essentially random walk. On large board, this may take a while anyway.
Now about StackOverflow: notice that you don't push anything on Move() when there are no places to go. So, on recursive call to FindPath() there still will be the same knight.Steps.Count, the same position, the same null return on Choose()... and so on, until you're out of stack space.
Obvious fix would be to add bool return value to Move() indicating if there was any move. Unless there is actual reason behind using random moves, more deterministic search algorithm is recommended.

Categories

Resources