Lock Boolean Value though while block - c#

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.

Related

Try to display a int through a static field, but return a weird value (C#)

I'm trying to cut down on how much duplication I have on my code, so I decided to make one of my classes a static class since I decided that its data should really be shared with everyone. Here's the static method below:
// A static class, that holds all object's coordinates, and methods to return & update their values.
internal static class Coordinate
{
private static int[,] PlayerCoordinate { get; set; }
public static int[,] GateCoordinate { get; }
public static int[,] FountainCoordinate { get; }
static Coordinate() // FIRST VALUE IS X (column), SECOND VALUE IS Y (row).
{
PlayerCoordinate = new int[,] { { 0, 0 } };
GateCoordinate = PlayerCoordinate; // Just starts off in the same place as player.
FountainCoordinate = new int[,] { { 2, 0 } };
}
// A static method, that sends the data of all object coordinates, deconstructed into seperate ints.
public static int PlayerColumn() { return PlayerCoordinate[0, 0]; }
public static int PlayerRow() { return PlayerCoordinate[0, 1]; }
public static int GateColumn() { return GateCoordinate[0, 0]; }
public static int GateRow() { return GateCoordinate[0, 1]; }
public static int FountainColumn() { return FountainCoordinate[0, 0]; }
public static int FountainRow() { return FountainCoordinate[0, 1]; }
// Updates the coordinates of the player.
public static void UpdatePlayerCoordinate(int column, int row) { PlayerCoordinate = new int[,] { { column, row } }; }
}
The main issue comes in from my GameManager class. On the console, the beginning section should print out "You are the room at (Column=0, Row=0), but it prints this instead:
Here is the code for my GameManager class:
internal class GameManager
{
private bool IsGameOver;
private Player Player;
private Updater Updater;
// Don't need to call Fountain or Coordinate since they're static
public GameManager()
{
IsGameOver = false;
Player = new();
Updater = new();
}
public void RunGame()
{
while (!IsGameOver)
{
Console.WriteLine("----------------------------------------------------------");
Updater.DisplayPlayerPosition(); // This is the main line that I'm having issues with as of right now. All other functions past this are another problem.
Updater.DisplayPlayerSenses();
string playerInput = Player.GetInput();
Updater.MovePlayer(playerInput);
IsGameOver = Updater.CheckForWin();
}
}
}
And just to make sure, here is the code from my updater class, with the specific method that I'm having issues with:
internal class Updater
{
// No fields
// Default constructor
// Gets the text to show the player his current position.
public void DisplayPlayerPosition() // This is the method that I'm having issues with.
{
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn}, Row={Coordinate.PlayerRow})");
}
...
I'm fairly new to the static keyword so I believe that I may be missing smth. I personally believe that it's because the class itself hasn't been initialized (like I haven't called the constructor for the Coordinate class, and apparently you can't call a static constructor anyways), but that's just me. If I could get any help, I'd greatly appreciate it!
PlayerColumn() and PlayerRow() are methods, but you are accesing them in the WriteLine statement as if they are properties.
Update your WriteLine to:
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn()}, Row={Coordinate.PlayerRow()})");

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;

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.

Inheritance - storing objects list<class> with loops C#

