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");
}
}
Related
In line 10 I cannot find out where my problem is at first. I place int a[100][100]={0} but the cpu speed is stuck.
Then, I try to change it into a[n][n] but no output is shown.
Last, I try to change it again as if it resembles the original ones.
However, nothing works instead of a new question.
#include<stdio.h>
int main() {
int n;
while (scanf("%d", &n)) {
n *= 2;
int x = 0, y = 0, num = 1;
int a[n][n] = {0};
a[x][y] = num++;
while (n * n >= num) //定義陣列
{
while (y + 1 < n && !a[x][y + 1]) //向右
a[x][++y] = num++;
while (x + 1 < n && !a[x + 1][y]) //向下
a[++x][y] = num++;
while (y - 1 >= 0 && !a[x][y - 1]) //向左
a[x][--y] = num++;
while (x - 1 >= 0 && !a[x - 1][y]) //向上
a[--x][y] = num++;
}
for (x = 0; x < n; x++) //print 陣列
{
for (y = 0; y < n; y++) {
if (y != n - 1) {
printf("%d ", a[x][y]);
} else {
printf("%d", a[x][y]);
}
}
printf("\n");
}
break;
}
return 0;
}
At least this problem:
Variable Length Arrays (VLA) cannot be initialized via the C standard.
Alternate, assign via memset() after defining a.
// int a[n][n]={0};
int a[n][n];
memset(a, 0, sizeof a);
void evolve(board prv, board nxt){
int i, j;
int n;
printf("\rGeneration %d\n", generation++);
if (printLazy == 1){
lazyPrint(prv);
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
if (prv[i][j] && (n == 3 || n == 2))
nxt[i][j] = true;
else if (!prv[i][j] && (n == 3))
nxt[i][j] = true;
else
nxt[i][j] = false;
}
}
}
** Some asked me to add the neighbors method so
static int neighbors (board b, int i, int j) {
int n = 0;
int i_left = max(0,i-1);
int i_right = min(HEIGHT, i+2);
int j_left = max(0,j-1);
int j_right = min(WIDTH, j+2);
int ii, jj;
for (ii = i_left; ii < i_right; ++ii) {
for (jj = j_left; jj < j_right; ++jj) {
n += b[ii][jj];
}
}
return n - b[i][j];
}
So I am working on optimizing this so that it will go faster and I'm stuck on how to optimize this more. Here's what I have so far
void evolve(board prv, board nxt) {
register int i, j;
int n;
bool next;
printf("\rGeneration %d\n", generation++);
if (printLazy == 1){
lazyPrint(prv);
}
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
if (prv[i][j])
if (n == 2)
next = true;
else if (n == 3)
next = true;
else
next = false;
else
if(n == 3)
next = true;
else
next = false;
nxt[i][j] = next;
}
}
}
Is there a better way to do this or are there any resources or videos y'all recommend?
Thanks, any help is appreciated.
Some ideas Inline your function neighbors(). Or turn it into a macro. Tidy up the conditional. To unroll the inner loop replace every use of i with the literal values so your code looks like :
for (j =0;.......
n = fun(prev, 0 ,j);
If.....
n = fun(prev, 1, j);
if......
and so on.
If the value of HEIGHT was let's say 100, then you get a code explosion of 100 function calls and 100 compound conditionals. Even worse if you unroll the outer loop.
If n was limited to say 8 neighbors, use a lookup table
bool foo[2][8] = { [1][2] = true, [1][3] = true, [0][3] = true };
for (j=0; j < WIDTH; ++j) {
for (i = 0; i < HEIGHT; ++i) {
n = neighbors(prv, i, j);
nxt[i][j] = foo[prv[i][j]][n];
}
}
A common weakness is the neighbors(prv, i, j) function itself. One trick to to oversize the 2D array by 1 on all four sides and populate the edge with false so neighbors() can always check 8 neighbors as it is never used on the edge/corners.
Making sure the 2nd dimension is a power of 2 helps also - simplifies index calculation. So if the original array way 12*11, make the new array (1+12+1)*(1+11+1+4) or 14*16.
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;
}
I'm trying to write a function or method for the code. I'm really lost at how to come with the loop that print out the number born and number died in the output below.
Here is my code:
#include <stdio.h>
char grid[10][10];
// Moved this function here
int occ(int x, int y) {
int i, j, count;
char gridCopy[10][10];
// You probably are going to do this often in the future
// Make a function for it instead of having the same code often
void printGrid() {
int i, j;
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++)
printf("%c", grid[i][j]);
printf("\n");
}
}
You don't need gridCopy in occ function.
Please remember that array is transposed. When you access element (x,y) you need to use grid[y][x]
Below is the working code with function generateNext() which generates next state for whole grid array. This is place where you need girdCopy. Results are exactly the same as in your example.
#include <stdio.h>
#include <stdlib.h>
char grid[10][10];
int born,died,generation;
// Moved this function here
int occ(int x, int y) {
int count;
int xm1,xp1,ym1,yp1;
xm1=x-1;xp1=x+1;ym1=y-1;yp1=y+1;
if (xm1<0) // handle boundary cases - wrap around
xm1=9;
if (ym1<0)
ym1=9;
if (xp1>9)
xp1=0;
if (yp1>9)
yp1=0;
// Checking on the value of the neighboring cells
count = 0;
if (grid[ym1][x] == '*')
count++;
if (grid[ym1][xp1] == '*')
count++;
if (grid[y][xp1] == '*')
count++;
if (grid[yp1][xp1] == '*')
count++;
if (grid[yp1][x] == '*')
count++;
if (grid[yp1][xm1] == '*')
count++;
if (grid[y][xm1] == '*')
count++;
if (grid[ym1][xm1] == '*')
count++;
return count;
}
void generateNext()
{
int x,y;
char gridCopy[10][10];
born=0;died=0;
generation++;
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
gridCopy[y][x]=grid[y][x];
}
}
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
if (grid[y][x]=='*' && occ(x,y)<2)
{gridCopy[y][x]='-';died++;}
if (grid[y][x]=='*' && occ(x,y)>3)
{gridCopy[y][x]='-';died++;}
if (grid[y][x]=='-' && occ(x,y)==3)
{gridCopy[y][x]='*';born++;}
}
}
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
grid[y][x]=gridCopy[y][x];
}
}
}
// You probably are going to do this often in the future
// Make a function for it instead of having the same code often
void printGrid() {
int x, y;
for (y = 0; y < 10; y++) {
for (x = 0; x < 10; x++)
printf("%c", grid[y][x]);
printf("\n");
}
}
/*
*
*/
int main(int argc, char** argv) {
int x, y, answ;
// Setting entire grid to '-'
for (y = 0; y < 10; y++)
for (x = 0; x < 10; x++)
grid[y][x] = '-'; // No need for a variable, just use '-' directly
// Printing out grid
printf("This is the original array\n");
printGrid();
// Setting initial state
grid[5][4] = '*'; // No need for a variable, just use '*' directly
grid[5][5] = '*';
grid[5][6] = '*';
grid[4][4] = '*'; grid[3][4] = '*';
grid[4][6] = '*'; grid[3][6] = '*';
// Printing out grid
printf("This is the new array\n");
printGrid();
//printf("The number of neighbors is: %d\n", occ(3, 3));
generation=0;
answ=1;
while(answ)
{
generateNext();
printf("\n\nGeneration number %d",generation);
printf("\nBorn=%d,Died=%d\n",born,died);
printGrid();
printf("\nPrint next generation-1,Exit-0:");
scanf("%d",&answ);
}
return (EXIT_SUCCESS);
}
Counting is similar to what you have to do to print or copy the whole grid: you use the same loop(s), but at each cell, add to the appropriate counter depending on what is in it.
Alternatively, if keep counts of the number of dead and live cells, you can update those as you update the grid: if a cell changes, update the counters appropriately if the cell becomes alive or becomes dead. This can also be used if you need to report how many were born & how many died each turn.
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.