How do I print an "x" shape? - c

I needed some help with my homework. I've spent about 2 hours on this but I can't get my head around it (c programming). I have to print an x like so:
* *
* *
* *
* *
*
* *
* *
* *
* *
The steps of the program should work like this.
1. User inputs a single number which is the size (this single number is basically the width and height). Also we can assume the user always puts an odd number (so we don't need conditions for that).
2. It draws the X in respect to that size.
However, I can only use while loops, and if statements, scanf and printf. Nothing else.
This is what I can get so far (just a diagonal)
row = 0;
while (row < size) {
column = 0;
while (column < size) {
if (row == column) {
printf("*");
} else {
printf(" ");
}
column++;;
}
printf("\n");
row++;
}

this should work
#include <stdio.h>
int main()
{
int size, row, column;
scanf("%d", &size);
row = 0;
while (row < size)
{
column = 0;
while (column < size)
{
if (column == row || column == size - row - 1)
{
printf("x");
}
else
{
printf(" ");
}
column++;
}
printf("\n");
row++;
}
return 0;
}

#include <stdio.h>
int main(void) {
int size = 11; //this should be the size given by user.
char line[size + 1];
int i;
for(i = 0; i < size; i++) line[i] = ' ';
line[size] = '\0';
int se = 0;
int sw = size - 1;
while(se < size && sw >= 0){
line[se] = line[sw] = 'x';
printf("%s\n", line);
line[se++] = line[sw--] = ' ';
}
return 0;
}
Tested on Ideone and worked.

You are checking only one diagonal.To get the required pattern ,change the if condition as follows...
if ((row == column)||(row==(size-column-1)))

Related

problem about using a dynamically allocated 2d array in a c program

I'm having a problem on making a move on my 9 x 9 tic tac toe program.
When I enter a coordinate such as (5,5), The x is displayed correctly on the grid.
MY PROBLEM IS THAT when I enter a coordinate which has the number 7 in it such as (4,7), TWO X's ARE DISPLAYED ON THE GRID.
I previously did the program declaring my array as a global variable. All was working fine. The issue started when I switched to a dynamically allocated array and passed the array using a double-pointer.
So I'm guessing that my problem is because of my array.
Can someone tell me where does this issue occur and how to fix it please.
I have declared the array in my main
//previously the array was declared here
//char grid[ROW][COLUMN];
int main()
{
//dynamically create an array of pointers os size ROW
char **grid = (char **)malloc(ROW * sizeof(char *));
// dynamically allocate memory of size ROW*COLUMN and let *grid point to it
*grid = (char *)malloc(sizeof(char) * ROW * COLUMN);
make move method
int make_move(char **grid, int x, int y,int row, int col, char letter)
{
if (x < 0 || x >= row || y < 0 || y >= col || grid[x][y] != ' ' )
{
// checks to see if the input is valid
return 1;
}
if( grid[x][y] == ' ')
grid[x][y] = letter;
// sets the coordinates in the grid to the letter
return 0;
}
update grid method
// Updates the grid accordingly every time a move is made
void update_grid(char **grid,int x, int y, int row, int col)
{
// int counter = 1;
//checks the input
while (x < 0 || x >= row || y < 0 || y >= col || grid[x][y] != ' ')
{
fputs("Error, Move not valid! Please reenter: ", stderr);
scanf("%d,%d", &x, &y);
}
++counter;
{
//Acts as an increment for the turns of the players
if(counter % 2 == 0)
{
//checks to see if it is player X's turn
grid[x][y] = 'X';
}
if(counter % 2 != 0)
{
//checks to see if it is player O's turn
grid[x][y] = 'O';
}
//prints grid
printf(" ");
for (int c = 0; c < col; c++)
{
printf(" ");
printf(" %d", c);
}
printf("\n");
for (int r = 0; r < row; ++r)
{
printf("%d", r);
printf("|");
for (int dot = 0; dot < (col*row); ++dot)
{
printf("|");
printf("%c", grid[r][dot]);
printf(" ");
if (dot == col - 1)
{
// stops j from over printing
printf("|| \n");
break;
}
}
}
}
}
As B. Go said your malloc is wrong, here's how it should look.
//dynamically create an array of pointers os size ROW
char **grid = malloc(ROW * sizeof(char *));
for(size_t i = 0; i < ROW; i++){
grid[i] = malloc(COLUMN);
}
you allocated ROW pointers but you only filled the first one, you need to give them each COLUMN bytes of data.

Build a simple text square/rectangle using "Xs" and printf

I am trying to build a square/rectangle using "Xs" on a 1:1 scale with the length and width, but the logic seems to be not perfect
void draw (float x, float y) {
int i, j;
int length = (int)x + 0;
int width = (int)y + 0;
for (i = 1; i < length; i++) {
for (j = 1; j < width; j++) {
if (((i = 1) || (i = length)) && ((j = 1) || (j = width))) {
printf("x");
} else {
printf(" ");
}
}
printf("\n");
}
}
The problem is that the loop iterates endlessly printing x's everywhere. I'm expecting Xs to be printed out in either a square or rectangular shape (depending on the length or width).
I see 3 flaws in your logic.
you mix = (assignment) with == comparison.
This is why your loop never ends: you always reset i to 1 with your if (((i = 1) || (i = length)) &...
you're not going far enough with your variables:
if i < length, then you'll never have it reach length and print the bottom line of X's
you can't draw a rectangle because your && in the test (((i = 1) || (i = length)) && ((j = 1) || (j = width))) is too restrictive. It can't work if width different from length.
You must learn the logic by yourself using tutorials:
Here such questions will be discarded by sometime-sad people. But as a welcome, here it is (you can replace y in the second case by x, but I thought it would help you understand):
#include <stdio.h>
#include <string.h>
void draw (float x, float y)
{
int i,j;
int length = (int)x + 0;
int width = (int)y + 0;
for(i=1; i<=length; i++) {
for(j=1;j<=width;j++) {
if(((i==1)||(i==length))) {
printf("x");
} else {
if (((j==1)||(j==width))) {
printf("y");
} else {
printf(" ");
}
}
}
printf("\n");
}
}

how to create a diamond in c using only 3 printf and 3 n\t\

I am attempting to create a diamond in c with the constraints of only 3 printfs and 3 n\t. this requires me to use loops. I know how to make an upside down triangle and a triangle but cant use that because there are too many printfs. i will attach my code so far. I am aware it does not make a diamond, and some awfully strange shape, but that it what i'm trying to work off and edit to make into a diamond, I just haven't been able to figure it out.
if (type_of_shape == 5)
{
for (i = 0; i < width; i++)
{
for (j = 0;j < ((width - 1) / 2) - i ||(width -1)/2 < i && j + (width-1)/2 < i; j++)
{
printf(" ");
}
for (k = 0;k<width && k < (j*2+1) ; k++)
{
printf("*");
}
printf("\n");
}
}
//int width = 5;
int row, col;
int spaces, stars;
int half, rate;
half = width / 2 + 1;
rate = 1;
for(row = 1; 0 < row && row <= half; row += rate) {
spaces = half - row;
stars = row * 2 -1;
printf("%*s", spaces, "");
for (col = 0; col < stars; col++)
printf("*");
printf("\n");
if(row == half)
rate = -rate;
}
I got it down to a single line which has a single loop, with a single printf statement.
It involved some tricky use of abs.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int w = 9;
for(int l=0; l < w; ++l) printf("%*.*s\n", abs(w/2 - l)+abs((2*l+1)-(2*l+1>w)*2*w), abs((2*l+1)-(2*l+1>w)*2*w), "**************");
return 0;
}
2 loops (one for, one while).
2 printf statements.
Note:
This works with odd Widths.
An even width produces a diamond with Width+1
My IDEOne code
int main(void)
{
int width = 9;
int layer;
width+=2;
for(layer=0; layer<width/2; ++layer)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
layer--;
while (layer --> 0)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
return 0;
}
Output
Success time: 0 memory: 2168 signal:0
*
***
*****
*******
*********
*******
*****
***
*
Here's a solution with no loops at all. (looping accomplished via recursion), and 3 printf statements:
#include <stdio.h>
void drawDiamond(int width, int stars)
{
static const char* txt = "*****************************";
if (stars == width) {
printf("%*.*s\n",width, width, txt);
return;
}
printf("%*.*s\n", (width+stars)/2, stars, txt);
drawDiamond(width, stars+2);
printf("%*.*s\n", (width+stars)/2, stars, txt);
}
int main(void)
{
drawDiamond(9, 1);
return 0;
}

Parse Text File in C - Skip Lines - Repeated Calculation

I have been spinning my wheels for a while trying to figure this out but have not been able to. Hope you can help!
I am currently working on a program that solves Sudoku. The current code that I am showing below takes in as input a 9x9 grid of integers (the Sudoku puzzle) and then generates a solution. This is working fine.
#include <stdio.h>
int isAvailable(int puzzle[][9], int row, int col, int num)
{
int rowStart = (row/3) * 3;
int colStart = (col/3) * 3;
int i, j;
for(i=0; i<9; ++i)
{
if (puzzle[row][i] == num) return 0;
if (puzzle[i][col] == num) return 0;
if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0;
}
return 1;
}
int fillSudoku(int puzzle[][9], int row, int col)
{
int i;
if(row<9 && col<9)
{
if(puzzle[row][col] != 0)
{
if((col+1)<9) return fillSudoku(puzzle, row, col+1);
else if((row+1)<9) return fillSudoku(puzzle, row+1, 0);
else return 1;
}
else
{
for(i=0; i<9; ++i)
{
if(isAvailable(puzzle, row, col, i+1))
{
puzzle[row][col] = i+1;
if((col+1)<9)
{
if(fillSudoku(puzzle, row, col +1)) return 1;
else puzzle[row][col] = 0;
}
else if((row+1)<9)
{
if(fillSudoku(puzzle, row+1, 0)) return 1;
else puzzle[row][col] = 0;
}
else return 1;
}
}
}
return 0;
}
else return 1;
}
int main()
{
int i, j;
int row,column;
int puzzle[9][9];
//printf("Enter your input:\n");
for (row=0; row <9; row++){
for(column = 0; column <9; column ++){
scanf("%d",&puzzle[row][column]);
}
}
//PRINT INPUT PUZZLE
printf("Original Puzzle:");
printf("\n+-----+-----+-----+\n");
for(i=1; i<10; ++i)
{
for(j=1; j<10; ++j) printf("|%d", puzzle[i-1][j-1]);
printf("|\n");
if (i%3 == 0) printf("+-----+-----+-----+\n");
}
printf("\n");
//PRINT OUTPUT PUZZLE
printf("Solved Puzzle:");
if(fillSudoku(puzzle, 0, 0))
{
printf("\n+-----+-----+-----+\n");
for(i=1; i<10; ++i)
{
for(j=1; j<10; ++j) printf("|%d", puzzle[i-1][j-1]);
printf("|\n");
if (i%3 == 0) printf("+-----+-----+-----+\n");
}
printf("\n");
}
else printf("\n\nNO SOLUTION\n\n");
return 0;
}
I now want to use a text file from Project Euler (https://projecteuler.net/project/resources/p096_sudoku.txt) and have my program generate all 50 of these solutions. The text file has the following format:
Grid 01
003020600
900305001
001806400
008102900
700000008
006708200
002609500
800203009
005010300
Grid 02
200080300
060070084
030500209
000105408
000000000
402706000
301007040
720040060
004010003
...
and so on for 50 total grids.
My question is: What is the best way to parse through this file to
Skip over the "Grid ##" line
Read in the next 9 lines for input
Continue on through the file to repeat the program until the end of the file
EDIT:
Between steps 2 & 3, this is what would happen:
After I read in 9 lines of numbers, I'll use that as input to the program and have the program run and generate a solution, and then look back to the input file and get the next set of numbers and run another iteration of the program.
Thank you for any input and guidance you can provide me!
-Colton
When data in a text file is line formatted, strongly recommend using fgets().
Consider each group of 10 lines as a record. They belong together, if 1 part is in error, the whole group is invalid.
// return 0 on success, -1 on EOF and 1 on format failure
int ReadPuzzle(FILE *inf, int puzzle[][9], int *Grid) {
char buffer[20]; // About 2x expected need
if (fgets(buffer, sizeof buffer, inf) == NULL)
return -1; // File EOF or IO error occurred.
if (sscanf(buffer, "Grid %d", Grid) != 1)
return 1;
for (int row = 0; row < 9; row++) {
if (fgets(buffer, sizeof buffer, inf) == NULL)
return 1; // If Grid line exists, 9 lines _should_ follow
char *p = buffer;
for (int col = 0; col < 9; col++) {
// Use %1d to limit scanning to 1 digit
if (sscanf(p, "%1d", &puzzle[row][col]) != 1)
return 1;
p++;
}
}
return 0;
}
Checks could be added to insure extra data is not on the lines.
You probably want to do some stuff between steps 2 & 3, but what you outline sounds reasonable.

C Chomp questions?

I'm trying to create the game Chomp. I am halfway through but pretty stuck.
The game will have 5 different functions. Pointers and structs are not allowed.
This is how far I have come and I have been struggeling with a few problems for a while, but I can't figure out how to solve them by myself so I thought I could get some help here.
BUGS
a) If you first input 2 2 and then input 2 1 it will say that the position already has been eaten, even though it's a perfectly valid position to eat. Instead of checking if the position is != 'O' I should check if it is == 'O', but that won't work either because in the check_move() loop the row and col will not always be an O...
b) If you input a position that is not inside the matrix (i.e. 20 20) you will get two lines of errors. I don't understand why. Of course I only want to display one error, not two.
c) If you input a position that has already been eaten you will get the error "Already been eaten!" several times due to the loop that is looping through the print several times.
QUESTION
a) What is the best way to alternate between Player 1 and Player 2? I thought about an int that will increase by +1 every time a player makes a valid move. Then I will check if the value of the int is odd or even. Odd = Player 1 and even = Player 2 or vice verca. But that won't work because I'm not allowed to have any more global variables than I currently has. And I'm only allowed to return one value from one function (check_move()).
#include <stdio.h>
int height = 4;
int width = 10;
char matrix[4][10];
void initialize()
{
for(int row = 0; row < height; row++)
for(int col = 0; col < width; col++)
matrix[row][col] = 'O';
}
void print_board()
{
printf("\n\n");
for(int row = 0; row < height; row++)
{
for(int col = 0; col < width; col++)
{
printf("%c", matrix[row][col]);
}
printf("\n");
}
printf("\n\n");
}
void get_move(int player, int input[])
{
printf("Player %d, make your move: ", player);
scanf("%d %d", &input[0], &input[1]);
}
int check_move(int position[])
{
int row = position[0];
int col = position[1];
int status = 1;
if(row <= height && col <= width)
{
for(row; row <= height; row++)
{
for(col; col <= width; col++)
{
// Checks if position already has been eaten
if(matrix[row-1][col-1] != 'O')
{
printf("Already eaten!\n");
status = 0;
}
}
}
}
else if(row >= height || col >= width)
{
printf("Your move must be inside the matrix!\n");
status = 0;
}
return status;
}
void update_board(int x, int y)
{
for(int xi = x; xi <= 10; ++xi)
{
for(int yi = y; yi <= 10; ++yi)
matrix[xi-1][yi-1] = ' ';
}
}
int main(void)
{
int player = 1;
int position[2];
initialize();
print_board();
while(1){
get_move(player, position);
check_move(position);
while(check_move(position) != 1)
{
printf("Try again!\n\n");
get_move(player, position);
}
update_board(position[0], position[1]);
print_board();
}
getchar();
getchar();
getchar();
return 0;
}
Bug a and c:
Your check_move function is wrong, you should only test if the position played is eaten or not, the status of the other positions are not relevant:
int check_move(int pos[])
{
if(pos[0] < 1 || pos[0] > height || pos[1] < 1 || pos[1] > width)
{
printf("Your move must be inside the matrix!\n");
return 0;
}
if(matrix[ pos[0] - 1 ][ pos[1] - 1 ] != 'O' ) {
printf("Already eaten!\n");
return 0;
}
return 1;
}
Bug b:
You get the error message twice because you're calling check_move twice in your main:
check_move(position);
while(check_move(position) != 1)
Just remove the useless first call to check_move().
Question a:
You can switch between players by updating the variable player inside your main :
player = (player + 1) % maxNumberOfPlayer;
This will go from 0 to maxNumberOfPlayer - 1, so you may use printf("Player %d, make your move: ", player + 1); for a more user-friendly output. Also, if maxNumberOfPlayer = 2, player = (player + 1) % 2; is equivalent to player = !player.
In main, inside your while loop just add:
player = !player;
Which will toggle player between 0 and 1.

Resources