C# Towers of Hanoi console application. - c#

I'll keep this succinct. I am learning C# and exploring the possibilities of the language. Being a python programmer by heart, I am fairly new to the .NET realm.
I am currently writing a Towers of Hanoi console application. I already understand the recursion part of the code as that is not challenging.
Here is my current code for my peg class.
namespace Tower_of_hanoi
{
class PegClass
{
private int pegheight;
private int y = 3;
int[] rings = new int[0];
public PegClass()
{
// default constructor
}
public PegClass(int height)
{
pegheight = height;
}
// other functions
public void AddRing(int size)
{
Array.Resize(ref rings, rings.Length + 1);
rings[rings.Length - 1] = size;
}
public void DrawPeg(int x)
{
for (int i = 1; i <= pegheight; i++)
{
Console.SetCursorPosition(x, y);
Console.WriteLine("|");
y++;
}
if (x < 7)
{
x = 7;
}
Console.SetCursorPosition(x - 7, y); // print the base
Console.WriteLine("----------------");
}
}
}
And this is my code for the main class to display the pegs. I have facilitated the printing of the pegs by putting them in a method.
namespace Tower_of_hanoi
{
class Program
{
static void Main(string[] args)
{
PegClass myPeg = new PegClass(8);
PegClass myPeg2 = new PegClass(8);
PegClass myPeg3 = new PegClass(8);
DrawBoard(myPeg, myPeg2, myPeg3);
Console.ReadLine();
}
public static void DrawBoard(PegClass peg1,PegClass peg2,PegClass peg3)
{
Console.Clear();
peg1.DrawPeg(20);
peg2.DrawPeg(40);
peg3.DrawPeg(60);
}
}
}
My question remains,
How does one move "rings" over to "pegs" in a console application? I understand how this would work in WinForms, but I want a challenge.
Thank you everyone in advance,
youmeoutside

All you have to do ,is modify the DrawPeg method to accept the number of current "rings"
public void DrawPeg(int x, int numberOfRings = 0)
{
for (int i = pegheight; i >= 1; i--)
{
string halfRing = new string(' ', i);
if (numberOfRings > 0)
{
if (i <= numberOfRings)
halfRing = new string('-', numberOfRings - i + 1);
}
Console.SetCursorPosition(x - halfRing.Length * 2 + i + (halfRing.Contains("-") ? (-i + halfRing.Length) : 0), y);
Console.WriteLine(halfRing + "|" + halfRing);
y++;
}
if (x < 7)
{
x = 7;
}
Console.SetCursorPosition(x - 7, y); // print the base
Console.WriteLine("----------------");
}
Then ,you can call your DrawBoard method with your current values (Now they are hard-coded)
public static void DrawBoard(PegClass peg1, PegClass peg2, PegClass peg3)
{
Console.Clear();
peg1.DrawPeg(20, 1);
peg2.DrawPeg(40, 2);
peg3.DrawPeg(60, 4);
}
Now all you have to do ,is call the methods with different numbers of rings every time your player makes a move

Related

C# Sliding Window Algorithm

So i have to sent a message from a Sender to a Destination(Shown in main class) by specifing how many letters i wanna sent (the size variable).When the laters left are less than letters i wanna sent,it automaticaly sent how many i have left,and after the algorithm stops;
The problem is when the message i supossely sent is 9 characters long,and when i wanna sent 6 characters and another 3 it throws me an error (System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
)
using System;
using System.Text;
using System.Threading;
namespace homework
{
internal class slidingWindow
{
private string name;
private StringBuilder message = new StringBuilder();
private bool isSource = false;
private int fin = 0;
public slidingWindow(string name, bool isSource)
{
this.name = name;
this.isSource = isSource;
}
public void messageSet(string _message)
{
if (isSource == true) message.Append(_message);
else Console.WriteLine("Is not source");
}
public void sendMessage(slidingWindow destination)
{
int counter= 0;
Console.WriteLine("Specify the size of data sent: ");
int size = Convert.ToInt32(Console.ReadLine()); //the size of how manny letters i should send
int countCharacterSent=size;
for (int x = 0; x < message.Length+(message.Length%size); x = x + size)
{
counter++;
for (int y = 0; y < size; y++)
{
if (x + size > message.Length + (message.Length % size)) { size=size-(message.Length%size); countCharacterSent = message.Length; }
else {destination.message.Append(message[x + y]); }
}
Console.WriteLine("Sennder---- " + destination.message + " ----->Destination" + " (" + counter+ ")"+ " Characters sent: "+size+ " Characters received: "+countCharacterSent+ '\n');
Thread.Sleep(TimeSpan.FromSeconds(1));
countCharacterSent = countCharacterSent + size;
}
fin = 1;
if (message.Length % size != 0) destination.fin = 1;
destination.print();
}
public void print()
{
Console.WriteLine("Destination has receveid the message: " + message+" FIN: "+fin);
}
}
and the main class
using System;
namespace homework
{
class main
{
static void Main(string[] args)
{
while (true)
{
int option = 0;
slidingWindow a = new slidingWindow("Sender", true);
a.messageSet("exampless");
slidingWindow b = new slidingWindow("Destination", false);
a.sendMessage(b);
Console.WriteLine("If you want to exit write 1:"+'\n');
option = Convert.ToInt32(Console.ReadLine());
if (option == 1) break;
}
}
}
example:
input:
message='example'
size=3;
output:
exa
mpl
e
Honestly I can see you try hard (too hard) to handle the limit case of the last block that can just not meet the expect size.
Since you do this in dotnet C#, and depending on the version you will see you have many different options....
Especially to create a batch of x out of a simple sequence....
here is a homemade version of things you will find for free in libraries like moreLinq and probably in latest Linq lib..
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
public static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int size)
{
return source
.Select( (c, i) => (c, index : i))
.Aggregate(
new List<List<T>>(),
(res, c) =>
{
if (c.index % size == 0)
res.Add(new List<T> { c.c });
else
res.Last().Add(c.c);
return res;
});
}
}
public class Program
{
public static void Main(string[] args)
{
var test = "xxxxxxxxxxx".AsEnumerable();
var blocks = test
.Batch(3)
.Select(b=> new string(b.ToArray()));
blocks.ToList().ForEach(System.Console.WriteLine);
}
}

How to find a way of output the number of attempts for each question of the quiz?

I am making the quiz application on C# in Console version. I have almost done all things, but I don't know how to show the number of attempts for each question, after when the quiz is finished. If you know something, let me know.
I can not add more lines of the code, as the website doesn't allow to do it
if (keys[index] == answer) // Answer is correct
{
Console.WriteLine();
Console.WriteLine("Congratulations. That's correct!");
Console.WriteLine();
totalScore += markPerQuestion;
index++;
Console.WriteLine("The total score is: {0}", totalScore);
Console.WriteLine("Used attempt(s): {0}", attempt);
attempt = 1;
count = attempt;
markPerQuestion = 20;
}
else // Answer is incorrect
{
attempt++;
count++;
if (attempt <= 3)
{
markPerQuestion /= 2;
}
else if (attempt > 3 && attempt < 5) // The fourth attempt gives zero points
{
markPerQuestion = 0;
totalScore += markPerQuestion;
}
else if(attempt >= 5) // Move to the next question
{
Console.WriteLine("Sorry, you used all attempts for that question. Moving to the next question");
index++;
markPerQuestion = 20;
attempt = 1;
count = attempt;
continue;
}
Console.WriteLine("Oops, try again");
}
if ((index > keys.Length - 1 && index > questions.Length - 1)) // Questions and answer keys are finished
{
for (int i = 0; i < questions.Length; i++)
{
Console.WriteLine("Question {0} was answered after {1} attempt(s)", (i + 1), count);
}
break;
}
Consider this solution:
Create a public class that will allow you to store the results.
public class QuizMark
{
public int Attempts;
public int Mark;
}
For the Console app create a method to control the Quiz. Call the method Quiz() from the Main method.
private const int MAX_ATTEMPTS = 5;
private static void Quiz()
{
var quizResults = new List<QuizMark>();
var questionAnswers = new List<int>() { 1, 3, 5, 2, 3, 6 };
foreach(var a in questionAnswers)
{
var v = QuizQuestion(a);
quizResults.Add(v);
}
int i = 0;
quizResults.ForEach(e => Console.WriteLine($"Question: {++i} Attempts: {e.Attempts} Mark: {e.Mark}"));
var total = quizResults.Sum(s => s.Mark);
Console.WriteLine($"Total Points: {total}");
}
Notice the List collection that stores an object of the class QuizMark. This is where the results of each question are stored: attempts and points.
The List questionAnswers simply contains the expected answer to each of the questions.
Now create the method that is going to control how each question in the quiz will be handled:
private static QuizMark QuizQuestion(int answer)
{
var quizMark = new QuizMark();
int guess = 0; //Store ReadLine in this variable
int mark = 20;
for (int attempt = 1; attempt < MAX_ATTEMPTS + 1; attempt++)
{
guess++; //remove when adding Console.ReadLine
if (guess.Equals(answer))
{
quizMark.Attempts = attempt;
quizMark.Mark = mark;
break;
}
else
{
mark = attempt <= 3 ? mark/2 : 0;
quizMark.Attempts = attempt;
quizMark.Mark = mark;
}
}
return quizMark;
}
You will need to replace the incrementor guess++ with the actual guess the user makes. This code is designed to go though automatically just as a demonstration.
IMPORTANT NOTE:
You will want to do some error handling any time you allow users to enter data. They might enter non-integer values. Probably using a loop around a Console.ReadLine where you check the value of the input with a Int32.TryParse().

Updating a clock whilst being able to input c# console [duplicate]

This question already has answers here:
Writing string at the same position using Console.Write in C# 2.0
(2 answers)
How can I get the position of the cursor in a console app?
(2 answers)
Closed 5 years ago.
I'm trying to create a console application that gives me an updating clock in the corner with the ability to give an input.
I've tried using multiple threads but it gives me weird errors.
My clock function:
public class Work
{
public void Count()
{
for (int i = 0; i < 100; i++)
{
DateTime date = DateTime.Now;
Console.SetCursorPosition(0, 1);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition((Console.WindowWidth - 8) / 2, 0);
Console.Write(String.Format("{0:HH:mm:ss}", date));
Console.WriteLine();
if (i == 90)
{
i = 0;
}
else
{
// Continue
}
}
}
}
My main function:
class Program
{
public static void Main(string[] args)
{
Console.CursorVisible = false;
Work w = new Work();
Console.WriteLine("Main Thread Start");
ThreadStart s = w.Count;
Thread thread1 = new Thread(s);
thread1.Start();
int i = 2;
Console.SetCursorPosition(0, i);
i = i + 1;
Console.WriteLine("Input:");
string input = Console.ReadLine();
Console.WriteLine(input);
}
}
Does anybody know how I can achieve this, is there any possible way that I can write to a clock with a different cursor or something along the lines of that?
Try change your code like this
class Program
{
static void Main(string[] args)
{
Console.CursorVisible = false;
var w = new Work();
Console.WriteLine("Main Thread Start");
ThreadStart s = w.Count;
var thread1 = new Thread(s);
thread1.Start();
int i = 2;
Console.SetCursorPosition(0, i);
var format = "Input:";
Console.WriteLine(format);
Console.SetCursorPosition(format.Length + 1, i);
string input = Console.ReadLine();
Console.WriteLine(input);
}
}
public class Work
{
public void Count()
{
while (true)
{
Thread.Sleep(1000);
var originalX = Console.CursorLeft;
var originalY = Console.CursorTop;
Console.SetCursorPosition(0, 1);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition((Console.WindowWidth - 8) / 2, 0);
Console.Write("{0:HH:mm:ss}", DateTime.Now);
Console.SetCursorPosition(originalX, originalY);
}
}
}
The main idea is to store original cursor position before drawing your clock and then renurn it back.
var originalX = Console.CursorLeft;
var originalY = Console.CursorTop;
Console.SetCursorPosition(originalX, originalY);

How to add integers in different methods

I'm very new to C# and have a very limited understanding of the "proper code" to use. I had the goal to imitate the old Pokemon battle systems as best I could with what I know and am having a hard time linking a stored int value for HP between two methods (assuming that's the right word), to calculate new Hp when the second method interacts with the main method. Had a hard time finding an answer for that in searches so here is the code:
" static void Main(string[] args)
{
Random Gen = new Random();
int enemyhealth = (150);
int playerhealth = (100); //the line i need to use
int edefense = (20);
int pattack = (30);
int rate = Gen.Next(1,5);
int critical = 0; "
static void enemyattack()
{
Random Gen1 = new Random();
int pdefense = (20);
int eattack = (20);
int erate = Gen1.Next(1, 5);
int ratattack = Gen1.Next(1,3);
int critical1 = 0;
Console.WriteLine("Enemy Ratta gets ready!");
Console.ReadKey();
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("\nEnemy Ratta attacks!\n");
Console.WriteLine("----------------------------------------------------------------------------");
ratattack = Gen1.Next(1,3);
if (ratattack = 1)
{
Console.WriteLine("Enemy Ratta used Tail Whip!");
pdefense = (pdefense - erate);
Console.ReadKey();
Console.WriteLine("----------------------------------------------------------------------------");
erate = Gen1.Next(1, 5);
if (erate <= 3)
{
Console.WriteLine("\nIt wasn't very effective!");
}
else
{
Console.WriteLine("\nIt was super effective!");
}
Console.WriteLine("Squirtle's Defense decreased by " + erate + "");
Console.WriteLine("----------------------------------------------------------------------------");
}
else if (ratattack == 2)
{
Console.WriteLine("\nRatta used Tackle");
erate = Gen1.Next(1, 5);
if (erate >= 5)
{
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("\nCRITICAL HIT!!!!");
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------\n");
Console.ReadKey();
Console.WriteLine("It was super effective!");
Console.ReadKey();
eattack = eattack + 10;
}
else
{
critical1 = Gen1.Next(1, 5);
eattack = critical1 + eattack;
}
phealth = Math.Abs((eattack - pdefense) - playerhealth); ***//This Line is where I'm having trouble because phealth is used in my first method as a stored integer and the new calculation for phealth won't interact with the phealth in the origional main, i simply belive I haven't learned that part of c#, I only have 5 hours of youtube tutorials.***
Console.WriteLine("Ratta dealt " + Math.Abs(eattack - pdefense) + " damage!");
eattack = 30;
Console.WriteLine("\n----------------------------------------------------------------------------");
Console.ReadKey();
Console.ReadKey();
}
}
}
}
Make Static method , or simply add your variable in the main Class (where Main method Stored)
Here example
class Program
{
int HP;
int Main()
{
HP=0; //Now you HP is 0;
Method();
}
void Method()
{
HP+=50; //Now you HP is 50
}
}
I would break things down into separate classes. For example you should have a Player class that contains all the information for the player. You can't have methods like that in your main program. You need to keep everything separate. Make a class for each object you need.
public class Player
{
int currentHp = 100;
int maxHp = 100;
int atkPower = 20;
int defense = 20;
string playerName = "Ashe"
public Player() {}
public void TakeDamage(int damage)
{
currentHp = currentHp - damage;
}
}
public class Enemy
{
int currentHp = 100;
int maxHp = 100;
int atkPower = 20;
int defense = 20;
string enemyName= "Rattata"
public Enemy(){}
public int AttackPlayer(Player player)
{
// all of your attack logic, pass in the player here
player.TakeDamage(someAmountofDamage);
}
}
Then in your main program:
static void Main(string[] args)
{
Player myPlayer = new Player();
Enemy myEnemy = new Enemy();
myEnemy.AttackPlayer(player);
}

Having issue creating recursive constructor

I'm trying to build Quad-tree which receive array of points and split them into 4 cells. those 4 cells(cell1...cell4) are suppose to be created recursively but it doesn't works.
What I'm doing wrong? wasted all day trying fix it.
I erased some basic things not to overload the script here.
class QuadTreeNode
{
private QuadTreeNode cell1;
private QuadTreeNode cell2;
private QuadTreeNode cell3;
private QuadTreeNode cell4;
private int maxppc;
private double leftminX, leftminY, rightmaxX, rightmaxY;
public QuadTreeNode(Point2D leftMin, Point2D rightMax, int maxPPC)
{
this.leftminX = leftMin.East;
this.leftminY = leftMin.North;
this.rightmaxX = rightMax.East;
this.rightmaxY = rightMax.North;
this.maxppc = maxPPC;
}
public QuadTreeNode(Point2D[] pointArray, Point2D leftMin, Point2D rightMax, int maxPPC)
{
for (int i=0; i <4; i++)
{
cellList[i] = new List<Point2D>();
}
allPointList = pointArray.ToList();
this.leftminX = leftMin.East;
this.leftminY = leftMin.North;
this.rightmaxX = rightMax.East;
this.rightmaxY = rightMax.North;
this.maxppc = maxPPC;
if (allPointList.Count > maxPPC)
{
Split(allPointList);
}
}
public void Split(List<Point2D> Array)
{
if (Array.Count > maxppc)
{
double centerE = (this.leftminX + this.rightmaxX) / 2;
double centerN = (this.leftminY + this.rightmaxY) / 2;
double deltaE = (this.rightmaxX - this.leftminX) / 2;
double deltaN = (this.rightmaxY - this.leftminY) / 2;
Point2D Center = new Point2D(centerE, centerN);
this.cell1 = new QuadTreeNode(cellList[0].ToArray(),new Point2D((Center.East - deltaE), (Center.North - deltaN)), Center, maxppc);
this.cell2 = new QuadTreeNode(cellList[1].ToArray(), new Point2D(Center.East, Center.North - deltaN), new Point2D((Center.East + deltaE), Center.North), maxppc);
this.cell3 = new QuadTreeNode(cellList[2].ToArray(), new Point2D((Center.East - deltaE), (Center.North)), new Point2D(Center.East, (Center.North + deltaN)), maxppc);
this.cell4 = new QuadTreeNode(cellList[3].ToArray(), Center, new Point2D((Center.East + deltaE), (Center.North + deltaN)), maxppc);
for (pntIndex = 0; pntIndex < Array.Count; pntIndex++)
{
CellIndex(Array[pntIndex]);
}
pntIndex = 0;
Array.Clear();
for (int c=0; c < 4; c++)
{
Array = cellList[c].ToList();
cellList[0].Clear();
cellList[1].Clear();
cellList[2].Clear();
cellList[3].Clear();
Split(Array);
}
return;
}
else
{
return;
}
}
public void CellIndex(Point2D point)
{
//locates points up to East,North
}
The problem may be with this part:
Array = cellList[c].ToList();
cellList[0].Clear();
cellList[1].Clear();
cellList[2].Clear();
cellList[3].Clear();
Split(Array);
Here, you're copying the list at location c but you're clearing each list at every iteration anyway, so you're likely losing some of your points.

Categories