Printing out mandlebrot in ascii - c

I'm trying to print out the ASCII version of mandlebrot in C and it doesn't seem to be working. The main thing is changing the complex c in escapeSteps as the grid changes.
Expected result:
This is my current code for printing out the result. I think the complex c changing is the reason why it's not working but its just printing out all spaces.
The escapeSteps function checks to see if its in the mandlebrot. C is a complex struct with real and imaginary values.
//TILE_SIZE = 512 pixels
int x = 0;
int y = 0;
for (y = 0; y < TILE_SIZE; y++) {
for (x = 0; x < TILE_SIZE; x++) {
complex(c) = {(x),(y)};
if (escapeSteps(c) == 256) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}
return 0;
}

Related

My dynamically allocated 2d array print random gibberish with no meaning

This code can get the first row to print, but for some reason will not get the first column to print. If this clarifies the question a bit the x values print but the y value barely does, I get some weird characters instead.
char** GenerateLand(int width, int height) {
char** GenLand;
int i;
GenLand = malloc(width * sizeof(char*));
for(i = 0; i < width; i++) {
GenLand[i] = malloc(sizeof(char) * height);
}
char RandChar = PickLandType();
int x, y;
for(x = 0; x < width; x++) {
if(x == 0) {
GenLand[x][0] = RandChar;
} else {
char RandChar1 = GenerateNeighbor(RandChar);
GenLand[x-1][0] = GenerateNeighbor(RandChar1);
for( y = 0; y < height ; y++){
if(y == 0){
GenLand[x][y] = RandChar;
} else {
char RandChar2 = GenerateNeighbor(RandChar);
GenLand[0][y-1] = GenerateNeighbor(RandChar2);
}
}
}
return GenLand;
for(i = 0; i < width; i++) {
free(GenLand[i]);
}
free(GenLand);
}
char GenerateNeighbor(char item)
{
switch(item)
{
case 'R':
return NewFromRuralLand();
break;
case 'F':
return NewFromForest();
break;
case 'T':
return NewFromTown();
break;
case 'W':
return NewFromWater();
break;
case 'C':
return NewFromCity();
break;
case 'M':
return NewFromMountain();
break;
default:
printf("Error!");
break;
}
}
char PickLandType()
{
int typeOfLand = rand()%5;
if(typeOfLand == 0){
return 'R';
} else if(typeOfLand == 1){
return 'F';
} else if(typeOfLand == 2){
return 'T';
} else if(typeOfLand == 3){
return 'W';
} else if(typeOfLand == 4){
return 'C';
} else if(typeOfLand == 5){
return 'M';
}
}
void PrintLand(char** Land, int width, int height) {
int x, y;
for( x = 0; x < width; x++){
for( y = 1; y < height ; y++){
printf("%c", Land[x][y]);
}
}
}
https://i.stack.imgur.com/t6Fec.png ^ Picture of error, was hoping someone could tell me why I keep getting these cryptic unreadable values. Sorry I don't have enough reputation points to directly embed the picture. I checked my NewFrom() functions and they all work so I do not believe they are the issue. The output is supposed to be organized by row and column:
I don't have enough reputation to comment, hence I have to write this as an answer.
Your freeing code at the end of GenerateLand will never run, there is an unconditional return statement prior to it. (NB: You shouldn't be freeing it regardless as you want to return GenLand, just remove the freeing code)
Without giving us the PickLandType and GenerateNeighbor functions, we can't tell you why your code returns a garbled mess of letters. Please edit and attach these functions.
This is the exact same question you asked before, except now you've attached different output - have you changed the code inbetween? If so, please attach the updated code.
This is bad code, the first iteration will access GenLand[0][-1]:
for(y = 0; y < height; y++) {
GenLand[0][y-1] = GenerateNeighbor(RandChar1);
}
Please try and keep your code nicely formatted to that it's easier for everyone to read.
If you want an answer that can actually help, give the GenerateNeighbor and PickLandType functions, and also give us an expected output.
Edit:
As Paul Ogilvie pointed out, the code in point 4 will also only ever generate the 0th column (the left most column). You probably meant for this to be GenLand[x][y] (but once again, see point 4)

Replace a character with another character + Setting a tie game

This is for Homework
I have to create a game of TicTacToe for a project and I have two issues. Also I apologize if I'm violating a rule by having two questions within one post, If it's not allowed then I'd appreciate someone notifying me in the comments and I'll go ahead and break this into two separate posts. I'll post my code then ask my questions following the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char table[3][3];
void clear_table();
void player1_move();
void player2_move();
void the_matrix(); // Like the movie
char check_three();
int main() {
srand(time(NULL));
char win;
printf("This program plays the game of Tic Tac Toe.\n");
win = ' ';
clear_table();
do {
the_matrix(); // Like the movie
player1_move();
win = check_three(); // Check win for player 1
if (win != ' ')
break;
player2_move();
win = check_three(); // Check win for player 2
}
while (win == ' ');
the_matrix(); // Shows the final move+Like the movie
if (win == 'O')
printf("Congratulations, Player 1 wins!\n");
else
printf("Congratulations, Player 1 lost!\n");
// the_matrix (); //Shows the final move+Like the movie
return 0;
}
void clear_table() {
// Creates empty spaces for the user and computer to enter stuff in
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
// for(l = 0; k < 3; j++)
table[i][j] = ' ';
}
}
void player1_move() {
// Moves that player 1 can and can't make
int x, y, z;
printf("Player 1 enter your selection[row, col]: ");
scanf("%d, %d", &x, &y);
x--;
y--;
// z--;
if (table[x][y] != ' ') {
printf("Space already taken, please try again.\n");
player1_move();
}
else
table[x][y] = 'O'; // O goes first for some reason
}
void player2_move() {
// Needs work!!
// Call srand in the main
int a = rand() % 3;
int b = rand() % 3;
// Make it so the game would end in a tie when possible
for (a = rand() % 3; a < 3; a++) {
for (b = rand() % 3; b < 3;
b++) // For loops causing issues in randomization?
// for(c = 0; c < 3; c++)
if (table[a][b] == ' ')
break;
if (table[a][b] == ' ') // Checks the rows and columns
break;
}
if (a * b == 9)
**Kinda works ? ** {
printf("Game Over, No Player Wins\n");
exit(0);
}
else
table[a][b] = 'X';
}
void the_matrix() { // Like the movie
**Get rid of the underscores **
int m;
printf("The current state of the board:\n");
for (m = 0; m < 3; m++) {
printf("%c_ %c_ %c_\n", table[m][0], table[m][1], table[m][2]);
}
printf("\n");
}
char check_three() {
int w;
// char table[3][3];
for (w = 0; w < 3; w++) {
if (table[w][0] == table[w][2] && table[w][0] == table[w][1])
return table[w][0]; // Row Check
}
for (w = 0; w < 3; w++) {
if (table[0][w] == table[2][w] && table[0][w] == table[1][w])
return table[0][w]; // Col Check
}
if (table[0][0] == table[1][1] && table[1][1] == table[2][2])
return table[0][0];
if (table[0][2] == table[1][1] && table[1][1] == table[2][0])
return table[0][2]; // Diag Check
return ' ';
}
First Question
So my first question is with a draw game. On the player two function I have a snip of code set to determine a draw game. Initially I assumed that if the X's and O's were to multiply to 9 then that would mean that the board would be filled up then that would result in a draw game. [This is within my third function - player2_move near the end of the function] It kind of works, but sometimes the program just preemptively ends the game. It's a bit hard to test it because the computers moves are randomized and most of the times I've tried, I ended up winning accidentally. My question is what would I need to do to set up my program to essentially have a better way of determining a draw game.
Second Question
On my 4th function called the_matrix I need help with formatting. The assignment requires the format to be a little like this where if I were to enter in the coordinates 1,1 then the board would look like this:
O _ _ with the proceeding lines near the bottom to be blank. However as my program is right now, it looks like this:
O_ _ _
What I want to do is swap or replace the underscore with the user's input. Not entirely sure how to do that and any help would be appreciated.
I apologize if I violated any rules for stackoverflow by having two questions in one and I'm also sorry for this huge post.

C: Comparing two elements not producing correct results?

My code is below, most of which may not be helpful, but maybe the problem lies outside of where I think it is. That being said, please read the following first because it gives the rundown of my code and states where I think the problem lies.
I'm trying to create a Battleship game in C. I first create two two-dimensional arrays, one representing the player's board and one representing the enemy's board. I fill both of them with periods. I print them out with numbers along the sides to make things look nice (using my initialPrintBoards function). I then set the locations of the enemy's ships by replacing some of the periods in the enemy's array with 's' and print it out to make sure they are where I want them to be. They are, which is great. I then have the player "fire" at the enemy's ship. This is done by replacing 's' in the enemy's array with 'x' (which represents a hit) or replacing '.' with 'o' (which represents a miss). I print this out, and everything works well.
Now, here's where I hit a problem. Up to this point, for the sake of testing, the enemy's ships have been completely visible to the player via my print method. I don't want that. So, what I figured I'd do is create a new print function (called printBoards) that does exactly what my previous print function does except it prints '.' on the board when it encounters 's' as an element in the enemy's array. My initial thought in accomplishing this was to use comparisons. Basically, if the element stored in the enemy's array at location whatever is 's', print '.', otherwise print out what's stored at that location in the array (which would be '.', 'x', or 'o'). Unfortunately, all it does is print all periods, even if there's an 'x' or 'o' stored at that location in the array. I'm at a loss as to why this is. I'm quite new to C (I've studied Java in the past), so maybe there's something about comparisons in C that I don't know about. But that's assuming the problem is with the comparisons, which it might not be.
Any help or hints would be greatly appreciated.
#include <stdio.h>
char playerBoard[8][8];
char enemyBoard[8][8];
void fillBoards()
{
int a;
for (a = 0; a < 8; a++)
{
int b;
for (b = 0; b < 8; b++)
{
enemyBoard[a][b] = '.';
}
}
int x;
for (x = 0; x < 8; x++)
{
int y;
for (y = 0; y < 8; y++)
{
playerBoard[x][y] = '.';
}
}
}
void initialPrintBoards()//This is used before the enemy's ships are set.
{
printf("Enemy Board\n*12345678\n");
int a;
for (a = 0; a < 8; a++)
{
printf("%d", a + 1);
int b;
for (b = 0; b < 8; b++)
{
printf("%c", enemyBoard[a][b]);
}
printf("\n");
}
printf("\n");
printf("Player Board\n*12345678\n");
int x;
for (x = 0; x < 8; x++)
{
printf("%d", x + 1);
int y;
for (y = 0; y < 8; y++)
{
printf("%c", playerBoard[x][y]);
}
printf("\n");
}
printf("\n");
}
void printGreeting()
{
printf("\nWelcome to Battleship!\n\n");
}
void setEnemyShips()
{
// Ship 1.
enemyBoard[3][2] = 's';
enemyBoard[4][2] = 's';
enemyBoard[5][2] = 's';
// Ship 2.
enemyBoard[1][1] = 's';
enemyBoard[1][2] = 's';
enemyBoard[1][3] = 's';
// Ship 3.
enemyBoard[6][5] = 's';
enemyBoard[6][6] = 's';
enemyBoard[6][7] = 's';
}
void playerFire()
{
if (enemyBoard[2][2] == 's')
{
enemyBoard[2][2] = 'x';
}
else
{
enemyBoard[2][2] = 'o';
}
}
void printBoards()//This is used after the enemy's ships are set.
{
printf("Enemy Board\n*12345678\n");
int a;
for (a = 0; a < 8; a++)
{
printf("%d", a + 1);
int b;
for (b = 0; b < 8; b++)
{
if (enemyBoard[1][0] == 's')
{
printf("%c", '.');
}
else
{
printf("%c", enemyBoard[1][0]);
}
}
printf("\n");
}
printf("\n");
printf("Player Board\n*12345678\n");
int x;
for (x = 0; x < 8; x++)
{
printf("%d", x + 1);
int y;
for (y = 0; y < 8; y++)
{
printf("%c", playerBoard[x][y]);
}
printf("\n");
}
printf("\n");
}
int main()
{
fillBoards();
printGreeting();
initialPrintBoards(); //This will print the boards before the enemy's ships are set.
setEnemyShips();
initialPrintBoards(); //This will end up printing the enemy ships' locations. Need a different print method.
playerFire();
initialPrintBoards(); //This prints to see if a hit or miss is properly printed.
printBoards(); //This prints to see if the ships are hidden and a hit or miss is properly printed.
return 0;
}
regarding this code, found in the printBoards() function:
if (enemyBoard[1][0] == 's')
{
printf("%c", '.');
}
else
{
printf("%c", enemyBoard[1][0]);
}
This always looks at the second row, first column to determine what is printed. As you saw, that is an error.
Suggest:
if (enemyBoard[a][b] == 's')
{
printf("%c", '.');
}
else
{
printf("%c", enemyBoard[a][b]);
}
Let the Board[][] variables contain the state '.' (water) or 'A', 'B' ... 'E' for the 5 ships.
When a ship is hit, change 'A' to 'a', etc.
When printing, pass in a control variable to control how the view is rendered: Enemy View, Player View, Programmer View.

Need some suggestions on how to print a histogram more neatly

I'm writing a program that will read input and then give back a histogram of the character count from K & R - Ex. 1.13
Any suggestions on how I can improve my code? Does it matter whether or not if I test for status in condition or out first? I have noticed in my examples people test to see if c is a blank or tab first.
I think I need to revisit my histogram. It doesn't really scale the results. It just draws a hyphen based on the length.
Revised to make a little bit more readable I think.
// Print a histogram of the length of words in it's input.
#include <stdio.h>
#define IN 1
#define OUT 2
#define MAX 99
int main(){
int c; // the character
int countOfLetters = 0;
int insideWord = OUT;
int frequencyOfLengths[MAX];
int longestWordCount = 0;
int i, j; // Counters
for (i = 0; i < MAX; i++){
frequencyOfLengths[i] = 0;
}
while ((c = getchar()) != EOF){
if (c == ' ' || c == '\n' || c == '\t'){
if (insideWord == IN){
if (countOfLetters > MAX){
return 1;
}
++frequencyOfLengths[countOfLetters];
if (countOfLetters >= longestWordCount) longestWordCount = countOfLetters;
}
countOfLetters = 0;
}
else {
countOfLetters++;
insideWord = IN;
}
}
for (i = 1; i <= longestWordCount; i++){
printf("%3i : %3i ", i, frequencyOfLengths[i]);
for (j = 0; j < frequencyOfLengths[i]; j++){
printf("*");
}
printf("\n");
}
return 0;
}
Definitely scale results, check out my Character Histogram that does a horizontal scaling histogram.
Also, you could benefit a y-axis label. It's hard to tell which bar is for which kind of word length. I have no idea which bar is for what word length.
I added this code right before you display the histogram, it basically halves every value, which does throw off your bar number labels. You can figure it out!
// Iterates and tells us the most frequent word length
int mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
// If the bar will be too big, cut every value in half
while (mostFrequent > 60) {
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > 0) {
charCount[i] /= 2;
charCount[i] |= 1;
}
// Check again to find the most frequent word length category
mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
}
Honestly the bars are hard to read, maybe just use a single row of characters such as █ !
Great book so far, we're practically reading it together and are on the same page!
Cheers

What is an efficient way to get column from multi-dimensional array in C?

I have two structs: ARRAY2D (multidimensional) and ARRAY (one-dimensional). I would like to get a column from type ARRAY2D and copy it into type ARRAY.
Although my code works below, and I recognize this is probably a poor way of getting a column from an array, I'm curious what optimizations there might be to avoid an O(n2) algorithm. What is an efficient way to get a column from an array in C?
BOOL arr2_getColumn(ARRAY2D *arr, const int column_index, ARRAY *returnedArray)
{
int x, y;
int i = 0;
/* Check for valid array. */
if (arr->blnIsInit != TRUE)
return FALSE;
/* Initialize array with the column's height. */
if (!arr_init(returnedArray, arr->height))
return FALSE;
/* Copy over column. */
for (y = 0; y < arr->height; y++)
{
for (x = 0; x <= column_index; x++)
{
if (x == column_index)
{
returnedArray->array[i] = arr->array[y * arr->width + x];
i++;
}
}
}
/* Set the new size. */
returnedArray->size = arr->height;
return TRUE;
}
Get rid of i and x.
for (y = 0; y < arr->height; y++)
{
returnedArray->array[y] = arr->array[y * arr->width + column_index];
}
/* Copy over column. */
for (y = 0; y < arr->height; y++)
{
x = column_index;
returnedArray->array[i] = arr->array[y * arr->width + x];
i++;
}

Resources