I'm stuck one an exercise which is very important to understand for my soon come final exam, in a basic C# course.
I have an issue that I can't describe in words. So I'll show you with code and perhaps then you might help me.
I've been stuck on this, not being able to solve it, for a long time. Cuz of that, I don't want any copy paste code. I want to understand it. So please enlighten me where I've failed.
Explanation what I want to do.
I want to create a dart game 501. So first I add players, they throw their darts, you get the score after each turn announced, then when one player reach 501 points, the game announce the winner and all of his throws.
My idea of approaching the problem is to have an add player loop, which terminates (I got this fixed already).
Once you done creating the players(list elements), then you'll execute the methods with a foreach loop running all the players in the player list, executing the objects one at a time and finally Here is my real problem: storing all their scores in another list.
Here we go with the code
The list.
private List<Player> players = new List<Player>(); //This list is fine
Here is the loop.
foreach (Player dartThrows in players) //My loop
{
dartThrows.DoThrow();
dartThrows.GetScore();
}
SubClass1(named Player)
public List<Darts> dartList = new List<Darts>(); //<--HERE IS THE PROBLEM
Just some random constructors and methods.
The throw method. It's not an issue but I typed it down to give you an idea
public void DoThrow()
{
var tries = 3;
for (int i = 0; i < tries; i++)
{
//No problems here just int read-user input data
}
AddDarts(int a, int b, intc)
}
Here lies all my problems, it would make my life so much easier if this could get solved.
public void AddDarts(Darts toDartList)
{
dartList.Add(toDartList);
}
SubClass2 (Darts)
Here are my constructors
private int dartOne;
private int dartOne;
private int dartOne;
Here is my method
public Darts(int DartOne, int DartTwo, int DartThree)
{
dartOne = DartOne;
dartTwo = DartTwo;
dartThree = DartThree;
}
Best regards Marcus Johansson
Here is my full program
class Program
{
static void Main(string[] args)
{
Game game = new Game();
game.PlayGame();
}
}
class Game
{
private List<Player> players = new List<Player>();
private List<Player> computers = new List<Player>();
public void AddPlayer(string newPlayers)
{
players.Add(new Player(newPlayers));
}
public void AddComputer(string newComputer)
{
computers.Add(new Player(newComputer));
}
static string UpperCaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
return char.ToUpper(s[0]) + s.Substring(1);
}
public void PlayGame()
{
bool noWinner = false;
bool stopLoop = false;
Console.WriteLine("<<<WELCOME TO DART 501>>>");
Console.WriteLine("\nPress [S] to start game!");
Console.Beep();
Console.ReadLine();
Console.Clear();
do
{
Console.WriteLine("Enter name of players and type [D]ator for adding NPC\nType [S]top to start the game");
string addPlayer = Console.ReadLine();
string FirstUpperLetter = UpperCaseFirst(addPlayer);
if (FirstUpperLetter == "Stop" || FirstUpperLetter == "S")
{
stopLoop = true;
}
if (FirstUpperLetter == "D" || FirstUpperLetter == "Dator")
{
string computer = FirstUpperLetter;
AddComputer(computer);
}
else
{
AddPlayer(FirstUpperLetter);
}
} while (stopLoop == false) ;
players.RemoveAt(players.Count - 1);
do
{
Console.Clear();
foreach (Player arrowThrows in players)
{
noWinner = true;
Console.WriteLine("\n~~~Starting Round~~~~");
arrowThrows.DoThrow();
Console.WriteLine("This round you got {0}", arrowThrows.CalculatePoints());
if (arrowThrows.Score > 501)
{
Console.Clear();
Console.WriteLine("<<<WE HAVE A WINNER>>>");
System.Threading.Thread.Sleep(500);
Console.WriteLine("...The winner is: ");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("{0} He made these epic throws: ", arrowThrows.Name);
foreach(Arrows finalResult in arrowThrows.arrowList)
{
Console.WriteLine(finalResult);
Console.ReadLine();
}
noWinner = false;
}
}
foreach (Player computerThrows in computers)
{
computerThrows.RandomThrow();
System.Threading.Thread.Sleep(500);
}
}while(noWinner == true);
}
}
class Player
{
public List<Arrows> arrowList = new List<Arrows>();
public List<int> ScoreBoard = new List<int>();
public Player() { }
public int Score { get; set; }
public Player(int score)
{
Score = score;
}
public string Name { get; set; }
public Player(string name)
{
Name = name;
}
public int RoundScore { get; set; }
public void RandomThrow()
{
Random rndComp = new Random();
Console.WriteLine("...Loading Npc_throw.exe");
System.Threading.Thread.Sleep(300);
int random1 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random2 = rndComp.Next(0, 60);
System.Threading.Thread.Sleep(300);
int random3 = rndComp.Next(0, 60);
Console.WriteLine("Random computer got this random score {0}", random1 + random2 + random3);
arrowList.Add(new Arrows(random1, random2, random3));
}
public void DoThrow()
{
Console.WriteLine("###{0} make your throws###", Name);
var tries = 3;
for (int i = 0; i < tries; i++)
{
Console.WriteLine("\nEnter score for {0} arrow", i + 1);
string arrowScore = Console.ReadLine();
int addScore = int.Parse(arrowScore);
while(-1 > addScore || 61 < addScore)
{
Console.WriteLine("\nInvalid score! Enter a score between 0-60/n<<<You may type [R]andom or [R] for a random score>>>");
arrowScore = Console.ReadLine().ToUpper();
if (arrowScore == "R" || arrowScore == "RANDOM")
{
Random rnd = new Random();
addScore = rnd.Next(0, 60);
goto start;
}
else
{
addScore = int.Parse(arrowScore);
}
}
start:
ScoreBoard.Add(addScore);
}
ScoreBoard.ToArray();
arrowList.Add(new Arrows(ScoreBoard[0],ScoreBoard[1], ScoreBoard[2]));
}
public int CalculatePoints()
{
Score = ScoreBoard.Sum();
return Score;
}
public void AddArrows(Arrows toArrowList)
{
toArrowList.ToString();
arrowList.Add(new Arrows(ScoreBoard[0], ScoreBoard[1], ScoreBoard[2]));
}
}
class Arrows
{
private int arrowOne;
private int arrowTwo;
private int arrowThree;
public int score { get; set; }
public Arrows(int ArrowOne, int ArrowTwo, int ArrowThree)
{
arrowOne = ArrowOne;
arrowTwo = ArrowTwo;
arrowThree = ArrowThree;
}
public int GetScore()
{
return arrowOne + arrowTwo + arrowThree;
}
public override string ToString()
{
return string.Format("{0}-1:st arrow: {1}-2:nd arrow: {2}- 3:rd arrow: {3}", GetScore(), arrowOne, arrowTwo, arrowThree);
}
}
}
The problem with your approach, is your utilizing a List. This collection has no unique information, simply a grouping of data. Which would have me recommend either a Tuple, Dictionary, KeyValuePair, or a clean Data Model.
Without the requirements are approaches may not be viable. Your issue stems from persistence related issues. Your multiple inheritance title is also incorrect, C# only allows a single class to be inherited.
What I would potentially do would be:
public class Player
{
public string Name { get; set; }
public string Throw { get; set; }
public string Points { get; set; }
}
What this does, is incredibly beneficial. The above class represents a specific Model. When your method is called for a throw you apply said results. Then when you calculate the score you iterate through the List<Player> for a specific person or all and display the output.
I'm not going to write your application, but think of it like this:
Player Registers
Player Turn
Player Throws
Play Scored
Store Player Result
Repeat Steps two through five, three times.
Display Output: Player, Throw, Score, and Total Score
By utilizing that model, you hold the relative information for your outcome. This conceptual notion is important for Object Oriented Programming.
You can use a Dictionary to save scores for each player
Dictionary<Player, List<int>> playerScores = new Dictionary<Player, List<int>>();
playerScores.Add(player1, new List<int>()); //init dictionary with a new player
playerScores[player1].Add(number); //add a value to the list associated with the player
So each player has a list of scores.

Null reference exception was unhandled in c#

For example in section a: i have a random number and in the section b: i want to multiply that random number by 2 but it has to be in a function and then section c: has to add 10 and so on. I guess this is very simple for you guys. and i am sure i am writing very silly codes but i am not a programmer.
thanks.
class Program
{
static void Main(string[] args)
{
Boot boot = new Boot();
Game game = new Game();
Console.WriteLine("Matrix Lengte: " + game.Matrix);
Console.WriteLine("Lengte boot: " + boot.Lengte);
Console.ReadLine();
class Game
{
private Boot boot;
private int matrix;
public int Matrix
{
get { return matrix; }
set { matrix = value; }
}
public Game()
{
matrix= boot.Lengte*2;
}
internal Boot Boot
{
get { return boot; }
set { boot = value; }
}
By default fields have their default values, which is null for reference types. So, just add boot initialization:
public Game()
{
boot = new Boot(); // or pass via constructor parameter
matrix = boot.Lengte * 2;
}

Categories

Resources