C enum debugging - c

I want to change my enum code with related values and want to get same output like before change. But i am getting different output. Codes before change were showed in comment lines. How and why it can be? I give the values to get same output. I can't understand why didn't i get the same output? (Random number not a problem. After change, it is not printing the board, just printing first user value not continue, not getting an error just keeping to look like the ss)
//enum {_,X,O}
enum {X,O,_};
//int user = 1;
//int comp = 2;
int user = 0;
int comp = 1;
void initBoard(int board[]){
int n_pieces_user; //number of pieces for user
int n_pieces_comp; //number of pieces for computer
int n_pieces_sum;
int chosen_player;
int position;
printf("Input number of pieces for user and computer respectively: ");
scanf("%d %d", &n_pieces_user, &n_pieces_comp);
int n_pieces_sum = n_pieces_user + n_pieces_comp;
int arr_pos[n_pieces_sum];
printf("Press 1 to choose Player1, press 2 to Player2 (Player1 plays first!): ");
while(1){
scanf("%d",&chosen_player);
if(chosen_player == 1){ //User plays first
srand((unsigned)time(&t)); //initializes random number generator
for(i=0; i<n_pieces_sum; i++){
position = rand()%SIZE;
for(k=0; k<i; k++){
//while((board[position]==1) || (board[position]==2)){
while((board[position] == 0) || (board[position] == 1)){
position = rand()%SIZE;
arr_pos[i] = position;
}
arr_pos[i] = position;
}
if(i<n_pieces_user){
arr_pos[i] = position;
printf("\nUser's random initial piece position: %d", arr_pos[i]);
board[position] = 0;
}
if(i>=n_pieces_user && i<n_pieces_sum){
arr_pos[i] = position;
printf("\nComputer's random initial piece position: %d", arr_pos[i]);
board[position] = 1;
}
}
turn = comp;
break;
}
else if(chosen_player == 2){ //Computer plays first
srand((unsigned)time(&t)); //initializes random number generator
for(i=0; i<n_pieces_sum; i++){
position = rand()%SIZE;
for(k=0; k<i; k++){
//while((board[position]==1) || (board[position]==2)){
while((board[position]==0) || (board[position]==1)){
position = rand()%SIZE;
arr_pos[i] = position;
}
arr_pos[i] = position;
}
if(i<n_pieces_comp){
arr_pos[i] = position;
printf("\nComputer's random initial piece position: %d", arr_pos[i]);
board[position] = 0;
}
if(i>=n_pieces_comp && i<n_pieces_sum){
arr_pos[i] = position;
printf("\nUser's random initial piece position: %d", arr_pos[i]);
board[position] = 1;
}
}
turn = user;
break;
}else
printf("Choose correct input!\n");
}
printf("\n");
}
void printBoard(const int board[]){
char symbol[] = { 'X','O','_' };
//char symbol[] = { '_','X','O' };
printf("\n BOARD\n\n");
for(i=0; i<SIZE; i++) {
if(i != 0 && i%7 == 0)
printf("\n\n");
printf(" %c ",symbol[board[i]]);
}
printf("\n\n");
}
First output:
Output after change:

Related

no repeating values in array

I need to make a program that stores numbers inside of an array. But it must have no duplicate elements.
int x;
int z[8];
for( x = 0; x<8;x++)
printf("number: ");
scanf("%d",&z[x]);
}
for( x=0;x<8;x++) {
printf("%d ",z[x]);
}
First, initialize the array, so that you do not end up reading an uninitialized value and fail the test.
int user_nums[6] = {0};
Next, you need to have another check in the for loop, to read the number again if it is a duplicate.
The code will look like this.
#include<stdio.h>
int main(){
int x,y;
int exists = 0;
int user_nums[6] = {0};
for( x = 0; x<6;x++){//for loop to get the players selected numbers
do {
exists = 0;
printf("Enter a number(from the #'s 1-42): ");
scanf("%d",&user_nums[x]);
for(y =0; y < x; y++) { //to check for duplicates
if (user_nums[x] == user_nums[y])
{
printf("Number already exists\n ");
exists = 1;
break;
}
}
}while (user_nums[x]<1 || user_nums[x]>42 || exists);//accepts only numbers from 1-42 which are not duplicates (continous to ask you for a number until condition is met).
}
printf("Your numbers: \n");
for( x=0;x<6;x++){
printf("%d ",user_nums[x]); // prints the numbers you inputed.
}
return 0;
}
The following code could work in O(n):
#include<stdio.h>
int main()
{
int user_nums[6];
int index[50];
for (int i = 0; i != sizeof(index) / sizeof(index[0]); ++i)
index[i] = -1;
for (int i = 0; i < sizeof(user_nums) / sizeof(user_nums[0]); ++i) {
for (;;) {
printf("Enter a number(from the #'s 1-42): ");
scanf("%d", user_nums + i);
if (user_nums[i] < 1 || user_nums[i] > 42) {
printf("wrong number\n");
continue;
}
if (index[user_nums[i]] != -1) {
printf("dump number\n");
continue;
}
index[user_nums[i]] = i;
break;
}
}
printf("Your numbers: \n");
for(int i = 0; i < 6; ++i)
printf("%d ", user_nums[i]);
return 0;
}

I am getting a _\377 in my output

I have a school assignment to make a hangman game. The game works how I want it to except for one small glitch. If the user entered word is 4 letters or less, the hidden word is displayed with an extra "_\377" at the end. When the user entered word is 5 letters or more, then there is no glitch. I am hoping that someone would be kind enough to help me trouble shoot the problem. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int letterfinder(char string[], char a, int vari)
{
int length = strlen(string);
int i = vari;
int val = 0;
while( i <= length && val != 1)
{
if( string[i] == a)
{
val = 1;
}
i++;
}
if( val == 0)
{
return 100;
}
else
{
return i;
}
}
int main()
{
char inWord[] = "1111111111111111111111111111";
char outWord2[] = "1111111111111111111111111111";
char guess;
int gameover = 0;
int trys = 10;
int vari = 0;
printf("Please enter a word: ");
gets(inWord);
printf("%s\n", inWord);
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
int i2 = 0;
int j2 = 0;
int i3 = 0;
i2 = strcspn(inWord, outWord2);
char outWord[80];
while(i3 < i2)
{
outWord[i3] = '1';
i3++;
}
while(j2 < i2)
{
outWord[j2] = '-';
j2++;
}
puts(outWord);
while(gameover != 1 )
{
printf("What is your guess: ");
scanf("%s", &guess);
vari = 0;
if(letterfinder(inWord, guess, vari) == 100)
{
printf("Wrong!");
trys--;
printf("You have %d attempts left\n", trys);
if(trys == 0)
{
gameover = 1;
printf("You ran out of attempts. Game over\n");
}
}
else
{
outWord[(letterfinder(inWord, guess, vari) - 1)] = guess;
vari = (letterfinder(inWord, guess, vari));
while(letterfinder(inWord, guess, vari) != 100)
{
outWord[(letterfinder(inWord, guess, vari) - 1)] = guess;
vari = letterfinder(inWord, guess, vari);
}
puts(outWord);
}
int value = 0;
i3 = 0;
while( i3 <= i2)
{
if( outWord[i3] == '-')
{
value = 1;
}
i3++;
}
if(value != 1)
{
printf("Congratulations, you have guessed the word!\n");
gameover = 1;
}
}
return 0;
}
Your code has Undefined Behaviour. In the cases it "works" it is only by chance/luck. char guess; scanf("%s", &guess); That causes memory corruption as you are writing a string to a variable that can only hold a single char. Even a single letter guess will require two characters to store as all C strings are NUL terminated.
– kaylum

Weird bug which seems to be solved by adding a surplus line of code. Game of fifteen

