How would I go about pausing the time (programming a game) - c

basically I need to implement a pause feature in my game (which is a simplified version of frogger) which stops the logs scrolling, and ignores any other input until the character p is pressed again). The way I've started to implement this in a while loop is to end it once another p Is pressed.
if(serial_input == 'p' || serial_input == 'P') {
while(1){
//need to pause the game
if(serial_input == 'p' || serial_input == 'P')
break;
}
This is how my logs are currently scrolling:
/* The following statements change the scrolling speeds of the individual logs */
current_time = get_clock_ticks();
if(is_frog_alive() && current_time >= last_move_time1 + 1000) {
scroll_lane(0, 1);
last_move_time1 = current_time;
} else if(is_frog_alive() && current_time >= last_move_time2 + 600) {
scroll_lane(1, -1);
last_move_time2 = current_time;
} else if(is_frog_alive() && current_time >= last_move_time3 + 800) {
scroll_lane(2, 1);
last_move_time3 = current_time;
} else if(is_frog_alive() && current_time >= last_move_time4 + 900) {
scroll_log_channel(0, -1);
last_move_time4 = current_time;
} else if(is_frog_alive() && current_time >= last_move_time5 + 1200) {
scroll_log_channel(1, 1);
last_move_time5 = current_time;
And this is implemented by a timer as described:
* We update a global clock tick variable - whose value
* can be retrieved using the get_clock_ticks() function.
*/
Any suggestions would be greatly appreciated

The best practice would depend on the libraries and general architecture you're using. That being said a naive implementation which I sometimes use would go somewhat like this:
while( playing) {
if( !paused) {
logic();
}
rendering();
input();
}
When doing small game projects, inside the main while loop I scatter logic, rendering and input in to different parts. In the input part there's the button that toggles the pause flag. In the main loop, the logic is simply enclosed in an if statement.
If you still need to do something inside the logic, you could pass it as a parameter or make it visible in some other way. Additionally you can do some special when-paused-graphics in the rendering section.
Details would vary but I hope this would at least give you a nudge to the right direction. That being said it is a common thing to implement and shouldn't be too hard to google.

Related

Identifying C syntax

So I was studying some tutorial code for a BLE implementation, and I came across this syntax which I have never seen before.
&p_ble_evt->evt.gatts_evt.params.write;
It is the &foo;bar-&baz part i'm unsure of.
I tried 'googleing' the code part, then tried running it through https://cdecl.org/.
But without getting an understanding for what this code does/is.
/**#brief Function for handling the Write event.
*
* #param[in] p_midi_service LED Button Service structure.
* #param[in] p_ble_evt Event received from the BLE stack.
*/
static void on_write(ble_midi_service_t * p_midi_service, ble_evt_t const * p_ble_evt)
{
ble_gatts_evt_write_t * p_evt_write = (ble_gatts_evt_write_t *) &p_ble_evt->evt.gatts_evt.params.write;
if ((p_evt_write->handle == p_midi_service->data_io_char_handles.value_handle) &&
(p_evt_write->len == 1) &&
(p_midi_service->evt_handler != NULL))
{
// Handle what happens on a write event to the characteristic value
}
// Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
if ((p_evt_write->handle == p_midi_service->data_io_char_handles.cccd_handle)
&& (p_evt_write->len == 2)
)
{
// CCCD written, call application event handler
if (p_midi_service->evt_handler != NULL)
{
ble_midi_evt_t evt;
if (ble_srv_is_notification_enabled(p_evt_write->data))
{
evt.evt_type = BLE_DATA_IO_EVT_NOTIFICATION_ENABLED;
}
else
{
evt.evt_type = BLE_DATA_IO_EVT_NOTIFICATION_DISABLED;
}
p_midi_service->evt_handler(p_midi_service, &evt);
}
}
}
So if some kind soul would help enlighten me that would be much appreciated.
Thank you.
Looks like xml/html escape sequences, should read:
&p_ble_evt->evt.gatts_evt.params.write;

curses move backwards accounting for previous lines

Is there any way to move the cursor backwards while accounting for previous lines, i.e. when the cursor goes back from the beginning of the line it goes to the last non-empty character of the previous line?
So there's no built in method for this, so I had to write my own
void backspace(){
int x,y;
getyx(stdscr,y,x);
if(x == 0) {
if( y == 0 ) {
return;
}
x = getmaxx(stdscr) - 1;
move(--y,x);
char ch = ' ';
while(ch == ' ' && x != 0){
move(y,--x);
ch=inch();
}
} else {
move(y,x-1);
}
delch();
}
Note that I have removed some irrelevant file I/O related code that was in this method.
You can do that easily in a curses (full-screen) application (by reading the characters from the virtual screen using winch or win_wch), but would find it much harder in a termcap/terminfo low-level application because there is no portable method for reading directly from the terminal's screen.

connect four - comparison of evaluation - c

I try to implement the minimax algorithm into my connect four game.
I´m done with the evaluation-function and halfway done with the algorithm-function.
I just can`t find the solution for the "last" problem. Here are my functions:
void minimax(field f){
int i;
field c;
convert_1D_to_2D(f, c);
for(i=0;i<COLS;i++) {
if(can_throw(c, i) == 0) {
throw(f, i);
convert_1D_to_2D(f, c);
if((is_winner(c) == 0) && (is_board_full(f) == 0)) { //no winner, board not full
minimax(f);
}
else if(is_winner(c) == 1) { //there is a winner
evaluate_turn(f);
//compare evaluation
undo_turn(f);
}
else if(is_winner(c) == 0 && (is_board_full(f) == 1)) { //no winner, board full
evaluate_turn(f);
//compare evaluation
undo_turn(f);
}
}
}
The field is an array with f[COLS*ROWS+1], where f[0] is the depth and the other elements save in which columns were thrown. the "c"-board represents the "graphical" board with 0 for free, 1 for player 1 and 2 for player 2.
static int evaluate_turn(field f) {
field c;
convert_1D_to_2D(f, c);
if (((f[0] % 2) == 1) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, max for him || +1
return 1;
}
else if (((f[0] % 2) == 2) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, max for him || +1
return 1;
}
if (((f[0] % 2) == 1) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, counting for 1 || -1
return -1;
}
else if (((f[0] % 2) == 2) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, counting for 2 || -1
return -1;
}
else if ((is_board_full(f) == 1) && (is_winner(c) == 0)) { //draw || 0
return 0;
}
So my problem is, that i can't think of a clean solution to compare the evaluation bottom to top. I really think, that I don't need to introduce a new datastructure (which would get way too big). It's like the solution is right in front of me but i can't grab it.
Is it possible to just compare the evaluation on the "way back" of the recursion? If yes, how?
Or do I really need to introduce something new more complex? Or maybe I'm missing off something completely?
Thanks!
Or do I really need to introduce something new more complex? Or maybe
I'm missing off something completely?
Unfortunately the answer is the latter. Minimax is not a void function. It returns the value of the node that it represents. That is how evaluation is compared. You are also missing another fundamental concept. Your function only considers terminal nodes to be those where the game is won or the board is full. While this is technically true, no real minimax function works that way. The number of nodes would be around 7^48, so your function would literally take upwards of ten years to terminate on a modern pc. What real world minimax functions do is set a maximum depth for the search to reach (unless you add tree pruning expect this to be 5 or 6), and consider all nodes at that depth to be terminal and evaluate them using a heuristic (inexact guess) evalation function. In connect four this could be based on something like the number of three in a rows. Another mistake you made is calling your eval function if you know there is a winner. If you know which player won than return the proper value straight out, no need to call the expensive eval function. You also cannot stream line your function for both min and max as you did. You must either create a seperate function for min and max, or use the negamax variant.
My advise: It seems you don't really understand how the algorithm should be implemented. Read up on minimax and negamax psuedocode.

C program shows no error but doesn't show output

Roy wants to change his profile picture on Facebook. Now Facebook has some restriction over the dimension of picture that we can upload.
Minimum dimension of the picture can be L x L, where L is the length of the side of square.
Now Roy has N photos of various dimensions.
Dimension of a photo is denoted as W x H
where W - width of the photo and H - Height of the photo
When any photo is uploaded following events may occur:
If any of the width or height is less than L, user is prompted to upload another one. Print "UPLOAD ANOTHER" in this case.
If width and height are both large enough and
(a) if the photo is already square then it is accepted. Print "ACCEPTED" in this case.
(b) else user is prompted to crop it. Print "CROP IT" in this case.
Code:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int len; /* len is the length of the side of square */
scanf("%d",&len);
int test;
scanf("%d",&test);
while(test--)
{
int w,h;
/* w - width of the photo and h- Height of the photo */
scanf("%d %d",&w,&h);
if(w==len && h==len)
{
printf("ACCEPTED\n");
}
else if(w>len || w==len && h>len || h==len)
{
printf("CROP IT\n");
}
else
{
printf("UPLOAD ANOTHER\n");/* print */
}
}
return 0;/* success */
}
If your problem is that you're seeing no output at all, it's likely because it's running in an IDE and the output window is closing before you can see it. Judicious use of a getchar() at the end of main() may be all you need to fix this, though I'd probably prefer to just run it from the command line.
In any case, since && has a higher precedence than ||, your second condition is effectively:
else if ((w > len) || (w == len && h > len) || (h == len))
which is clearly wrong since having a photo with width more than what was necessary would result in a request for cropping regardless of the other sub-conditions.
You would be better off following the textual specs more closely so that you can actually check it more easily. That would entail something like (with slightly simplified specs still meeting the original intent):
If any of the width or height is less than L, user is prompted to upload another one.
Otherwise both are large enough. If the photo is already square then it is accepted.
Otherwise user is prompted to crop it.
The code for that is a much simpler:
if ((w < len) || (h < len)) {
puts ("UPLOAD ANOTHER");
} else if (h == w) { // Both large enough otherwise previous
puts ("ACCEPTED"); // condition would have been true.
} else {
puts ("CROP IT");
}
Due to operator precedence,
else if(w>len || w==len && h>len || h==len)
is equivalent to:
else if(w>len || (w==len && h>len) || h==len)
What you need to use is:
else if( (w>len || w==len) && (h>len || h==len) && (w == h) )
You can simplify that to:
else if( w >= len && h >= len && w == h )
which can be further simplified to:
else if( w >= len && w == h )
It will show output but the program runs faster than you expect. It will close as soon as the output is displayed . It will not wait till you read it.
So use getch(); declared in conio.h to get a single key press as input after you have printed all the output (right before the return statement. It will make the program wait for the user to press a key before exiting.
here is the screenshot. it is running without error on me.
NOTE: This is not an answer. But this is just the only way to give picture example :) no need to up
Maybe you only need to put getchar(); at the end of the code before return to let the screen to pause for a while. it is just exiting very fast

How to set an int to 1 if dependent on a button and in a while loop?

I'm programming a robot, and unfortunately in its autonomous mode I'm having some issues.
I need to set an integer to 1 when a button is pressed, but in order for the program to recognize the button, it must be in a while loop. As you can imagine, the program ends up in an infinite loop and the integer values end up somewhere near 4,000.
task autonomous()
{
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
wait1Msec(0350);
}
}
}
I've managed to get the value by using a wait, but I do NOT want to do this. Is there any other way I can approach this?
assuming that the SensorValue comes from a physical component that is asynchronous to the while loop, and is a push button (i.e. not a toggle button)
task autonomous()
{
while(true)
{
// check whether
if(current_time >= next_detect_time && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
next_detect_time = current_time + 0350;
}
// carry on to other tasks
if(enemy_is_near)
{
fight();
}
// current_time
current_time = built_in_now()
}
}
Get the current time either by some built-in function or incrementing an integer and wrap around once reach max value.
Or if you are in another situation:
task autonomous()
{
while(true)
{
// check whether the flag allows incrementing
if(should_detect && SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect + 1;
// no waiting here
should_detect = false;
}
// carry on to other tasks
if(enemy_is_near)
{
if(fight() == LOSING)
should_detect = true;
}
}
}
Try remembering the current position of the button, and only take action when its state changes from off to on.
Depending on the hardware, you might also get a signal as though it flipped back and forth several times in a millisecond. If that's an issue, you might want to also store the timestamp of the last time the button was activated, and then ignore repeat events during a short window after that.
You could connect the button to an interrupt and then make the necessary change in the interrupt handler.
This might not be the best approach, but it will be the simplest.
From The Vex Robotics catalogue :
(12) Fast digital I/O ports which can be used as interrupts
So, most probably which ever micro-controller of Vex you are using will support Interrupts.
Your question is a bit vague
I m not sure why u need this variable to increment and how things exactly work...but i ll make a try.Explain a bit more how things work for the robot to move...and we will be able to help more.
task autonomous()
{
int buttonPressed=0;
while(true)
{
if(SensorValue[positionSelectButton] == 1)
{
positionSelect = positionSelect +1;
buttonPressed=1;
}
else{
buttonPressed = 0;
}
//use your variables here
if( buttonPressed == 1){
//Move robot front a little
}
}
}
The general idea is :
First you detect all buttons pressed and then you do things according to them
All these go in your while loop...that will(and should) run forever(at least as long as your robot is alive :) )
Hope this helps!

Resources