I wrote a TicTacToe program in C that reads 68.3 KB on my hard disk, and I was wondering if there are any sort of optimization techniques I could use to decrease the amount of bytes in my .exe file.
For instance, is there anything in my code that I could change to make the resulting executable "smaller"?
Code:
#include <stdio.h>
#include <stdbool.h>
void drawBoard(int [3][3]);
bool boardFull(int [3][3]);
bool checkWin(int [3][3], int);
int main()
{
int board[3][3];
int marker, turn, row, column, i, j;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
board[i][j] = -1;
}
printf("Player One is X\n");
printf("Player Two is O\n");
drawBoard(board);
while(!boardFull(board))
{
if((turn % 2) == 0)
{
printf("Player One's turn.\n");
marker = 1;
}
else
{
printf("Player Two's turn.\n");
marker = 0;
}
printf("Which row? ");
scanf("%i", &row);
printf("Which column? ");
scanf("%i", &column);
if(board[row - 1][column - 1] != -1)
{
while(board[row - 1][column - 1] != -1)
{
printf("Space already taken. Try again.\n");
printf("Which row? ");
scanf("%i", &row);
printf("Which column? ");
scanf("%i", &column);
printf("\n");
}
}
board[row - 1][column - 1] = marker;
drawBoard(board);
if(checkWin(board, marker))
{
if(marker == 1)
printf("Player One wins!!");
else
printf("Player Two wins!!");
return 0;
}
turn++;
}
printf("Cat's game!\n");
return 0;
}
void drawBoard(int board[3][3])
{
int i, j;
printf("\n");
for(i = 0; i < 3; i++)
{
printf(" ");
for(j = 0; j < 3; j++)
{
if(board[i][j] == 0)
printf("O");
else if(board[i][j] == 1)
printf("X");
else
printf(" ");
if(j == 2)
continue;
else
printf(" | ");
}
if(i == 2)
printf("\n\n");
else
printf("\n -----------\n");
}
}
bool boardFull(int board[3][3])
{
int i, j;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
if(board[i][j] == -1)
return false;
}
}
return true;
}
bool checkWin(int board[3][3], int w)
{
return
board[0][0] == w && board[1][1] == w && board[2][2] == w
|| board[0][2] == w && board[1][1] == w && board[2][1] == w
|| board[0][0] == w && board[1][0] == w && board[2][0] == w
|| board[0][1] == w && board[1][1] == w && board[2][1] == w
|| board[0][2] == w && board[1][2] == w && board[2][2] == w
|| board[0][0] == w && board[0][1] == w && board[2][2] == w
|| board[1][0] == w && board[1][1] == w && board[2][2] == w
|| board[2][0] == w && board[2][1] == w && board[2][2] == w;
}
Related
I'm new to C and I'm trying to make a tic-tac-toe game for my college project and I'm struggling on how to reset my array in my game.
Every time I play again it does not reset the array. Can anyone help me with this?
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
char space[3][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
void board();
int checkWin();
int game();
void reset();
int main(){
int choice = -1;
do{
printf("\n\n\n\n\n\n\n\t\t\t ================\n");
printf("\t\t\t Tic Tac Toe\n");
printf("\t\t\t ================\n");
printf("\t\t -----------Menu-----------\n\n");
printf("\t\t 1. Play\n");
printf("\t\t 2. Exit\n");
scanf("%d", &choice);
switch(choice){
case 1: game();
break;
case 2: printf("Goodbye!!");
exit(0);
break;
default: printf(".......Wrong Key !.......Try Again!......");
break;
}
}while(choice != 0);
}
int game(){
int player = 1, i, choice;
char mark;
do
{
system("cls");
board();
player = (player % 2) ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
mark = (player == 1) ? 'X' : 'O';
if (choice == 1)
space[0][0] = mark;
else if (choice == 2)
space[0][1] = mark;
else if (choice == 3)
space[0][2] = mark;
else if (choice == 4)
space[1][0] = mark;
else if (choice == 5)
space[1][1] = mark;
else if (choice == 6)
space[1][2] = mark;
else if (choice == 7)
space[2][0] = mark;
else if (choice == 8)
space[2][1] = mark;
else if (choice == 9)
space[2][2] = mark;
else
{
printf("Invalid move ");
player--;
getch();
}
i = checkWin();
player++;
}while (i == - 1);
board();
reset();
if (i == 1)
printf("==>\aPlayer %d win \n\n", --player);
else
printf("==>\aGame draw\n\n");
getch();
return 0;
}
int checkWin(){
if (space[0][0] == space[0][1] && space[0][1] == space[0][2])
return 1;
else if (space[1][0] == space[1][1] && space[1][1] == space[1][2])
return 1;
else if (space[2][0] == space[2][1] && space[2][1] == space[2][2])
return 1;
else if (space[0][0] == space[1][0] && space[1][0] == space[2][0])
return 1;
else if (space[0][1] == space[1][1] && space[1][1] == space[2][1])
return 1;
else if (space[0][2] == space[1][2] && space[1][2] == space[2][2])
return 1;
else if (space[0][0] == space[1][1] && space[1][1] == space[2][2])
return 1;
else if (space[0][2] == space[1][1] && space[1][1] == space[2][0])
return 1;
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
return 0;
else
return - 1;
}
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
void board(){
system("cls");
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[0][0], space[0][1], space[0][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[1][0], space[1][1], space[1][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[2][0], space[2][1], space[2][2]);
printf(" | | \n\n");
}
I tried using for loop but it does not work; how can I solve this?
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
Your reset function is filling the entire 3x3 board matrix with zeros; these represent the nul character, not the character representing the '0' digit. Those nul characters aren't printed (and cannot be), so the board looks 'wrong' after a reset.
However, simply changing the space[i][j] = 0; line to space[i][j] = '0'; won't work! Although you will then initially see a board full of 0 digits, the way your checkWin() function works will then ensure that "Player 1" will have won the new game immediately after their first move, because there will already be rows/columns/diagonals of three identical characters.
So, to get the original ('1' thru '9') display, write your reset() function as below. (Note that the C Standard requires that the characters representing the numerical digits be in order and contiguous, so adding a value of 1 thru 9 to the '0' character will yield the appropriate digit character.)
void reset()
{
int number = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = number++ + '0';
}
}
}
Alternatively, you can just declare and initialize a new 'board array' with the data in it, then just use memcpy to rest the space array with the contents of that:
#include <string.h> // For "memcpy"
void reset()
{
char empty[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} };
memcpy(space, empty, sizeof(space));
}
Note, also that all the tests in the following statement are wrong:
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
Each one of these is testing if an element is not equal to itself. This can never be true, so that else if block (the return 0; line) is never executed. But you don't actually need it, so you can just delete that block.
while loop give result back when one of the condition succeed , i need both of them, any help
#include <stdio.h>
int yRechner()
{
int x = 2;
int y =0;
int i =0;
char answer[2];
while (i < 1 && y <= x)
{
printf("is the wall here pleas answer yes(Y/y) or No(N/n) \n");
scanf("%s", &answer);
if (answer[0] == 'N' || answer[0] == 'n')
{
printf("one step \n");
y++;
}
else if (answer[0] == 'Y' || answer[0] == 'y')
{
if (i < 1 && y > x)
{
i++;
printf("rotate \n");
}
else
{
printf("am not seeing the wall please say no. \n");
}
}
else
{
printf("wrong answer \n");
}
}
return y;
}
int main()
{
int y = yRechner();
printf("y = %d\n", y);
return 0;
}
It isn't apparent whether these conditions, i < 1 and y <= x, are negated or not. In general, if you want to loop while not both of the conditions are true, !(c1 && c2), you can use De Morgan's laws to simplify !c1 || !c2.
I found a Solution , thx for your hints
#include <stdio.h>
int yRechner()
{
int x = 2;
int y =0;
int i =0;
char answer[2];
while (i < 1 )
{
printf("is the wall here please answer yes(Y/y) or No(N/n) \n");
scanf("%s", &answer);
if (answer[0] == 'N' || answer[0] == 'n')
{
printf("one step \n");
y++;
}
else if (answer[0] == 'Y' || answer[0] == 'y')
{
if (i < 1 && y > x )
{
i++;
printf("rotate \n");
continue;
}
else if (i < 1 && y < x)
{
printf("am not seeing the wall please say no. \n");
continue;
}
}
else
{
printf("wrong answer \n");
}
}
return y;
}
int main()
{
int y = yRechner();
printf("y = %d\n", y);
return 0;
}
We're supposed to create a number board whereby a user is allowed to select a number for instance, number 5 and one of the number 5's in the board will be clearly indicated as selected with a hyphen above and below it.
Problem now is: No matter what I try the hyphens refuse to move to the right spot.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define HEIGHT 9
#define WIDTH 8
void board(char array[HEIGHT][WIDTH])
{
int x,y,i,j,score,steps = 0;
/****BORDER CREATION*/
for (i = 0; i < WIDTH+4; i ++)
printf("# ");
printf("\n");
for(y=0;y<WIDTH+1;y++)
{
printf("\n");
printf("# ");
for(x=0;x<HEIGHT+1;x++)
{
printf("%c ",array[y][x]);
}
printf("# ");
printf("\n\n");
}
for (i = 0; i < WIDTH+4; i ++)
printf("# ");
printf("\n");
/****BORDER CREATION*/
}
void instruc(char *name, int *steps, int *selected)
{
/*User record & score header*/
printf("\n-----Hello %s! Let's see what you can do------\n",name);
printf("----------WELCOME TO NUMBER CONNECT----------\n");
printf("----------PREVIOUS PLAYERS' RECORDS----------\n");
printf("----------Name: %s Score(Steps): %i--\n\n",name,*steps);
printf("\nYour score: %i",*steps);
printf("\nNumber %i is currently selected",*selected);
printf("\n\nAction Keys: ");
printf("\nPush 'U' to move UP");
printf("\nPush 'D' to move DOWN");
printf("\nPush 'L' to move LEFT");
printf("\nPush 'R' to move RIGHT");
printf("\nPush 'X' to REMOVE path\n");
printf("\nTo select a new number, press digits from 1 to 7\n");
printf("\nPush 'q' or 'Q' to QUIT\n\n");
}
void select(int *selected,char array[HEIGHT][WIDTH])
{
int i,j,x;
printf("\nPlease select a number (1-8): ");
fflush(stdin);
scanf("%i",selected);
/*POINTER TYPE CONVERTION FAIL
selected = (char)*selected;*/
/*ASCII CHARACTER ATTEMPT FAIL
if (*selected == 1){
*selected = 1;
}
else if (*selected == 2){
*selected = 2;}
else if (*selected == 3){
*selected = 3;}
else if (*selected == 52){
*selected = 4;}
else if (*selected == 53){
*selected = 5;}
else if (*selected == 54){
*selected = 6;}
else if (*selected == 55){
*selected = 7;}
else if (*selected == 56){
*selected = 8;}
else{
printf("Non-Numeric Input not allowed");}*/
printf("\nNumber Selected: %i",*selected);
/*To indicate selected number with hyphens (denoted by 45)*/
for (i = 0; i < WIDTH+1;i++)
{
for (j =0; j < HEIGHT+1; j++){
if (array[i][j] == *selected){
array[i-1][j] = 45;
array[i+1][j] = 45;
}
}
}
printf("\nPosition of i: %i ",i);
printf("Position of j: %i\n\n",j);
}
void assign(char array[HEIGHT][WIDTH], int *selected)
{
int i,j;
/*int rr,rrr;
int x = 0;
srand((unsigned) time(NULL));
for (i = 0; i < WIDTH+3;i++)
{
for (j = 0; j < HEIGHT; j++){
x = (rand()%8+1)+48;
array[i][j] = x;
}
}
for (i = 0; i < WIDTH+3;i++)
{
for (j = 0; j < HEIGHT+3; j++){
rr = rand()%WIDTH;
rrr = rand()%HEIGHT;
x= 32;
array[rr][rrr] = x;
}
}
printf("\n");*/
/*To blank our everything that is not a symbol*/
array[0][1] = 49;
array[0][7] = 49;
array[5][9] = 50;
array[6][1] = 50;
array[1][4] = 51;
array[5][7] = 51;
array[7][2] = 52;
array[5][5] = 52;
array[3][3] = 53;
array[1][1] = 53;
array[7][3] = 54;
array[6][2] = 54;
array[3][7] = 55;
array[7][6] = 55;
array[2][4] = 56;
array[4][4] = 56;
for (i = 0; i < WIDTH+4;i++)
{
for (j = 0; j < HEIGHT+4; j++){
if ((array[i][j] != 49) && (array[i][j] != 50) && (array[i][j] != 51) &&
(array[i][j] != 52) && (array[i][j] != 53) && (array[i][j] != 54) && (array[i][j] != 55) &&
(array[i][j] != 56)){
array[i][j] = 32;
}
}
}
}
int main(void)
{
int i,j,x,y,score = 0,steps = 0,result = 0,selected=0;
char array[HEIGHT][WIDTH],name[20];
printf("Please Input Name: ");
scanf("%s",&name);
instruc(name,&steps,&selected);
assign(array,&selected);
board(array);
select(&selected,array);
board(array);
return 0;
}
So i built this really simple game in c language, where you are a ship and need to avoid a bullet rising up the screen. Once I run it in terminal, every time I want to move the ship I enter a (left) s(straight) or d(right). I was wondering if there was a way to not be forced use the enter key after every move and rather have the bullet gradually rise up like one space a second or something automatically.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#define height 20
#define width 15
int main (int argc, char *argv[]) {
printf("Beginning Game\n");
printf("Press 's' to start\n");
char move = 0;
int count = 6;
int turn = 0;
int row = 0;
int col = 0;
int left = 0;
int right = 14;
srand(time(NULL));
int shootcol = rand() % (width - 3) + 2 ;
int shootrow = height + 1;
int shoot2col = rand() % (width - 3) + 2 ;
int shoot2row = height + 15;
while (move != 'e') {
printf("\n");
scanf(" %c", &move);
if (move == 's') {
turn++;
}
else if (move == 'a') {
count--;
turn++;
} else if (move == 'd') {
count++;
turn++;
}
row = 0;
col = 0;
printf("TURN: %d\n", turn);
while (row < height) {
while (col < width) {
//printf("%d", col );
if (((row == shootrow) && (col == shootcol)) || ((row == shoot2row) && (col == shoot2col))) {
printf(":");
} else if (col == left) {
printf("|");
} else if (col == right) {
printf("|");
} else if (row < 5) {
printf(" ");
} else if (row == 5) {
if (col < count) {
printf(" ");
} else if (col == count) {
printf("|");
} else if (col == count + 1) {
printf("-");
} else if (col == count + 2) {
printf("|");
} else if (col >= count + 3) {
printf(" ");
}
} else if (row == 6) {
if (col < count) {
printf(" ");
} else if (col == count) {
printf("\\");
} else if (col == count + 1) {
printf(" ");
} else if (col == count + 2) {
printf("/");
} else if (col >= count + 3) {
printf(" ");
}
} else {
printf(" ");
}
col++;
}
col = 0;
printf("\n");
row++;
}
shootrow--;
shoot2row--;
if ((count == left) || (count == right - 2)) {
printf("YOU LOSE!!\n");
move = 'e';
} else if ((shootrow == 5) || (shootrow == 4)) {
if ((count == shootcol) || (count == shootcol - 2 ) || (count == shootcol - 1)) {
printf("YOU LOSE!!\n");
move = 'e';
} if ((count == shoot2col) || (count == shoot2col - 2 ) || (count == shoot2col - 1)) {
printf("YOU LOSE!!\n");
move = 'e';
}
} if (shootrow <= 0) {
shootrow = height - 1;
shootcol = rand() % (width - 3) + 2 ;
} if (shoot2row <= 0) {
shoot2row = height - 1;
shoot2col = rand() % (width - 3) + 2;
}
}
return 0;
}
The simplest way is using the conio library
#include <conio.h>
#define DELAY 300 // define here the amount of milliseconds to sleep
If you are using linux or mac
#include <unistd.h>
If you are using Windows
#include <windows.h>
and this is how the beginning of your loop would look like
while (move != 's')
scanf(" %c", &move);
move = ' ';
while (move != 'e') {
printf("\n");
//Sleep(DELAY); // windows only sleep 's' lowercase for linux
usleep(DELAY); // for mac
if (_kbhit())
{
move = _getch();
}
if (move == 's') {
turn++;
}
/*
Program to calculate trip and plan flights
*/
#define TRIP 6
#define NUMLEG 10
#include <stdio.h>
#include <string.h>
int input_trip(void);
int input_leg(int travel_leg[NUMLEG], int index);
char input_travel_type(char leg_type[TRIP][NUMLEG], int n, int index, int leg_num);
int main(void)
{
int row, col, trip_num, index, travel_leg[NUMLEG], leg_num, n;
char leg_type[TRIP][NUMLEG];
trip_num = input_trip();
for (index =0; index < trip_num; index++)
{
leg_num = input_leg(travel_leg,index);
printf("At Trip Number:%d\n", index);
printf("Number of legs %d\n", leg_num );
printf("A Airplane\n");
printf("R Train and rail travel\n");
printf("B Bus\n");
printf("C Car\n");
printf("F Ferry\n");
printf("S Cruise ship\n");
printf("M Motorcycle\n");
printf("Y Bicycle\n");
printf("T Boat other than a ferry or cruise ship\n");
printf("D Dirigible\n");
printf("O Other\n");
printf("NOTE!!:Please using capital letters (case sensitive).\n");
for (n = 0; n < leg_num; n ++)
{
printf("At leg Number%d\n", n);
input_travel_type(leg_type, n, index, leg_num);
}
}
for (index = 0; index < trip_num; index++)
{
printf("Trip#:%d Num_leg:%d ", index+1, travel_leg[index]);
for (n = 0; n < leg_num ; n++)
printf("Leg_type(#%d):%c ",n+1, leg_type[index][n]);
printf("\n");
}
return 0;
}
int input_trip(void)
{
int trip_num;
printf("Please enter the number of trips:");
scanf("%d", &trip_num);
// if( (trip_num <= TRIP) && (trip_num >= 3))
if( (trip_num <= TRIP) && (trip_num >=1) )
{
return trip_num;
}
else
{
while ((trip_num < 1) || ( trip_num > TRIP))
{
printf("Invalid number of trip. (Min of 3 trips and Max 6 trips).\n"); /*input number of trips*/
printf("Please enter the number of trips:");
scanf("%d", &trip_num);
if( (trip_num <= TRIP) && (trip_num >= 1))
{
return trip_num;
}
}
}
}
int input_leg(int travel_leg[NUMLEG], int index)
{
int leg_num, i;
char travel_type, checkA, A, R, B, C, F, S, M, Y, T, D, O;
printf("Please enter the number of legs in your trip:");
scanf("%d", &leg_num);
if ( (leg_num <= NUMLEG) && (leg_num > 0) )
{
travel_leg[index]=leg_num;
return leg_num;
}
else
{
while ( (leg_num < 0) || (leg_num > NUMLEG))
{
printf("Invalid number of legs(min 1 and max 10 legs).\n");
printf("Please enter the number of legs in your trip:");
scanf("%d", &leg_num);
if ( (leg_num <= NUMLEG) && (leg_num > 0) )
{
travel_leg[index]=leg_num;
return leg_num;
}
}
}
}
char input_travel_type(char leg_type[TRIP][NUMLEG], int n, int index, int leg_num)
{
char travel_type, checkA;
printf("Please enter the leg type for leg#%d:", n+1);
scanf("%c", &travel_type);
checkA = ( (travel_type == 'A') || (travel_type == 'R') || (travel_type == 'B') ||
(travel_type == 'C') || (travel_type == 'F') || (travel_type == 'S') ||
(travel_type == 'M') || (travel_type == 'Y') || (travel_type == 'T') ||
(travel_type == 'D') || (travel_type == '0') );
if (checkA == 1)
{
leg_type[index][n]=travel_type;
}
else
{
while (checkA != 1)
{
printf("Please enter the leg type for leg#%d:", n+1);
scanf("%c", &travel_type);
checkA = ( (travel_type == 'A') || (travel_type == 'R') || (travel_type == 'B') ||
(travel_type == 'C') || (travel_type == 'F') || (travel_type == 'S') ||
(travel_type == 'M') || (travel_type == 'Y') || (travel_type == 'T') ||
(travel_type == 'D') || (travel_type == '0') );
if (checkA == 1)
leg_type[index][n]=travel_type;
}
}
}
(I ask this question a while back but my code was too messy so I re-wrote it in functions so it was easier to read)
The problem I'm having is that my leg_num is getting over written every time I step out of the loop, so when I try to print out in the printf the last leg_num I put in is the number that is being use at:
for (n = 0; n < leg_num ; n++) the 2nd one in the printing loop
EDITED
So when I put in 2 trips trip# 1 has 3 legs trip# 2 has 2 legs when it runs through the printing loops it will only print 2 legs for each trip.
Trip#:1 Num_leg:3 Leg_type(#1):C Leg_type(#2):B
Trip#:2 Num_leg:2 Leg_type(#1):A Leg_type(#2):R
Trip#:1 Num_leg:1 Leg_type(#1):S Leg_type(#2):
Trip#:2 Num_leg:2 Leg_type(#1):F Leg_type(#2):S
Everything else works fine because I put printf statements along the way to check if that was the issue but it wasn't. I was thinking of saving the leg_num into a array and using that but not sure how to do it, plus the fact that this is part of a homework and our professor is restricting almost everything but the basic loops simple arrays.
printf("Trip#:%d Num_leg:%d ", index+1, travel_leg[index]);
for (n = 0; n < leg_num ; n++)
Change to
printf("Trip#:%d Num_leg:%d ", index+1, travel_leg[index]);
for (n = 0; n < travel_leg[index] ; n++)