Related
Hey so my problem is that the when I go run this code and choose to "Zufallstand generieren" (Generate random state) and then type in the "Prozentualer Anteil lebender Zellen" (Percentage of living cells) and then "Schrittweise Animation" or "Fließende Animation" (Step-by-step animation/Flowing animation) the second generation is absolute trash it does not match the first generation in one thing.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#pragma warning (disable: 4996)
#define MAX_ROWS 30
#define MAX_COLS 20
typedef struct {
char data[MAX_ROWS][MAX_COLS];
int rows;
int cols;
} Matrix;
char neighbor_count(Matrix *m, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
if (i < 0 || i >= m->rows) {
continue;
}
for (int j = col - 1; j <= col + 1; j++) {
if (j < 0 || j >= m->cols) {
continue;
}
if (m->data[i][j] == '*' && (i != row || j != col)) {
count++;
}
}
}
return count;
}
void check_cell(Matrix *m, int row, int col) {
char neighbors_count = neighbor_count(m, row, col);
char current_cell = m->data[row][col];
if (neighbors_count < 2) { //Die Zelle stirbt an Vereinsamung
m->data[row][col] = ' ';
}
else if (neighbors_count > 3 && current_cell == '*') { //Die Zelle stirbt an Übervölkerung
m->data[row][col] = ' ';
}
else if (neighbors_count == 3 && current_cell == ' ') { //Aus der toten Zelle wird eine neue lebende Zelle
m->data[row][col] = '*';
}
else if (neighbors_count == 2 || neighbors_count == 3) { //Die Zelle lebt weiter
m->data[row][col] = '*';
}
}
void load_from_file(Matrix *m, const char *filename) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
printf("File not found\n");
exit(-1);
}
int row_idx = 0;
char ch;
while ((ch = fgetc(f)) != EOF && row_idx < MAX_ROWS) {
if (ch == '\n') {
row_idx++;
continue;
}
#
m->data[row_idx][m->cols] = ch;
m->cols++;
}
m->rows = row_idx;
fclose(f);
}
void randomize(Matrix *m, int percent) {
memset(m->data, (int)' ', MAX_COLS * MAX_ROWS);
m->rows = MAX_ROWS;
m->cols = MAX_COLS;
int cells = (m->rows * m->cols) * (percent / 100.0f);
srand(time(NULL));
while (cells > 0) {
int row = rand() % m->rows;
int col = rand() % m->cols;
if (m->data[row][col] == ' ') {
m->data[row][col] = '*';
cells--;
}
}
}
void print_matrix(Matrix *m) {
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
printf("%c", m->data[i][j]);
}
printf("\n");
}
printf("\n");
}
void step(Matrix *m) {
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
check_cell(&m_tmp, i, j);
}
}
*m = m_tmp;
}
int main() {
Matrix m;
// Menü zur Auswahl des Startzustands
printf("1. Aus Datei laden\n");
printf("2. Zufallszustand generieren\n");
int selection;
scanf("%d", &selection);
switch (selection) {
case 1: // Aus Datei laden
{
char filename[20];
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
}
case 2: // Zufallszustand generieren
{
int percent;
printf("Prozentualer Anteil an lebenden Zellen: ");
scanf("%d%%", &percent);
randomize(&m, percent);
break;
}
default:
printf("Ungültige Eingabe\n");
return 0;
}
// Menü zur Auswahl der Animation
printf("1. Schrittweise Animation\n");
printf("2. Fließende Animation\n");
scanf("%d", &selection);
switch (selection) {
case 1: // Schrittweise Animation
while (1) {
print_matrix(&m);
step(&m);
getchar();
}
break;
case 2: // Fließende Animation6
while (1) {
print_matrix(&m);
step(&m);
Sleep(2000);
}
break;
default:
printf("Ungültige Eingabe\n");
break;
}
return 0;
}
I tried to change the how the matrix works but without any success.
As others have mentioned, you are modifying the current matrix. You need to have a copy.
Ironically, your step function makes a copy. But, it still passes only one pointer to check_cell.
check_cell needs to have two matrix pointers. One for old/current state and another for new/future state.
Here are the changed functions:
void
check_cell(Matrix *mnew, Matrix *mold, int row, int col)
{
char neighbors_count = neighbor_count(mold, row, col);
char current_cell = mold->data[row][col];
do {
// Die Zelle stirbt an Vereinsamung
if (neighbors_count < 2) {
current_cell = ' ';
break;
}
// Die Zelle stirbt an Übervölkerung
if (neighbors_count > 3 && current_cell == '*') {
current_cell = ' ';
break;
}
// Aus der toten Zelle wird eine neue lebende Zelle
if (neighbors_count == 3 && current_cell == ' ') {
current_cell = '*';
break;
}
// Die Zelle lebt weiter
if (neighbors_count == 2 || neighbors_count == 3) {
current_cell = '*';
break;
}
} while (0);
mnew->data[row][col] = current_cell;
}
void
step(Matrix *m)
{
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++)
check_cell(m, &m_tmp, i, j);
}
}
I'm trying to run this code on Visual Studio 2022, but it gives an error:
C1083: Cannot open include file: 'unistd.h': No such file or directory.
As I understood that the code was written for the UNIX system, but I would like to run it on Windows.
Snake game
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include<time.h>
#include<ctype.h>
#include <time.h>
#include <windows.h>
#include <process.h>
#include <unistd.h>
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
int length;
int bend_no;
int len;
char key;
void record();
void load();
int life;
void Delay(long double);
void Move();
void Food();
int Score();
void Print();
void gotoxy(int x, int y);
void GotoXY(int x, int y);
void Bend();
void Boarder();
void Down();
void Left();
void Up();
void Right();
void ExitGame();
int Scoreonly();
struct coordinate {
int x;
int y;
int direction;
};
typedef struct coordinate coordinate;
coordinate head, bend[500], food, body[30];
int main()
{
char key;
Print();
system("cls");
load();
length = 5;
head.x = 25;
head.y = 20;
head.direction = RIGHT;
Boarder();
Food(); //to generate food coordinates initially
life = 3; //number of extra lives
bend[0] = head;
Move(); //initialing initial bend coordinate
return 0;
}
void Move()
{
int a, i;
do {
Food();
fflush(stdin);
len = 0;
for (i = 0; i < 30; i++)
{
body[i].x = 0;
body[i].y = 0;
if (i == length)
break;
}
Delay(length);
Boarder();
if (head.direction == RIGHT)
Right();
else if (head.direction == LEFT)
Left();
else if (head.direction == DOWN)
Down();
else if (head.direction == UP)
Up();
ExitGame();
} while (!kbhit());
a = getch();
if (a == 27)
{
system("cls");
exit(0);
}
key = getch();
if ((key == RIGHT && head.direction != LEFT && head.direction != RIGHT) || (key == LEFT && head.direction != RIGHT && head.direction != LEFT) || (key == UP && head.direction != DOWN && head.direction != UP) || (key == DOWN && head.direction != UP && head.direction != DOWN))
{
bend_no++;
bend[bend_no] = head;
head.direction = key;
if (key == UP)
head.y--;
if (key == DOWN)
head.y++;
if (key == RIGHT)
head.x++;
if (key == LEFT)
head.x--;
Move();
}
else if (key == 27)
{
system("cls");
exit(0);
}
else
{
printf("\a");
Move();
}
}
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void GotoXY(int x, int y)
{
HANDLE a;
COORD b;
fflush(stdout);
b.X = x;
b.Y = y;
a = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(a, b);
}
void sleep(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
void load() {
int row, col, r, c, q;
gotoxy(36, 14);
printf("loading...");
gotoxy(30, 15);
for (r = 1; r <= 20; r++) {
sleep(200);//to display the character slowly
printf("%c", 177);
}
getch();
}
void Down()
{
int i;
for (i = 0; i <= (head.y - bend[bend_no].y) && len < length; i++)
{
GotoXY(head.x, head.y - i);
{
if (len == 0)
printf("v");
else
printf("*");
}
body[len].x = head.x;
body[len].y = head.y - i;
len++;
}
Bend();
if (!kbhit())
head.y++;
}
void Delay(long double k)
{
Score();
long double i;
for (i = 0; i <= (10000000); i++);
}
void ExitGame()
{
int i, check = 0;
for (i = 4; i < length; i++) //starts with 4 because it needs minimum 4 element to touch its own body
{
if (body[0].x == body[i].x && body[0].y == body[i].y)
{
check++; //check's value increases as the coordinates of head is equal to any other body coordinate
}
if (i == length || check != 0)
break;
}
if (head.x <= 10 || head.x >= 70 || head.y <= 10 || head.y >= 30 || check != 0)
{
life--;
if (life >= 0)
{
head.x = 25;
head.y = 20;
bend_no = 0;
head.direction = RIGHT;
Move();
}
else
{
system("cls");
printf("All lives completed\nBetter Luck Next Time!!!\nPress any key to quit the game\n");
record();
exit(0);
}
}
}
void Food()
{
if (head.x == food.x && head.y == food.y)
{
length++;
time_t a;
a = time(0);
srand(a);
food.x = rand() % 70;
if (food.x <= 10)
food.x += 11;
food.y = rand() % 30;
if (food.y <= 10)
food.y += 11;
}
else if (food.x == 0)/*to create food for the first time coz global variable are initialized with 0*/
{
food.x = rand() % 70;
if (food.x <= 10)
food.x += 11;
food.y = rand() % 30;
if (food.y <= 10)
food.y += 11;
}
}
void Left()
{
int i;
for (i = 0; i <= (bend[bend_no].x - head.x) && len < length; i++)
{
GotoXY((head.x + i), head.y);
{
if (len == 0)
printf("<");
else
printf("*");
}
body[len].x = head.x + i;
body[len].y = head.y;
len++;
}
Bend();
if (!kbhit())
head.x--;
}
void Right()
{
int i;
for (i = 0; i <= (head.x - bend[bend_no].x) && len < length; i++)
{
//GotoXY((head.x-i),head.y);
body[len].x = head.x - i;
body[len].y = head.y;
GotoXY(body[len].x, body[len].y);
{
if (len == 0)
printf(">");
else
printf("*");
}
/*body[len].x=head.x-i;
body[len].y=head.y;*/
len++;
}
Bend();
if (!kbhit())
head.x++;
}
void Bend()
{
int i, j, diff;
for (i = bend_no; i >= 0 && len < length; i--)
{
if (bend[i].x == bend[i - 1].x)
{
diff = bend[i].y - bend[i - 1].y;
if (diff < 0)
for (j = 1; j <= (-diff); j++)
{
body[len].x = bend[i].x;
body[len].y = bend[i].y + j;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
else if (diff > 0)
for (j = 1; j <= diff; j++)
{
/*GotoXY(bend[i].x,(bend[i].y-j));
printf("*");*/
body[len].x = bend[i].x;
body[len].y = bend[i].y - j;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
}
else if (bend[i].y == bend[i - 1].y)
{
diff = bend[i].x - bend[i - 1].x;
if (diff < 0)
for (j = 1; j <= (-diff) && len < length; j++)
{
/*GotoXY((bend[i].x+j),bend[i].y);
printf("*");*/
body[len].x = bend[i].x + j;
body[len].y = bend[i].y;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
else if (diff > 0)
for (j = 1; j <= diff && len < length; j++)
{
/*GotoXY((bend[i].x-j),bend[i].y);
printf("*");*/
body[len].x = bend[i].x - j;
body[len].y = bend[i].y;
GotoXY(body[len].x, body[len].y);
printf("*");
len++;
if (len == length)
break;
}
}
}
}
void Boarder()
{
system("cls");
int i;
GotoXY(food.x, food.y); /*displaying food*/
printf("F");
for (i = 10; i < 71; i++)
{
GotoXY(i, 10);
printf("!");
GotoXY(i, 30);
printf("!");
}
for (i = 10; i < 31; i++)
{
GotoXY(10, i);
printf("!");
GotoXY(70, i);
printf("!");
}
}
void Print()
{
//GotoXY(10,12);
printf("\tWelcome to the mini Snake game.(press any key to continue)\n");
getch();
system("cls");
printf("\tGame instructions:\n");
printf("\n-> Use arrow keys to move the snake.\n\n-> You will be provided foods at the several coordinates of the screen which you have to eat. Everytime you eat a food the length of the snake will be increased by 1 element and thus the score.\n\n-> Here you are provided with three lives. Your life will decrease as you hit the wall or snake's body.\n\n-> YOu can pause the game in its middle by pressing any key. To continue the paused game press any other key once again\n\n-> If you want to exit press esc. \n");
printf("\n\nPress any key to play game...");
if (getch() == 27)
exit(0);
}
void record() {
char plname[20], nplname[20], cha, c;
int i, j, px;
FILE* info;
info = fopen("record.txt", "a+");
getch();
system("cls");
printf("Enter your name\n");
scanf("%[^\n]", plname);
//************************
for (j = 0; plname[j] != '\0'; j++) { //to convert the first letter after space to capital
nplname[0] = toupper(plname[0]);
if (plname[j - 1] == ' ') {
nplname[j] = toupper(plname[j]);
nplname[j - 1] = plname[j - 1];
}
else nplname[j] = plname[j];
}
nplname[j] = '\0';
//*****************************
//sdfprintf(info,"\t\t\tPlayers List\n");
fprintf(info, "Player Name :%s\n", nplname);
//for date and time
time_t mytime;
mytime = time(NULL);
fprintf(info, "Played Date:%s", ctime(&mytime));
//**************************
fprintf(info, "Score:%d\n", px = Scoreonly());//call score to display score
//fprintf(info,"\nLevel:%d\n",10);//call level to display level
for (i = 0; i <= 50; i++)
fprintf(info, "%c", '_');
fprintf(info, "\n");
fclose(info);
printf("wanna see past records press 'y'\n");
cha = getch();
system("cls");
if (cha == 'y') {
info = fopen("record.txt", "r");
do {
putchar(c = getc(info));
} while (c != EOF);
}
fclose(info);
}
int Score()
{
int score;
GotoXY(20, 8);
score = length - 5;
printf("SCORE : %d", (length - 5));
score = length - 5;
GotoXY(50, 8);
printf("Life : %d", life);
return score;
}
int Scoreonly()
{
int score = Score();
system("cls");
return score;
}
void Up()
{
int i;
for (i = 0; i <= (bend[bend_no].y - head.y) && len < length; i++)
{
GotoXY(head.x, head.y + i);
{
if (len == 0)
printf("^");
else
printf("*");
}
body[len].x = head.x;
body[len].y = head.y + i;
len++;
}
Bend();
if (!kbhit())
head.y--;
}
I tried to find information on how to fix the code, but I did not succeed.
Here is code for my connect four game for exam. There are seven columns, if a number above 7 is entered it should say "Move not allowed", but if 0 is entered it should save the game.
When I enter 0 it says "Move not allowed". There is a code to save the game when 0 is entered but it says "Move not allowed" and doesn't go there. Can someone help?
#include <stdio.h>
#include <string.h>
typedef struct gameState{
int id;
char board[6][7];
int numberOfMoves;
char player1Name[20];
char player2Name[20];
}GameState;
void ShowMenu() {
printf("\n\n\n1. New Game \n");
printf("2. Load Game \n");
printf("3. Exit \n\n");
printf("Choose: ");
}
void ReadPlayerNames(char player1Name[20], char player2Name[20]) {
printf("\nName of first player:");
scanf("%s", player1Name);
printf("\nName of second player:");
scanf("%s", player2Name);
}
void PrintBoard(char board[6][7])
{
char header[] = " 1 2 3 4 5 6 7 ";
char border[] = "|---|---|---|---|---|---|---|";
printf("%s\n", header);
printf("%s\n", border);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 7; j++)
{
printf("| %c ", board[i][j]);
}
printf("|\n");
printf("%s\n", border);
}
}
void ClearBoard(char board[6][7]) {
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckDiagonals(char board[6][7], int i, int j, int goUpRight){
int connectedO = 0;
int connectedX = 0;
while(i >= 0){
if (board[i][j] != ' '){
if (board[i][j] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (goUpRight = 0){
board[i][j] = 'Y'; //checking if x won, putting Y on places of x
board[i + 1][j + 1] = 'Y';
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (goUpRight = 0){
board[i][j] = 'Y';
board[i + 1][j + 1] = 'Y'; //checking if o won, putting Y on places of o
board[i + 2][j + 2] = 'Y';
board[i + 3][j + 3] = 'Y';
} else {
board[i][j] = 'Y';
board[i + 1][j - 1] = 'Y';
board[i + 2][j - 2] = 'Y';
board[i + 3][j - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
i--;
if (goUpRight == 1){
j++;
}else{
j--;
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckRowsOrCols(char board[6][7], int rows){
int connectedO = 0;
int connectedX = 0;
int brI = 6;
int brJ = 7;
if (rows == 0){
brI = 7;
brJ = 6;
}
for (int i = 0; i < brI; i++){
for (int j = 0; j < brJ; j++) {
int pI = i, pJ = j;
if (rows == 0){
pI = j;
pJ = i;
}
if (board[pI][pJ] != ' '){
if (board[pI][pJ] == 'X'){
connectedX++;
connectedO = 0;
if (connectedX == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 1;
}
} else {
connectedO++;
connectedX = 0;
if (connectedO == 4){
if (rows == 0){
board[pI][pJ] = 'Y';
board[pI - 1][pJ] = 'Y';
board[pI - 2][pJ] = 'Y';
board[pI - 3][pJ] = 'Y';
} else {
board[pI][pJ] = 'Y';
board[pI][pJ - 1] = 'Y';
board[pI][pJ - 2] = 'Y';
board[pI][pJ - 3] = 'Y';
}
return 2;
}
}
} else {
connectedO = 0;
connectedX = 0;
}
}
}
return 0;
}
// 1 - X wins, 2 - O wins, 0 - still playing
int CheckForWinner(char board[6][7]) {
int rezultat = CheckRowsOrCols(board, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckRowsOrCols(board, 0);
if (rezultat != 0){
return rezultat;
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 0, 1);
if (rezultat != 0){
return rezultat;
}
}
for (int j = 0; j < 7; j++){
rezultat = CheckDiagonals(board, 5, j, 1);
if (rezultat != 0){
return rezultat;
}
rezultat = CheckDiagonals(board, 5, j, 0);
if (rezultat != 0){
return rezultat;
}
}
for (int i = 0; i < 6; i++){
rezultat = CheckDiagonals(board, i, 6, 0);
if (rezultat != 0){
return rezultat;
}
}
return 0;
}
void SaveGame(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]){
printf("\n\n\nEnter ID for your game: ");
int id;
scanf("%d", &id);
GameState state;
state.id = id;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
state.board[i][j] = board[i][j];
}
}
state.numberOfMoves = movesPlayed;
strcpy(state.player1Name, player1Name);
strcpy(state.player2Name, player2Name);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "ab");
if (filePointer == NULL){
printf("\nGames not found!");
return;
}
fwrite(&state, sizeof(state), 1, filePointer);
fclose(filePointer);
printf("\nGame with ID:%d saved!", id);
}
int MakeMove(char board[6][7], int movesPlayed, char player1Name[20], char player2Name[20]) {
char sign = 'X';
if (movesPlayed % 2 == 1){
sign = 'O';
}
int column;
while (1){
printf("\nChoose the column player %c(0 for save and exit): ", sign);
column;
scanf("%d", &column);
if (column >= 0 && column <= 7 && board[0][column-1] == ' '){
break;
}
printf("\nMove not allowed!\n");
}
if (column != 0){
for (int i = 6; i >= 0; i--) {
if (board[i][column-1] == ' ') {
board[i][column-1] = sign;
printf("\n\n\n");
break;
}
}
}else {
SaveGame(board, movesPlayed, player1Name, player2Name);
return 1;
}
return 0;
}
void PlayGame(char board[6][7], char player1Name[20], char player2Name[20], int movesPlayed){
while (1){
PrintBoard(board);
if (MakeMove(board, movesPlayed, player1Name, player2Name) == 1){
break;
}
movesPlayed++;
int result = CheckForWinner(board);
if (result != 0){
PrintBoard(board);
if (result == 1){
printf("\nX wins\n\n\n");
} else {
printf("\nO wins\n\n\n");
}
break;
}
if (movesPlayed == 42){
PrintBoard(board);
printf("\nTie!\n\n\n");
break;
}
}
}
void ListAllSavedGames(){
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
fclose(filePointer);
}
void ListAllPlayerGames(){
char playerName[20];
printf("\nName of player: ");
scanf("%s", playerName);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (strcmp(playerName, state.player1Name) == 0 || strcmp(playerName, state.player2Name) == 0){
printf("\n%d, X: %s, O: %s, %d", state.id, state.player1Name, state.player2Name, (42 - state.numberOfMoves));
}
}
fclose(filePointer);
}
int ShowTheBoard(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
printf("\nX: %s, O: %s", state.player1Name, state.player2Name);
PrintBoard(state.board);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
int LoadAGame(){
int ID;
printf("\nEnter ID: ");
scanf("%d", &ID);
FILE *filePointer;
filePointer = fopen("SavedGames.dat", "rb");
if (filePointer == NULL){
printf("\nGames not played yet!");
return;
}
int IDfound = 0;
GameState state;
while(fread(&state, sizeof(state), 1, filePointer) == 1){
if (ID == state.id){
IDfound = 1;
PlayGame(state.board, state.player1Name, state.player2Name, state.numberOfMoves);
}
}
fclose(filePointer);
if (IDfound == 0){
return 1;
}
return 0;
}
void ShowLoadMenu(){
int returnToMainMenu = 0;
while (returnToMainMenu == 0){
printf("\n\n\n1. List all saved games\n");
printf("2. List all saved games for a particular player\n");
printf("3. Show the board of one of the saved games\n");
printf("4. Load a game\n");
printf("5. Return to main menu\n");
printf("Choose: ");
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ListAllSavedGames();
break;
case 2:
ListAllPlayerGames();
break;
case 3:
while (ShowTheBoard() == 1){
printf("ID not valid!");
}
break;
case 4:
while (LoadAGame() == 1){
printf("ID not valid!");
}
returnToMainMenu = 1;
break;
case 5:
returnToMainMenu = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
int main(){
int endOfProgram = 0;
while (endOfProgram == 0){
char board[6][7];
char player1Name[20];
char player2Name[20];
int movesPlayed = 0;
ShowMenu();
int choice;
scanf("%d", &choice);
switch(choice){
case 1:
ClearBoard(board);
ReadPlayerNames(player1Name, player2Name);
PlayGame(board, player1Name, player2Name, movesPlayed);
break;
case 2:
ShowLoadMenu();
break;
case 3:
printf("Goodbye!");
endOfProgram = 1;
break;
default:
printf("Wrong choice, try again!");
}
}
}
Culprit is likely to be inside MakeMove:
if (column >= 0 && column <= 7 && board[0][column-1] == ' ') {
break;
}
if you pass 0 as column, the first 2 tests will indeed succeed (both 0 >= 0 and 0 <= 7 are true). But third one tries to use board[0][-1]. -1 is not a valid index and you are invoking UB.
If column is 0, you should not test anything else, so your test should be:
if (column == 0 || (column > 0 && column <= 7
&& board[0][column-1] == ' ')) {
break;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SPECKLE '.'
#define WALL '#'
/*char a[1000][1000] = {
{'#','.','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
{'#','.','.','.','#','.','.','.','.','.','.','.','.','.','.','.','#'},
{'#','.','#','#','#','.','#','#','#','#','#','.','#','.','#','#','#'},
{'#','.','.','.','.','.','.','.','.','.','#','.','#','.','.','.','#'},
{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','.','#'},
};*/
#define SIZE 1000
void print_arr()
{
char a[SIZE][SIZE];
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 7; ++j)
{
printf("%c",a[i][j]);
}
printf("\n");
}
}
int main(int argc, char const *argv[])
{
int x = 0, y = 1;
char a[SIZE][SIZE];
for(int i=0;i<SIZE;i++)
{
scanf("%s",&a[i]);
}
continue_in_road:
while(1)
{
if(y == 16 && x == 4)
break;
if(a[x][y] == SPECKLE)
{
a[x][y] = '1';
y++;
continue;
}
else if(a[x][y] == WALL)
{
y--;
goto go_back_and_check;
}
go_back_and_check:
while(1)
{
if(a[x+1][y] == SPECKLE)
{
x++;
goto continue_in_road;
}
else if(a[x-1][y] == SPECKLE)
{
x--;
goto continue_in_road;
}
else if(a[x][y-1] == WALL)
{
a[x][y] = '2';
x--;
continue;
}
else if(a[x][y-1] == '1')
{
a[x][y] = '2';
y--;
continue;
}
else if(a[x][y-1] == SPECKLE)
{
y--;
goto switch_to_left;
}
}
switch_to_left:
while(1)
{
if(a[x][y] == SPECKLE)
{
a[x][y] = '1';
y--;
continue;
}
else if(a[x][y] == WALL)
{
y++;
goto go_back_and_check;
}
}
}
//print_arr();
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < 18; ++j)
{
if(a[i][j] == '1')
a[i][j] = '*';
if(a[i][j] == '2')
a[i][j] = '.';
printf("%c",a[i][j]);
}
printf("\n\n");
}
// print_arr();
return 0;
}
The code is for finding the path or the road in the graph, which looks like :
Input:
Output:
I'm searching for an alternative to goto command as I would like to teach more than this command how to jump in loops. I was told that goto command is ugly and so on, so I would be happy if any of you will help me with this one.
THANKS GUYS !
Using functions is the best way to get rid of those gotos. However don't dislike gotos just because someone told you so.
Here is a good reading about goto which enlighted me about goto when I was convinced by teachers and the internet that they were the Evil. Now I love goto; it just has it's applications on which it is the best tool available:
https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
Great power comes with great responsibility :)
Now your code:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SPECKLE '.'
#define WALL '#'
#define SIZE 1000
#if 01
static char aa[1000][1000] = {
{'#','.','#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'},
{'#','.','.','.','#','.','.','.','.','.','.','.','.','.','.','.','#'},
{'#','.','#','#','#','.','#','#','#','#','#','.','#','.','#','#','#'},
{'#','.','.','.','.','.','.','.','.','.','#','.','#','.','.','.','#'},
{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#','.','#'}
};
#endif
static int x, y;
static void print_arr(void);
static void continue_in_road(char a[SIZE][SIZE]);
static bool check(char a[SIZE][SIZE]);
static void switch_to_left(char a[SIZE][SIZE]);
/*
* Note that int main(void) is completely valid, and in fact is what you need,
* because you're not using the arguments.
*/
int main(void)
{
int i, j;
// char a[SIZE][SIZE];
x = 0;
y = 1;
// for (i = 0; i < SIZE; i++)
// scanf(" %s", &a[i]);
continue_in_road(aa);
print_arr();
for (i = 0; i < 5; i++) {
for (j = 0; j < 18; j++) {
if(aa[i][j] == '1')
aa[i][j] = '*';
if(aa[i][j] == '2')
aa[i][j] = '.';
printf("%c",aa[i][j]);
}
printf("\n\n");
}
print_arr();
return 0;
}
static void continue_in_road(char a[SIZE][SIZE])
{
bool initial_chk = true;
while (1) {
if (initial_chk) {
if ((y == 16) && (x == 4))
return;
if (a[x][y] == SPECKLE) {
a[x][y] = '1';
y++;
continue;
} else if (a[x][y] == WALL) {
y--;
}
}
if (check(a)) {
initial_chk = true;
continue;
}
initial_chk = false;
switch_to_left(a);
}
}
static bool check(char a[SIZE][SIZE])
{
while (1) {
if (a[x+1][y] == SPECKLE) {
x++;
return true;
} else if (a[x-1][y] == SPECKLE) {
x--;
return true;
} else if (a[x][y-1] == WALL) {
a[x][y] = '2';
x--;
} else if (a[x][y-1] == '1') {
a[x][y] = '2';
y--;
} else if (a[x][y-1] == SPECKLE) {
y--;
return false;
}
}
}
static void switch_to_left(char a[SIZE][SIZE])
{
while (1) {
if (a[x][y] == SPECKLE) {
a[x][y] = '1';
y--;
} else if(a[x][y] == WALL) {
y++;
return;
}
}
}
/* What is this supposed to do? */
static void print_arr(void)
{
char a[SIZE][SIZE];
int i, j;
for (i = 0; i < 5; ++i) {
for (j = 0; j < 7; ++j)
printf("%c",a[i][j]);
printf("\n");
}
}
It runs if you compile it just like that. I have commented the input loop to use the static const array initializer you've created, so that it was easy to test.
However I think you should reconsider changing the structure of the functions, because it is difficult to understand what it is doing. If I had understood what it does, I could have improved more the code, but as I didn't understand it so much, I limited myself to get rid of those gotos.
I hope you can help me I worked on this code. The code works like this
user inputs a string for example "hey john, how are you john?
the program erases signs like "'?' , ',' '!' " etc.
the program writes a string after erasing the signs : "hey john how are you john?"
and the code outputs the frequency of each word:
hey : 1
john: 2
how : 1
are : 1
you : 1
but my code counts sometimes wrong. For example when I type "bye bye bye hello hello hello"
the output is :
bye : 3
hello : 1
My code does the john example right, but the bye bye... example wrong.
How do I have to change my code? Thank you
#include <stdio.h>
#include <string.h>
char words[80][80];
void clear_string(char *text);
int extract_and_count(char *source, int *count);
void clearArray(char array[]);
int indexInWords(char string[]);
void print(int countOfWords, int count[]);
int equals(char *string1, char *string2);
int main() {
char string[80];
int count[80];
printf("please enter your text: ");
scanf("%[^\n]s", string);
clear_string(string);
printf("%s\n", string);
int countOfWords = extract_and_count(string, count);
print(countOfWords, count);
return 0;
}
void clear_string(char *text){
int i = 0;
for(;i < strlen(text);++i){
if( text[i] == '.' || text[i] == ',' || text[i] == '!' || text[i] == '?'){
int k = i + 1;
for(; k < strlen(text);++k){
text[k-1] = text[k];
}
k = strlen(text) - 1;
text[k] = ' ';
}
}
}
int extract_and_count(char *source, int *count){
int wordCounter = 0;
char string[80];
int i = 0, k = 0;
clearArray(string);
for(; i < strlen(source);++i, ++k){
if(source[i] != ' '){
string[k] = source[i];
}else{
if(string[0] == '\0'){
break;
}
int index = indexInWords(string);
if(index == -1){
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
}else{
count[index] += 1;
}
clearArray(string);
k = -1;
}
}
return wordCounter;
}
void clearArray(char array[]){
memset(array,0,strlen(array));
//array[0] = '\0';
}
int indexInWords(char string[]){
int i = 0;
for(;i < 80;++i){
if(equals(words[i], string) == 0){
return i;
}
}
return -1;
}
void print(int countOfWords, int count[]){
for(int i = 0;i < countOfWords; ++i){
printf("%s : %d\n",words[i], count[i]);
}
}
int equals(char string1[], char string2[]){
return strcmp(string1, string2);
}
The most significant problem I found was in extract_and_count() -- it doesn't count the last word as it only counts words followed by space. The bandaid is to check if string has anything in it after the loop, and if so, process it. Below is my rework for that fix and general style:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void clear_string(char *text);
int extract_and_count(char *source, int count[]);
void clearArray(char array[]);
int indexInWords(char string[]);
void print(int countOfWords, int count[]);
bool equals(char *string1, char *string2);
#define BUFFER_SIZE (512)
#define MAX_WORD_COUNT (80)
#define MAX_WORD_SIZE (64)
char words[MAX_WORD_COUNT][MAX_WORD_SIZE];
int main() {
char string[BUFFER_SIZE];
int count[MAX_WORD_COUNT];
printf("Please enter your text: ");
while (fgets(string, BUFFER_SIZE, stdin) == NULL) {
printf("Please (re)enter your text: ");
}
clear_string(string);
int countOfWords = extract_and_count(string, count);
print(countOfWords, count);
return 0;
}
void clear_string(char *text) {
for (int i = 0; i < strlen(text); i++) {
if (text[i] == '.' || text[i] == ',' || text[i] == '!' || text[i] == '?' || text[i] == '\n') {
int length = strlen(text);
for (int k = i + 1; k < length; k++) {
text[k - 1] = text[k];
}
text[length - 1] = '\0';
i--;
}
}
}
int extract_and_count(char *source, int count[]) {
int wordCounter = 0;
char string[MAX_WORD_SIZE] = {'\0'};
for (int i = 0, k = 0; i < strlen(source); i++, k++) {
if (source[i] != ' ') {
string[k] = source[i];
} else {
if (string[0] == '\0') {
break;
}
int index = indexInWords(string);
if (index == -1) {
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
} else {
count[index] += 1;
}
clearArray(string);
k = -1;
}
}
if (string[0] != '\0') {
int index = indexInWords(string);
if (index == -1) {
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
} else {
count[index] += 1;
}
}
return wordCounter;
}
void clearArray(char array[]) {
memset(array, 0, strlen(array));
}
int indexInWords(char string[]) {
for (int i = 0; i < MAX_WORD_COUNT; i++) {
if (equals(words[i], string)) {
return i;
}
}
return -1;
}
void print(int countOfWords, int count[]) {
for (int i = 0; i < countOfWords; i++) {
printf("%s : %d\n", words[i], count[i]);
}
}
bool equals(char string1[], char string2[]) {
return strcmp(string1, string2) == 0;
}
The next most significant issue I see is you don't keep track of how many entries in words[][] are used, so indexInWords() could easily wander off making comparisons against uninitialized memory.
In extract_and_count you break out of the for-loop when you find 2 spaces. Also you did not check for the last word of source. Changed it to:
int extract_and_count(char *source, int *count){
int wordCounter = 0;
char string[80];
int i = 0, k = 0;
clearArray(string);
for(; i < strlen(source)+1;++i, ++k){
if(source[i] != ' ' && source[i] != 0){
string[k] = source[i];
}else{
if(string[0] != '\0'){
int index = indexInWords(string);
if(index == -1){
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
}else{
count[index] += 1;
} }
clearArray(string);
k = -1;
}
}
return wordCounter;
}