This is a puzzle game where in a 4x4 grid one has to arrange 15 numbered tiles in order.
Most of the scenarios, the program runs fine. However, when swapping the "1" digit to the nth row, n-2th column, the program seems to bug and duplicate the number 1.
Here's the catch. When I add a random line of code, say
int blah = 0;
or
printf("abc");
The problem just magically disappears.
Because I'm unable to locate the source of the problem, I'll have to post up the entirety of it.
To see the problem, run the code without any command line arguments, then enter 2 followed by 1.
When I added the random line of code at the end of my main() function, the problem just disappears. Please try it out, and help me find out what's happening; it's really confusing.
#include <stdio.h>
#include <stdlib.h>
int n=4;
int win(int board[n][n]);
void print(int board[n][n]);
int main(int argc, char * argv[])
{
if(argc != 2)
{
printf("No valid number accepted. Board size set as 4x4.\n");
}
else if(argc == 2)
{
n = atoi(argv[1]);
if(n<2 || n>5)
{
printf("No valid number accepted. Board size set as 4x4.\n");
}
else
{
printf("Preparing board of size %dx%d\n",n,n);
}
}
int board[n][n];
printf("\n The aim of the game is to sort the board so that it runs in ascending order, from 1 to %d, from left to right and up to down starting from the top left square. To make a move, enter the number of the tile you want to move. No diagonal movement is allowed.\n\n",n*n-1);
int c = n*n-1;
for(int x = 0;x<n;x++)
{
for(int y=0;y<n;y++)
{
board[x][y] = c;
c--;
}
}
if(n%2==0)
{
int temp1 = board[n-1][n-2];
board[n-1][n-2] = board[n-1][n-3];
board[n-1][n-3] = temp1;
}
print(board);
int spacex = n-1;
int spacey = n-1;
char buffer[10];
while(win(board) == 0)
{
printf("To move, enter the number you wish to move. Take note that this number must be adjacent to the blank space. Diagonal movement is not allowed.\nYour move: ");
fgets(buffer,10,stdin);
int move;
char temp[20];
if(sscanf(buffer," %d %s",&move,temp)!= 1)
{
printf("Enter a number please.\n");
continue;
}
if(move == board[spacex+1][spacey])
{
board[spacex][spacey] = board[spacex+1][spacey];
board[spacex+1][spacey] = 0;
spacex++;
}
else if(move == board[spacex-1][spacey])
{
board[spacex][spacey] = board[spacex-1][spacey];
board[spacex-1][spacey] = 0;
spacex--;
}
else if(move == board[spacex][spacey+1])
{
board[spacex][spacey] = board[spacex][spacey+1];
board[spacex][spacey+1] = 0;
spacey++;
}
else if(move == board[spacex][spacey-1])
{
board[spacex][spacey] = board[spacex][spacey-1];
board[spacex][spacey-1] = 0;
spacey--;
}
else if(move == 0)
{
printf("Enter a valid digit please.\n");
continue;
}
else
{
printf("Enter a valid number please.\n");
continue;
}
printf("\n");
print(board);
}
printf("You won!\n");
}
///////////////////////////////////////////////////////
void print(int board[n][n])
{
for(int x=0;x<n;x++)
{
for(int y=0;y<n;y++)
{
if(board[x][y] == 0)
{
printf("__ ");
}
else
printf("%2d ",board[x][y]);
}
printf("\n\n");
}
}
///////////////////////////////////////////////////////
int win(int board[n][n])
{
int check = 1;
for(int x=0;x<n;x++)
{
for(int y=0;y<n;y++)
{
if(board[x][y] != check)
{
if(x==n-1 && y == n-1);
else
{
return 0;
}
}
check++;
}
}
return 1;
}
Any other comments about the code would be greatly appreciated too. Thanks in advance!
Code is reading out of bounds.
These two variables point to the last elements of the array board:
int spacex = n-1;
int spacey = n-1;
but are used incorrectly in all if statements. whenever a +1 is used, they will read out of bounds or read an incorrect element:
if(move == board[spacex+1][spacey])
{
board[spacex][spacey] = board[spacex+1][spacey];
board[spacex+1][spacey] = 0;
spacex++;
}
else if(move == board[spacex-1][spacey])
{
...
else if(move == board[spacex][spacey+1])
{
board[spacex][spacey] = board[spacex][spacey+1];
...

MiniMax algorithm tic-tac-toe in C explanation

trying to learn about computer game players to familiarise myself with AI. I understand how minimax works in theory but cant get my head around how this code I found online works.
can someone explain the minimax fruction/computer move function (lines 38-78)to me.
credit: https://gist.github.com/MatthewSteel/3158579
thanks
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int minimax(int board[9], int player) {
//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;
move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
Here is the essence of minimax:
int minimax(int board[9], int player) {
// ....
for(i = 0; i < 9; ++i) { //For all moves,
// ....
int thisScore = -minimax(board, player*-1);
}
}
Go through each possible move, and for each such possible move, turn the board around, pretend to be the other player (that's the player*-1 part), and try each possible move. thisScore is set to the negative return value from the recursive call to minimax, since good for the other player equals bad for ourselves.
computerMove just goes through all the possible moves, calls minimax for each such possible move, and uses the one with the best result.

junk output in the array of structs

This is my project in the sortstudents() function I try to read from file the data is on one row or one line contentiously when I try to print the array I got junk data
this is example about how data look like in the file (2 records):
1 mohamed talaat €#A
2 ahmed mohamed #A
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
///////////////////////////////////////////////////////////////////////////
struct student
{
char id[5];
char name[30];
int term;
float gpa;
char grade;
};
struct student stu;
typedef struct student stud;
//////////////////////////////////////////////////////////////////////////
//set the cordinate to 0, 0 (top-left corner of window)
//<windows.h> is needed
COORD coord = {0,0};
//////////////////////////////////////////////////////////////////////////
//need cordinate struct to use it
//gotoxy to set coordinate x,y
void gotoxy(int x, int y)
{
//X and Y coordinates
coord.X = x; coord.Y = y;
// ew3a tensa Microsoft
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//////////////////////////////////////////////////////////////////////////
//print regtangle shape Ascii table www.asciitable.com
// window width = 80 character window hight = 25 character
void drawRectangle()
{
int i, j;
//print the corner rear top left
gotoxy(0,0);
printf("%c",201);
// print 78 line shape = starts from rear top left ended at the top rear right
for(i = 1; i < 78; i++)
{
gotoxy(i, 0);
printf("%c",205);
}
//print the corner rear top right
gotoxy(78,0);
printf("%c",187);
//print the corner rear right side with width = 25
for(i = 1; i < 25; i++)
{
gotoxy(78, i);
//print T-shape at width 6 and after 6 proceed until 25 printing right side
if(i == 6)
{
printf("%c",185);
}
else
{
printf("%c",186);
}
}
//print the corner rear bottom right
gotoxy(78, 25);
printf("%c",188);
// -i- already = 78
// print bottom side pf the regtangle
for(i = 77; i > 0; i--)
{
gotoxy(i,25);
// print T-shape at width 35 and after that proceed until 78 printing rgt base side
if(i == 35)
{
printf("%c",202);
}
else
{
printf("%c",205);
}
}
//print the corner rear bottom left
gotoxy(0,25);
printf("%c",200);
// print T-shape at width 6 and after 6 proceed until 25 printing left side
for(i = 24; i > 0; i--)
{
gotoxy(0,i);
if(i == 6)
{
printf("%c",204);
}
else
{
printf("%c",186);
}
}
// print T-shape at width 36 and connect left side to right side
for(i = 1; i < 78; i++)
{
gotoxy(i,6);
if(i == 35)
{
printf("%c",203);
}
else
{
printf("%c",205);
}
}
// connect middle T-shape at the middle of the regtangle to the base
for(i = 7; i < 25; i++)
{
gotoxy(35,i);
printf("%c",186);
}
}
//////////////////////////////////////////////////////////////////////////
// Build Program window interface using functions --drawRectangle
// with color 1 = Blue & Font color 7 = White
void swindow()
{
int i;
drawRectangle();
gotoxy(28,1);
system("color 17");
printf("STUDENT GRADE SYSTEM");
gotoxy(28,2);
for(i=1;i<21;i++)
{
printf("%c",205);
}
gotoxy(15,3);
printf("College of Computing and Information Technology");
gotoxy(10,4);
printf(" ");
gotoxy(10,5);
printf("Arab Academy for Science, Technology & Maritime Transport");
gotoxy(25,24);
}
//////////////////////////////////////////////////////////////////////////
void print_heading(const char st[])
{
gotoxy(50,8);
printf("%s",st);
}
//////////////////////////////////////////////////////////////////////////
void clearWindow()
{
int i,j;
for(i = 37; i < 78; i++)
{
for(j = 7; j < 25; j++)
{
gotoxy(i,j);
printf(" ");
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void add()
{
clearWindow();
print_heading("Add Record");
int print = 37;
char ans;
int i;
FILE *fp;
fp = fopen("record.txt","ab+");
if(fp == NULL)
{
MessageBox(0,"Error in Opening file\nMake sure your file is not write protected","Warning",0);
}
else
{
fflush(stdin);
//here i can Add Records ...
////////////////////////////////////////////////////////////////////////////////
gotoxy(print,10);printf("ID: ");gets(stu.id);
gotoxy(print,12);printf("Name: ");gets(stu.name);
gotoxy(print,14);printf("Term: ");scanf("%d",&stu.term);
gotoxy(print,16);printf("Score % : ");scanf("%f",&stu.gpa);
if (stu.gpa>=3.40)
{
stu.grade='A';
}
else {
if (stu.gpa>=2.80)
{stu.grade='B';}
else
{
if (stu.gpa>=2.20)
{stu.grade='C';}
else
{
if (stu.gpa>=2.00)
{stu.grade='D';}
else
{stu.grade='F';}
}
}
}
gotoxy(print,18);printf("GPA: %c",stu.grade);printf("\n");
gotoxy(print,20);printf("Press(Y) to Save (N) for Cancel... ");//scanf("%c",&ans);
ans = getche();
if (ans=='y' || ans=='Y')
{
fwrite(&stu, sizeof(stu), 1, fp);
gotoxy(40,22); printf("The record is sucessfully added");
}
else
{
gotoxy(40,22); printf("Entry process cancelled");
}
}
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////
void search(){
clearWindow();
print_heading("Search Record");
char s_id[5];
int isFound = 0;
gotoxy(37,10);
printf("Enter ID to Search: ");
fflush(stdin);
gets(s_id);
//Read the record file from File
FILE *fp;
fp = fopen("record.txt","ab+");
while(fread(&stu,sizeof(stu),1,fp) == 1)
{
if(strcmp(s_id,stu.id) == 0)
{
isFound = 1;
break;
}
}
if(isFound == 1){
gotoxy(37,12);printf("The record is Found");
gotoxy(37,13);printf("--------------------");
gotoxy(37,14);printf("ID: %s",stu.id);
gotoxy(37,16);printf("Name: %s",stu.name);
gotoxy(37,18);printf("Term: %d",stu.term);
gotoxy(37,20);printf("Score %: %0.1f",stu.gpa);
gotoxy(37,22);printf("GPA: %c",stu.grade);
}else
{
gotoxy(37,12);printf("Sory, No record found in the database");
}
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////
void sortstudents()
{
clearWindow();
FILE *fp;
fp = fopen("record.txt","r");
//////// detect number of characters ////////
char nextChar = getc(fp);
int numCharacters = 0;
while (nextChar != EOF)
{
//Do something else, like collect statistics
numCharacters++;
nextChar = getc(fp);
}
//////// detect number of characters ////////
int chunck = numCharacters/sizeof(stu);
//stud *arr = (stud *)malloc(chunck);
stud starray[25];
int d;
int numStudents = 0;
while( fscanf(fp,"%s%s%d%f%c",stu.id,stu.name,&stu.term,&stu.gpa,&stu.grade) > 0)
{
starray[numStudents++] = stu;
}
gotoxy(37,12);printf("The record is Found");
gotoxy(37,13);printf("--------------------");
gotoxy(37,14);printf("ID: %s",starray[0].id);
gotoxy(37,16);printf("Name: %s",starray[0].name);
gotoxy(37,18);printf("Term: %d",starray[0].term);
gotoxy(37,20);printf("Score %: %0.1f",starray[0].gpa);
gotoxy(37,22);printf("GPA: %c",starray[0].grade);
/*"ID: %s",stu.id);
"Name: %s",stu.name);
"Term: %d",stu.term);
Score %: %0.1f",stu.gpa);
"GPA: %c",stu.grade);*/
fclose(fp);
}
//////////////////////////////////////////////////////////////////////////
void menu(){
int choice;
int x = 2;
while(1)
{
gotoxy(x,10);
printf("1. Add Student");
gotoxy(x,12);
printf("2. Search Student");
gotoxy(x,14);
printf("3. Statistics");
gotoxy(x,16);
printf("4. Close");
gotoxy(x,20);
printf("Please enter your choice :");
scanf("%d",&choice);
switch(choice)
{
case 1:
add();
break;
case 2:
search();
break;
case 3:
sortstudents();
break;
case 4:
exit(0);
break;
default:
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
int main()
{
// draw entry window
//drawRectangle();
swindow();
menu();
//clearWindow();
system("PAUSE");
return 0;
}
In the sortStudents you have a loop in the beginning that will read all characters in the file. Then you attempt to read the files as a kind of records. This usage of fscanf will return EOF as you are attempting to read beyond the end of the file.
And even when you don't read any records into your starray array, you still print values from starray[0] which will be all uninitialized (and therefore contain indeterminate (e.g. seemingly random) values).

Resources