Trying to make a tic-tac-toe game in C - arrays

So I am trying to make a tic-tac-toe game in C and I've gotten most of the code written out, no error messages, but I want to know what code to add to get the computer to play the game as well. I just don't know what else to add here to make sure the game is interact-able and not just the user typing in one letter and being done. If anyone could help, that'd be appreciated! The code is below:
#include <time.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
system("clear");
const char ROWS = 3;
const char COLS = 3;
int rows, cols, tile = 1, choice;
for (rows = 0; rows < ROWS; rows++)
{
for (cols = 0; cols < COLS; cols++)
{
printf("[%d]", tile++);
}
printf("\n");
}
printf("\nWhere would you like to put your X: ");
scanf("%d", &choice);
tile = 1;
for (rows = 0; rows < ROWS; rows++)
{
for (cols = 0; cols < COLS; cols++)
{
if (tile == 1 || tile == 2 || tile == 3 || tile == 4 || tile == 5 || tile == 6 || tile== 7 || tile == 8 || tile == 9)
{
printf("[%d]", tile++);
}
if (choice == tile)
{
tile -= tile;
printf("[X]");
choice += 1000;
}
}
printf("\n");
}
return 0;
}

Instead of worrying about implementing a computer player, I think your first step shoud be to offer support for a second human player.
First, you will need some array to represent the state of the game board. A multi-dimensional array of type char seems appropriate, in which each char can have one of three values:
'E' for empty
'X' for first player
'O' for second player
You could define the array like this:
char board[3][3];
Also, you will need an additional variable to keep track of whose turn it currently is. A variable of type bool with the name first_players_turn would probably be appropriate. When it is the first player's turn, this variable should be set to true, otherwise to false.
I also suggest that you create your own function print_board for printing the game board to the screen.
You will also need a function evaluate_game_state in order to determine the state of the game, which can be one of the following:
The game is still undecided.
The game is a draw.
Player 1 has won.
Player 2 has won.
To represent these 4 possible game states, I recommend that you use an enum, like this:
enum game_state
{
GAMESTATE_UNDECIDED,
GAMESTATE_DRAW,
GAMESTATE_WINNER_PLAYER1,
GAMESTATE_WINNER_PLAYER2
};
You can now declare the function evaluate_game_state like this:
enum game_state evaluate_game_state( char board[3][3] );
As long as the function evaluate_game_state returns GAMESTATE_UNDECIDED, you will have to prompt the user for input in a loop.
Here is my implementation of everything stated above, which I have tested a bit and seems to work, but I have not tested all corner cases. I took over the function get_int_from_user from this answer of mine from another question, and made a slight modification, so that it accepts variadic arguments, so that I can pass a string containing %d to that function and it treats it as a printf format specifier. Although your implementation of using printf and scanf would also work, that solution has the disadvantage that scanf does not perform proper input validation, so I used my function get_int_from_user instead.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
enum game_state
{
GAMESTATE_UNDECIDED,
GAMESTATE_DRAW,
GAMESTATE_WINNER_PLAYER1,
GAMESTATE_WINNER_PLAYER2
};
void init_board( char board[3][3] );
void print_board( char board[3][3] );
enum game_state evaluate_game_state( char board[3][3] );
int get_int_from_user( const char *prompt, ... );
int main( void )
{
char board[3][3];
bool first_players_turn = true;
enum game_state gs;
init_board( board );
while ( ( gs = evaluate_game_state( board ) ) == GAMESTATE_UNDECIDED )
{
//prompt user for input until input is valid
for (;;)
{
int input;
print_board( board );
input = get_int_from_user(
"It is player %d's turn.\n"
"Please select a move (1-9): ",
first_players_turn ? 1 : 2
);
if ( 1 <= input && input <= 9 )
{
int x = ( input - 1 ) % 3;
int y = ( input - 1 ) / 3;
//make sure field is empty
if ( board[y][x] != 'E' )
{
printf( "That field is already occupied!\n\n" );
continue;
}
//perform the move
board[y][x] = first_players_turn ? 'X' : 'O';
first_players_turn = !first_players_turn;
break;
}
printf( "Input must be between 1 and 9!\n\n" );
}
}
//game is over
print_board( board );
switch ( gs )
{
case GAMESTATE_DRAW:
printf( "The game is a draw.\n\n" );
break;
case GAMESTATE_WINNER_PLAYER1:
printf( "Player 1 wins!\n\n" );
break;
case GAMESTATE_WINNER_PLAYER2:
printf( "Player 2 wins!\n\n" );
break;
}
}
void init_board( char board[3][3] )
{
for ( int i = 0; i < 3; i++ )
for ( int j = 0; j < 3; j++ )
board[i][j] = 'E';
}
void print_board( char board[3][3] )
{
printf( "\n\n" );
for ( int i = 0; i < 3; i++ )
{
for ( int j = 0; j < 3; j++ )
{
//add spacing if necessary
if ( j != 0 )
printf( " " );
if ( board[i][j] == 'E' )
//replace empty field with number of field
printf( "%d", (i*3) + (j+1) );
else
printf( "%c", board[i][j] );
}
//end the line
printf( "\n" );
}
printf( "\n" );
}
enum game_state evaluate_game_state( char board[3][3] )
{
//check for horizontal wins
for ( int i = 0; i < 3; i++ )
{
char possible_winner = board[i][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[i][1] && possible_winner == board[i][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for vertical wins
for ( int i = 0; i < 3; i++ )
{
char possible_winner = board[0][i];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][i] && possible_winner == board[2][i] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for diagonal-down win
{
char possible_winner = board[0][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][1] && possible_winner == board[2][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check for diagonal-up win
{
char possible_winner = board[2][0];
if ( possible_winner != 'E' )
{
if ( possible_winner == board[1][1] && possible_winner == board[0][2] )
{
return possible_winner == 'X' ? GAMESTATE_WINNER_PLAYER1 : GAMESTATE_WINNER_PLAYER2;
}
}
}
//check if board is full
for ( int i = 0; i < 3; i++ )
for ( int j = 0; j < 3; j++ )
if ( board[i][j] == 'E' )
return GAMESTATE_UNDECIDED;
return GAMESTATE_DRAW;
}
int get_int_from_user( const char *prompt, ... )
{
for (;;) //loop forever until user enters a valid number
{
va_list args;
char buffer[1024], *p;
long l;
//prompt user for input
va_start( args, prompt );
vprintf( prompt, args );
va_end( args );
//get one line of input from input stream
if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
{
fprintf( stderr, "unrecoverable error reading from input\n" );
exit( EXIT_FAILURE );
}
//make sure that entire line was read in (i.e. that
//the buffer was not too small)
if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )
{
int c;
printf( "line input was too long!\n" );
//discard remainder of line
do
{
c = getchar();
if ( c == EOF )
{
fprintf( stderr, "unrecoverable error reading from input\n" );
exit( EXIT_FAILURE );
}
} while ( c != '\n' );
continue;
}
//attempt to convert string to number
errno = 0;
l = strtol( buffer, &p, 10 );
if ( p == buffer )
{
printf( "error converting string to number\n" );
continue;
}
//make sure that number is representable as an "int"
if ( errno == ERANGE || l < INT_MIN || l > INT_MAX )
{
printf( "number out of range error\n" );
continue;
}
//make sure that remainder of line contains only whitespace,
//so that input such as "6sdfh4q" gets rejected
for ( ; *p != '\0'; p++ )
{
if ( !isspace( (unsigned char)*p ) )
{
printf( "unexpected input encountered!\n" );
//cannot use `continue` here, because that would go to
//the next iteration of the innermost loop, but we
//want to go to the next iteration of the outer loop
goto continue_outer_loop;
}
}
return l;
continue_outer_loop:
continue;
}
}
This program has the following behavior:
1 2 3
4 5 6
7 8 9
It is player 1's turn.
Please select a move (1-9): 5
1 2 3
4 X 6
7 8 9
It is player 2's turn.
Please select a move (1-9): 4
1 2 3
O X 6
7 8 9
It is player 1's turn.
Please select a move (1-9): 1
X 2 3
O X 6
7 8 9
It is player 2's turn.
Please select a move (1-9): 6
X 2 3
O X O
7 8 9
It is player 1's turn.
Please select a move (1-9): 9
X 2 3
O X O
7 8 X
Player 1 wins!
If you want to make a good computer opponent, then I suggest that you take a look at the Wikipedia article on Minimax.

Related

Error with code: Segmentation Fault, Core dumped

I am having an issue with the output of my code, which is trying to return an array backwards in c using pointers. Do you guys have any solutions to the error I am getting?
Sample input:
Please enter the array size: 3
Please enter 3 elements:
4, 5, 7
Segmentation fault (core dumped)
Code:
#include <stdio.h>
int main(void){
int size, i;
int *pointer;
int arr[size];
printf("Please enter the array size: ");
scanf("%d/n", &size);
pointer = &arr[0];
printf("Please enter %d elements: \n", size);
for(i = 0; i < size; i++){
scanf("%d", arr[i]);
pointer++;
}
pointer = &arr[size - 1];
printf("The reversed array is \n");
for(i = size; i > 0; i--){
printf("%d", arr[i]);
pointer--;
}
return 0;
}
The task is not simple for beginners like you and me.
As I have understood the user can enter any number of integers in one line and all entered integers in the line must be outputted like
You entered 2
In this case neither array nor character array nor integer array will help. And in fact you need not to define an array if you want only to output numbers stored in the input buffer.
In this case you can just use the standard function getchar. Using the function in a loop you can read all numbers placed by the user in one line in the I/O buffer.
Here is a sample program. It is a little complicated because I allow the user to enter sign symbols.
There is no check in the program whether the user entered not a digit or a sign. You can develop the program further. The program demonstrates an approach to solve the task.
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
printf( "Enter a seria of integer numbers in one line: " );
int c;
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n' )
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
}
The program output might look for example like
Enter a seria of integer numbers in one line: 1 -1 +12-12+13 +14 -15
You entered 1
You entered -1
You entered 12
You entered -12
You entered 13
You entered 14
You entered -15
If you want to enter several lines of numbers and output numbers that are present in each line then the program can look the following way
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
size_t i = 0;
while (1)
{
printf( "Enter a seria of integer numbers in one line (or press just Enter to exit): " );
int c = getchar();
if (c == EOF || c == '\n') break;
ungetc( c, stdin );
printf( "Line %zu contains the following numbers:\n", i++ );
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n')
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
putchar( '\n' );
}
}
The program output might look for example like
Enter a seria of integer numbers in one line (or press just Enter to exit): 1 -2 3 +4
Line 0 contains the following numbers:
You entered 1
You entered -2
You entered 3
You entered 4
Enter a seria of integer numbers in one line (or press just Enter to exit): 11-12 13+14
Line 1 contains the following numbers:
You entered 11
You entered -12
You entered 13
You entered 14
Enter a seria of integer numbers in one line (or press just Enter to exit):
As the program just outputs entered numbers then actually there is no need to build an object of the type int like
num = Base * num + c;
You could just output adjacent digits in a line.
int array[100];
int n;
scanf("%d", &n);
for(int i=0; i<n; i++) {
scanf("%d", &array[i]);
}
for(int i=0; i<n; i++) {
printf("You entered %d \n", array[i]);
}
We use the array to get all of the values, and just print them out at the end.
In C and C++ it does not matter if the values are separated by space or a newline, so you can get every integer in a single line if separated by spaces.
output
3
1 2 3
You entered 1
You entered 2
You entered 3
C makes this very easy, but you need to leverage some library functions. At the most simple:
use fgets() and strpbrk() to obtain and verify a line of text
use strtok() and strtol() to parse and verify integer values.
What you do with those values is up to you. Following your example prompt, let’s just print them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int error( const char * message, const char * value )
{
fprintf( stderr, "%s%s\n", message, value );
return 1;
}
int main()
{
printf( "Input: " );
// Get all input on a single line
char text[1000];
fgets( text, sizeof(text), stdin );
// Verify that the entire line of input was obtained
char * nl = strpbrk( text, "\r\n" );
if (!nl) return error( "Line too long!", "" );
*nl = '\0';
puts( "Output:" );
// For each whitespace-delimited (spaces, tabs) token in the line:
for (char * token = strtok( text, " \t" ); token; token = strtok( NULL, " \t" ))
{
// Attempt to convert it to an integer
char * nok;
int n = strtol( token, &nok, 10 );
if (*nok) return error( "Invalid integer value: ", token );
// Success!
printf( "You entered %d\n", n );
}
return 0;
}
Notice also how it is OK to create a little helper function (error()). You can make helpers as complex or simple as you need. For this helper, all we need was to complain with one or two strings and return an “error happened” exit code that main() can pass right to the shell.
fgets can be used to read a line.
strtol can parse integers and report overflow and invalid input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int parselint ( char *line, int *value, char **end) {
long int number = 0;
errno = 0;
number = strtol ( line, end, 10);
if ( *end == line) {// nothing was parsed. no digits
size_t span = strcspn ( *end, "-+0123456789"); // characters to next int
if ( ! span) {
span = 1;
}
fprintf ( stderr, "problem parsing: %.*s\n", (int)span, line);
*end += span; // advance pointer to next int
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
fprintf ( stderr, "problem %.*s", (int)(*end - line), line);
perror ( " ");
return 0;
}
if ( number > INT_MAX || number < INT_MIN) {
fprintf ( stderr, "problem %.*s ", (int)(*end - line), line);
fprintf ( stderr, "out of int range\n");
return 0;
}
*value = number;//assign number to pointer
return 1;//success
}
int main ( void) {
char line[4096] = "";
char *parse = line;
int number = 0;
fgets ( line, sizeof line, stdin);
line[strcspn ( line, "\r\n")] = 0; // remove newline
while ( *parse) {
if ( 1 == parselint ( parse, &number, &parse)) {
printf ( "you entered %d\n", number);
}
}
return 0;
}

Program to calculate digits in credit card numbers ? Getting wrong input when the leading numbers start from 0

printf("Enter your Credit/Debit Card Number.\n");
scanf("%ld",&card_num);
while(card_num>0)
{
count++;
card_num = card_num/10;
}
printf("%d",count);
The above code contains a huge problem.
Let's assume if a card is starting with 0 then the loop will fail. And Count 1 less digit.
Meaning if it's a 15 digit card then it will show 14.
To solve this problem I made
(while card_num> = 0)
But the problem with this is it's going to infinite loop. Since 0/10 = 0 and it will go infinity
Note: I am not allowed to use arrays.
Also, I would like do it so:
#include <stdio.h>
int main(void)
{
char singleChar;
int count = 0;
printf("Enter your Credit/Debit Card Number.\n");
while((singleChar = getchar()) != '\n')
{
if (singleChar >= '0' && singleChar <= '9')
{
count++;
}
}
printf("%d",count);
return 0;
}
Shorter Version:
#include <stdio.h>
int main(void)
{
char singleChar;
int count = 0;
printf("Enter your Credit/Debit Card Number.\n");
while((singleChar = getchar()) != '\n')
{
//#Clifford wanna isdigit()
if (isdigit(singleChar))
{
count++;
}
}
printf("%d",count);
return 0;
}
Output:
Enter your Credit/Debit Card Number.
00123
5
Enter your Credit/Debit Card Number.
0034567854378987
16
While storing a credit card number in an integer is a bad idea because it is not an arithmetic object, it is possible to do it by making leading zeros implicit - adding then only at presentation. For example:
printf( "%16.16llu", card_num ) ;
will print 16 digits with leading zeros.
In that case any value less than 10000000000000000 is valid:
#include <stdio.h>
#include <math.h>
int main()
{
unsigned long long card_num = 0 ;
printf( "Enter your Credit/Debit Card Number.\n");
scanf( "%llu", &card_num ) ;
int count = 16 ;
if( card_num > 9999999999999999ULL )
{
count = (int)log10( (double)card_num ) + 1 ;
}
printf("%d\n", count);
printf( "%16.16llu", card_num ) ;
return 0;
}
One issue with the above is that if a number is entered with leading zeros, but more than 16 significant digits, the leading zeros are not counted - the (int)log10( (double)card_num ) + 1 expression yields the number of significant digits. But if you are counting digits for validation, but leading zeros are valid then you need only test card_num <= 10000000000000000ull - the number of digits is irrelevant.
#include <stdio.h>
#include <stdbool.h>
#define MAX_CARD_NUM 9999999999999999ULL
int main()
{
unsigned long long card_num = 0 ;
bool card_valid = false ;
while( !card_valid )
{
printf( "Enter your Credit/Debit Card Number.\n");
int check = scanf( "%llu", &card_num ) ;
card_valid = (check == 1 && card_num <= MAX_CARD_NUM ) ;
if( !card_valid )
{
printf( "Invalid card number\n" ) ;
}
}
printf( "%16.16llu", card_num ) ;
return 0;
}
However while it is be possible to encode and store a card number in an integer, it does not make much sense for initial entry because you would normally want to check the user had explicitly entered the leading zeroes as they are important security information, and you cannot do that with integer entry. In which case you would do better to enter and validate a string and then if you wish, convert the string to an integer encoding:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
#define CARD_NUM_LEN 16
int main()
{
unsigned long long card_num = 0 ;
bool card_valid = false ;
char card_str[32] ;
while( !card_valid )
{
printf( "Enter your Credit/Debit Card Number.\n");
fgets( card_str, sizeof( card_str) - 1, stdin ) ;
card_valid = true ;
int numlen = 0 ;
for( numlen = 0; card_valid &&
card_str[numlen] != '\0' &&
card_str[numlen] != '\n'; numlen++ )
{
card_valid = isdigit( card_str[numlen] ) && numlen < CARD_NUM_LEN ;
}
card_valid = card_valid && numlen == CARD_NUM_LEN ;
card_str[numlen] = '\0' ;
if( !card_valid )
{
printf( "Invalid card number\n" ) ;
}
}
printf( "String: %s\n", card_str ) ;
// Convert validated string to integer
card_num = strtoull( card_str, NULL, 10 ) ;
// Present the integer version with leading zeros.
printf( "Number: %16.16llu", card_num ) ;
return 0;
}

Building a pyramid of letters in C99

#include <stdio.h>
#define FINISH 'Z'
int main(void){
int spacenm, currentspacenm, i;
char ini, inirecord;
int rownm, currentrownm;
printf("PLease enter a random uppercase letter: ");
scanf("%c", &inirecord);
spacenm = rownm = FINISH - inirecord;
for (i = 0; i<= spacenm; i++)
printf(" ");
printf("%c\n", inirecord);
i = 0;
for (currentrownm = 1; currentrownm <= rownm; currentrownm ++){
for (currentspacenm = 1; currentspacenm <= spacenm; currentspacenm++)
printf(" ");
spacenm--;
for (ini = inirecord; ini<=inirecord+i; ini++)
printf("%c", ini);
i++;
for (; ini>=inirecord; ini--)
printf("%c", ini);
printf("\n");
}
return 0;
}
I wonder if there're better ways where less variables are needed or less redundant code structure is used to improve efficiency.
We beginners should help each other.:)
There is no check in your program relative to whether the user input is valid.
Also if I'm not mistaken not all coding tables as for example the EBCDIC table contain sequentially upper letters.
There is no need to write a separate snippet of code to output the first row of the pyramid as you are doing
for (i = 0; i<= spacenm; i++)
printf(" ");
printf("%c\n", inirecord);
Using formating you can eliminate the number of loops.
Take into account that in general instead of this format specification
scanf("%c", &inirecord);
^^^^
you should use the following
scanf(" %c", &inirecord);
^^^^^
Otherwise control characters will be also read.
Here are my three cents.:)
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
const char *letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const size_t N = strlen( letters );
while ( 1 )
{
char alpha[3];
_Bool exit_status;
const char *p;
do
{
printf( "PLease enter a random uppercase letter (Enter - exit ): " );
exit_status = fgets( alpha, sizeof( alpha ), stdin ) == NULL || alpha[0] == '\n';
if ( !exit_status )
{
p = NULL;
if ( alpha[1] == '\n' )
{
alpha[0] = toupper( ( unsigned char )alpha[0] );
p = strchr( letters, alpha[0] );
}
}
} while ( !exit_status && !p );
if ( exit_status ) break;
int n = &letters[N] - p;
putchar( '\n' );
for ( int i = 0; i < n; i++ )
{
printf( "%*c", n - i, alpha[0] );
int j = 0;
while ( j != i ) putchar( p[++j] );
while ( j != 0 ) putchar( p[--j] );
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
The program output might look like
PLease enter a random uppercase letter (Enter - exit ): Z
Z
PLease enter a random uppercase letter (Enter - exit ): Y
Y
YZY
PLease enter a random uppercase letter (Enter - exit ): X
X
XYX
XYZYX
PLease enter a random uppercase letter (Enter - exit ): A
A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
ABCDEFGFEDCBA
ABCDEFGHGFEDCBA
ABCDEFGHIHGFEDCBA
ABCDEFGHIJIHGFEDCBA
ABCDEFGHIJKJIHGFEDCBA
ABCDEFGHIJKLKJIHGFEDCBA
ABCDEFGHIJKLMLKJIHGFEDCBA
ABCDEFGHIJKLMNMLKJIHGFEDCBA
ABCDEFGHIJKLMNONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVUTSRQPONMLKJIHGFEDCBA
PLease enter a random uppercase letter (Enter - exit ):

How do I store (scanf) a randomly generated number? ( Code inside)

This is the code i used to generate the number:
printf("%d\n", rand()%10);
I am creating a card game HiLo. I want to know how to store the number generated from that and then make the user guess wether the next number is going to be higher or lower than the previous. After that, another number is generated and not stored just yet. I want to compare the new number with the old number too see if the user is correct (alot points) and then store the new number.
You just want to use a variable. All variables may include alphabetic characters, as well as numeric characters, however the first character must be alphabetic. The concept of creating a variable is that you are creating an area of temporary storage for the successful operation of your program. Any areas of code using a particular variable are considered to be dependent on it, and variables work in "scopes". Scopes are started using the { character and are ended using the } character. Any variables declared between these characters are usable only within those characters, and not outside of them, as they do not exist except within those characters.
I have created an example of the program I believe you are trying to write in order to demonstrate the software programming practices involved in such a task.
The example is shown below:
#include <stdio.h>
#include <string.h>
#define LENGTH_OF_BUFFER 100
int main( int argc, char **argv )
{
int prevRandomNumber = rand() % 10;
int continuePlaying = 1;
while( continuePlaying == 1 )
{
int randomNumber = rand() % 10;
int userSelection = 0;
char lineBuffer[LENGTH_OF_BUFFER];
printf( "Previous random number %d\n", prevRandomNumber );
while( userSelection == 0 )
{
printf( "higher or lower?" );
gets( lineBuffer );
if ( strcmp( "higher", lineBuffer ) == 0 )
{
userSelection = 1;
printf( "You selected higher!\n" );
}
else if ( strcmp( "lower", lineBuffer ) == 0 )
{
userSelection = -1;
printf( "You selected lower!\n" );
}
else
{
printf( "Sorry, I didn't understand you, please check your input and try again!\n" );
}
}
if ( userSelection == 1 )
{
if ( randomNumber > prevRandomNumber )
{
printf( "Correct, you really are a marvel!\n" );
}
else
{
printf( "Incorrect, I pity you!\n" );
}
}
else if ( userSelection == -1 )
{
if ( randomNumber < prevRandomNumber )
{
printf( "Correct, you really are a marvel!\n" );
}
else
{
printf( "Incorrect, I pity you!\n" );
}
}
printf( "Number was %d\n", randomNumber );
printf( "Care to play again?\n" );
gets( lineBuffer );
prevRandomNumber = randomNumber;
if ( strcmp( "yes", lineBuffer ) != 0 )
{
continuePlaying = 0;
}
}
}
I hope this helps...
int number = rand()%10;
int nextNumber;
char choice;
while(choice != 'Q' && choice != 'q')
{
printf("Current Number is : %d",number);
printf("\nYou want to guess the next number : ");
printf("\nPress L if number will be greater than current number ");
printf("\nPress S if number will be smaller than current number ");
printf("\nPress Q if you want to quit playing : ");
Printf("\n\nEnter your choice : ")
scanf("%c",&choice);
nextNumber = rand()%10;
if(choice == 'L' || choice == 'l')
{
if(nextNumber > number)
{
printf("\nYour Guess is Right...");
}
else
{
printf("\nYour Guess is wrong...");
}
}
else if(choice == 'L' || choice == 'l')
{
if(nextNumber < number)
{
printf("\nYour Guess is Right...");
}
else
{
printf("\nYour Guess is wrong...");
}
}
else
{
printf("\nYour choice is invalid. Try Again...");
}
number = nextNumber;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(){
char* bet, cmd;
long random_number, new_random_number;
while (1)
{
srand(time(NULL));
random_number = rand();
printf("%d\n", random_number);
printf("bet if the next number is bigger (+) or lower (-): ");
scanf("%s",bet);
srand(time(NULL));
new_random_number = rand();
printf("%d\n", new_random_number);
/* TODO - you might want to put that into a function some how */
if ( bet[0] == '+')
{
if ( new_random_number >= random_number ) /* user is correct */
{
printf("yeah! you are right\n");
printf("\nlet's play again!!\n");
continue;
}
else
{
printf("trololol :P That was wrong\n");
printf("\nlet's play again!!\n");
continue;
}
}
if ( bet[0] == '-')
{
if ( new_random_number < random_number ) /* user is correct */
{
printf("yeah! you are right\n");
printf("\nlet's play again!!\n");
continue;
}
else
{
printf("trololol :P That was wrong\n");
printf("\nlet's play again!!\n");
continue;
}
}
}
}
/* vim: set et sw=4 ts=4: */

Understanding that scanf is doing in this code

Please help me in understanding the below code.
The function get_digit takes a character argument by address. I am unable to get what
scanf("%1[0123456789]", ch) does here.
If I give 1234 on the terminal then it takes only the first digit. Same is if I give 2345 it takes 2. I have never came across such usage of scanf. Please help me in understanding this feature.
int get_digit ( char *ch )
{
int rc;
printf ( "Enter a single digit: " );
fflush ( stdout );
if ( rc = scanf ( "%1[0123456789]", ch ) == 1 ) {
jsw_flush();
}
return rc;
}
void jsw_flush ( void )
{
int ch;
do
ch = getchar();
while ( ch != '\n' && ch != EOF );
clearerr ( stdin );
}
void fill_table ( char table[] )
{
char ch;
while ( get_digit ( &ch ) ) {
unsigned i = ch - '0';
if ( table[i] != 0 ) {
printf ( "That index has been filled\n" );
}
else {
table[i] = ch;
}
}
}
void show_table ( const char table[], size_t size )
{
size_t i;
for ( i = 0; i < size; i++ ) {
printf ( "%c\n", table[i] != 0 ? table[i] : '~' );
}
}
scanf ( "%1[0123456789]", ch ) scans 1 character (%1) which is a decimal digit ([0123456789]) int the characer pointed to by ch.
The number immediately following the % is the field width, how many characters (maximally) to scan. The characters inside the square brackets are the characters scanf will accept. The scan ends when a character not listed is encountered.
An extremely simple example to scan two-digit numbers:
#include <stdlib.h>
#include <stdio.h>
int main(void) {
char chs[2] = {0}; // space for two digits, zero-initialized
unsigned u = 0, i;
if (scanf("%2[0123456789]",&chs[0]) == 1) {
// parse the number
for(i = 0; i < 2 && chs[i]; ++i) {
u = 10*u + chs[i] - '0';
}
printf("Got %u\n",u);
} else {
puts("Scan failed.");
}
return EXIT_SUCCESS;
}
Of course, instead of parsing ourselves, we could make the character array one longer than we expect digits (zero-initialise!, scanf doesn't add a 0-terminator with that format) and leave the parsing to strtoul(chs,NULL,10).

Resources