First version.
This commit is contained in:
commit
c02ff71daa
|
@ -0,0 +1,130 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "arghandler.h"
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
* @see arghandler.h
|
||||
*
|
||||
* My implementation for argp. Handles arguments for the Connect Four game.
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Program version.
|
||||
*/
|
||||
const char *argp_program_version = "Connect Four (Version 3/03/2017)";
|
||||
|
||||
/*
|
||||
* My email address for bug reports.
|
||||
*/
|
||||
const char *argp_program_bug_address = "mcclougj@mail.gvsu.edu";
|
||||
|
||||
/*
|
||||
* Game description.
|
||||
*/
|
||||
char doc[] = "Connect Four: Game where you place tokens until a player connects four!";
|
||||
|
||||
/*
|
||||
* Accepted arguments. Unused, but defined.
|
||||
*/
|
||||
char args_doc[] = "";
|
||||
|
||||
/*
|
||||
* Saved width board parameter.
|
||||
*/
|
||||
int wid;
|
||||
|
||||
/*
|
||||
* Saved height board parameter.
|
||||
*/
|
||||
int hei;
|
||||
|
||||
/*
|
||||
* Saved square board parameter.
|
||||
*/
|
||||
int sqr;
|
||||
|
||||
/*
|
||||
* Saved win length parameter.
|
||||
*/
|
||||
int winlen;
|
||||
|
||||
/*
|
||||
* Saved filename for loading.
|
||||
*/
|
||||
char* loadFile;
|
||||
|
||||
struct argp_option options[] = {
|
||||
{ "width", 'w', "WIDTH", 0, "Width dimension for board." },
|
||||
{ "height", 'h', "HEIGHT", 0, "Height dimension for board." },
|
||||
{ "square", 's', "SQUARE", 0, "Dimensions for a square board (width and height will be overrided)." },
|
||||
{ "connect", 'c', "CONNECT", 0, "Length to win the game." },
|
||||
{ "load", 'l', "LOAD", 0, "Load a previous saved game." },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Required arguments for the argp struct.
|
||||
*/
|
||||
struct argp argp = { options, parse_opt, args_doc, doc };
|
||||
|
||||
/*
|
||||
* Argument values for flags.
|
||||
*/
|
||||
struct arguments arguments;
|
||||
|
||||
/*
|
||||
* Function that sets up values post-parsing.
|
||||
*
|
||||
* @param key, the key of the argument.
|
||||
* @param arg, the argument being passed.
|
||||
* @param state, the state of parser.
|
||||
*/
|
||||
error_t parse_opt(int key, char* arg, struct argp_state *state) {
|
||||
struct arguments *arguments = state->input;
|
||||
switch (key) {
|
||||
case 'w':
|
||||
arguments->width = atoi(arg);
|
||||
break;
|
||||
case 'h':
|
||||
arguments->height = atoi(arg);
|
||||
break;
|
||||
case 's':
|
||||
arguments->square = atoi(arg);
|
||||
break;
|
||||
case 'c':
|
||||
arguments->winL = atoi(arg);
|
||||
break;
|
||||
case 'l':
|
||||
arguments->loadFile = arg;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses arguments.
|
||||
* @param argc, number of command line arguments.
|
||||
* @param argv, the command line arguments.
|
||||
*/
|
||||
void setup(int argc, char** argv) {
|
||||
wid= 0;
|
||||
hei= 0;
|
||||
sqr = 0;
|
||||
winlen = 0;
|
||||
loadFile = NULL;
|
||||
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
wid = arguments.width;
|
||||
hei = arguments.height;
|
||||
sqr = arguments.square;
|
||||
winlen = arguments.winL;
|
||||
|
||||
if (arguments.loadFile != NULL) {
|
||||
loadFile = arguments.loadFile;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef ARG_HANDLER
|
||||
#define ARG_HANDLER
|
||||
#include <argp.h>
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
* @see argp.h
|
||||
*
|
||||
* My implementation for argp. Will handle arguments for the Connect Four game.
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Saved width board parameter.
|
||||
*/
|
||||
int wid;
|
||||
|
||||
/*
|
||||
* Saved height board parameter.
|
||||
*/
|
||||
int hei;
|
||||
|
||||
/*
|
||||
* Saved square board parameter.
|
||||
*/
|
||||
int sqr;
|
||||
|
||||
/*
|
||||
* Saved win length parameter.
|
||||
*/
|
||||
int winlen;
|
||||
|
||||
/*
|
||||
* Saved filename for loading.
|
||||
*/
|
||||
char* loadFile;
|
||||
|
||||
/*
|
||||
* Argument values for flags.
|
||||
*/
|
||||
struct arguments {
|
||||
int width;
|
||||
int height;
|
||||
int square;
|
||||
int winL;
|
||||
char* loadFile;
|
||||
};
|
||||
|
||||
/*
|
||||
* Function that sets up values post-parsing.
|
||||
*/
|
||||
error_t parse_opt(int key, char* arg, struct argp_state *state);
|
||||
|
||||
/*
|
||||
* Parses arguments.
|
||||
*/
|
||||
void setup(int argc, char** argv);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,171 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gamelogic.h"
|
||||
#include "arghandler.h"
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
* @see gamelogic.h
|
||||
* @see arghandler.h
|
||||
*
|
||||
* Includes the main method for our Connect Four game. Uses <argp.h> to handle
|
||||
* command line arguments.
|
||||
*
|
||||
* This post taught me how to use colored text in Linux.
|
||||
* http://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Main method for the Connect Four game. Uses all of the functions from the
|
||||
* game logic file and allows the player to play the game.
|
||||
*
|
||||
* @param argc, number of command line arguments.
|
||||
* @param argv, the command line arguments.
|
||||
* @return 0 if the operation failed and 1 if it succeeded.
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
// Variables and array setup
|
||||
char* input = malloc(100 * sizeof(char));
|
||||
int player = 1;
|
||||
setup(argc, argv);
|
||||
|
||||
// Fixes invalid height or width arguments
|
||||
if (hei <= 0 || hei > 2147483647 || wid <= 0 || wid > 2147483647) {
|
||||
setHeight(7);
|
||||
setWidth(7);
|
||||
}
|
||||
else {
|
||||
setHeight(hei);
|
||||
setWidth(wid);
|
||||
}
|
||||
|
||||
// Fixes invalid win length arguments
|
||||
if (winlen <= 0 || winlen > 2147483647) {
|
||||
setWinLength(4);
|
||||
}
|
||||
else {
|
||||
setWinLength(winlen);
|
||||
}
|
||||
|
||||
// Fixes invalid square dimension arguments
|
||||
if (sqr > 0 && sqr <= 2147483647) {
|
||||
setHeight(sqr);
|
||||
setWidth(sqr);
|
||||
}
|
||||
|
||||
// Either starts new game or loads from argument
|
||||
printf("%sWelcome to Connect Four!\nType 'save' to save, 'load' to load, and 'quit' to quit.\n%s", "\x1B[32m", "\033[0m");
|
||||
if (loadFile != NULL) {
|
||||
if (loadGame(loadFile) == 0) {
|
||||
printf("\nInvalid file.\n");
|
||||
return 0;
|
||||
}
|
||||
printBoard();
|
||||
} else {
|
||||
populateBoard();
|
||||
printBoard();
|
||||
}
|
||||
|
||||
// While loop for the game logic
|
||||
while (1) {
|
||||
// Checks if player 1 has won
|
||||
if (checkWin('o') == 1) {
|
||||
printf("Player 1 wins!\n");
|
||||
printf("Would you like to play again? Type 'yes' for yes or 'no' for no.\n");
|
||||
while (1) {
|
||||
scanf("%s", input);
|
||||
if ((strcmp("yes", input) == 0)) {
|
||||
printf("\n");
|
||||
populateBoard();
|
||||
player = 1;
|
||||
printBoard();
|
||||
break;
|
||||
}
|
||||
if ((strcmp("no", input) == 0)) {
|
||||
printf("\n");
|
||||
return 1;
|
||||
} else {
|
||||
printf("Invalid input.\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if player 2 has won
|
||||
if (checkWin('x') == 1) {
|
||||
printf("Player 2 wins!\n");
|
||||
printf("Would you like to play again? Type 'yes' for yes or 'no' for no.\n");
|
||||
while (1) {
|
||||
scanf("%s", input);
|
||||
if ((strcmp("yes", input) == 0)) {
|
||||
populateBoard();
|
||||
player = 1;
|
||||
printBoard();
|
||||
printf("\n");
|
||||
break;
|
||||
} if ((strcmp("no", input) == 0)) {
|
||||
return 1;
|
||||
} else {
|
||||
printf("Invalid input.\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User input
|
||||
printf("\nPlayer %d's turn.\n", player);
|
||||
printf("Input a column (from 1 to %d) to place a token:\n", width);
|
||||
scanf("%s", input);
|
||||
|
||||
// For quitting
|
||||
if (strcmp("quit", input) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Saving functionality
|
||||
if (strcmp("save", input) == 0) {
|
||||
printf("Input a filename:\n");
|
||||
scanf("%s", input);
|
||||
saveGame(input);
|
||||
printf("Game saved.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Loading functionality
|
||||
if (strcmp("load", input) == 0) {
|
||||
printf("Input a filename:\n");
|
||||
scanf("%s", input);
|
||||
if (loadGame(loadFile) == 0) {
|
||||
printf("\nInvalid file.\n");
|
||||
continue;
|
||||
} else {
|
||||
printBoard();
|
||||
printf("\nGame loaded.\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Checks to make sure input is valid
|
||||
if (atoi(input) < 1 || atoi(input) > width) {
|
||||
printf("Invalid input. Input another column:\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Checks to make sure input is valid
|
||||
if (placeChip(atoi(input) - 1, player) == 0) {
|
||||
printf("Invalid input. Input another column:\n");
|
||||
} else {
|
||||
if (player == 1) {
|
||||
player = 2;
|
||||
}
|
||||
else {
|
||||
player = 1;
|
||||
}
|
||||
printBoard();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include "file_utils.h"
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
* @see file_utils.h
|
||||
*
|
||||
* Implementation for file_utils.h. Contains functions
|
||||
* for reading from a file and putting it into a selected array
|
||||
* and for writing the array backwards into a selected file.
|
||||
*
|
||||
* This post taught me everything I now know about files in C:
|
||||
* http://stackoverflow.com/questions/22697407/reading-text-file-into-char-array
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Reads the .txt file passed as a parameter into the array (buffer)
|
||||
* pointed to as a parameter.
|
||||
*
|
||||
* @param filename, the name of the .txt file being read from.
|
||||
* @param buffer, a pointer to the array that will have the data read in.
|
||||
* @return 0 if the operation failed and the number of bytes if it succeeded.
|
||||
*/
|
||||
int read_file(char* filename, char **buffer) {
|
||||
// Variables. The stat struct is from Professor Woodring.
|
||||
FILE *fil;
|
||||
struct stat st;
|
||||
stat(filename, &st);
|
||||
int size = st.st_size;
|
||||
|
||||
// Opens up the file for extracting the data. If statement is for error-checking.
|
||||
fil = fopen(filename, "r");
|
||||
if (!fil) {
|
||||
fprintf(stderr, "Unable to read file.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Creates the space for our array. If statement is for error-checking.
|
||||
*buffer = malloc((size) * sizeof(char));
|
||||
if (!*buffer) {
|
||||
fprintf(stderr, "Unable to allocate memory.");
|
||||
fclose(fil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reads the data into our array. If statement is for error-checking, but it also contains the
|
||||
command that reads in the data. */
|
||||
if (fread(*buffer, size, 1, fil) != 1) {
|
||||
fprintf(stderr, "Error copying file to memory.");
|
||||
fclose(fil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Closes the file and returns the size of the array.
|
||||
fclose(fil);
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes to the filename passed as a parameter from the array (buffer)
|
||||
* passed as a parameter. The size of the array must be specified.
|
||||
*
|
||||
* @param filename, the name of the .txt file being written to.
|
||||
* @param buffer, the array that the data is being written from.
|
||||
* @param size, the size of the array. If read in properly by the read_file
|
||||
* function, this should have been returned.
|
||||
* @return 0 if the operation failed and 1 if it succeeded.
|
||||
*/
|
||||
int write_file(char* filename, char *buffer, int size) {
|
||||
// File being operated on.
|
||||
FILE *fil;
|
||||
|
||||
// Opens up the file for printing the data. If statement is for error-checking.
|
||||
fil = fopen(filename, "w");
|
||||
if (!fil) {
|
||||
fprintf(stderr, "Unable to write to that file.");
|
||||
fclose(fil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Iterates through the buffer passed and prints it backwards to a text file.
|
||||
If statement is for error-checking, but it also contains the command that writes the data. */
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (fprintf(fil, "%c", buffer[i]) != 1) {
|
||||
fprintf(stderr, "Error when writing to file.");
|
||||
fclose(fil);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Closes the file and returns 1.
|
||||
fclose(fil);
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef FILE_UTILS
|
||||
#define FILE_UTILS
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
*
|
||||
* Header file for file utilities for reading in a file to an array and then
|
||||
* writing that file backwards to another file.
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Reads the .txt file passed as a parameter into the array (buffer)
|
||||
* pointed to as a parameter.
|
||||
*
|
||||
* @param filename, the name of the .txt file being read from.
|
||||
* @param buffer, a pointer to the array that will have the data read in.
|
||||
* @return 0 if the operation failed and the number of bytes if it succeeded.
|
||||
*/
|
||||
int read_file(char* filename, char** buffer);
|
||||
|
||||
/*
|
||||
* Writes to the filename passed as a parameter from the array (buffer)
|
||||
* passed as a parameter. The size of the array must be specified.
|
||||
*
|
||||
* @param filename, the name of the .txt file being written to.
|
||||
* @param buffer, the array that the data is being written from.
|
||||
* @param size, the size of the array. If read in properly by the read_file
|
||||
* function, this should have been returned.
|
||||
* @return 0 if the operation failed and 1 if it succeeded.
|
||||
*/
|
||||
int write_file(char* filename, char* buffer, int size);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,396 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gamelogic.h"
|
||||
#include "file_utils.h"
|
||||
#include <string.h>
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
* @see gamelogic.h
|
||||
*
|
||||
* Implementation for the Connect Four game logic. Includes all of the functions
|
||||
* for operating the game and the variables for storing the game's state.
|
||||
*
|
||||
* This post taught me how to use colored text in Linux.
|
||||
* http://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Doubly array that will store the game board.
|
||||
*/
|
||||
char** gameBoard;
|
||||
|
||||
/*
|
||||
* Height of the game board.
|
||||
*/
|
||||
int height;
|
||||
|
||||
/*
|
||||
* Width of the game board.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/*
|
||||
* Length to win the game.
|
||||
*/
|
||||
int winLength;
|
||||
|
||||
/*
|
||||
* Sets the board height to the parameter passed.
|
||||
*
|
||||
* @param h, the board height to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setHeight(int h) {
|
||||
height = h;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the board width to the parameter passed.
|
||||
*
|
||||
* @param w, the board width to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setWidth(int w) {
|
||||
width = w;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the win length to the parameter passed.
|
||||
*
|
||||
* @param l, the win length to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setWinLength(int l) {
|
||||
winLength = l;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints the current state of the board to the terminal.
|
||||
*
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int printBoard() {
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
if (gameBoard[i][j] == 'o') {
|
||||
printf("\x1b[34m%c\x1b[0m", gameBoard[i][j]);
|
||||
} else if (gameBoard[i][j] == 'x') {
|
||||
printf("\x1b[31m%c\x1b[0m", gameBoard[i][j]);
|
||||
} else {
|
||||
printf("%c", gameBoard[i][j]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resets the board with the current board parameters.
|
||||
*
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int populateBoard() {
|
||||
gameBoard = malloc(sizeof(char*) * height);
|
||||
for (int i = 0; i < height; i++) {
|
||||
gameBoard[i] = malloc(sizeof(char) * width);
|
||||
}
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
gameBoard[i][j] = '*';
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Places a chip in the desired column. Designed to emulate
|
||||
* putting a chip into a column in the actual game of Connect
|
||||
* Four.
|
||||
*
|
||||
* @param col, the desired column.
|
||||
* @param p, the player placing the chip.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int placeChip(int col, int p) {
|
||||
// Handles bad arguments
|
||||
if (col > width - 1 || col < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Checks to make sure the move is valid and places if so
|
||||
for (int i = height - 1; i >= 0; i--) {
|
||||
if (i > 0 && (gameBoard[i][col] == 'o' || gameBoard[i][col] == 'x')) {
|
||||
continue;
|
||||
}
|
||||
else if (i == 0 && gameBoard[i][col] != '*') {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if (p == 1) {
|
||||
gameBoard[i][col] = 'o';
|
||||
}
|
||||
if (p == 2) {
|
||||
gameBoard[i][col] = 'x';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the current game. Puts the game's state into
|
||||
* a text file so that it can be loaded later on.
|
||||
*
|
||||
* @param filename, the name of the file to be saved to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int saveGame(char* filename) {
|
||||
// Variables and character array setup
|
||||
char* buffer;
|
||||
int count = 33;
|
||||
buffer = malloc((sizeof(char) * width * height) + (33 * sizeof(char)));
|
||||
char* widthVal = malloc(10 * sizeof(char));
|
||||
char* heightVal = malloc(10 * sizeof(char));
|
||||
char* winVal = malloc(10 * sizeof(char));
|
||||
|
||||
// Stores board parameter and win length as strings
|
||||
sprintf(widthVal, "%010d", width);
|
||||
sprintf(heightVal, "%010d", height);
|
||||
sprintf(winVal, "%010d", winLength);
|
||||
|
||||
/* Copies the board parameters and win length character
|
||||
by character to the buffer to be saved to memory */
|
||||
buffer[0] = widthVal[0];
|
||||
buffer[1] = widthVal[1];
|
||||
buffer[2] = widthVal[2];
|
||||
buffer[3] = widthVal[3];
|
||||
buffer[4] = widthVal[4];
|
||||
buffer[5] = widthVal[5];
|
||||
buffer[6] = widthVal[6];
|
||||
buffer[7] = widthVal[7];
|
||||
buffer[8] = widthVal[8];
|
||||
buffer[9] = widthVal[9];
|
||||
buffer[10] = '\n';
|
||||
buffer[11] = heightVal[0];
|
||||
buffer[12] = heightVal[1];
|
||||
buffer[13] = heightVal[2];
|
||||
buffer[14] = heightVal[3];
|
||||
buffer[15] = heightVal[4];
|
||||
buffer[16] = heightVal[5];
|
||||
buffer[17] = heightVal[6];
|
||||
buffer[18] = heightVal[7];
|
||||
buffer[19] = heightVal[8];
|
||||
buffer[20] = heightVal[9];
|
||||
buffer[21] = '\n';
|
||||
buffer[22] = winVal[0];
|
||||
buffer[23] = winVal[1];
|
||||
buffer[24] = winVal[2];
|
||||
buffer[25] = winVal[3];
|
||||
buffer[26] = winVal[4];
|
||||
buffer[27] = winVal[5];
|
||||
buffer[28] = winVal[6];
|
||||
buffer[29] = winVal[7];
|
||||
buffer[30] = winVal[8];
|
||||
buffer[31] = winVal[9];
|
||||
buffer[32] = '\n';
|
||||
|
||||
// Saves the state of the board to the buffer
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
buffer[count] = gameBoard[i][j];
|
||||
count++;
|
||||
}
|
||||
if (count >(width * height + 32)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
// Writes the buffer into memory.
|
||||
write_file(filename, buffer, (sizeof(char) * width * height) + (33 * sizeof(char)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a previous game. Reloads a previous game's
|
||||
* state from a text file so that a past game can be
|
||||
* continued.
|
||||
*
|
||||
* @param filename, the name of the file to be loaded from.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int loadGame(char* filename) {
|
||||
// Variables
|
||||
char* buffer;
|
||||
int count = 33;
|
||||
char* sub;
|
||||
|
||||
// Reads in the previous game to memory
|
||||
if (read_file(filename, &buffer) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copies the board and victory data
|
||||
sub = malloc(10 * sizeof(char));
|
||||
strncpy(sub, buffer, 10);
|
||||
setWidth(atoi(sub));
|
||||
strncpy(sub, buffer + 11, 10);
|
||||
setHeight(atoi(sub));
|
||||
strncpy(sub, buffer + 22, 10);
|
||||
setWinLength(atoi(sub));
|
||||
|
||||
// Resets board with new board parameters
|
||||
populateBoard();
|
||||
|
||||
// Copies past game's state to board.
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
gameBoard[i][j] = buffer[count];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the current state of the board is a victory
|
||||
* for the player token passed as a parameter.
|
||||
*
|
||||
* @param p, the player token being checked for.
|
||||
* @return 0 if the player passed has not won, and 1 if the
|
||||
* player passed has won.
|
||||
*/
|
||||
int checkWin(char p) {
|
||||
// Variables for the diagonal check algorithm
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
// Handles 1 by 1 boards
|
||||
if (height == 1 && width == 1 && winLength == 1 ) {
|
||||
if (gameBoard[0][0] == p) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checks horizontally
|
||||
int count = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
if (gameBoard[i][j] == p) {
|
||||
count++;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
if (count == winLength) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
}
|
||||
|
||||
// Checks vertically
|
||||
count = 0;
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
if (gameBoard[j][i] == p) {
|
||||
count++;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
if (count == winLength) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
}
|
||||
|
||||
// Checks negative slope diagonal
|
||||
count = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
row = i;
|
||||
col = j;
|
||||
count = 0;
|
||||
while (row < height && col < width) {
|
||||
if (gameBoard[row][col] == p) {
|
||||
count++;
|
||||
row++;
|
||||
col++;
|
||||
} else {
|
||||
row++;
|
||||
col++;
|
||||
count = 0;
|
||||
}
|
||||
if (count == winLength) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks positive slope diagonal
|
||||
count = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
row = i;
|
||||
col = j;
|
||||
count = 0;
|
||||
while (row >= 0 && col < width) {
|
||||
if (gameBoard[row][col] == p) {
|
||||
count++;
|
||||
row--;
|
||||
col++;
|
||||
} else {
|
||||
row--;
|
||||
col++;
|
||||
count = 0;
|
||||
}
|
||||
if (count == winLength) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modifies the position passed on the board to whatever
|
||||
* character is passed. Mostly used for testing.
|
||||
*
|
||||
* @param row, the row of the position.
|
||||
* @param col, the column of the position.
|
||||
* @param c, the character that the position will be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int modifyPostition(int row, int col, char c) {
|
||||
gameBoard[row][col] = c;
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
#ifndef GAME_LOGIC
|
||||
#define GAME_LOGIC
|
||||
|
||||
/************************************************************************************
|
||||
* @author Jacob McCloughan
|
||||
* @version 3/03/2017
|
||||
*
|
||||
* Header file for the Connect Four game logic.
|
||||
*************************************************************************************/
|
||||
|
||||
/*
|
||||
* Doubly array that will store the game board.
|
||||
*/
|
||||
char** gameBoard;
|
||||
|
||||
/*
|
||||
* Height of the game board.
|
||||
*/
|
||||
int height;
|
||||
|
||||
/*
|
||||
* Width of the game board.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/*
|
||||
* Length to win the game.
|
||||
*/
|
||||
int winLength;
|
||||
|
||||
/*
|
||||
* Sets the board height to the parameter passed.
|
||||
*
|
||||
* @param h, the board height to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setHeight(int h);
|
||||
|
||||
/*
|
||||
* Sets the board width to the parameter passed.
|
||||
*
|
||||
* @param w, the board width to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setWidth(int w);
|
||||
|
||||
/*
|
||||
* Sets the win length to the parameter passed.
|
||||
*
|
||||
* @param l, the win length to be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int setWinLength(int l);
|
||||
|
||||
/*
|
||||
* Prints the current state of the board to the terminal.
|
||||
*
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int printBoard();
|
||||
|
||||
/*
|
||||
* Resets the board with the current board parameters.
|
||||
*
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int populateBoard();
|
||||
|
||||
/*
|
||||
* Places a chip in the desired column. Designed to emulate
|
||||
* putting a chip into a column in the actual game of Connect
|
||||
* Four.
|
||||
*
|
||||
* @param col, the desired column.
|
||||
* @param p, the player placing the chip.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int placeChip(int col, int p);
|
||||
|
||||
/*
|
||||
* Saves the current game. Puts the game's state into
|
||||
* a text file so that it can be loaded later on.
|
||||
*
|
||||
* @param filename, the name of the file to be saved to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int saveGame(char* filename);
|
||||
|
||||
/*
|
||||
* Loads a previous game. Reloads a previous game's
|
||||
* state from a text file so that a past game can be
|
||||
* continued.
|
||||
*
|
||||
* @param filename, the name of the file to be loaded from.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int loadGame(char* filename);
|
||||
|
||||
/*
|
||||
* Checks if the current state of the board is a victory
|
||||
* for the player token passed as a parameter.
|
||||
*
|
||||
* @param p, the player token being checked for.
|
||||
* @return 0 if the player passed has not won, and 1 if the
|
||||
* player passed has won.
|
||||
*/
|
||||
int checkWin(char p);
|
||||
|
||||
/*
|
||||
* Modifies the position passed on the board to whatever
|
||||
* character is passed. Mostly used for testing.
|
||||
*
|
||||
* @param row, the row of the position.
|
||||
* @param col, the column of the position.
|
||||
* @param c, the character that the position will be set to.
|
||||
* @return 0 if the operation failed, and 1 if the operation
|
||||
* succeeded.
|
||||
*/
|
||||
int modifyPostition(int row, int col, char c);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue