I wrote this C code for Conway's Game of Life simulation. It works perfectly except for when user enter a character as input.This is what I've done so far. If I enter any character e.g. * or / when the program asks for input, the program freezes or goes in a infinite loop. Can someone help me about it. I've tweaked the code in all possible ways to remove the bug but all in vain.
#include "stdio.h" //for all basic functions
#include "stdlib.h"//for exit function
#include "time.h" //for random seed
#include "windows.h" //for Sleep function
#include "conio.h" //for _kbhit function
#define scanf_s scanf //typing scanf_s is tedious compared to typing scanf
void neighbour_manager();//custom function to calculate neighbours and make a cell alive or dead accordingly
void generation_printer();//custom function to print the generations after selecting seed type
//initializing all variables
int generation;
char fill_char;
char array[35][85];
char array1[35][85];
char live = '+';//using + sign for live cells
char dead = ' ';//using blank spaces for dead cells
char n;
char random_seed[3]={' ','+','\0'};//for random seed i.e. (case:12)
//SEEDS
char block[2][2] = {{'+','+'}, {'+','+'}};
char boat[3][3] = {{'+','+',' '}, {'+',' ','+'}, {' ','+',' '}};
char loaf[4][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', ' ', '+'},{' ', ' ', '+', ' '}};
char beehive[3][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', '+', ' '}};
char blinker[1][3] = {{'+', '+','+'}};
char beacon[4][4] = {{'+','+',' ',' '},{'+',' ',' ',' '},{' ',' ',' ','+'},{' ',' ','+','+'}};
char toad[2][4] = {{' ','+','+','+'},{'+','+','+',' '}};
char pulsar[15][15] = {
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'},
{' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '},
{'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '}
};
char glider[3][3] = {{' ','+',' '},{' ',' ','+'},{'+','+','+'}};
char spaceship[4][5] = {{'+',' ',' ','+',' '},{' ',' ',' ',' ','+'},{'+',' ',' ',' ','+'},{' ','+','+','+','+',}};
char gosper_glider_gun[15][38] = {
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' },
{ ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', ' ', '+', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
};
//main function starts here
int main(void)
{int i = 0, j = 0; //initializing some more variables
int a = 0, b = 0, seed_type = 0;
int choice_after_execution=0;
system("title CONWAY'S GAME OF LIFE");//to change the console title
_flushall();//to remove garbage values
printf("\t\t\t\t\tWelcome to Conway's Game of Life\n");//welcome note
Sleep(2500);//for dramatic purposes
system("cls");
printf("Please make sure the console is maximized for optimal simulation.");//whole grid is not visible if console is not maximized
Sleep(2000);//to create a pause to maximize screen before proceeding
start: //jump point in case user decides to restart the game
for (i = 0; i < 35; i++) { //emptying the array to avoid double printing of patterns in the same grid
for (j = 0; j < 85; j++) {
array[i][j]=dead;
}
}
system("cls");
printf("Select the seed type\nSTILL LIFE PATTERNS\nEnter 1 for Block \nEnter 2 for Loaf \nEnter 3 for Boat\nEnter 4 for Beehive\n\nOSCILLATORS\nEnter 5 for Blinker\nEnter 6 for Beacon\nEnter 7 for Toad\nEnter 8 for Pulsar\n\nGLIDERS AND SPACSHIPS\nEnter 9 for Glider\nEnter 10 for Spaceship\n\nGOSPER GLIDER GUN\nEnter 11 for Gosper Glider Gun\n\nRANDOM\nEnter 12 for Random\n\nYour choice: ");
retake_seed_type: //jump point for invalid choice
scanf("%d", &seed_type);
srand(time(NULL)); //random seed generator
a = 1 + rand() % 35; //randomizing the row for first generation
b = 1 + rand() % 85; //randomizing the column for first generation
switch (seed_type)//switch case for different seed types
{
case 1: //for block
for (i = a; i < a + 2; i++){
for (j = b; j < b + 2; j++){
array[i%35][j%85] = block[i - a][j - b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 2://for loaf
for (i = a; i <a + 4; i++){
for (j = b; j <b + 4; j++){
array[i%35][j%85] = loaf[i - a][j - b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 3://for boat
for (i = a; i <a + 3; i++){
for (j = b; j <b + 3; j++){
array[i%35][j%85] = boat[i - a][j - b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 4://beehive
for(i = a; i <a + 3; i++){
for(j = b; j <b + 4; j++){
array[i%35][j%85] = beehive[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 5://blinker
for(i=a;i<a+1;i++){
for(j=b;j<b+3;j++){
array[i%35][j%85] = blinker[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 6://beacon
for(i=a;i<a+4;i++){
for(j=b;j<b+4;j++){
array[i%35][j%85] = beacon[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 7://Toad
for(i=a;i<a+2;i++){
for(j=b;j<b+4;j++){
array[i%35][j%85] = toad[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 8://Pulsar
for(i=a;i<a+15;i++){
for(j=b;j<b+15;j++){
array[i%35][j%85] = pulsar[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 9://glider
for(i=a;i<a+3;i++){
for(j=b;j<b+3;j++){
array[i%35][j%85] = glider[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 10://spaceship
for(i=a;i<a+4;i++){
for(j=b;j<b+5;j++){
array[i%35][j%85] = spaceship[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 11://gosper glider gun
for(i=a;i<a+15;i++){
for(j=b;j<b+38;j++){
array[i%35][j%85] = gosper_glider_gun[i-a][j-b];//i%35 and j%85 to facilitate wrap around
}
}
break;
case 12://random
a=0;
b=0;
for(i=a;i<35;i++){
for(j=b;j<85;j++){
array[i][j] = random_seed[1+rand()%2];
}
}
break;
default://default case asks for input again
printf("Enter a valid choice i.e. from 1 to 12: ");
goto retake_seed_type;//go-to statement to take seed_type input again
}
printf("\nEnter the number of generations(-1 for infinite): ");
scanf_s("%d", &generation);
if(generation>0){//different cases for generation input
for (i = 1; i <= generation; i++){
system("cls");
neighbour_manager();
generation_printer();
printf("GENERATION NUMBER: %d\n", i);//to know how many generations have been printed
printf("Press any key to stop simulation.\n");
if(_kbhit())//if user presses a key to stop simulation
{
printf("Generation Interrupted.");
break;
}
if(i==generation)//if user does not interrupt generations
{
Sleep(200);//dramatic purposes
printf("Generation completed successfully.");
}
Sleep(700);//according to the instructions
}
}
if (generation <0)
{int z=0;
while (!_kbhit())//to make sure loop continues printing unless user press a key on keyboard
{
system("cls");
neighbour_manager();
generation_printer();
z++;//generation counter
printf("GENERATION NUMBER: %d\n", z);//to know how many generations have been printed
printf("Press any key to stop simulation.\n");
Sleep(700);//according to the instructions
if(_kbhit())//if user presses a key to stop simulation
{
printf("Generation Interrupted.");
break;
}
}
}
if(generation==0)
{ system("cls");
printf("No generations printed.");
}
printf("\nPress 1 to Restart.\nPress 2 to Exit.\nYour Choice: ");//exit message
after_generation_valid_choice://jump point in case of wrong input choice
scanf("%d",&choice_after_execution);
if(choice_after_execution==1)
goto start;//if user wants to start simulation again then go back to start
if(choice_after_execution==2)//if user wants to exit
{
printf("Thank you for using this program.");
Sleep(2000);//for dramatic purposes
goto exit;//if user decides to exit the program then skip system pause and just exit
}
else
{
printf("Enter a valid choice: ");//if invalid choice is entered ask again
goto after_generation_valid_choice;
}
exit://jump point in case user wants to exit
exit(0);
}//main end
void neighbour_manager(){ //custom function to decide whether cells should be alive or dead
int i, j; //corresponding to the number of neighbours alive or dead
int neighbour;
for ( i = 0; i < 35; i++){
for ( j = 0; j < 85; j++){
neighbour = 0;
if (array[i - 1 < 0 ? 34 : i - 1][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;//modifications in row and
if (array[i - 1 < 0 ? 34 : i - 1][j] == live) neighbour = neighbour + 1; //column numbers to ensure
if (array[i - 1 < 0 ? 34 : i - 1][(j + 1) % 85] == live) neighbour = neighbour + 1; //that the patterns wrap
if (array[i][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1; //around
if (array[i][(j + 1) % 85] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][j] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][(j + 1) % 85] == live) neighbour = neighbour + 1;
if(neighbour == 3) //game rules that decide whether a cell would be alive or
{ //not in the next generation
array1[i][j] = live;
}
else if (neighbour < 2 || neighbour > 3)
{
array1[i][j] = dead;
}
else
{
array1[i][j] = array[i][j];
}
}
}
for(i=0; i<35; i++){ //replace array1 with array
for(j=0; j<85; j++){
array[i][j] = array1[i][j];
array1[i][j] = ' '; // now empty array1
}
}
return;
}
int ran_out_of_variable_names1 = 35;
int ran_out_of_variable_names2 = 85;
void generation_printer() //custom function that prints both border and the array(with patterns)
{
int i,j;
// Top border
for (i = 0; i < ran_out_of_variable_names2 + 2; i++) {
printf("*");
}
printf("\n");
for (i = 0; i < ran_out_of_variable_names1; i++) {
// Star to the beginning of the line
printf("*");
// Contents of the line
for (j = 0; j < ran_out_of_variable_names2; j++) {
printf("%c", array[i][j]);
}
// Star at the end of the line
printf("*\n");
}
// Bottom border
for (i = 0; i < ran_out_of_variable_names2+ 2; i++) {
printf("*");
}
printf("\n");
}
//END OF CODE
If the input buffer contains non-digit characters and you use scanf() rith %d to read input, the input will fail and the non-digit characters will remain buffered, only for the subsequent scanf() to fail because nothing has changed.
Solutions are legion; here's one:
while( scanf("%d",&choice_after_execution) != 1 )
{
while( getchar() != '\n' ) ; // read buffer until end of line
}
An alternative is to read an entire line of input using fgets() and parse it using sscanf().
I strongly suggest that however you do it, you wrap the solution in a function for reuse (so you only have to solve the problem once):
int getDecimalInput()
{
int input = 0 ;
while( scanf("%d",&input) != 1 )
{
while( getchar() != '\n' ) ; // read buffer until end of line
}
return input ;
}
Related
Trying to make a tic-tac-toe game and having trouble with the grid, I'm new to C and have looked everywhere but nothing seems to work.
int main(void) {
char grid[GRID_HEIGHT][GRID_WIDTH];
grid = make_grid((char **)grid);
print_grid((char **)grid);
}
char ** make_grid(char **grid) {
char grid[GRID_HEIGHT][GRID_WIDTH] = {
{ '\n', ' ', '1', ' ', '|', ' ', '2', ' ', '|', ' ', '3', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '4', ' ', '|', ' ', '5', ' ', '|', ' ', '6', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '7', ' ', '|', ' ', '8', ' ', '|', ' ', '9', ' ' }
};
return grid;
}
void print_grid(char **grid) {
for (int row = 0; row < GRID_HEIGHT; row++) {
for (int column = 0; column < GRID_WIDTH; column++) {
printf("%c", grid[row][column]);
}
}
printf("\n");
}
How would I parse the grid into a function and also return it without the program crashing?
You already declared the array grid in main.
char grid[GRID_HEIGHT][GRID_WIDTH];
So for example this function definition
char ** make_grid(char **grid) {
char grid[GRID_HEIGHT][GRID_WIDTH] = {
{ '\n', ' ', '1', ' ', '|', ' ', '2', ' ', '|', ' ', '3', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '4', ' ', '|', ' ', '5', ' ', '|', ' ', '6', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '7', ' ', '|', ' ', '8', ' ', '|', ' ', '9', ' ' }
};
return grid;
}
does not make sense at least because the parameter is redeclared in the outer block scope of the function.
The function could look the following way
void make_grid( char ( *grid )[GRID_WIDTH] )
{
static const char *rows[] =
{
{ "\n 1 | 2 | 3 " } ,
{ "\n-----------" } ,
{ "\n 4 | 5 | 6 " } ,
{ "\n-----------" } ,
{ "\n 7 | 8 | 9 " }
};
const size_t N = sizeof( rows ) / sizeof( *rows );
for ( size_t i = 0; i < N; i++ )
{
strncpy( grid[i], rows[i], GRID_WIDTH );
}
}
and called like
make_grid( grid );
The function print_grid can be defined like
void print_grid( char ( *grid )[GRID_WIDTH], size_t height )
{
for ( size_t row = 0; row < height; row++) {
for ( size_t column = 0; column < GRID_WIDTH; column++) {
printf("%c", grid[row][column]);
}
putchar( '\n' );
}
putchar( '\n' );
}
and called like
print_grid( grid, GRID_HEIGHT );
Fundamental problems:
You need to #include relevant headers.
You need to declare functions before calling them.
You cannot return arrays from functions in C. You can return pointers, but that might be the wrong solution. If you wish to copy an array, you must use memcpy.
You cannot have two variables with the same name grid in the same scope.
Pointer-to-pointers cannot point at arrays and they are not compatible with arrays. So you cannot use pointer-to-pointer here.
Fixed code:
#define GRID_HEIGHT 5
#define GRID_WIDTH 12
#include <stdio.h>
#include <string.h>
void make_grid (char grid[GRID_HEIGHT][GRID_WIDTH]);
void print_grid (char grid[GRID_HEIGHT][GRID_WIDTH]);
int main(void) {
char grid[GRID_HEIGHT][GRID_WIDTH];
make_grid(grid);
print_grid(grid);
}
void make_grid (char grid[GRID_HEIGHT][GRID_WIDTH]) {
const char GRID [GRID_HEIGHT][GRID_WIDTH] = {
{ '\n', ' ', '1', ' ', '|', ' ', '2', ' ', '|', ' ', '3', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '4', ' ', '|', ' ', '5', ' ', '|', ' ', '6', ' ' } ,
{ '\n', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-' } ,
{ '\n', ' ', '7', ' ', '|', ' ', '8', ' ', '|', ' ', '9', ' ' }
};
memcpy( grid, GRID, sizeof(char[GRID_HEIGHT][GRID_WIDTH]) );
}
void print_grid (char grid[GRID_HEIGHT][GRID_WIDTH]) {
for (int row = 0; row < GRID_HEIGHT; row++) {
for (int column = 0; column < GRID_WIDTH; column++) {
printf("%c", grid[row][column]);
}
}
printf("\n");
}
In this example, the parameter grid in each function is an array, which "decays" into a pointer to the first element. The first element of a 2D array is a 1D array, so you end up with an array pointer. If you don't want the compiler to "decay" the array you could write the array pointer syntax manually: char (*grid)[GRID_WIDTH], but it is harder to read so I wouldn't recommend it.
Hi I am using a variable:
char board[9][9] = {
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, /* Game board */
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
};
What I want to do is use my structs which look like this:
typedef struct {
int adjacent_mines;
bool revealed;
bool is_mine;
char identifier[1];
} Tile;
struct GameState {
Tile tiles[NUM_TILES_X][NUM_TILES_Y];
};
typedef struct GameState GameState;
So that I can then use the following function to attach a character to my board[][]:
for (int i = 0; i < NUM_TILES_X; i++) {
for (int j = 0; j < NUM_TILES_Y; j++) {
board[i][j] = tileInfo.tiles[i][j].identifier;
}
}
Where the tileInfo.tiles[i][j].identifier has been set using this:
strcpy(tileInfo->tiles[x][y].identifier, "*");
The output I get on my console is that incompatible pointer to integer conversion assigning to 'char' from 'char [1]' how can I solve this and can someone please explain what is happening? Sorry if its dumb, I am new to C and pointers
Change
board[i][j] = tileInfo.tiles[i][j].identifier;
to
board[i][j] = tileInfo.tiles[i][j].identifier[0];
identifier is a array of characters of size 1. And board[i][j] is a char
Or change the type foridentifier to char since it size is 1
char identifier;
Two related problems:
You cannot do strcpy(tileInfo->tiles[x][y].identifier, "*"); into a char identifier[1];, because you didn't allocate room for the null terminator. You would have to do char identifier[2]; if you wish to use it as a string, rather than a single character.
board[i][j] = tileInfo.tiles[i][j].identifier; doesn't work because board[i][j] is a single character but identifier is an array.
You need to make up your mind about what identifier is supposed to be - a single character or a string? Right now it is neither. The simplest is to just make it char identifier; without array notation and then replace strcpy with simple assignment =.
I am struggling to build a function that can convert a number 0-9 in a string into the spelling word of it. Here is what I have so far, and I realize 'word' is not a built in conversion, it's just what my thoughts on how to construct this would be:
CREATE FUNCTION [dbo].[fn_Numbers2Words]
(#strText VARCHAR(1000))
RETURNS varchar(1000)
AS
BEGIN
WHILE PATINDEX('%[0-9]%', #strText) > 0
BEGIN
SET #strText = STUFF(#strText, PATINDEX('%[0-9]%', #strText), 1, CONVERT(word, PATINDEX('%[0-9]%', #strText)))
END
RETURN #strText
END
The idea would be to input something like this:
SELECT [dbo].[fn_Numbers2Word]('1900testnumber')
and return this:
'oneninezerozerotestnumber'
I have tried functions that do entire numbers, but since my strings will have alphas they do not work. I also tried incorporating those functions into this function above with no luck. I'm sure it's just something I'm doing syntax wise.
Can anyone help me alter my above function so that it produces my desired result?
Since you are just wanting a simple replacement then using nested replace would super crazy fast and simple. I would avoid using a scalar function here.
declare #strText varchar(1000) = '1900testnumber'
select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(#strText, '1', ' one'), '2', 'two'), '3', 'three'), '4', 'four'), '5', 'five'), '6', 'six'), '7', 'seven'), '8', 'eight'), '9', 'nine'), '0', 'zero')
Just for fun, here's another option that you could put into a function
Example
Declare #S varchar(max) = '1900testnumber'
Select #S = replace(#S,sFrom,sTo)
From (values ('0','zero')
,('1','one')
,('2','two')
,('3','three')
,('4','four')
,('5','five')
,('6','six')
,('7','seven')
,('8','eight')
,('9','nine')
) A(sFrom,sTo)
Select #S
Returns
oneninezerozerotestnumber
Brute force with CHOOSE:
Returns the item at the specified index from a list of values in SQL Server.
DECLARE #num INT = 20;
SELECT CHOOSE(#num,
'one ',
'two ',
'three ',
'four ',
'five ',
'six ',
'seven ',
'eight ',
'nine ',
'ten',
'eleven ',
'twelve ',
'thirteen ',
'fourteen ',
'fifteen ',
'sixteen ',
'seventeen ',
'eighteen ',
'nineteen ',
'twenty',
'twenty-one ',
'twenty-two ',
'twenty-three ',
'twenty-four ',
'twenty-five ',
'twenty-six ',
'twenty-seven ',
'twenty-eight ',
'twenty-nine ',
'thirty',
'thirty-one ',
'thirty-two ',
'thirty-three',
'thirty-four ',
'thirty-five ',
'thirty-six ',
'thirty-seven ',
'thirty-eight ',
'thirty-nine ',
'forty',
'forty-one ',
'forty-two ',
'forty-three ',
'forty-four ',
'forty-five ',
'forty-six ',
'forty-seven ',
'forty-eight ',
'forty-nine ',
'fifty',
'fifty-one ',
'fifty-two ',
'fifty-three ',
'fifty-four ',
'fifty-five ',
'fifty-six ',
'fifty-seven ',
'fifty-eight ',
'fifty-nine ',
'sixty',
'sixty-one ',
'sixty-two ',
'sixty-three ',
'sixty-four ',
'sixty-five ',
'sixty-six ',
'sixty-seven ',
'sixty-eight ',
'sixty-nine ',
'seventy',
'seventy-one ',
'seventy-two ',
'seventy-three ',
'seventy-four ',
'seventy-five ',
'seventy-six ',
'seventy-seven ',
'seventy-eight ',
'seventy-nine ',
'eighty',
'eighty-one ',
'eighty-two ',
'eighty-three ',
'eighty-four ',
'eighty-five ',
'eighty-six ',
'eighty-seven ',
'eighty-eight ',
'eighty-nine ',
'ninety',
'ninety-one ',
'ninety-two ',
'ninety-three ',
'ninety-four ',
'ninety-five ',
'ninety-six ',
'ninety-seven ',
'ninety-eight ',
'ninety-nine'
)
DBFiddle Demo
I have the simulation Game of Life in C language as my assignment. I've tried and failed many times to build a border of asterisks around the final printed array. Also I've used a few goto statements, which caused another problem: if i restart the game from the menu the last generating function namely "generation_printer" does not exit and as a result two patters appear on the grid instead of one.This is my progress so far
#include "stdio.h" //for all basic functions
#include "stdlib.h"//for exit function
#include "time.h" //for random seed
#include "windows.h" //
#include "conio.h" //
#define scanf_s scanf
void neighbour_manager();//custom function to calculate neighbours and make a cell alive or dead accordingly
void generation_printer();//custom function to print the generations after selecting seed type
//initializing all variables
int generation;
char fill_char;
char array[35][85];
char array1[35][85];
char live = '+';
char dead = ' ';
char n;
//SEEDS
char block[2][2] = {{'+','+'}, {'+','+'}};
char boat[3][3] = {{'+','+',' '}, {'+',' ','+'}, {' ','+',' '}};
char loaf[4][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', ' ', '+'},{' ', ' ', '+', ' '}};
char beehive[3][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', '+', ' '}};
char blinker[1][3] = {{'+', '+','+'}};
char beacon[4][4] = {{'+','+',' ',' '},{'+',' ',' ',' '},{' ',' ',' ','+'},{' ',' ','+','+'}};
char toad[2][4] = {{' ','+','+','+'},{'+','+','+',' '}};
char pulsar[15][15] = {
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'},
{' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '},
{'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'},
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
{' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '},
{' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '}
};
char glider[3][3] = {{' ','+',' '},{' ',' ','+'},{'+','+','+'}};
char spaceship[4][5] = {{'+',' ',' ','+',' '},{' ',' ',' ',' ','+'},{'+',' ',' ',' ','+'},{' ','+','+','+','+',}};
char gosper_glider_gun[15][38] = {
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' },
{ ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', ' ', '+', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
{ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }
};
//main function starts here
int main(void)
{
system("title CONWAY'S GAME OF LIFE");//to change the console title
_flushall();//to remove garbage values
printf("\t\t\t\t\tWelcome to Conway's Game of Life\n");//welcome note
Sleep(2000);//for dramatic purposes
system("cls");
printf("Please make sure the console is maximized for optimal simulation.");//whole grid is not visible if console is not maximized
Sleep(2000);//to create a pause to maximize screen before proceeding
start:
system("cls");
int i = 0, j = 0;
int a = 0, b = 0, seed_type = 0;
printf("Select the seed type\nSTILL LIFE PATTERNS\nEnter 1 for Block \nEnter 2 for Loaf \nEnter 3 for Boat\nEnter 4 for Beehive\n\nOSCILLATORS\nEnter 5 for Blinker\nEnter 6 for Beacon\nEnter 7 for Toad\nEnter 8 for Pulsar\n\nGLIDERS AND SPACSHIPS\nEnter 9 for Glider\nEnter 10 for Spaceship\n\nGOSPER GLIDER GUN\nEnter 11 for Gosper Glider Gun\nYour choice: ");
retake_seed_type: //For invalid choice
scanf_s("%d", &seed_type);
srand(time(NULL));
a = 1 + rand() % 35;
b = 1 + rand() % 85;
switch (seed_type)
{
case 1: //for block
for (i = a; i < a + 2; i++){
for (j = b; j < b + 2; j++){
array[i][j] = block[i - a][j - b];
}
}
break;
case 2://for loaf
for (i = a; i <a + 4; i++){
for (j = b; j <b + 4; j++){
array[i][j] = loaf[i - a][j - b];
}
}
break;
case 3://for boat
for (i = a; i <a + 3; i++){
for (j = b; j <b + 3; j++){
array[i][j] = boat[i - a][j - b];
}
}
break;
case 4://beehive
for(i = a; i <a + 3; i++){
for(j = b; j <b + 4; j++){
array[i][j] = beehive[i-a][j-b];
}
}
break;
case 5://blinker
for(i=a;i<a+1;i++){
for(j=b;j<b+3;j++){
array[i%35][j%85] = blinker[i-a][j-b];
}
}
break;
case 6://beacon
for(i=a;i<a+4;i++){
for(j=b;j<b+4;j++){
array[i%35][j%85] = beacon[i-a][j-b];
}
}
break;
case 7://Toad
for(i=a;i<a+2;i++){
for(j=b;j<b+4;j++){
array[i%35][j%85] = toad[i-a][j-b];
}
}
break;
case 8://Pulsar
for(i=a;i<a+15;i++){
for(j=b;j<b+15;j++){
array[i%35][j%85] = pulsar[i-a][j-b];
}
}
break;
case 9://glider
for(i=a;i<a+3;i++){
for(j=b;j<b+3;j++){
array[i%35][j%85] = glider[i-a][j-b];
}
}
break;
case 10://spaceship
for(i=a;i<a+4;i++){
for(j=b;j<b+5;j++){
array[i%35][j%85] = spaceship[i-a][j-b];
}
}
break;
case 11://gosper glider gun
for(i=a;i<a+15;i++){
for(j=b;j<b+38;j++){
array[i][j] = gosper_glider_gun[i-a][j-b];
}
}
break;
default:
printf("Enter a valid choice i.e. from 1 to 11: ");
goto retake_seed_type;
}
printf("\nEnter the number of generations(-1 for infinite): ");
scanf_s("%d", &generation);
for (i = 1; i <= generation; i++){
system("cls");
neighbour_manager();
printf("GENERATION NUMBER: %d\n", i);
generation_printer();
Sleep(1500);
}
if (generation == -1)
{int z=0;
while (!_kbhit())
{
system("cls");
neighbour_manager();
generation_printer();
z++;
printf("GENERATION NUMBER: %d\n", z);
printf("Press any key to stop.\n\n\n\n\n");
Sleep(1500);
}
}
int choice_after_execution=0;
printf("\n\nAll generations have been generated.\nPress 1 to Restart.\nPress 2 to Exit.\nYour Choice: ");
after_generation_valid_choice:
scanf("%d",&choice_after_execution);
if(choice_after_execution==1)
goto start;
if(choice_after_execution==2)
{
printf("Thank you for using this program.");
Sleep(2000);//for dramatic purposes
goto exit;//if user decides to exit the program then skip system pause and just exit
}
else
{
printf("Enter a valid choice: ");
goto after_generation_valid_choice;
}
exit:
exit(0);
}
void neighbour_manager(){
int i, j;
int neighbour;
for ( i = 0; i < 35; i++){
for ( j = 0; j < 85; j++){
neighbour = 0;
if (array[i - 1 < 0 ? 34 : i - 1][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;
if (array[i - 1 < 0 ? 34 : i - 1][j] == live) neighbour = neighbour + 1;
if (array[i - 1 < 0 ? 34 : i - 1][(j + 1) % 85] == live) neighbour = neighbour + 1;
if (array[i][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;
if (array[i][(j + 1) % 85] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][j] == live) neighbour = neighbour + 1;
if (array[(i + 1) % 35][(j + 1) % 85] == live) neighbour = neighbour + 1;
if(neighbour == 3)
{
array1[i][j] = live;
}
else if (neighbour < 2 || neighbour > 3)
{
array1[i][j] = dead;
}
else
{
array1[i][j] = array[i][j];
}
}
}
for(i=0; i<35; i++){
for(j=0; j<85; j++){
array[i][j] = array1[i][j];
array1[i][j] = ' ';
}
}
return;
}
void generation_printer()
{
int i,j;
for (i = 0; i < 35; i++) {
for (j = 0; j < 85; j++) {
printf("%c", array[i][j]);
}
printf("\n");
}
}
Here's a slight modification of your generation_printer() function that should print a little border around the output:
// It's a good idea to extract the size of your grid to constants that you
// can easily tweak.
const int kLineWidth = 85;
const int kLineHeight = 35;
void generation_printer()
{
int i, j;
// Top border
for (i = 0; i < kLineWidth + 2; i++) {
printf("*");
}
printf("\n");
for (i = 0; i < kLineHeight; i++) {
// Star to the beginning of the line
printf("*");
// Contents of the line
for (j = 0; j < kLineWidth; j++) {
printf("%c", array[i][j]);
}
// Star at the end of the line
printf("*\n");
}
// Bottom border
for (i = 0; i < kLineWidth + 2; i++) {
printf("*");
}
printf("\n");
}
Regarding the goto statement, there are much cleaner ways to handle control flow! Start by splitting your main() into several smaller functions, and use while or do... while loops to repeat sections in case of invalid choices.
Also, _kbhit() is a Windows-specific function and should be replaced so that your code is more portable (i.e. can run on several operating systems).
I made an extermely simple labirinth game out of boredom, however there's a weird bug that i can't figure out why is happening.
When i try to move into the obstacle, the first row of my output shifts. Also, depending on where i try to move, it can shift just 1 or more than 1 characters to the right. This is pretty weird to me considering that my showFrame() function clears the screen every time before outputting.
The 90th line is in action when you try to move into an obstacle. In case the new position is invalid, it will first revert the position, then invoke showFrame(), and showFrame() clears the console before outputting. So what causes the first row to shift? AND why does it shift differently depending on which key is pressed?
The code follows. If i understand correctly, you need to compile and run on linux, not windows, because of the ncurses thing and the getchar function? But i'm not sure. (not really a C programmer much)
Add the -lncurses argument when compiling. If you don't have the ncurses library installed, it can be downloaded here:
http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz
#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
int positionX = 1,
positionY = 19,
oldPositionX,
oldPositionY,
sizeX,
sizeY;
char matrix[20][20] =
{'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', '|', '-', '-', ' ', ' ', ' ', '-', '-', '|', ' ', ' ', ' ', ' ', '|',
'|', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', ' ', '|', ' ', '|', ' ', ' ', ' ', '-', '-', ' ', '|', ' ', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '-', '-', '|', ' ', ' ', '|', ' ', '|', ' ', '|',
' ', '|', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '|', '|', ' ', '|', ' ', '|',
' ', '|', ' ', ' ', ' ', '-', '-', '|', '|', ' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '|',
' ', '-', '-', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '|', ' ', '-', '-', '-', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', '|', ' ', '|', '-', '-', '-', ' ', '|', ' ', '|', ' ', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', '|', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '-', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', '-', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', ' ', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', ' ', ' ', ' ', ' ', ' ', ' ', '|',
'|', '-', '-', '-', '-', '-', ' ', '|', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', '-', '-', '-', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '-', '|', ' ', ' ', ' ', ' ', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', '-', '-', '|', ' ', '|', ' ', ' ', ' ', ' '};
void main() {
char key;
int stty;
// Get the size of the matrix
sizeX = sizeof(matrix) / sizeof(matrix[0]);
sizeY = sizeof(matrix[0]);
while(1) {
// Output level
showFrame();
// Wait for user input to move player position
stty = system("stty raw");
key = getchar();
system("stty cooked");
// Store previou position and move player position accordingly
oldPositionX = positionX;
oldPositionY = positionY;
switch(key) {
case 'w': positionY--;
break;
case 'a': positionX--;
break;
case 's': positionY++;
break;
case 'd': positionX++;
break;
default: printf("\bThat's an invalid key, stupid!\nYou're supposed to play with WASD keys.\n");
exit(0);
}
// Check to see if new position is okay
if(positionY >= sizeY || positionY < 0 || positionX >= sizeX || positionX < 0) {
revertPosition();
}
// Check to see if level cleared!
if(positionX == 1 && positionY == 0) {
showFrame();
printf("You cleared the level, Sherlock.\nYou must be really proud of yourself\n");
return;
}
}
}
int showFrame() {
int i, j;
// Output the matrix
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
void revertPosition() {
positionX = oldPositionX;
positionY = oldPositionY;
}
It seems there is a problem with clear.
To identify the problem, you should start finding what those characters that shift your first row come from. Adding:
system("clear");
printf('\n');
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
brings a little bit of light. It seems that if i want to go up, the characters there are the same as those from the upper line, to my position.
Now, you need to find why those characters are not deleted by system("clear"); , as it is supposed. After some trial and error, I managed to find that if you print a '\n' before clearing, it works as it is supposed.
As I have never used ncurses before, I can not explain you why is this happening. My assuption is that clear command clears the terminal line by line. And a line is ended with newline character. So, everything you need to do is to append newline after those trailing characters (I would suggest you printing it at the beginning of the showFrame function, to avoid simillar situations):
int showFrame() {
int i, j;
// Output the matrix
printf('\n');
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
I hope this was useful for you. Also, let me make some remarks about your code:
Using global variables is strongly discouraged.
About the main's return value, I would recommend you to read this.
Also, your ethier declare your functions before main:
int showFrame();
void revertPosition();
either move their entire definitions before main. As it is, your code did not compile on my machine (gcc 4.8.1).