In: Computer Science
The following is a C program that is a video game version of Connect 4. The code works fine as is now but I want to change the way you input which column you drop a disk into. Currently, you type in 1 and it goes into column 1. If you type in 6, it goes into column 6 and so on. But I want to make it so you input A or a, then it goes into column 1 and if you input G or g then it goes into column 7. (A-G instead of 1-7 for the columns) Additionally I want to make it so if you press Q or q the game quits and exits. I want to implement this in the whoseTurnIsNext function. Help would be appreciated.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BOARD_ROWS 6
#define BOARD_COLS 7
void displayWorld(char *board);
int whoseTurnIsNext(char *board, int player, const char*);
int checkWin(char *board);
int checkFour(char *board, int, int, int, int);
int horizontalCheck(char *board);
int verticalCheck(char *board);
int diagonalCheck(char *board);
int main(int argc, char *argv[]){
const char *PIECES = "XO";
char board[BOARD_ROWS * BOARD_COLS];
memset(board, ' ', BOARD_ROWS * BOARD_COLS);
int turn, done = 0;
for(turn = 0; turn < BOARD_ROWS * BOARD_COLS &&
!done; turn++){
displayWorld(board);
while(!whoseTurnIsNext(board, turn % 2, PIECES)){
displayWorld(board);
puts("**Column full!**\n");
}
done = checkWin(board);
}
displayWorld(board);
if(turn == BOARD_ROWS * BOARD_COLS && !done){
puts("It's a tie!");
} else {
turn--;
printf("Player %d (%c) wins!\n", turn % 2 + 1, PIECES[turn %
2]);
}
return 0;
}
void displayWorld(char *board){
int row, col;
//system("clear");
puts("\n ****Connect Four****\n");
for(row = 0; row < BOARD_ROWS; row++){
for(col = 0; col < BOARD_COLS; col++){
printf("| %c ", board[BOARD_COLS * row + col]);
}
puts("|");
puts("-----------------------------");
}
puts(" 1 2 3 4 5 6 7\n");
}
int whoseTurnIsNext(char *board, int player, const char
*PIECES){
int row, col = 0;
printf("Player %d (%c):\nEnter number coordinate: ", player + 1,
PIECES[player]);
while(1){
if(1 != scanf("%d", &col) || col < 1 || col > 7 ){
while(getchar() != '\n');
puts("Number out of bounds! Try again.");
} else {
break;
}
}
col--;
for(row = BOARD_ROWS - 1; row >= 0; row--){
if(board[BOARD_COLS * row + col] == ' '){
board[BOARD_COLS * row + col] = PIECES[player];
return 1;
}
}
return 0;
}
int checkWin(char *board){
return (horizontalCheck(board) || verticalCheck(board) ||
diagonalCheck(board));
}
int checkFour(char *board, int a, int b, int c, int d){
return (board[a] == board[b] && board[b] == board[c]
&& board[c] == board[d] && board[a] != ' ');
}
int horizontalCheck(char *board){
int row, col, idx;
const int WIDTH = 1;
for(row = 0; row < BOARD_ROWS; row++){
for(col = 0; col < BOARD_COLS - 3; col++){
idx = BOARD_COLS * row + col;
if(checkFour(board, idx, idx + WIDTH, idx + WIDTH * 2, idx + WIDTH
* 3)){
return 1;
}
}
}
return 0;
}
int verticalCheck(char *board){
int row, col, idx;
const int HEIGHT = 7;
for(row = 0; row < BOARD_ROWS - 3; row++){
for(col = 0; col < BOARD_COLS; col++){
idx = BOARD_COLS * row + col;
if(checkFour(board, idx, idx + HEIGHT, idx + HEIGHT * 2, idx +
HEIGHT * 3)){
return 1;
}
}
}
return 0;
}
int diagonalCheck(char *board){
int row, col, idx, count = 0;
const int DIAG_RGT = 6, DIAG_LFT = 8;
for(row = 0; row < BOARD_ROWS - 3; row++){
for(col = 0; col < BOARD_COLS; col++){
idx = BOARD_COLS * row + col;
if(count <= 3 && checkFour(board, idx, idx + DIAG_LFT,
idx + DIAG_LFT * 2, idx + DIAG_LFT * 3) || count >= 3 &&
checkFour(board, idx, idx + DIAG_RGT, idx + DIAG_RGT * 2, idx +
DIAG_RGT * 3)){
return 1;
}
count++;
}
count = 0;
}
return 0;
}
I have made changes in the code from line 27 to 36 (main function) and from line 74 to 114 (whoseTurnIsNext function). And also added #include <ctype.h>
C code screenshot:
C code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define BOARD_ROWS 6
#define BOARD_COLS 7
void displayWorld(char *board);
int whoseTurnIsNext(char *board, int player, const char *);
int checkWin(char *board);
int checkFour(char *board, int, int, int, int);
int horizontalCheck(char *board);
int verticalCheck(char *board);
int diagonalCheck(char *board);
int main(int argc, char *argv[])
{
const char *PIECES = "XO";
char board[BOARD_ROWS * BOARD_COLS];
memset(board, ' ', BOARD_ROWS * BOARD_COLS);
int turn, done = 0, turnNext;
for (turn = 0; turn < BOARD_ROWS * BOARD_COLS && !done; turn++)
{
displayWorld(board);
turnNext = whoseTurnIsNext(board, turn % 2, PIECES);
// If user enters q then the value should be -1
if (turnNext == -1)
{
// exit the program
printf("Quitting the game...\n");
return 0;
}
while (!turnNext)
{
displayWorld(board);
puts("**Column full!**\n");
}
done = checkWin(board);
}
displayWorld(board);
if (turn == BOARD_ROWS * BOARD_COLS && !done)
{
puts("It's a tie!");
}
else
{
turn--;
printf("Player %d (%c) wins!\n", turn % 2 + 1, PIECES[turn % 2]);
}
return 0;
}
void displayWorld(char *board)
{
int row, col;
//system("clear");
puts("\n ****Connect Four****\n");
for (row = 0; row < BOARD_ROWS; row++)
{
for (col = 0; col < BOARD_COLS; col++)
{
printf("| %c ", board[BOARD_COLS * row + col]);
}
puts("|");
puts("-----------------------------");
}
puts(" 1 2 3 4 5 6 7\n");
}
int whoseTurnIsNext(char *board, int player, const char *PIECES)
{
char ch;
int row, col = 0;
again:
printf("Player %d (%c):\nEnter letter coordinate (A-G): ", player + 1, PIECES[player]);
while (1)
{
// get a letter from user and if the letter is Q or present in A to G then break the loop
// toupper function changes the letter from lower alphabet to upper alphabet
if (scanf("%c", &ch) == 1 && (toupper(ch) == 'Q' || (toupper(ch) >= 'A' && toupper(ch) <= 'G')))
{
// Removing extra characters after user's first character input
while (getchar() != '\n')
;
break;
}
else
{
// Removing extra characters after user's first character input
while (getchar() != '\n')
;
puts("Letter out of bounds! Try again.");
}
}
// If user input is Q then return to main function with -1
if (toupper(ch) == 'Q')
return -1;
col = (int)(toupper(ch) - 'A');
for (row = BOARD_ROWS - 1; row >= 0; row--)
{
if (board[BOARD_COLS * row + col] == ' ')
{
board[BOARD_COLS * row + col] = PIECES[player];
return 1;
}
}
if (row == -1)
{
printf("\nSelected board coordinate is already full ! Please select different coordinate !\n");
goto again;
}
return 0;
}
int checkWin(char *board)
{
return (horizontalCheck(board) || verticalCheck(board) || diagonalCheck(board));
}
int checkFour(char *board, int a, int b, int c, int d)
{
return (board[a] == board[b] && board[b] == board[c] && board[c] == board[d] && board[a] != ' ');
}
int horizontalCheck(char *board)
{
int row, col, idx;
const int WIDTH = 1;
for (row = 0; row < BOARD_ROWS; row++)
{
for (col = 0; col < BOARD_COLS - 3; col++)
{
idx = BOARD_COLS * row + col;
if (checkFour(board, idx, idx + WIDTH, idx + WIDTH * 2, idx + WIDTH * 3))
{
return 1;
}
}
}
return 0;
}
int verticalCheck(char *board)
{
int row, col, idx;
const int HEIGHT = 7;
for (row = 0; row < BOARD_ROWS - 3; row++)
{
for (col = 0; col < BOARD_COLS; col++)
{
idx = BOARD_COLS * row + col;
if (checkFour(board, idx, idx + HEIGHT, idx + HEIGHT * 2, idx + HEIGHT * 3))
{
return 1;
}
}
}
return 0;
}
int diagonalCheck(char *board)
{
int row, col, idx, count = 0;
const int DIAG_RGT = 6, DIAG_LFT = 8;
for (row = 0; row < BOARD_ROWS - 3; row++)
{
for (col = 0; col < BOARD_COLS; col++)
{
idx = BOARD_COLS * row + col;
if (count <= 3 && checkFour(board, idx, idx + DIAG_LFT, idx + DIAG_LFT * 2, idx + DIAG_LFT * 3) || count >= 3 && checkFour(board, idx, idx + DIAG_RGT, idx + DIAG_RGT * 2, idx + DIAG_RGT * 3))
{
return 1;
}
count++;
}
count = 0;
}
return 0;
}
Output 1:
Output 2: