Quote:
Logging every dice roll but the player names get corrupted
After first analyzing the game, it does not seem to make sense to log individual dice rolls if the goal is to load or save the current game state. The log would perhaps make sense if you wanted to track every single move.
The fact that the player name and other variables are overwritten is due to the fact that several parts of the source code have already been implemented incorrectly.
Example:
In the mainGame() function, things go massively wrong right at the start:
while (GamemodeChoice == NETWORTH) {
char inp[1]; printf("\n\n\tEnter maximum net worth after which game is to end: ");
scanf("%s",&inp); if (atoi(inp) >= 1400){
maxNetworth=atoi(inp);
break;
}
printf("\n\n\tInvalid Input (Enter a number from greater than 1400) \n\tEntered: %s\n",inp);
}
The field for a string containing at least one character must be at least 2 bytes in size. If, as in the previous case, a multi-digit decimal number is to be entered, the buffer must be correspondingly larger. Buffer overflows could be avoided even with minimal changes.
while (GamemodeChoice == NETWORTH) {
char inp[6];
printf("\n\n\tEnter maximum net worth after which game is to end (min. 1400): ");
scanf("%5s",&inp);
if (atoi(inp) >= 1400){
maxNetworth=atoi(inp);
break;
}
printf("\n\n\tInvalid Input (Enter a number from greater than 1400) \n\tEntered: %s\n",inp);
}
Since other data or return addresses on the stack are obviously overwritten when user input is read in, a good compiler should notice this. I have also integrated the minimum expected value into the prompt, as otherwise you would have to guess first.
I assume that save and load means that the last game state should be saved or restored. It is necessary to save the player data and the state of the properties. Logging past or future actions seems unnecessary.
The first step would be to analyze what exactly should be saved.
Most of the structures to be saved are in the definitions.h file. The properties are stored in the struct location.
Initially, the key figures and names are loaded from the locations.csv file and would not necessarily have to be be saved and loaded twice if the locations.csv file is read in beforehand anyway.
struct location {
unsigned int ID :6;
unsigned int type:3;
} location[40];
In order to save the score, the number of players and their possessions should be saved, preferably in one file.
struct player {
unsigned int ID:4;
char name[30];
}
The game generates event cards at random, so nothing can be saved here in this version. In addition, further status-dependent details might have to be saved.
I suggest writing a function save_game_score() and a function load_game_score() and adding the item "Load last game" to the menu. In order to save the score at any point, a key, possibly a function key, would have to be documented and implemented.
When testing the program under Windows, it is particularly annoying that the program is terminated if the command window is not the right size. This should be changed so that the program is easier to debug from the development environment.
Here is the improved version for Windows, which adjusts the window to the size instead of closing the program.
#ifdef _WIN32
#include <windows.h>
void checkWindowSize(int screenWidth, int screenHeight)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (!GetConsoleScreenBufferInfo(hStdout, &csbi)) {
printf("Error: GetConsoleScreenBufferInfo (%d)\n", GetLastError());
exit(1);
}
SMALL_RECT srctWindow = csbi.srWindow;
int width = srctWindow.Right - srctWindow.Left + 1;
int height = srctWindow.Bottom - srctWindow.Top + 1;
if (width < screenWidth || height < screenHeight) {
if(width < screenWidth)
srctWindow.Right = screenWidth;
if(height < screenHeight)
srctWindow.Bottom = screenHeight;
COORD wbuff = { screenWidth +1, screenHeight +1 };
SetConsoleScreenBufferSize(hStdout, wbuff);
SetConsoleWindowInfo( hStdout, TRUE, &srctWindow);
}
As already said, the code has many weaknesses, ranging from uninitialized variables to stack problems. In the ReadPlayers() function, for example, a stack overflow occurs which the debugger reports.
Here, scanf and %s are used to read a string into an array with one byte, which looks unhealthy.