I'm currently writing a tic-tac-toe program using C for my CS class and I keep running into errors when running that stop me from placing my move in the positions [2,3],[3,1],[3,2],[3,3], essentially only letting me place moves on the top row, and the left two columns of the second row. I'm assuming it has something to do with my check_legal_option function but I can't figure out what the problem is. Any help would be appreciated
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stdbool.h>
void clear_table(char table[3][3]);
void generate_player2_move(char table[3][3],int *row,int *col);
int check_table_full(char table[3][3]);
int check_three_in_a_row(char table[3][3]);
void display_table(char table[3][3]);
int check_legal_option(char table[3][3],int moveRow,int moveCol);
void update_table(char table[3][3],int pRow,int pCol);
int main(void){
char emptyTable[3][3];
int row,col,cpuRow,cpuCol,full,three,legal;
printf("This program plays the game of tic-tac-toe\n");
clear_table(emptyTable);
printf("\n");
full = check_table_full(emptyTable);
three = check_three_in_a_row(emptyTable);
while(three == 0 && full == 0){
display_table(emptyTable);
printf("Player 1 enter your selection [row,col]: ");
scanf("%d,%d",&row,&col);
legal=check_legal_option(emptyTable,row,col);
printf("%d",legal);
while(legal!=1){
printf("Player 1 enter your selection [row,col]: ");
scanf("%d,%d",&row,&col);
legal=check_legal_option(emptyTable,row,col);
}
update_table(emptyTable,row-1,col-1);
generate_player2_move(emptyTable,&cpuRow,&cpuCol);
full = check_table_full(emptyTable);
three = check_three_in_a_row(emptyTable);
}
if(three == 1){
printf("Congratulations, Player 1 wins!\n");
}
else if(three == 2){
printf("Congratulations, Computer wins!\n");
}
else{
printf("Game over, no player wins.\n");
}
}
void clear_table(char table[3][3]){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
table[i][j] = '_';
}
}
}
void generate_player2_move(char table[3][3],int *row,int *col){
srand (time(NULL));
do{
*row = rand()%3;
*col = rand()%3;
int legal = check_legal_option(table,*row,*col);
}while(!check_legal_option(table,*row,*col));
table[*row][*col] = 'O';
}
int check_table_full(char table[3][3]){
if(table[0][0] == table[0][1] && table[0][1] == table[0][2] && table[0][2] == table[1][0] && table[1][0] == table[1][1] && table[1][1] == table[1][2] && table[1][2]
== table[2][0] && table[2][0] == table[2][1] && table[2][1] == table[2][2] && table[0][0] != '_' && check_three_in_a_row(table) == 0){
return 3;
}
return 0;
}
int check_three_in_a_row(char table[3][3]){
for(int i=0;i<3;i++){
if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && table[i][0] == 'X'){
return 1;
}
if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && table[i][0] == 'O'){
return 2;
}
}
for(int j=0;j<3;j++){
//checks if player 1 or CPU gets vertical win
if(table[0][j] == table[1][j] && table[1][j] == table[2][j] &&
table[0][j] == 'X'){
return 1;
}
if(table[0][j] == table[1][j] && table[1][j] == table[2][j] && table[0][j] == 'O'){
return 2;
}
}
//checks if player 1 or CPU gets diagonal win one way
if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && table[0][0] == 'X'){
return 1;
}
if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && table[0][0] == 'O'){
return 2;
}
//checks if player 1 or CPU gets diagonal win another way
if(table[0][2] == table[1][1] && table[1][1] == table[2][0] && table[0][2] == 'X'){
return 1;
}
if(table[0][2] == table[1][1] && table[1][1] == table[2][0] && table[0][2] == 'O'){
return 2;
}
//if no one has three in a row, return 0
return 0;
}
void display_table(char table[3][3]){
printf("The current state of the game is:");
for(int i=0;i<3;i++){
printf("\n");
for(int j=0;j<3;j++){
printf("%c ",table[i][j]);
}
}
printf("\n");
}
int check_legal_option(char table[3][3],int moveRow,int moveCol){
if(table[moveCol][moveCol]=='_'){
return 1;
}
return 0;
}
void update_table(char table[3][3],int pRow,int pCol){
table[pRow][pCol] = 'X';
}
The check_legal function uses movecol in both the columns and rows.
Related
What I'm trying to do here is a tie toe game, but when my code enters the do - while part, it ends the process by itself. Since I could not solve this part, I did not have a chance to try whether there are other problems with the code, unfortunately, I would be glad if you could help with this issue.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player {
bool turn;
char mark;
int ID;
};
int main()
{
int return_result;
int player_number;
struct Player player1;
struct Player player2;
struct Player users[2];
users[0] = player1;
users[1] = player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
for (int i = 0; i < 2; i++) {
if (users[i].turn == true)
{
make_move(users[i].ID);
box_creat();
users[i].turn = false;
users[i + 1].turn = true; \\ I made the logic of this section wrong
\\I will try to fix it, I realized after I sent the question
}
}
return_result = check_the_winner();
} while (return_result == 1 || return_result == -1);
return 0;
}
void box_creat(void) {
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
}
void make_move(int Player_ID)
{
int choice;
printf("Please select a area between 0-9 ");
scanf("%d", choice);
if (choice == '0' && box_area[0] == '0')
{
if (Player_ID == 1) {
box_area[0] = 'X';
}
else {
box_area[0] = 'O';
}
}
else if (choice == '1' && box_area[1] == '1')
{
if (Player_ID == 1) {
box_area[1] = 'X';
}
else {
box_area[1] = 'O';
}
}
else if (choice == '2' && box_area[2] == '2')
{
if (Player_ID == 1) {
box_area[2] = 'X';
}
else {
box_area[2] = 'O';
}
}
else if (choice == '3' && box_area[3] == '0')
{
if (Player_ID == 1) {
box_area[3] = 'X';
}
else {
box_area[3] = 'O';
}
}
else if (choice == '4' && box_area[4] == '0')
{
if (Player_ID == 1) {
box_area[4] = 'X';
}
else {
box_area[4] = 'O';
}
}
else if (choice == '5' && box_area[5] == '0')
{
if (Player_ID == 1) {
box_area[5] = 'X';
}
else {
box_area[5] = 'O';
}
}
else if (choice == '6' && box_area[6] == '0')
{
if (Player_ID == 1) {
box_area[6] = 'X';
}
else {
box_area[6] = 'O';
}
}
else if (choice == '7' && box_area[7] == '0')
{
if (Player_ID == 1) {
box_area[7] = 'X';
}
else {
box_area[7] = 'O';
}
}
else if (choice == '8' && box_area[8] == '0')
{
if (Player_ID == 1) {
box_area[8] = 'X';
}
else {
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if (box_area[0] && box_area[1] && box_area[2] == 'X' || 'O') {
return 1;
}
else if(box_area[3] && box_area[4] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[6] && box_area[7] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[4] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[3] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[8] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[4] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[1] && box_area[4] && box_area[7] == 'X' || 'O') {
return 1;
}
else {
return -1;
}
}
I tried out your program and found a few glitches that needed revision as well as adding in some additional bits of code just to neaten things up a bit. Following is your code with those revisions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player
{
bool turn;
char mark;
int ID;
};
void box_creat(void)
{
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
printf("\n"); /* Added for aesthetics */
}
void make_move(int Player_ID)
{
int choice;
printf("Player %d - please select a area between 0-9 ", Player_ID);
scanf("%d", &choice); /* Corrected missing ampersand */
printf("Player: %d makes a move\n", Player_ID);
if (choice == 0 && box_area[0] == '0') /* FYI - '0' is equivalent to integer value 48 */
{
if (Player_ID == 1)
{
box_area[0] = 'X';
}
else
{
box_area[0] = 'O';
}
}
else if (choice == 1 && box_area[1] == '1')
{
if (Player_ID == 1)
{
box_area[1] = 'X';
}
else
{
box_area[1] = 'O';
}
}
else if (choice == 2 && box_area[2] == '2')
{
if (Player_ID == 1)
{
box_area[2] = 'X';
}
else
{
box_area[2] = 'O';
}
}
else if (choice == 3 && box_area[3] == '3')
{
if (Player_ID == 1)
{
box_area[3] = 'X';
}
else
{
box_area[3] = 'O';
}
}
else if (choice == 4 && box_area[4] == '4')
{
if (Player_ID == 1)
{
box_area[4] = 'X';
}
else
{
box_area[4] = 'O';
}
}
else if (choice == 5 && box_area[5] == '5')
{
if (Player_ID == 1)
{
box_area[5] = 'X';
}
else
{
box_area[5] = 'O';
}
}
else if (choice == 6 && box_area[6] == '6')
{
if (Player_ID == 1)
{
box_area[6] = 'X';
}
else
{
box_area[6] = 'O';
}
}
else if (choice == 7 && box_area[7] == '7')
{
if (Player_ID == 1)
{
box_area[7] = 'X';
}
else
{
box_area[7] = 'O';
}
}
else if (choice == 8 && box_area[8] == '8')
{
if (Player_ID == 1)
{
box_area[8] = 'X';
}
else
{
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if ((box_area[0] == box_area[1]) && (box_area[1] == box_area[2]) && (box_area[0] != '0')) /* Corrected the testing for proper "and" conditioning */
{
return 1;
}
else if ((box_area[3] == box_area[4]) && (box_area[4] == box_area[5]) && (box_area[3] != '3'))
{
return 1;
}
else if ((box_area[6] == box_area[7]) && (box_area[7] == box_area[8]) && (box_area[6] != '6'))
{
return 1;
}
else if ((box_area[2] == box_area[4]) && (box_area[4] == box_area[6]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[3]) && (box_area[3] == box_area[6]) && (box_area[0] != '0'))
{
return 1;
}
else if ((box_area[2] == box_area[5]) && (box_area[5] == box_area[8]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[4]) && (box_area[4] == box_area[8]) && (box_area[4] != '4'))
{
return 1;
}
else if ((box_area[1] == box_area[4]) && (box_area[4] == box_area[7]) && (box_area[1] != '1'))
{
return 1;
}
else
{
return -1;
}
}
int main()
{
int return_result;
//int player_number; /* Compiler said that this wasn't being used */
int swap = 1;
int i;
struct Player player1;
struct Player player2;
struct Player *users[2]; /* Used these as address pointers to player "1" and player "2" */
users[0] = &player1; /* Before making these pointers, the users array just contained copies of the player structures */
users[1] = &player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
swap += 1;
i = swap % 2;
if (i == 1)
{
make_move(users[1]->ID);
//box_creat(); /* Being performed at the top of the loop */
users[0]->turn = false;
users[1]->turn = true;
}
else
{
make_move(users[0]->ID);
//box_creat();
users[1]->turn = false;
users[0]->turn = true;
}
return_result = check_the_winner();
if (check_the_winner() == 1) /* Added when a winner has been sensed */
{
box_creat();
if (i == 1)
{
printf("Player 2 won!\n");
}
else
{
printf("Player 1 won!\n");
}
}
}
while (return_result != 1);
return 0;
}
I added comments to most of the places I had tweaked, but here are the highlights:
I shuffled some of the functions around so that the "main" function followed all of the helper functions (the compiler was giving warnings about the original sequence of the function positions).
I corrected the "choice" tests as "choice" is an integer, so the test of "choice" needed to be compared to an integer value (e.g. zero) as opposed to character '0' (which actually has a value of 48).
The tests for three letters in a row for either player do not work in that manner. Either a test needed to be made for each box for a certain row needed to tested for an "X" or an "O", and then if that test was true the test needed to be continued for the next box in the row, and then again for the third box in the row. In lieu of that route, the test was revised to basically say "if the character in the first box in the row is the same as the character in the second box in the row, and the character in the second box in the row is the same as the character in the third box in the row, and the first box does not contain a digit character (which means is contains an "X" or an "O"), then there is a winner.
It appears that an attempt was made to mirror the contents of "Player1" and "Player2" into an array of player structures. Although initially, structure "users[0]" contained the same data as "Player1" and structure "users[1]" contained the same data as "Player2", once the data in "Player1" and "Player2" were updated, those changes did to propagate over to the "users" array. So to utilize "users" in the spirit of this program, they were defined as pointers to their respective player structures.
Those were the most significant bits. The other bits were added for a logical conclusion of the game. Note that no logic was added for a draw.
Give that a test and see if that clarifies things and follows the spirit of the project.
I've been working on a battleship program in C for a class and I am having trouble with my print_node function returning the values from my head node (currentState, ship_type, charInput etc.). Each time I run it, it compiles however it always outputs "0". I'm hoping a second set of eyes could help me figure this out. Thank you, and forgive me for the messy code.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#define SIZE 10
typedef struct Node{
char currentState;
char ship_type[20];
char charInput;
int intInput;
struct Node* next;
}Node;
char** initialization(){
int i, j, k, row, col;
char **board = (char**)malloc(sizeof(char*)*SIZE);
for (i = 0; i < SIZE; i++){
board[i] = (char*)malloc(sizeof(char)*SIZE);
}
for(i = 0; i < SIZE; i++){
for(j = 0; j < SIZE; j++){
board[i][j] = '-';
}
}
//place the first ship
//the direction of placement is hard coded
//you can change it if you want
bool placed1 = false;
while(placed1 == false){
row = rand()%10;
col = rand()%10;
if(row+1 < 10 && row-1 >= 0){
if((board[row][col] = '-') &&
(board[row+1][col] = '-')){
board[row][col] = 'D';
board[row+1][col] = 'D';
placed1 = true;
}
else if((board[row][col] == '-') &&
(board[row-1][col] == '-')){
board[row][col] = 'D';
board[row-1][col] = 'D';
placed1 = true;
}
}
}
//place the second ship
bool placed2 = false;
while (placed2 == false){
row = rand()%10;
col = rand()%10;
if((row+1 < 10 && row+2 < 10) &&
(row-1 >= 0 && row-2 >= 0) &&
(col+1 < 10 && col+2 < 10) &&
(col-1 >= 0 && col-2 >= 0)){
if((board[row][col] == '-') &&
(board[row][col+1] == '-') &&
(board[row][col+2] == '-')){
board[row][col] = 'C';
board[row][col+1] = 'C';
board[row][col+2] = 'C';
placed2 = true;
}
else if((board[row][col] == '-') &&
(board[row][col-1] == '-') &&
(board[row][col-2] == '-')){
board[row][col] = 'C';
board[row][col-1] = 'C';
board[row][col-2] = 'C';
placed2 = true;
}
else if((board[row][col] == '-') &&
(board[row+1][col] == '-') &&
(board[row+2][col] == '-')){
board[row][col] = 'C';
board[row+1][col] = 'C';
board[row+2][col] = 'C';
placed2 = true;
}
else if((board[row][col] == '-') &&
(board[row-1][col] == '-') &&
(board[row-2][col] == '-')){
board[row][col] = 'C';
board[row-1][col] = 'C';
board[row-2][col] = 'C';
placed2 = true;
}
}
}
//place the third ship
bool placed3 = false;
while (placed3 == false){
row = rand()%10;
col = rand()%10;
if((row+1 < 10 && row+2 < 10) &&
(row-1 >= 0 && row-2 >= 0) &&
(col+1 < 10 && col+2 < 10) &&
(col-1 >= 0 && col-2 >= 0)){
if((board[row][col] == '-') &&
(board[row][col+1] == '-') &&
(board[row][col+2] == '-')){
board[row][col] = 'S';
board[row][col+1] = 'S';
board[row][col+2] = 'S';
placed3 = true;
}
else if((board[row][col] == '-') &&
(board[row][col-1] == '-') &&
(board[row][col-2] == '-')){
board[row][col] = 'S';
board[row][col-1] = 'S';
board[row][col-2] = 'S';
placed3 = true;
}
else if((board[row][col] =='-') &&
(board[row+1][col] == '-') &&
(board[row+2][col] == '-')){
board[row][col] = 'S';
board[row+1][col] = 'S';
board[row+2][col] = 'S';
placed3 = true;
}
else if((board[row][col] == '-') &&
(board[row-1][col] == '-') &&
(board[row-2][col] == '-')){
board[row][col] = 'S';
board[row-1][col] = 'S';
board[row-2][col] = 'S';
placed3 = true;
}
}
}
bool placed4 = false;
while (placed4 == false){
row = rand()%10;
col = rand()%10;
if((row+1 < 10 && row+2 < 10 && row+3 < 10) &&
(row-1 >= 0 && row-2 >= 0 && row-3 >= 0) &&
(col+1 < 10 && col+2 < 10 && col+3 < 10) &&
(col-1 >= 0 && col-2 >= 0 && col-3 >= 0)){
if((board[row][col] == '-') &&
(board[row+1][col] == '-') &&
(board[row+2][col] == '-') &&
(board[row+3][col] == '-')){
board[row][col] = 'B';
board[row+1][col] = 'B';
board[row+2][col] = 'B';
board[row+3][col] = 'B';
placed4 = true;
}
else if((board[row][col] == '-') &&
(board[row-1][col] == '-') &&
(board[row-2][col] == '-') &&
(board[row-3][col] == '-')){
board[row][col] = 'B';
board[row-1][col] = 'B';
board[row-2][col] = 'B';
board[row-3][col] = 'B';
placed4 = true;
}
else if((board[row][col] == '-') &&
(board[row][col+1] == '-') &&
(board[row][col+2] == '-') &&
(board[row][col+3] == '-')){
board[row][col] = 'B';
board[row][col+1] = 'B';
board[row][col+2] = 'B';
board[row][col+3] = 'B';
placed4 = true;
}
else if((board[row][col] == '-') &&
(board[row][col-1] == '-') &&
(board[row][col-2] == '-') &&
(board[row][col-3] == '-')){
board[row][col] = 'B';
board[row][col-1] = 'B';
board[row][col-2] = 'B';
board[row][col-3] = 'B';
placed4 = true;
}
}
}
bool placed5 = false;
while (placed5 == false){
row = rand()%10;
col = rand()%10;
if((row+1 < 10 && row+2 < 10 && row+3 < 10 && row+4 < 10) &&
(row-1 >= 0 && row-2 >= 0 && row-3 >= 0 && row-4 >= 0) &&
(col+1 < 10 && col+2 < 10 && col+3 < 10 && col+4 < 10) &&
(col-1 >= 0 && col-2 >= 0 && col-3 >= 0 && col-4 >= 0)){
if((board[row][col] == '-') &&
(board[row+1][col] == '-') &&
(board[row+2][col] == '-') &&
(board[row+3][col] == '-') &&
(board[row+4][col] == '-')){
board[row][col] = 'R';
board[row+1][col] = 'R';
board[row+2][col] = 'R';
board[row+3][col] = 'R';
board[row+4][col] = 'R';
placed5 = true;
}
else if((board[row][col] == '-') &&
(board[row-1][col] == '-') &&
(board[row-2][col] == '-') &&
(board[row-3][col] == '-') &&
(board[row-4][col] == '-')){
board[row][col] = 'R';
board[row-1][col] = 'R';
board[row-2][col] = 'R';
board[row-3][col] = 'R';
board[row-4][col] = 'R';
placed5 = true;
}
else if((board[row][col] == '-') &&
(board[row][col+1] == '-') &&
(board[row][col+2] == '-') &&
(board[row][col+3] == '-') &&
(board[row][col+4] == '-')){
board[row][col] = 'R';
board[row][col+1] = 'R';
board[row][col+2] = 'R';
board[row][col+3] = 'R';
board[row][col+4] = 'R';
placed5 = true;
}
else if((board[row][col] == '-') &&
(board[row][col-1] == '-') &&
(board[row][col-2] == '-') &&
(board[row][col-3] == '-') &&
(board[row][col-4] == '-')){
board[row][col] = 'R';
board[row][col-1] = 'R';
board[row][col-2] = 'R';
board[row][col-3] = 'R';
board[row][col-4] = 'R';
placed5 = true;
}
}
}
return board;
}
void update_state(char* state, char ** board, char character, int col){
int row;
char shipType[20];
row = character % 65;
if(board[row][col] == '-'){
strcpy(state, "MISS");
}
else{
strcpy(state, "HIT!");
/* add code to change the board to indicate
* that shot hit , for example you could change
* the corresponding letter back to '-'.
* but before this, you need to record the letter
* and corresponding ship type.
*/ //COMPLETED
char shipChar = board[row][col];
if(shipChar == 'R'){
strcpy(shipType,"Carrier");
printf("%s", shipType);
}
else if(shipChar == 'B'){
strcpy(shipType,"Battleship");
printf("%s", shipType);
}
else if(shipChar == 'S'){
strcpy(shipType,"Submarine");
printf("%s", shipType);
}
else if(shipChar == 'C'){
strcpy(shipType,"Cruiser");
printf("%s", shipType);
}
else if(shipChar == 'D'){
strcpy(shipType,"Destroyer");
printf("%s", shipType);
}
printf("%c", shipChar);
board[row][col] = '-'; //set target coordinates to '-'
}
/* add code to update temp node's attributes (i.e
* hit or miss, ship type, then insert the temp node
* the node into the linked list.
* You may need to write the insert node function
* (you can refer to the insert node function in lab5
* handout )
*/
struct Node *head, *tail;
head = tail = NULL;
insert_node(&head, &tail, col, row, *state, shipType);
print_node(head);
//check if game is over //completed
int m = 0;
int k, l;
for(k = 0; k < SIZE; k++){
for(l = 0; l < SIZE; l++){
if(board[k][l] == '-'){
m++;
if(m >= 100){
strcpy(state, "GAME OVER!");
}
}
}
}
}
int accept_input(char * c, int * i){
bool flag = true;
do{
printf("Enter a letter A-J and number 0-9 ex. B4 - enter Z0 to end\n");
int size = scanf(" %c%d", c, i);
if(size != 2){
printf("INVALID INPUT\n");
continue;
}
*c = toupper(*c);
if(*c == 'Z' && *i == 0)
break;
if (*c < 65 || *c > 74)
printf("INVALID INPUT\n");
else if (*i <0 || *i >9)
printf("INVALID INPUT\n");
else
flag = false;
}while(flag);
}
/*
char currentState;
char ship_type;
*/
void insert_node(struct Node **h, struct Node **t, int x, char y, char* state, char shipTyp){
//create new node with value given by int x, y
struct Node *temp;
if ((temp = (struct Node *)malloc(sizeof(struct Node))) == NULL){
printf("Node Allocation Failed \n");
exit(1);
}
//space for node obtained, copy values into node
temp->charInput = y; //store user character input
temp->intInput = x; //store user number input
temp->currentState = state; //store state
temp->ship_type[20] = shipTyp; //store shipType
temp->next = NULL;
if (*h == NULL){
//list is empty if so
*h = *t = temp;
}
else{ //list isnt empty, use *t to add node at the end
(*t)->next = temp;
*t = (*t)->next;
}
}
//will be converted to a write to file function
void print_node(struct Node *h){
if(h == NULL){
printf("The list is empty.\n");
}
else{
printf("Values in the list are: \n");
while(h != NULL) {
printf("%c\n", h->charInput);
printf("%s\n", h->ship_type);
h = h->next;
}
}
}
void display_state(char* state, char** board){
int i, j;
printf("\n**** %s ****\n", state);
printf(" 0 1 2 3 4 5 6 7 8 9\n");
for (i = 0; i < SIZE; i++){
printf("%c ", 65+i);
for (j = 0; j < SIZE; j++){
printf("%c ", board[i][j]);
}
printf("\n");
}
}
int teardown(char ** board){
int i;
for(i = 0; i < SIZE; i++)
free(board[i]);
free(board);
/* add code below to traverse the linkded list
* you should create a log file name "log.txt"
* traverse each node in the linked list, and
* write the information in each node into "log.txt"
* Each line should follow this format:
* Fired at A1. Hit - Carrier.
* Fired at C2. Miss.
* You may refer to the print_list function in lab5
* handout.
* In addition, remember to free the nodes of the
* linked list.
*/
return 0;
}
int main(void){
//
void print_node(struct Node*);
void insert_node(struct Node**, struct Node**, int, char, char*, char);
srand(time(NULL));
char** board;
char state[] = "GAME START";
char flag[] = "GAME OVER!";
char character;
int integer;
/* declare a linked list below*/ //COMPLETED
//struct Node* head = NULL;
//struct Node* second = NULL;
//head = (struct Node*)malloc(sizeof(struct Node));
//second = (struct Node*)malloc(sizeof(struct Node));
board = initialization();
do{
display_state(state, board);
if(display_state)
/*modify the accept_input function
* accept input function should return
* a temp node, which stores the current valid
* input (i.e. character and letter)
*/
accept_input(&character, &integer);
if(character == 'Z' && integer == 0)
break;
/*modify the update_state function
* update_state function should accept
* the head node of linked list and the
* temp node
*/
update_state(state, board, character, integer);
} while((character != 'Z' || integer != 0) && strcmp(state, flag) );
/*modify the teardown function
* tear_down function should accept
* a head node of linked list
*/
teardown(board);
return 0;
}
//modularize insertNode, etc. inito own functions
Try this
void print_node(struct Node *h) {
if(h != null){
printf("%c\n", h->charInput);
printf("%s\n", h->ship_type);
print_node(h->next);
}
}
I noticed you call your print function in update_state, which means you are storing to the file every move.
number 1, you need to append to the file and not write
change:
fPTR = fopen("log.txt", "w");
to:
fPTR = fopen("log.txt", "a");
And change your write function to:
//will be converted to a write to file function
void print_node(struct Node *h, FILE *fPTR){
printf("got this far");
if (h == NULL) {
printf("THE LIST IS EMPTY\n");
}
else{
printf("\nThis move was:\n");
printf("%c\n", h->charInput);
printf("%s\n", h->ship_type);
printf("%d\n", h->intInput);
printf("%s\n", h->currentState);
fprintf(fPTR, "Fired at %c%d. %s - %s. \n", h->charInput, h->intInput, h->currentState, h->ship_type);
fclose(fPTR);
}
}
This is assuming your linkedist head is created correctly
EDIT: This code gets the last move played and adds it to the file, you will have to delete the file whenever you start a new game.
Issue: I'm trying to utilize recTest to check and return the winner of a simple Tic-Tac-Toe game.
I'm just unsure of what I need to pass in the call (line I've highlighted), and how to integrate my public square array.
I apologize if this is overly simple, I'm just having a rough time connecting the dots.
#include<stdio.h>
#include<conio.h>
char square[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
// returns -1 if no v[i] satisfies p
// returns i if v[i] satisfies p (picks largest i)
// (i>=0) and (i<n)
const int numwinpos = 8;
const int winpos[8][3] = {{1,2,3},
{4,5,6},
{7,8,9},
{1,4,7},
{2,5,8},
{3,6,9},
{1,5,9},
{3,5,7}};
//Function below, and variables above<--------------------------------------
int recTest(const int v[], const int n){
if( (n>0) && (!p(v[n-1])) )
return recTest(v,n-1);
else
return n-1;
}
/*int winnerCheck() {
//not even hard-coded tho...
if (square[1] == square[2] && square[2] == square[3])
return 1;
else if (square[4] == square[5] && square[5] == square[6])
return 1;
else if (square[7] == square[8] && square[8] == square[9])
return 1; //above 3 check across
else if (square[1] == square[4] && square[4] == square[7])
return 1;
else if (square[2] == square[5] && square[5] == square[8])
return 1;
else if (square[3] == square[6] && square[6] == square[9])
return 1; //above 3 check down
else if (square[1] == square[5] && square[5] == square[9])
return 1;
else if (square[3] == square[5] && square[5] == square[7])
return 1; //above 2 check diagonal
else if (square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4]
!= '4' && square[5] != '5' &&
square[6] != '6' && square[7] != '7' && square[8]
!= '8' && square[9] != '9')
return 0;
else
//exit
return -1;
}
*/
void board() {
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
//prints the board after every input
printf(" | | \n");
printf(" %c | %c | %c \n", square[1], square[2],square[3]);
printf("____|_____|____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[4], square[5],square[6]);
printf("____|_____|____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[7], square[8],square[9]);
printf(" | | \n");
}
int main() {
/*
char board[3][3] = {
};
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("________|_______|________\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("________|_______|________\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
*/
int player = 1, i, choice;
char mark;
do {
board();
player = player % 2 ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
//mark = (player == 1) ? 'X' : 'O';
if (player == 1) {
mark = 'X';
} else {
mark = 'O';
}
if (choice == 1)
square[1] = mark;
else if (choice == 2)
square[2] = mark;
else if (choice == 3)
square[3] = mark;
else if (choice == 4)
square[4] = mark;
else if (choice == 5)
square[5] = mark;
else if (choice == 6)
square[6] = mark;
else if (choice == 7)
square[7] = mark;
else if (choice == 8)
square[8] = mark;
else if (choice == 9)
square[9] = mark;
i = recTest(square, numwinpos); //HERE <--------------------------------------
player++;
} while (i == -1);
board();//call board
if (i == 1)
printf("----->\aPlayer %d WINS!<-----", --player);//nice alert sound when printed
else
printf("----->\aC-could it be...? Game draw!<-----");//nice alert sound when printed
//getch();//waits for user input before ending
return 0;
}
A quick and dirty way to use recursion would be to do something like below... and yes this can be optimized..
int winnerCheck(int x)
{
if(x < numwinpos)
{
if((square[winpos[x][0]] == 'x') && (square[winpos[x][1]] == 'x') && (square[winpos[x][2]] == 'x') ||
(square[winpos[x][0]] == 'o') && (square[winpos[x][1]] == 'o') && (square[winpos[x][2]] == 'o'))
return 1;
else
{
return winnerCheck(++x);
}
}
return 0;
}
I have just written some C code for checking for a checkmate (in chess), but I really can't understand what's wrong with my syntax, this is the compile error:
main.c:2:30: error: expected ';', ',' or ')' before 'board'
int is_check(const char[][8] board,int i,int j){
^ main.c:117:27: error: expected ';', ',' or ')' before 'board'
int check(const char[][8] board)
and this is my code:
#include <stdio.h>
int is_check(const char[][8] board,int i,int j){
int row = i;
int clmn = j;
//check clmn , up
do{
i--;
}
while(board[i][j] == 'z');
if(i>=0){
if(board[i][j] == 'H'){
return 1;
}
}
i = row;//init
//check clmn , down
do{
i++;
}
while(board[i][j] == 'z');
if(i<8){
if(board[i][j] == 'H'){
return 1;
}
}
i = row;//init
//check row , up
do{
j--;
}
while(board[i][j] == 'z');
if(j>=0){
if(board[i][j] == 'H'){
return 1;
}
}
j = clmn;//init
//check row , down
do{
j++;
}
while(board[i][j] == 'z');
if(j<8){
if(board[i][j] == 'H'){
return 1;
}
}
j = clmn;//init
//check orib!4
do{
j++;
i++;
}
while(board[i][j] == 'z');
if(j<8 && i<8){
if(board[i][j] == 'H'){
return 1;
}
}
j = clmn;
i = row;
//check orib!1
do{
j++;
i--;
}
while(board[i][j] == 'z');
if(j<8 && i>=0){
if(board[i][j] == 'H'){
return 1;
}
}
j = clmn;
i = row;
//check orib!3
do{
j--;
i++;
}
while(board[i][j] == 'z');
if(j>=0 && i<8){
if(board[i][j] == 'H'){
return 1;
}
}
j = clmn;
i = row;
//check orib!2
do{
j--;
i--;
}
while(board[i][j] == 'z');
if(j>=0 && i>=0){
if(board[i][j] == 'H'){
return 1;
}
}
return 0;
}//end func
int check(const char[][8] board)
{
int i = 0;
int j = 0;
for(;i<8;i++){
for(;j<8;j++){
if(board[i][j] == 'q')
return is_check(board,i,j);
}
}
return 0;
}
int main(){
char x[8][8] ={{'R','z','B','Q','H','z','q','R'},
{'A','A','A','A','z','z','A','A'},
{'z','z','z','d','z','z','D','z'},
{'z','z','z','z','z','z','z','b'},
{'z','z','z','z','a','z','z','z'},
{'a','z','z','a','z','z','z','z'},
{'z','a','a','z','z','a','a','a'},
{'r','d','b','z','h','z','z','r'}};
printf("%d",check(x));
return 0;
}
Because it should be
const char board[][8];
Here's my code for my tic-tac-toe game:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int board[3][3] = {
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
};
int main (void)
{
int const user1 = 1;
int const user2 = 2;
char move[10];
while (! all_locations_filled()) {
printf("User-1, please enter your move:");
scanf("%s", move);
if(valid_location(move)) {
mark_location(user1, move);
display_board(board[3][3]);
}
else if(won_the_game(user1)) {
printf("Congratulations User-1, You Won the Game!");
break;
}
else {
printf("Invalid Move");
}
printf("User-2, please enter your move:");
scanf("%s", move);
if(valid_location(move)) {
mark_location(user2, move);
display_board();
}
else if(won_the_game(user2) {
printf("Congratulations User-2, You Won the Game!");
break;
}
else {
printf("Invalid Move");
}
}
return 0;
}
bool valid_location(char str[10]) {
int strcmp(x, y);
if (strcmp(str[10], "upperLeft") == 0 || strcmp(str[10], "up") == 0 || strcmp(str[10], "upperRight") == 0 || strcmp(str[10], "left") == 0 || strcmp(str[10], "center") == 0 || strcmp(str[10], "right") == 0 || strcmp(str[10], "lowerLeft") == 0 || strcmp(str[10], "down") == 0 || strcmp(str[10], "lowerRight") == 0)
return true;
}
void mark_location(int userU, char str[10]) {
int strcmp(x, y);
if (strcmp(str[10], "upperLeft") == 0)
board[0][0] = userU;
else if (strcmp(str[10], "up") == 0)
board[0][1] = userU;
else if (strcmp(str[10], "upperRight") == 0)
board[0][2] = userU;
else if (strcmp(str[10], "left") == 0)
board[1][0] = userU;
else if (strcmp(str[10], "center") == 0)
board[1][1] = userU;
else if (strcmp(str[10], "right") == 0)
board[1][2] = userU;
else if (strcmp(str[10], "lowerLeft") == 0)
board[2][0] = userU;
else if (strcmp(str[10], "down") == 0)
board[2][1] = userU;
else if (strcmp(str[10], "lowerRight") == 0)
board [2][2] = userU;
}
char display_board(int array[][]) {
int i, j;
for (i=0; i<3; ++i)
for (j=0; j<3; ++j)
if (array[i][j] == 0)
print("-");
else if (array[i][j] == 1)
print("x");
else if (array[i][j] == 2)
print("o");
}
bool all_locations_filled() {
int i, j;
for (i=0; i<3; ++i)
for (j=0; j<3; ++j)
if board[i][j] == 0
return false;
return true;
}
bool won_the_game(userU) {
int i, j;
if (board[0][0] == userU && board[0][1] == userU && board[0][2] == userU)
return true;
else if (board[1][0] == userU && board[1][1] == userU && board[1][2] == userU)
return true;
else if (board[2][0] == userU && board[2][1] == userU && board[2][2] == userU)
return true;
else if (board[0][0] == userU && board[1][0] == userU && board[2][0] == userU)
return true;
else if (board[0][1] == userU && board[1][1] == userU && board[2][1] == userU)
return true;
else if (board[0][2] == userU && board[1][2] == userU && board[2][2] == userU)
return true;
else if (board[0][0] == userU && board[1][1] == userU && board[2][2] == userU)
return true;
else if (board[2][2] == userU && board[1][1] == userU && board[2][0] == userU)
return true;
else
return false;
}
There are a few errors that I don't understand, here they are:
tictactoe.c:50: error: expected expression before ‘}’ token
This error is at the end of the main function but I'm not sure what I did wrong.
tictactoe.c:52: error: nested functions are disabled, use -fnested-functions to re-enable
I didn't know I used a nested function.
tictactoe.c:53: warning: parameter names (without types) in function declaration
This is referring to int strcmp(x, y)
tictactoe.c:55: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast
What did I do wrong with strcmp?
If someone could help me out I'd greatly appreciate it.
You're missing a closing parenthesis here (line #40):
else if(won_the_game(user2) {
Should be:
else if(won_the_game(user2)) {
You have a couple or problems with the strcmp as well.
strcmp(str[10], "upperRight")
The compiler is complaining about the first parameter str[10]. One problem is that this selects a single character from the string, and not the whole string. Another problem is that in an array of size 10, the positions are numbered 0..9 so there isn't even a position 10!
Also, a string literal like "upperRight" contains 10 visible characters plus an extra zero character as a terminator. So it needs 11 positions when stored in the str.