I'm trying to create a simple clickclickclick game for the console in c# with Visual Studio. The only thing that is not working yet, is how the console can count presses of any button on the keyboard. The problem with the existing code is that the statement stays true even after releasing the button.
using System;
using System.Diagnostics;
public class clickclickclickgame
{
public static void Main()
{
Stopwatch timer = new Stopwatch();
int amountofpresses = 0;
timer.Start();
while (timer.ElapsedMilliseconds < 2000)
{
if (Console.KeyAvailable == true) // this is where my question is about.
{
timer.Restart();
amountofpresses++;
}
timer.Stop();
Console.WriteLine(amountofpresses);
}
}
Replace it by:
int i = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
while(true)
{
Console.ReadKey(true);//True makes it so you don't see the key in Console
if(sw.ElapsedMilliseconds < 2000)
{
i++;
sw.Restart();
}
else
{
sw.Stop();
break;
}
}
Console.WriteLine("Pressed amount: " + i);
Console.ReadKey();
This works like you wan't the only problem is it checks the state after ReadKey witch means if I'm game over I have to press once more for my highscore. btw 2000 ms is 2 seconds, quite high for this game :)
To help you on your way to increasing difficulty id say make 2000 a variable and subtract score * 2 (just an example) every key press. That way it gets harder and harder.
Related
I'm on a project coding a 4 axes robot arm.
I'm working on Virtual Studio and coding in C#. I'm NEW to C# so please be tolerant.
The robot came with a large .cs library and a Programming Manual with sample methods.
The sample interface :
sample_interface
I used cetains of these samples to build an operation method which makes the arm accomplishes repetitive movements for a chosen number of times. (I erased some movements here to avoid too much useless code) Here it comes :
private async void button_operation_Click(object sender, EventArgs e)
{
int op_number;
for (op_number = 0; op_number < Convert.ToInt32(textBox_operation.Text); op_number++) {
int i;
for (i = 0; i < 4; i++)
{
axis_list[i] = i;
}
v_dist[0] = 60;
v_dist[1] = 10000;
v_dist[2] = -1000;
v_dist[3] = -8000;
if ((int)g_handle != 0)
{
zmcaux.ZAux_Direct_Base(g_handle, 4, axis_list);
zmcaux.ZAux_Direct_SetSpeed(g_handle, axis_list[0], 10000);
zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, v_dist);
zmcaux.ZAux_Direct_GetIfIdle(g_handle, 3, ref idle_state[3]);
make_pause(g_handle, 3);
v_dist[0] = 50;
v_dist[2] = -1700;
v_dist[3] = -10550;
zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, v_dist);
zmcaux.ZAux_Direct_GetIfIdle(g_handle, 3, ref idle_state[3]);
make_pause(g_handle, 3);
v_dist[0] = 60;
v_dist[2] = -1000;
v_dist[3] = -8000;
zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, v_dist);
zmcaux.ZAux_Direct_GetIfIdle(g_handle, 3, ref idle_state[3]);
make_pause(g_handle, 3);
}
}
}
The make_pause() method is to make the robot wait the end of a movement before beggining the next :
{
while (idle_state[iaxis] == 0)
{
zmcaux.ZAux_Direct_GetIfIdle(g_handle, iaxis, ref idle_state[iaxis]);
}
}
By side, I also used another sample to add a "STOP" button but for this one, I just had to copy the whole method as it comes. Its role is to obviously cancel every movement. However, it's not working.
The sample method I used for the Stop Button :
{
if ((int)g_handle != 0)
{
zmcaux.ZAux_Direct_Rapidstop(g_handle,2);
}
}
My first though is that my operation method construction does not allow another method call to cancel.
Thus, I made a TEST button to create a single movement just like on my sample project.
Problem is that the STOP button is still not working.
What am I missing ? Is there something wrong with the way I am building the methods or project ?
Thanks
I want to create a timer of 30 seconds and after 30 seconds the timer should end and display some message.
In those 30 seconds I want user to enter an option if he fails to enter a option then I need to show some message like timed out.
public void AskEasyQues(EasyQuestion easyQuestion)
{
System.Console.WriteLine("Here is Your:"+sQcount+" Question:");
System.Console.WriteLine("***********************************");
System.Console.WriteLine("Question is of The Category:"+easyQuestion.MCat);
System.Console.WriteLine("***********************************");
System.Console.WriteLine(easyQuestion.MDescription);
System.Console.WriteLine("--------------------------------------");
System.Console.WriteLine("1:"+easyQuestion.MOption1+" "+"2:"+easyQuestion.MOption2);
System.Console.WriteLine();
System.Console.WriteLine("3:"+easyQuestion.MOption3+" "+"4:"+easyQuestion.MOption4);
System.Console.WriteLine();
System.Console.WriteLine("Enter your Choice:");
for (int a = 60; a >= 0; a--)
{
Console.Write("\rGenerating Preview in {0:00}", a);
System.Threading.Thread.Sleep(1000);
}
string ans = Console.ReadLine();
if(ans == easyQuestion.MAnswer)
{
mNoOfQuesAnswerd++;
System.Console.WriteLine();
System.Console.WriteLine("------Well Played Champion!!!!!!-----");
sPlayerScore=sPlayerScore+100;
}
else
{
System.Console.WriteLine();
System.Console.WriteLine("------Wrong Choice Lets Move On--------");
}
System.Console.WriteLine();
System.Console.WriteLine("Press any Key To Continue For Next Question");
Console.ReadLine();
System.Console.WriteLine();
System.Console.WriteLine("----------------------------");
sQcount = sQcount + 1;
Console.Clear();
}
This is my code and I have also tried simply a countdown timer using for loop like below:
for (int a = 60; a >= 0; a--)
{
Console.Write("\rGenerating Preview in {0:00}", a);
System.Threading.Thread.Sleep(1000);
}
but it is not i want to implement please share a minute to help me.
I think what you want to use is a Timer.
Firstly add the following namespace.
using System.Timers;
Next add a modular/global variable to do the timing.
static Timer questionTimer = new Timer(30000) //Time in milliseconds to fire event..
Next you need to wire up to the Elapsed event and enable the timer.
questionTimer.Elapsed += QuestionTimer_Elapsed;
questionTimer.Enabled = true;
and your method for time up might look something like this.
private static void QuestionTimer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Time up!");
questionTimer.Stop();
}
and finally you would start this timer every time you display a new question. (Don't forget to stop the timer if the question is answered correctly otherwise the event will still fire)
questionTimer.Start(); //Start question timer...
Console.Write("What is 5+5? "); //Ask the question...
string ans = Console.ReadLine(); //Get the user input...
if (ans == "10")
{
//If it's correct stop timing...
Console.WriteLine("Correct!");
questionTimer.Stop();
}
I hope this helps you and if you need any further explanation, leave a comment. :)
Okay I think I mis-understood your question in my previous answer.
What you want is a line that counts down the time remaining?
Similar process of wiring up a timer, but also create a int variable called secondCounter and we will set the interval for our Timer to 1000. (1 second).
Our timer elapsed method now looks something like this:
private static void QuestionTimer_Elapsed(object sender, ElapsedEventArgs e)
{
secondCounter = secondCounter + 1;
Console.SetCursorPosition(0, 2); //This is a row number...
Console.Write("\rSeconds Remaining: {0}: ", 30 - secondCounter);
if (secondCounter >= 30)
{
Console.WriteLine("Time's up!");
questionTimer.Stop();
}
}
Then you will handle your question logic outside of the timer.
questionTimer.Start();
Console.WriteLine("What is 5 + 5?");
var input = Console.ReadLine();
Console.WriteLine($"You anwsered {input}");
questionTimer.Stop();
I'm pretty new to C# and coding in general so it is hard for me to explain
and this might be something simple.
The program I am trying to make changes values in the game (Assault Cube).
Without the inner while loops, it just changes the values, I would like them to loop.
I have one outer while loop with multiple loops inside.
The inner while loops are there to loop the function but it stops the outer while loop.
I would like multiple inner loops to run along with the outer one.
I have tried what feels like everything. I tried Booleans, Breaks, Returns.
But nothing I have tried has fixed my problem. It may not be because they don't work, it may just be me using them wrong.
while (true) //outer loop
{
Console.Title = "SlavScripts";
int address1 = LocalPlayer + Health;
int address2 = LocalPlayer + Armor;
string Player = "";
Console.WriteLine("---SlavScripts v2.0---");
Console.WriteLine("");
Console.WriteLine("[1] Player Options");
Console.WriteLine("");
string answer = "";
answer = Console.ReadLine();
if (answer == "1")
{
Console.WriteLine("--Player Options--");
Console.WriteLine("");
Console.WriteLine("[1] Godmode");
Console.WriteLine("[2] Armor");
Console.WriteLine("");
Player = Console.ReadLine();
if (Player == "1")
{
Console.WriteLine("Godmode Enabled");
Console.WriteLine("");
while (true)
{
vam.WriteInt32((IntPtr)address1, 6969); //value to loop.
}
}
else if (Player == "2")
{
Console.WriteLine("Infinite Armor Enabled");
Console.WriteLine("");
while (true)
{
vam.WriteInt32((IntPtr)address2, 6969); //value to loop.
}
}
}
}
(full code: https://pastebin.com/bBcBPYs6)
Expected:
I enter the corresponding digit to activate the function
The function that was activated loops, and original text appears which allows me to navigate to another function.
Actual:
I enter the corresponding digit to activate the function.
The function activates and loops, but does not show opening text and disallows my to type further.
Think about what is happening in your code. Each instruction in your code is executing one after the other (superficially thinking - this might not be exactly true at assembly execution level but you get the idea). For example the line if (answer == "1") will only executed when the line before it (that is answer = Console.ReadLine();) completes its execution.
When you create the "outer while loop" (as you called), everything inside the loop will execute 1 instruction at a time following the order they are written and when the last instruction inside the loop is executed, the execution will jump back to the first line of code inside the loop.
If you put another while loop inside the "outer one", and say it will not have an exit condition (by declaring while(true) you are creating a loop that will never stop executing its embedded statements). Therefore when the execution reaches one of these while(true) loops it will be trapped inside them looping its embedded statements forever.
What I described is how instructions are executed. The other part you need to know is what is a thread. You can think of a thread as an isolated machine where every code is executed. When you don't deal with threads directly in your code, the compiler will automatically asks the operating system to create a thread to run your code at - this is usually referred to as the main thread.
So, what you actually need in your code is to inform the operating system to put the execution of each one of those "inner while(true)" loops inside a thread other than the main one and leaving the main thread to execute only code that can sequentially be executed.
You can learn how to use threads in your application here.
And as a side-note: that is probably not what you want to create a loop spinning code every cycle. You should consider pausing the execution inside those "inner loops" by putting the thread that is executing it to sleep for some time each time it iterates through (you can do this by just calling System.Threading.Thread.Sleep(100) - it will pause the thread execution by 100 milliseconds and will save some cpu execution time).
As per your expectation,
Please find the sample code snippet for getting user input continuously - achieved using Task in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SampleTaskStop
{
class Program
{
static public void SetValue(string address, int value)
{
while (!_cancelled)
{
//vam.WriteInt32((IntPtr)address1, 6969); //value to loop.
}
Console.WriteLine(address + " - completed");
}
static bool _cancelled = false;
static void Main(string[] args)
{
while (true) //outer loop
{
Console.Title = "SlavScripts";
Console.WriteLine("---SlavScripts v2.0---");
Console.WriteLine("");
Console.WriteLine("[1] Player Options");
Console.WriteLine("");
string answer = "";
answer = Console.ReadLine();
_cancelled = false;
if (answer == "1")
{
var acceptUserInput = Task.Factory.StartNew(AcceptUserInput);
acceptUserInput.Wait();
}
}
}
private static void AcceptUserInput()
{
// Task to perform the value setting in the
Task computationTask = null;
Console.WriteLine("Enter Player Input");
Console.WriteLine("1 God Mode");
Console.WriteLine("2 Armour Mode");
Console.WriteLine("Press Esc to cancel");
var key = Console.ReadKey(true);
while (key.Key != ConsoleKey.Escape)
{
if (key.Key == ConsoleKey.D1 || key.Key == ConsoleKey.NumPad1 )
{
Console.WriteLine("Godmode Enabled");
Console.WriteLine("");
_cancelled = true;
if (computationTask != null)
{
computationTask.Wait(new System.Threading.CancellationToken());
}
_cancelled = false;
computationTask = Task.Factory.StartNew(() => SetValue("data1", 6979));
}
else if (key.Key == ConsoleKey.D2 || key.Key == ConsoleKey.NumPad2)
{
Console.WriteLine("Infinite Armor Enabled");
Console.WriteLine("");
_cancelled = true;
if (computationTask != null)
{
computationTask.Wait(new System.Threading.CancellationToken());
}
_cancelled = false;
computationTask = Task.Factory.StartNew(() => SetValue("data2", 6979));
}
key = Console.ReadKey(true);
}
_cancelled = true;
Console.Write("Computation was cancelled");
}
}
}
Thanks to everyone who replied!
Multi-Threading sounds alot harder than it actually is and it also simplified my code alot!
Still have to add Thread.Sleep's :D
Cheers!
New & Improved - pastebin.com/qN7ci0By
I would be very thankful if anyone could give me a pointer in the right direction towards solving this problem I've been having in the last two days: I am working on a typing software for the Visual Studio 2010 console and need to represent time and be able to get input from the keyboard at the same time.
The problem is that the ReadLine() method allows me to write only when the timer thread is sleeping, maybe I could solve it via delegates or advanced task continuation methods, I'm a bit confused really since these are new concepts. Here is the code (sorry for the ugly formatting):
using System;
using System.Threading.Tasks;
using System.Threading;
namespace Typing_Game_tests
{
class Input_and_timer_multithread
{
public static void TimerThread()
{
for (int i = 1, mins = -1; i <= 1860; i++)
{
Console.SetCursorPosition(0, 0);
if (i % 60 == 1)
{
mins++;
}
Console.WriteLine("Timer: " + mins + " minute(s) and " + i % 60 + " seconds elapsed");
Console.SetCursorPosition(0, 6);
Thread.Sleep(1000);
}
}
static string keysRead;
public static void GetInput()
{
while (Console.ReadKey(true).Key != ConsoleKey.Enter)
{
Console.SetCursorPosition(0, 6);
keysRead = Console.ReadLine();
Console.SetCursorPosition(0, 6);
}
Console.SetCursorPosition(0, 6);
Console.WriteLine(keysRead);
}
static void Main(string[] args)
{
Thread timerMain = new Thread(new ThreadStart(TimerThread));
timerMain.Start();
Task getinputMain = new Task(GetInput);
getinputMain.Start();
}
}
}
Most of the examples I have found and studied have lambda expressions and delegates, which are new subjects I still have some difficulties understanding and thus implementing.
It would've been easier if I could've stopped the main timer thread until the ReadLine() did his job, but it wouldn't have made sense; plus I've tried using the Timers namespace, but I've had the same problem.
I wanted to give the impression that the cursor was permanently getting input from the user, but I still haven't found a way to efficiently switch back and forth the threads without deadlocking them.
Thanks.
This kind of code doesn't work any more since .NET 4.5. Console.ReadKey() and ReadLine() take a lock that prevents other threads from writing to the console. You'll need to replace it so the lock can't be taken anymore. That requires polling the keyboard with Console.KeyAvailable. Here is a simplistic replacement method for Console.ReadLine():
static object ConsoleLock = new object();
static string ReadString() {
var buf = new StringBuilder();
for (; ; ) {
while (!Console.KeyAvailable) System.Threading.Thread.Sleep(31);
lock(ConsoleLock) {
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter) {
Console.WriteLine();
return buf.ToString();
}
else if (key.Key == ConsoleKey.Backspace) {
if (buf.Length > 0) {
buf.Remove(buf.Length - 1, 1);
Console.Write("\b \b");
}
}
else {
buf.Append(key.KeyChar);
Console.Write(key.KeyChar);
}
}
}
}
Also lock on the ConsoleLock in your other thread that moves the cursor so output is strictly separated.
I have written my Desktop application but it's a little slow at times so I am trying to Optimize it as much as possible. Trouble is I don't know how.
Here is the code I have questions about
if (((mainRibbonForm)Parent.Parent.Parent.Parent.Parent.Parent.Parent)).myParentScopeVar == false)
{
//something goes here
}
//VS
if (myLocalScopeVar == false)
{
//something goes here
}
All the objects are created in mainRibbonForm and assigned, It seems that I can't call something like this.
mainRibbonForm.myparentScopeVar == false
So while in the last object, I just walked backwards to grab the variable using the Parent command variable.
I am not sure if I should always look at the parent scope for the variable or assign the variable to the last control as a localscope and only update it when the parent scope variable changes, which is not very often, but it does change.
I have some of these in timers and peppered every where in the code.. I am very new to C# and I translated everything from VB.Net to C# I am just trying to learn the correct or the best practices of programming in C#
Which is Faster and uses less resources?
How to I benchmark on my own next time?
I think that this code is overkill and horrible to see:
if (((mainRibbonForm)Parent.Parent.Parent.Parent.Parent.Parent.Parent)).myParentScopeVar == false)
{
//something goes here
}
Instead of this I prefer use a static variable and then call it using mainRibbonForm.myParentScopeVar. So you could insert this in your class:
public static bool myParentScopeVar;
Or you can pass this boolean through the constructors.
If you want to do a benchmark use the Stopwatch class that is a high resolution timer to measure how long your code will run and loop the code that you are testing more times to get a medium time that includes his best and worst performances:
Stopwatch timer = new Stopwatch();
timer.Start();
for(int i = 0; i < 1000; i++)
{
if (((mainRibbonForm)Parent.Parent.Parent.Parent.Parent.Parent.Parent)).myParentScopeVar == false)
{
//something goes here
}
}
timer.Stop();
TimeSpan timespan = timer.Elapsed;
MessageBox.Show(String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10));
timer.Restart();
for(int i = 0; i < 1000; i++)
{
if (myLocalScopeVar == false)
{
//something goes here
}
}
timer.Stop();
TimeSpan timespan = timer.Elapsed;
MessageBox.Show(String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10));
I think that my solution and your second solution using myLocalScopeVar are more efficient.