Saya membuat game connect 4 di C dan sebagian dari game tersebut sedang memuat dan menyimpan status game.. cara menyimpannya adalah melalui potongan kode di bawah ini
if (strncmp (temp, "save", 5) == 0){
int r, c;
// this writes the game settings to a file
int *rows = &num_rows;
int *cols = &num_columns;
int *len = &length_to_win;
FILE *fp = fopen("gameSave.txt", "w+");
fprintf(fp, "%d ", *rows);
fprintf(fp, "%d ", *cols);
fprintf(fp, "%d ", *len);
fprintf(fp, "\n\n");
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
fprintf(fp, "%c ", aPtr[r][c]);
}
fprintf(fp, "\n");
}
printf("Game Saved\n");
fclose(fp);
}
"temp" mengacu pada input pengguna yang biasanya berupa nomor kolom yang diinginkan pemain untuk meletakkan bidaknya; namun, jika mereka memasukkan "simpan", potongan kode ini akan dieksekusi dan membuat file seperti ini
cat gameSave.txt
5 5 4
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
9 9 9 9 9
9 9 9 9 9
5 5 4 mengacu pada baris kolom dan panjang untuk menang, dan array 2D di bawahnya (yang dipisahkan oleh dua \n) adalah representasi karakter papan (mereka memang karakter, bukan bilangan bulat). JADI masalah saya, adalah saya menggunakan potongan kode di bawah ini untuk memuat data simpanan di tengah permainan
if (strncmp (temp, "load", 5) == 0){
int r, c;
// this loads the game settings into game
FILE *fp = fopen("gameSave.txt", "r");
fscanf(fp, "%d %d %d", &num_rows, &num_columns, &length_to_win);
fscanf(fp, "\n\n");
aPtr = malloc(num_rows * sizeof(char*));
for (i = 0; i < num_rows; i++){
aPtr[i] = malloc(num_columns * sizeof (char));
}
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
fscanf(fp, "%c ", aPtr[r][c]);
}
fscanf(fp, "\n");
}
printf("Game Loaded\n");
fclose(fp);
}
ini berhasil memuat pengaturan permainan (baris, kolom, dan panjang untuk menang); namun, baris kode yang seharusnya memuat status permainan sebenarnya (di bawah)
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
fscanf(fp, "%c ", aPtr[r][c]);
}
fscanf(fp, "\n");
}
memberi saya peringatan, khususnya salurannya
fscanf(fp, "%c ", aPtr[r][c]);
peringatannya adalah
"peringatan: format menentukan tipe 'char *' tetapi argumennya memiliki tipe 'int' [-Wformat]"
ini membingungkan... karena pada dasarnya baris kodenya sama persis dengan yang digunakan di blok penyimpanan
fprintf(fp, "%c ", aPtr[r][c]);
dan itu tidak memberi saya masalah apa pun... Adakah pemikiran tentang apa yang sebenarnya terjadi? Jika Anda ingin menjalankannya sendiri, cukup beri komentar pada kode pemuatan yang dimaksudkan untuk menarik status permainan yang sebenarnya. Kode lengkapnya ada di bawah ini:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
void initialize(int num_rows, int num_cols, char **aPtr) {
int i, r, c;
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_cols; c++) {
aPtr[r][c] = '9';
}
}
}
// end of initialize
void printBoard(int num_rows, int num_columns, char **aPtr) {
int row, col;
int r, c;
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
printf("%c ", aPtr[r][c]);
}
printf("\n");
}
printf("\n");
puts("------ Connect *Four ------");
puts("Connect X Command Line Game");
// for fancy top of board frame
printf("&&");
for(col = 1; col < num_columns; col++) {
printf("====");
}
printf("===");
printf("&&\n");
// for the rows/columns of the board
for(row = num_rows - 1; row >= 0; row--){
printf("|");
for(col = 0; col < num_columns; col++){
if(aPtr[row][col] == '0') {
printf("| X ");
}
else if(aPtr[row][col] == '1') {
printf("| O ");
}
else {
printf("| ");
}
}
puts("||");
}
// for fancy bottom of board frame
printf("&&");
for(col = 1; col < num_columns; col++) {
printf("====");
}
printf("===");
printf("&&\n");
printf(" ");
if (col < 100){
for(col = 0; col < num_columns; col++) {
if (col < 10) {
printf(" %d ", col + 1);
}
else {
printf("%d ", col + 1);
}
}
puts("\n");
}
}
// end of printBoard
/*Global var to hold the current winner value*/
char winnerVal = '0';
int checkFullBoard(int num_rows, int num_columns, char **aPtr) {
for (int i = 0; i < num_columns; i++) {
if (aPtr[num_rows - 1][i] == '9') {
return 0;
}
}
return 1;
}
/*
* Checks for the first avalible cell to insert token in given column.
* NOTE: This fuction is designed based on row 0 being the bottom (lowest row of the board)
* This means that tokens are inserted from row 0 upward. Based on your tests, this should not cause
* any problems.
*/
int checkForColHeight(int num_rows, int num_columns, int column, char **aPtr) {
for (int i = 0; i < num_rows; i++) {
if (aPtr[i][column] == '9') {
return i;
}
}
return -1;
}
int place_token(char player, int column, int num_rows, int num_columns, char **aPtr) {
/*Check for invalid Parameters*/
if(column > (num_columns - 1) || column < 0 || (player != '1' && player != '0')
|| num_columns <= 0 || num_rows <= 0) {;
return -1;
}
int firstOpenRow = checkForColHeight(num_rows, num_columns, column, aPtr);
if (firstOpenRow == -1) {
return -1;
}else {
aPtr[firstOpenRow][column] = player;
return 1;
}
}
char checkForSeries(int direction, int num_rows, int num_columns, int length_to_win, int r, int c, char **aPtr) {
switch (direction) {
/*Horizontal*/
case 0:
for (int i = 1; i < length_to_win; i++) {
if (aPtr[r][c] == '9' ) {
return '2';
}else if (aPtr[r][c] != aPtr[r][c + i] ) {
return '2';
}
}
return aPtr[r][c];
break;
/*Vertical*/
case 1:
for (int i = 1; i < length_to_win; i++) {
if (aPtr[r][c] == '9' ) {
return '2';
}else if (aPtr[r][c] != aPtr[r + i][c] ) {
return '2';
}
}
return aPtr[r][c];
break;
/*Left Diag*/
case 2:
for (int i = 1; i < length_to_win; i++) {
if (aPtr[r][c] == '9' ) {
return '2';
}else if (aPtr[r][c] != aPtr[r + i][c - i] ) {
return '2';
}
}
return aPtr[r][c];
break;
/*Right Diag*/
case 3:
for (int i = 1; i < length_to_win; i++) {
if (aPtr[r][c] == '9' ) {
return '2';
}else if (aPtr[r][c] != aPtr[r + i][c + i] ) {
return '2';
}
}
return aPtr[r][c];
break;
return '2';
}
return '0';
}
/*Interate over each row and column. For each cell in the row, check for series of tokens*/
int checkHorizontal(int num_rows, int num_columns, int length_to_win, char **aPtr){
int r, c;
for (r = 0; r < num_rows; r++) {
for(c = 0; c < num_columns - (length_to_win - 1); c++) {
char winner = checkForSeries(0, num_rows, num_columns, length_to_win, r, c, aPtr);
if(winner != '2') {
winnerVal = winner;
return 1;
}
}
}
return 0;
}
/*Interate over each row and column. For each cell in the row, check for series of tokens*/
int checkVertical(int num_rows, int num_columns, int length_to_win, char **aPtr){
int r, c;
for (c = 0; c < num_columns; c++) {
for(r = 0; r < num_rows - (length_to_win - 1); r++) {
char winner = checkForSeries(1, num_rows, num_columns, length_to_win, r, c, aPtr);
if(winner != '2') {
winnerVal = winner;
return 1;
}
}
}
return 0;
}
/*Interate over each row and column. For each cell in the row, check for series of tokens*/
int checkDiagLeft(int num_rows, int num_columns, int length_to_win, char **aPtr){
int r, c;
for (r = 0; r < num_rows - (length_to_win - 1); r++) {
for(c = num_columns - 1; c > (length_to_win - 2); c--) {
char winner = checkForSeries(2, num_rows, num_columns, length_to_win, r, c, aPtr);
if(winner != '2') {
winnerVal = winner;
return 1;
}
}
}
return 0;
}
/*Interate over each row and column. For each cell in the row, check for series of tokens*/
int checkDiagRight(int num_rows, int num_columns, int length_to_win, char **aPtr){
// printf("%s\n", "Check Right Diag: ");
int r, c;
for (r = 0; r < num_rows - (length_to_win - 1); r++) {
// printf("%s", "Row #: ");
// printf("%d\n", r);
for(c = 0; c < num_columns - (length_to_win - 1); c++) {
// printf("%s", "Col #: ");
// printf("%d\n", c);
char winner = checkForSeries(3, num_rows, num_columns, length_to_win, r, c, aPtr);
if(winner != '2') {
winnerVal = winner;
// printf("%s", "Row Location: ");
// printf("%d\n", r);
// printf("%s", "Col Location: ");
// printf("%d\n", c);
return 1;
}
}
}
return 0;
}
/*Return the integer representation of the winning player, -1 if a tie or error*/
char winner(int num_rows, int num_columns, int length_to_win, char **aPtr) {
/*Check for invalid Parameters*/
if (length_to_win <= 0 || length_to_win > num_columns || num_columns <= 0 || num_rows <= 0) {
return '2';
}
if (checkHorizontal(num_rows, num_columns, length_to_win, aPtr)
|| checkVertical(num_rows, num_columns, length_to_win, aPtr)
|| checkDiagLeft(num_rows, num_columns, length_to_win, aPtr)
|| checkDiagRight(num_rows, num_columns, length_to_win, aPtr)
) {
return winnerVal;
}
if(checkFullBoard(num_rows, num_columns, aPtr)) {
return '2';
}
return '2';
}
// *******************************************************************************************************
// *******************************************************************************************************
int main (int argc, char *argv[]) {
setvbuf(stdout, NULL, _IONBF, 0);
int num_rows = 7;
int num_columns = 7;
int length_to_win = 4;
int i;
int index;
char **aPtr;
// FILE *fp = fopen("test.txt", "r");
printf("Starting Game\n");
// this loop checks for command line arguments and sets game variables accordingly.
for(index = 0; index < argc; ++index) {
if ( strncmp( argv[index], "-h", 5) == 0 ) {
num_rows =atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-height", 5) == 0 ) {
num_rows =atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-w", 5) == 0 ) {
num_columns = atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-width", 5) == 0 ) {
num_columns = atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-s", 5) == 0 ) {
num_rows = atoi(argv[index + 1]);
num_columns = atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-square", 5) == 0 ) {
num_rows = atoi(argv[index + 1]);
num_columns = atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-c", 5) == 0 ) {
length_to_win = atoi(argv[index + 1]);
}
if ( strncmp( argv[index], "-connect", 5) == 0 ) {
length_to_win = atoi(argv[index + 1]);
}
}
// these conditionals check for valid board size
if (num_rows <= 0 || num_columns <= 0 ){
printf("%s\n","You entered a width or length that was invalid." );
}
if (length_to_win <= 0 || length_to_win > (num_rows - 1)) {
printf("%s\n","You entered a winning length that was invalid." );
}
// create the space for the board
aPtr = malloc(num_rows * sizeof(char*));
for (i = 0; i < num_rows; i++){
aPtr[i] = malloc(num_columns * sizeof (char));
}
initialize(num_rows, num_columns, aPtr);
int answer;
int attmpt;
char player = '0';
printf("%s\n", "*********************");
printf("%s\n", " Starting Board ");
printf("%s\n", "*********************");
puts("\n");
printBoard(num_rows, num_columns, aPtr);
printf("Player: %cs Turn\n", player + 1);
puts("\n");
/*Start game loop*/
while(1) {
// prompts the user to select which column they want their piece to be placed
// -1 on the temp because the first column is technically 0 so if a player
// wants to place their piece in column "1", it'll be placed at index[0] accordingly
printf("%s\n", "Enter Column # To Place Token");
int column;
char temp[20];
char temp2[20];
scanf("%s", temp);
if (strncmp (temp, "save", 5) == 0){
int r, c;
// this writes the game settings to a file
int *rows = &num_rows;
int *cols = &num_columns;
int *len = &length_to_win;
FILE *fp = fopen("gameSave.txt", "w+");
fprintf(fp, "%d ", *rows);
fprintf(fp, "%d ", *cols);
fprintf(fp, "%d ", *len);
fprintf(fp, "\n\n");
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
fprintf(fp, "%c ", aPtr[r][c]);
}
fprintf(fp, "\n");
}
printf("Game Saved\n");
fclose(fp);
}
if (strncmp (temp, "load", 5) == 0){
int r, c;
// this loads the game settings into game
FILE *fp = fopen("gameSave.txt", "r");
fscanf(fp, "%d %d %d", &num_rows, &num_columns, &length_to_win);
fscanf(fp, "\n\n");
aPtr = malloc(num_rows * sizeof(char*));
for (i = 0; i < num_rows; i++){
aPtr[i] = malloc(num_columns * sizeof (char));
}
for (r = 0; r < num_rows; r++) {
for (c = 0; c < num_columns; c++) {
fscanf(fp, "%c ", aPtr[r][c]);
}
fscanf(fp, "\n");
}
printf("Game Loaded\n");
fclose(fp);
}
column = atoi(temp) - 1;
attmpt = place_token(player, column, num_rows, num_columns, aPtr);
if ((column < 0 || column > (num_columns - 1)) && (strncmp (temp, "save", 5) != 0) && (strncmp (temp, "load", 5) != 0)) {
printf("%s\n","You entered a column that was invalid. Please try again." );
continue;
}
if (attmpt != 1 && (strncmp (temp, "save", 5) != 0) && (strncmp (temp, "load", 5) != 0)) {
printf("%s\n","This row is already full. Please try again." );
continue;
}
printf("%s\n", "************************");
printf("%s\n", " Board Updated ");
printf("%s\n", "************************");
puts("\n");
printBoard(num_rows, num_columns, aPtr);
puts("\n");
if ((strncmp (temp, "save", 5) != 0) && (strncmp (temp, "load", 5) != 0)) {
if (checkFullBoard(num_rows, num_columns, aPtr)) {
printf("%s\n","This game is a tie. Thanks for Playing.\n");
return 0;
}
}
// this if-statement will constantly be run while the game progresses,
// meaning that winner will be called at every turn and
// all of the win conditions will be checked until a winner is found
char isWin = winner(num_rows, num_columns, length_to_win, aPtr);
if(isWin != '2') {
printf("Player: %c is the winner! Thanks for Playing.\n", isWin + 1);
printf("Play again? (enter 'y' to continue)\n");
scanf("%s", temp2);
if (strncmp (temp2, "y", 5) == 0){
initialize(num_rows, num_columns, aPtr);
printBoard(num_rows, num_columns, aPtr);
puts("\n");
}
else {
printf("Game over, goodbye!\n");
return 0;
}
}
// if a winner is not found then this if/else will continue to switch
// between players at the end of each turn
if ((strncmp (temp, "save", 5) != 0) && (strncmp (temp, "load", 5) != 0) && (strncmp (temp2, "y", 5) != 0)) {
if (player == '1') {
player = '0';
}
else {
player = '1';
}
}
memset(temp, 0, sizeof temp);
memset(temp2, 0, sizeof temp2);
printf("Player: %cs Turn\n", player +1);
} // end of while loop
return 0;
}
fscanf(fp, "%c ", aPtr[r][c]);
menjadifscanf(fp, " %c", &aPtr[r][c]);
-- beri spasi sebelum%c
dan Anda perlu memberi penunjuk kefscanf()
. - person Barmar   schedule 06.03.2017