Converting 2D array of numbers into chars - c

I am making a maze using Depth-First search algorithm as a school project. The maze is working pretty much as I want but I have a little problem. I have to use # as a wall and . as a path when printing the maze but I used 0 as a wall and 1 as a path at first thinking that it is gonna be easy to change it later but I was wrong. How can I change 0 and 1 into # and .?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void nahodne_suradnice(int *r, int *s, int n)
{
srand(time(NULL));
*r = ((rand() % n) - 1) + 2;
if (*r == 1 || *r == n)
{
*s = (rand() % n) + 2;
}
else
{
if (rand() % 2 == 1)
*s = 1;
else
*s = n;
}
}
int main()
{
int i, j, n, r, s,smer,posledny_smer[1500];
int maze[500][500];
scanf_s("%d", &n);
if (n < 10 || n > 100)
{
return 0;
}
//vynulovanie pola/bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
maze[i][j] = 0;
}
}
//nahodny vyber zaciatku bludiska
nahodne_suradnice(&r, &s, n);
//generovanie bludiska
j = 0;
maze[r][s] = 2;
for (i = 0 ;; i++)
{
//backtracking
if ((maze[r - 1][s] == 1 || maze[r - 2][s] == 1 || r - 2 <=1 || s==n || s==1) && (maze[r][s + 1] == 1 || maze[r][s + 2] == 1 || s + 2 >= n || r == n || r==1) && (maze[r + 1][s] == 1 || maze[r + 2][s] == 1 || r + 2 >= n || s == n || s==1) && (maze[r][s - 1] == 1 || maze[r][s - 2] == 1 || s - 2 <=1 || r == n || r==1))
{
if (posledny_smer[j-1] == 1)
if (maze[r + 1][s] == 1 && maze[r + 2][s] == 1)
{
r += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 2)
if (maze[r][s - 1] == 1 && maze[r][s - 2] == 1)
{
s -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 3)
if (maze[r - 1][s] == 1 && maze[r - 2][s] == 1)
{
r -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 4)
if (maze[r][s + 1] == 1 && maze[r][s + 2] == 1)
{
s += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (j == 0)
{
if (r == n)
{
nahodne_suradnice(&r, &s,n);
maze[1][s] = 3;
maze[2][s] = 3;
}
if (r == 1)
{
nahodne_suradnice(&r, &s, n);
maze[n][s] = 3;
maze[n - 1][s] = 3;
}
if (s == n-2)
{
nahodne_suradnice(&r, &s, n);
maze[r][1] = 3;
maze[r][2] = 3;
}
if (s == 3)
{
nahodne_suradnice(&r, &s, n);
maze[r][n] = 3;
maze[r][n-1] = 3;
}
break;
}
}
//buranie stien
smer = (rand() % 4) + 1;
if (smer == 1)
{
if (r - 2 >1 && s<n && s>1)
{
if (maze[r - 1][s] == 1 || maze[r - 2][s] == 1)
continue;
maze[r - 1][s] = 1;
maze[r - 2][s] = 1;
r -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 2)
{
if (s + 2 < n && r < n && r>1)
{
if (maze[r][s+1] == 1 || maze[r][s+2] == 1)
continue;
maze[r][s + 1] = 1;
maze[r][s + 2] = 1;
s += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 3)
{
if (r + 2 < n && s < n && s>1)
{
if (maze[r + 1][s] == 1 || maze[r + 2][s] == 1)
continue;
maze[r + 1][s] = 1;
maze[r + 2][s] = 1;
r += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 4)
{
if (s - 2 >1 && r < n && r>1)
{
if (maze[r][s-1] == 1 || maze[r][s-2] == 1)
continue;
maze[r][s - 1] = 1;
maze[r][s - 2] = 1;
s -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
}
//vypis bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
printf("%d", maze[i][j]);
}
printf("\n");
}
system("PAUSE");
return 0;
}
`
Thanks.

Change the definition of maze to:
char maze[500][500]
and change all references to use char instead of int. Then return '#' and '.' instead of 0 and 1.

You can change from 0 and 1 to # and . (or any other representation) when printing. For instance you can change:
printf("%d", maze[i][j]);
to
switch(maze[i][j]) {
case 0:
printf("#");
break;
case 1:
printf(".");
break;
default:
printf("X"); /* in case you have some value other than 0 or 1 in the maze */
}
If you do it like this, you can change which letters you want to display the maze as without changing other parts of your code.

Related

My If-statements seem to be ignored even though my variables look fine in the debugger

I just started learning C (I'm an absolute beginner) and I'm trying to make a program that translates Roman numbers to Arabic and vice versa.
If I were to type "IX" my program should give me a "9" as an output but instead I get a "1". I tried to find the issue on my own using the debugger and I can see my program entering the first If-Statement
if (userString[localIndex] == 'I')
but then it skips the inner If-Statement
else if (userString[++localIndex] == 'X') {
ARABIC_NUM += 9;
localIndex++;
}
I'm not sure why this is happening. If I type "IV" my program outputs a "4" which is the correct answer but if I type "IVIV" my programs once again outputs a lonely "4" and ignores the rest of my input.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define NOT_A_NUMBER 0
#define IS_ROMAN 1
#define IS_ARABIC 2
int ARABIC_NUM = 0;
int findStringLength(char* userString) {
int stringLength = 0;
size_t index = 0;
while (userString[index] != '\0')
{
if (userString[index] != '\0') {
stringLength++;
index++;
}
}
return stringLength;
}
void resetString(char* userString)
{
size_t stringLength = findStringLength(userString);
for (size_t index = 0; index < stringLength; index++)
{
userString[index] = '\0';
}
}
void printString(char* userString)
{
size_t stringLength = findStringLength(userString);
for (size_t index = 0; index < stringLength; index++)
{
if (userString[index] != '\0')
printf("~%zu:%c~ ", index, userString[index]);
else
printf("Null character");
}
}
bool ifEnd(char* numberInput, size_t counter) {
bool userEnd = false;
for (size_t index = 0; index < counter; index++)
{
if ((numberInput[index - 2] == 'E' && numberInput[index - 1] == 'N' && numberInput[index] == 'D')) {
userEnd = true;
}
}
return userEnd;
}
int isNumTrue(char userChar) {
int isRoman = NOT_A_NUMBER;
int isArabic = NOT_A_NUMBER;
if (userChar == 'I' || userChar == 'V' || userChar == 'X' ||
userChar == 'L' || userChar == 'C' || userChar == 'D' || userChar == 'M') {
isRoman = IS_ROMAN;
return isRoman;
}
else if (userChar == '0' || userChar == '1' || userChar == '2' || userChar == '3' || userChar == '4' || userChar == '5' || userChar == '6' || userChar == '7' || userChar == '8' || userChar == '9') {
isArabic = IS_ARABIC;
return isArabic;
}
else {
return NOT_A_NUMBER;
}
}
void convertToArabic(char* userString, size_t counter) {
for (size_t localIndex = 0; userString[localIndex] != '\0'; localIndex++) {
// printf("[ %c%s]", userString[localIndex], "-o ");
if (userString[localIndex] == 'I') {
if (userString[++localIndex] == 'V') {
printf("Made it in");
ARABIC_NUM += 4;
localIndex++;
}
else if (userString[++localIndex] == 'X') {
ARABIC_NUM += 9;
localIndex++;
}
else {
ARABIC_NUM += 1;
}
}
else if (userString[localIndex] == 'V') {
ARABIC_NUM += 5;
}
else if (userString[localIndex] == 'X') {
if (userString[localIndex++] == 'L') {
ARABIC_NUM += 40;
localIndex++;
}
else if (userString[localIndex++] == 'C') {
ARABIC_NUM += 90;
localIndex++;
}
else {
ARABIC_NUM += 10;
}
}
else if (userString[localIndex] == 'L') {
ARABIC_NUM += 50;
}
else if (userString[localIndex] == 'C') {
if (userString[localIndex++] == 'D') {
ARABIC_NUM += 400;
localIndex++;
}
else if (userString[localIndex++] == 'M') {
ARABIC_NUM += 900;
localIndex++;
}
else {
ARABIC_NUM += 100;
}
}
else if (userString[localIndex] == 'D') {
ARABIC_NUM += 500;
}
else if (userString[localIndex] == 'M') {
ARABIC_NUM += 1000;
}
else {
printf("Switch default. You shouldn't be seeing this");
}
/* else
{
printf("[ %c%s]", userString[localIndex],"-x ");
}*/
}
printf("%s%d%s", "\n Number was :", ARABIC_NUM, "\n");
}
bool convertToRoman(char* userString, char* romanStringHolder, size_t counter) {
bool isValid = true;
int arabicNum = atoi(userString);
char repetitionLimit = '\0';
for (size_t index = 0; arabicNum != 0; index++) {
/* if ((isNumTrue(userString[index]) == IS_ARABIC || userString[index] == '\n') && index < counter)
{
printf("[ %c%s]", userString[index], "-o ");
}*/
if (arabicNum >= 4000) {
do {
if (romanStringHolder[index - 2] == romanStringHolder[index - 1] == romanStringHolder[index]) {
repetitionLimit = romanStringHolder[index - 2];
}
if (arabicNum / 1000000 >= 1)//&& repetitionLimit != 'M')
{
romanStringHolder[index] = 'M';
arabicNum -= 1000000;
}
else if (arabicNum / 900000 >= 1)// && repetitionLimit != 'M')
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'M';
arabicNum -= 900000;
}
else if (arabicNum / 500000 >= 1)// && repetitionLimit != 'D')
{
romanStringHolder[index] = 'D';
arabicNum -= 500000;
}
else if (arabicNum / 400000 >= 1)//&& repetitionLimit != 'D')
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'D';
arabicNum -= 400000;
}
else if (arabicNum / 100000 >= 1)// && repetitionLimit != 'C')
{
romanStringHolder[index] = 'C';
arabicNum -= 100000;
}
else if (arabicNum / 90000 >= 1)//&& repetitionLimit != 'C')
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'C';
arabicNum -= 90000;
}
else if (arabicNum / 50000 >= 1)// && repetitionLimit != 'L')
{
romanStringHolder[index] = 'L';
arabicNum -= 50000;
}
else if (arabicNum / 40000 >= 1)// && repetitionLimit != 'L')
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'L';
arabicNum -= 40000;
}
else if (arabicNum / 10000 >= 1)//&& repetitionLimit != 'X')
{
romanStringHolder[index] = 'X';
arabicNum -= 10000;
}
else if (arabicNum / 9000 >= 1)// && repetitionLimit != 'X')
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'X';
arabicNum -= 9000;
}
else if (arabicNum / 5000 >= 1)//&& repetitionLimit != 'V')
{
romanStringHolder[index] = 'V';
arabicNum -= 5000;
}
else if (arabicNum / 4000 >= 1)//&& repetitionLimit != 'I')
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'V';
arabicNum -= 4000;
}
else if (arabicNum / 1000 >= 1)// && repetitionLimit != 'I')
{
romanStringHolder[index] = 'I';
arabicNum -= 1000;
}
index++;
} while (arabicNum >= 4000);
romanStringHolder[index] = '_';
index++;
}
if (arabicNum <= 3999) {
if (arabicNum / 1000 >= 1)
{
romanStringHolder[index] = 'M';
arabicNum -= 1000;
}
if (arabicNum / 900 >= 1)
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'M';
arabicNum -= 900;
}
else if (arabicNum / 500 >= 1)
{
romanStringHolder[index] = 'D';
arabicNum -= 500;
}
else if (arabicNum / 400 >= 1)
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'D';
arabicNum -= 400;
}
else if (arabicNum / 100 >= 1)
{
romanStringHolder[index] = 'C';
arabicNum -= 100;
}
else if (arabicNum / 90 >= 1)
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'C';
arabicNum -= 90;
}
else if (arabicNum / 50 >= 1)
{
romanStringHolder[index] = 'L';
arabicNum -= 50;
}
else if (arabicNum / 40 >= 1)
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'L';
arabicNum -= 40;
}
else if (arabicNum / 10 >= 1)
{
romanStringHolder[index] = 'X';
arabicNum -= 10;
}
else if (arabicNum / 9 >= 1)
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'X';
arabicNum -= 9;
}
else if (arabicNum / 5 >= 1)
{
romanStringHolder[index] = 'V';
arabicNum -= 5;
}
else if (arabicNum / 4 >= 1)
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'V';
arabicNum -= 4;
}
else if (arabicNum / 1 >= 1)
{
romanStringHolder[index] = 'I';
arabicNum -= 1;
}
}
}
if (romanStringHolder > 3999999)
printf("\n");
return isValid;
}
int findNumSystem(char* userString, char* toRomanString) {
//printf(" -%zu and %d-", counter, findStringLength(userString));
size_t counter = findStringLength(userString);
int romanNumAmount = 0;
int arabicNumAmount = 0;
int notNumAmount = 0;
for (size_t localIndex = 0; localIndex < counter; localIndex++) {
if (isNumTrue(userString[localIndex]) == IS_ROMAN || ((isNumTrue(userString[localIndex - 1]) == IS_ROMAN) && (userString[localIndex] == '\n')))
{
printf("[ %c%s]", userString[localIndex], "-R ");
romanNumAmount++;
if (romanNumAmount == (findStringLength(userString) - 1)) {
printf("\nAll Numbers are Roman");
convertToArabic(userString, counter);
break;
}
}
else if (isNumTrue(userString[localIndex]) == IS_ARABIC || ((isNumTrue(userString[localIndex - 1]) == IS_ARABIC) && (userString[localIndex] == '\n')))
{
printf("[ %c%s]", userString[localIndex], "-A ");
arabicNumAmount++;
if (arabicNumAmount == (findStringLength(userString) - 1))
{
printf("\nAll numbers are Arabic");
convertToRoman(userString, toRomanString, counter);
printString(toRomanString);
break;
}
}
else if (isNumTrue(userString[localIndex]) == NOT_A_NUMBER)
{
printf("[ %c%s]", userString[localIndex], "-X ");
notNumAmount++;
if (notNumAmount == (findStringLength(userString))) {
printf("\nNone of the characters is a number of either system");
}
}
}
}
#define LENGTH 1000u
int main() {
typedef char user_Input_Stream;
char lol = '\0';
user_Input_Stream arabToRomanString[LENGTH] = { '\0' };
user_Input_Stream numberInput[LENGTH] = { '\0' };
size_t counter = 0;
bool userEnd = false;
while ((lol != EOF) && (userEnd == false))
{
counter = 0;
printString(&numberInput);
resetString(&numberInput);
resetString(&arabToRomanString);
counter = 0;
printString(&numberInput);
ARABIC_NUM = 0;
printf("\n\n||Beta version, remember to not mix number systems yet||\n");
//Repeats until variable lol countains EOF or until boolean holds a true value
while ((lol != EOF) && (lol != '\n') && (userEnd == false))
{
//gets characters, assigns string with them. Gets rid of newline and stores string in array in uppercase
lol = getchar();
numberInput[counter] = toupper(lol);
userEnd = ifEnd(numberInput, counter);
counter++;
}
//TESTING Travels through String and outputs cells contents. Also, sets boolean to True if user writes END
for (size_t i = 0; i < counter; i++) {
if (numberInput[i] == '\n')
{
lol = '\\';
numberInput[i] = toupper(lol);
}
// printf("| [%zu] = %c |", i, numberInput[i]);
}
findNumSystem(numberInput, arabToRomanString);
printf("\n");
}
printf("\n");
return 0;
}
Does anyone have an idea of what the issue could be? (ARABIC_NUM is a global variable, the name is to make it easier for me to find for now.)
Just in case this might help somebody else, here's the solution I came up with using some of the pointers people in the comment section gave me. It was fairly simple:
I was under the impression that expressions within if-statements don't affect any variables they reference, but in reality they do.
For example: if(userString[localIndex] == 'I' && userString[localIndex++] == 'X')
In the line above, I was expecting the program to check both the current index and the next upcoming index, which it did but the expression userString[localIndex++] within the if-statement also permanently incremented my localIndex variable when I wasn't expecting that change to exist outside of the if-statement's parenthesis. So, my program would check the wrong indexes after the first comparison was made and thus why it gave me the wrong output.
To solve this, I created the variable nextIndex and used it to store the value localIndex +1 meaning it will always represent the index after localIndex. So, It now works as intended.
Below is what my program looks like now. (I moved around the if and if-else statements for better readability but the only changed that solved my predicament was the addition of nextIndex)
void convertToArabic(char* userString, size_t counter) {
size_t nextIndex = 0;
for (size_t localIndex = 0; localIndex < findStringLength(userString); localIndex++) {
// printf("[ %c%s]", userString[localIndex], "-o ");
nextIndex = localIndex+1;
if (userString[localIndex] == 'M') {
ARABIC_NUM += 1000;
}
else if (userString[localIndex] == 'C' && userString[nextIndex] == 'M') {
ARABIC_NUM += 900;
localIndex++;
}
else if (userString[localIndex] == 'D') {
ARABIC_NUM += 500;
}
else if (userString[localIndex] == 'C' && userString[nextIndex] == 'D') {
ARABIC_NUM += 400;
localIndex++;
}
else if(userString[localIndex] == 'C'){
ARABIC_NUM += 100;
}
else if (userString[localIndex] == 'X' && userString[nextIndex] == 'C') {
ARABIC_NUM += 90;
localIndex++;
}
else if (userString[localIndex] == 'L') {
ARABIC_NUM += 50;
}
else if (userString[localIndex] == 'X' && userString[nextIndex] == 'L'){
ARABIC_NUM += 40;
localIndex++;
}
else if (userString[localIndex] == 'X') {
ARABIC_NUM += 10;
}
else if ((userString[localIndex] == 'I') && (userString[nextIndex] == 'X')) {
//localIndex--;
ARABIC_NUM += 9;
localIndex++;
}
else if (userString[localIndex] == 'V') {
ARABIC_NUM += 5;
}
else if ((userString[localIndex] == 'I') && (userString[nextIndex] == 'V')) {
//localIndex--;
printf("Made it in");
ARABIC_NUM += 4;
localIndex++;
}
else if (userString[localIndex] == 'I') {
ARABIC_NUM += 1;
}
/* else
{
printf("[ %c%s]", userString[localIndex],"-x ");
}*/
}
printf("%s%d%s", "\n Number was :", ARABIC_NUM, "\n");
}

Movement for game character doesn't work at all

Here is the .c code from start to finish. I suspect it's an order of operations issue or something else.
The code is supposed to have a title screen where you can exit or play. If you hit play it renders a new char array in which you can move either left, right, or down (a/d/s). You get points for going down a row each time as well as going over 'P' spots on the array.
Once you hit y-coordinate 202 on the array as well as have positive points, you win and it renders a congrats char array. If you go negative in points (by hitting the '#' paces or the 'L' wall that goes down a row every 1/2 second) then you will lose and be told you lost in a new char array as well as be asked if you want to exit or play again.
And as mentioned before, the movement for the 'L's and the play character 'O' simply doesn't move.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
char quickchar(float delay);
void render();
void titleRender();
void renderLoss();
void renderWin();
int score();
char titlescreen[20][59] = { };
char diffdiff[20][46] = {
(Grid removed due to char limit)
};
char gameover[20][50] = {
(Grid removed due to char limit)
};
char gameboard[203][26] = {
(Grid removed due to char limit)
};
int playerx;
int playery;
int pts;
void entryRender();
void gameRender();
int main() {
int input;
char replay;
int lx;
int ly;
char walkin;
int gaming;
char titlechoice;
int diff;
int running;
lx = 0;
ly = 0;
running = 1;
playerx = 13;
playery = 5;
pts = 25;
gaming = 0;
while (gaming == 0) {
titleRender();
printf("\033[1;32m");
printf("\nPress 'p' to play or 'x' to exit!");
printf("\033[0m");
scanf(" %c", &titlechoice);
if (titlechoice == 'p') {
gaming += 4;
}
if (titlechoice == 'x') {
return 0;
}
}
while (gaming == 4) {
system("stty -echo raw");
render();
printf("\033[1;35m");
printf("Choose a direction: s/Down, a/Left, d/Right.\n\r");
printf("\033[0m");
walkin = quickchar(0.5);
scanf("%c", &walkin);
//obj behaviour
if (walkin == 's' &&
gameboard[playery +1][playerx] != '#' &&
gameboard[playery + 1][playerx] != '+' &&
gameboard[playery + 1][playerx] != '|' &&
gameboard[playery + 1][playerx] != '-') {
playery++;
pts += 5;
if (gameboard[playery + 1][playerx] == '#') {
pts -= 25;
}
if (gameboard[playery + 1][playerx] == 'P') {
printf("Points increased!\n\r");
pts += 50;
gameboard[playery + 1][playerx] = '_';
}
}
else if (walkin == 'a' &&
gameboard[playery][playerx - 1] != '#' &&
gameboard[playery][playerx - 1] != '+' &&
gameboard[playery][playerx - 1] != '|' &&
gameboard[playery][playerx - 1] != '-') {
playerx--;
if (gameboard[playery][playerx - 1] == '#') {
pts -= 25;
}
if (gameboard[playery][playerx - 1] == 'P') {
printf("Points increased!\n\r");
pts += 50;
gameboard[playery][playerx - 1] = '_';
}
}
else if (walkin == 'd' &&
gameboard[playery][playerx + 1] != '#' &&
gameboard[playery][playerx + 1] != '+' &&
gameboard[playery][playerx + 1] != '|' &&
gameboard[playery][playerx + 1] != '-') {
playerx++;
if (gameboard[playery][playerx + 1] == '#') {
pts -= 25;
}
if (gameboard[playery + 1][playerx] == 'P) {
printf("Points increased!\n\r");
pts += 50;
gameboard[playery][playerx + 1] = '_';
}
}
if (walkin == 'a' || walkin == 's' || walkin == 'd' ||
walkin != 'a' || walkin != ' ' || walkin != 'd' ) {
for (ly = 0; ly = 202; ly++) {
for (lx = 1; lx = 25; lx++) {
gameboard[ly][lx] = 'L';
}
}
}
if (pts <= 0) {
system("clear");
renderLoss();
scanf("%c", replay);
if (replay == 'Y') {
gaming = 3;
}
if (replay == 'N') {
gaming = 5;
}
}
if (playery == 202) {
renderWin();
printf("");
printf("Congrats! You got a score of %d !", pts);
printf("");
scanf("%c", &replay);
if (replay == 'Y') {
gaming = 4;
}
if (replay == 'N') {
gaming = 5;
}
}
//player postion == 203y, then congrta screen
//ask player to set gaming to 4(replay) or none (exit program)
}
system("stty echo -raw");
return 0;
}
void render() {
int y,x,k;
system("clear");
printf("\033[01;33m");
printf("||POINTS: %d||\r\n", pts);
printf("\033[0m");
for (y = 0; y < 203; y++) {
for (x = 0; x < 26; x++) {
if (y == playery && x == playerx) {
printf("\033[0;32m");
printf("O");
printf("\033[0m");
}
else {
printf("\033[1;36m");
printf("%c", gameboard[y][x]);
printf("\033[0m");
}
}
printf("\r\n");
}
}
void titleRender() {
int y, x;
system("clear");
for (y = 0; y < 20; y++) {
for (x = 0; x < 59; x++) {
printf("\033[0;32m");
printf(" %c", titlescreen[y][x]);
printf("\033[0m");
}
printf("\r\n");
}
}
void renderLoss() {
int y, x;
system("clear");
for (y = 0; y < 26; y++) {
for (x = 0; x < 50; x++) {
printf("\033[0;31m");
printf(" %c", gameover[y][x]);
printf("\033[0m");
}
printf("\r\n");
}
}
void renderWin() {
int y, x;
system("clear");
for (y = 0; y < 20; y++) {
for (x = 0; x < 46; x++) {
printf("\033[0;33m");
printf(" %c", diffdiff);
printf("\033[0m");
}
printf("\r\n");
}
}
char quickchar(float delay) {
int flags;
char c;
usleep((int)(delay*1000000));
flags = fcntl(0, F_GETFL, 0);
fcntl(0, F_SETFL, flags | O_NONBLOCK);
c = getchar();
fcntl(0, F_SETFL, flags ^ O_NONBLOCK);
return c;
}

For Loop running infinite C

I am making a checksum error verifying program using C language but I have encountered an infinite loop while executing the program and I don't have any clue why I am getting this.
So what I have done in this program is that I am going to first convert characters of a string into respective ASCII codes and then checking for checksum error and for this I have made this program below.
#include <stdio.h>
int a[2], i, dec[10][8], de[2][8], j, k, add[8], carry = 0, n = 5;
int u[] = {0, 0, 0, 0, 0, 0, 0, 1};
char b[] = {'H', 'e', 'l', 'l', 'o'};
int main()
{
for (k = 0; k < 2; k++)
{
for (j = 0; j < 8; j++)
{
dec[k][j] = 0;
}
}
for (k = 0; k < 2; k++)
{
a[k] = b[k];
}
for (k = 0; k < 2; k++)
{
i = 0;
while (a[k] > 0)
{
dec[k][i] = a[k] % 2;
a[k] = a[k] / 2;
i++;
}
}
i = 0;
s:
for (k = 0; k < 2; k++)
{
for (j = 7; j >= 0; j--)
{
de[k][i] = dec[k][j];
i++;
}
i = 0;
}
for (k = 0; k < 2; k++)
{
for (j = 0; j < 8; j++)
{
printf("%d", de[k][j]);
}
printf("\n");
}
i = 0;
for (j = 7; j >= 0; j--)
{
if (de[i][j] == 1 && de[i + 1][j] == 1 && carry == 0)
{
add[j] = 0;
carry = 1;
}
else if (de[i][j] == 1 && de[i + 1][j] == 1 && carry == 1)
{
add[j] = 1;
carry = 1;
}
else if (de[i][j] == 0 && de[i + 1][j] == 1 && carry == 1)
{
add[j] = 0;
carry = 1;
}
else if (de[i][j] == 0 && de[i + 1][j] == 1 && carry == 0)
{
add[j] = 1;
carry = 0;
}
else if (de[i][j] == 0 && de[i + 1][j] == 1 && carry == 1)
{
add[j] = 0;
carry = 1;
}
else if (de[i + 1][j] == 0 && de[i][j] == 1 && carry == 0)
{
add[j] = 1;
carry = 0;
}
else if (de[i + 1][j] == 0 && de[i][j] == 0 && carry == 0)
{
add[j] = 0;
carry = 0;
}
else if (de[i + 1][j] == 0 && de[i][j] == 0 && carry == 1)
{
add[j] = 1;
carry = 0;
}
}
i = i + 2;
for (k = 0; k < 8; k++)
{
de[i][j] = add[j];
}
if (carry == 1 && i < n)
{
for (k = 0; k < 8; k++)
{
de[i + 1][j] = u[j];
}
goto s;
}
else if (carry == 0 && i < n)
{
for (k = 0; k < 8; k++)
{
de[i + 1][j] = u[j];
}
goto s;
}
for (i = 0; i < 8; i++)
printf("%d", add[i]);
return 0;
}

SetConsoleCursorPosition : Getting black rows in console upon use

Following my previous question about making a snake program more fluid, I went and tried ANSI escape sequences and console functions to put back the text cursor on the top left corner.
I want to get the cursor on the top left corner of the screen, but while it does so I get black stripes across the screen every other line.
I am working in a windows environment making this program for the windows console.
Here is the painting function :
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
I tried putting the escape code and console function in the main right before calling the paint function but I got the same results.
here is the whole program if someone wants to test :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
void create(int tab[28][120], int Nbligne, int Nbcolonne,
int randligne, int randcols)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
tab[i][j] = ' ';
if (i == 0 || i == Nbligne - 1)
tab[i][j] = 205;
if (j == 0 || j == Nbcolonne - 1)
tab[i][j] = 186;
if (i == 0 && j == 0)
tab[i][j] = 201;
if (i == 0 && j == Nbcolonne - 1)
tab[i][j] = 187;
if (i == Nbligne - 1 && j == 0)
tab[i][j] = 200;
if (i == Nbligne - 1 && j == Nbcolonne - 1)
tab[i][j] = 188;
if (i == 14 && j == 60)
tab[i][j] = 219;
if (i == 14 && j == 59)
tab[i][j] = 79;
if (i == 14 && j == 58)
tab[i][j] = 35;
if (i == randligne && j == randcols)
tab[i][j] = 176;
}
}
}
void destroyTail(int tab[28][120], int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 35)
{
tab[i][j] = ' ';
if (tab[i][j + 1] == 79)
tab[i][j + 1] = 35;
else if (tab[i][j - 1] == 79)
tab[i][j - 1] = 35;
else if (tab[i + 1][j] == 79)
tab[i + 1][j] = 35;
else if (tab[i - 1][j] == 79)
tab[i - 1][j] = 35;
goto stop;
}
}
}
stop: NULL;
}
void translate(int tab[28][120], char direction, int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 219)
{
if (direction == 'R')
{
tab[i][j] = 79;
tab[i][j + 1] = 219;
}
if (direction == 'D')
{
tab[i][j] = 79;
tab[i + 1][j] = 219;
}
if (direction == 'L')
{
tab[i][j] = 79;
tab[i][j - 1] = 219;
}
if (direction == 'U')
{
tab[i][j] = 79;
tab[i - 1][j] = 219;
}
goto stop;
}
}
}
stop: NULL;
}
int checkExpand(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && tab[i][j + 1] == 176) ||
(direction == 'L' && tab[i][j] == 219 && tab[i][j - 1] == 176) ||
(direction == 'U' && tab[i][j] == 219 && tab[i - 1][j] == 176) ||
(direction == 'D' && tab[i][j] == 219 && tab[i + 1][j] == 176))
return 1;
}
}
return 0;
}
int checkDeath(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && (tab[i][j + 1] == 186 || tab[i][j + 1] == 79)) ||
(direction == 'L' && tab[i][j] == 219 && (tab[i][j - 1] == 186 || tab[i][j - 1] == 79)) ||
(direction == 'U' && tab[i][j] == 219 && (tab[i - 1][j] == 205 || tab[i - 1][j] == 79)) ||
(direction == 'D' && tab[i][j] == 219 && (tab[i + 1][j] == 205 || tab[i + 1][j] == 79)))
return 1;
}
}
return 0;
}
int main()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 241);
int tab[28][120];
int randligne = rand() % 26 + 1;
int randcols = rand() % 118 + 1;
create(tab, 28, 120, randligne, randcols);
paint(tab, 28, 120, hConsole);
char i = '1';
char direction = 'R';
int eaten = 0;
int expand = 0;
int death = 0;
while(i != 'k')
{
if (kbhit())
i = getch();
switch(i) {
case 'z':
if (direction != 'D')
direction = 'U';
break;
case 's':
if (direction != 'U')
direction = 'D';
break;
case 'd':
if (direction != 'L')
direction = 'R';
break;
case 'q':
if (direction != 'R')
direction = 'L';
break;
}
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
death = checkDeath(tab, 28, 120, direction);
if (death == 1)
break;
translate(tab, direction, 28, 120);
expand = checkExpand(tab, 28, 120, direction);
if (expand == 0)
destroyTail(tab, 28, 120);
else
{
while (tab[randligne][randcols] != ' ')
{
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
}
tab[randligne][randcols] = 176;
eaten++;
}
printf("Number of biscuits eaten : %d ; direction : %c ; expand : %d", eaten, direction, expand);
paint(tab, 28, 120, hConsole);
Sleep(100);
}
while(i != 'k')
{
if (kbhit())
i = getch();
}
}
Too much code to take in quickly. If you have Windows console ouput for the snake, can't you simply printf the next line and leave it at that?
If you want to hide the cursor (instead of trying to park it out of sight) you can make it invisible by calling SetConsoleCursorInfo and the struct passed is shown here.

Tic Tac Toe AI error

char checkwinner(char ttt[][3]) {
char winner = 0;
for (int p = 0; winner == 0 && p < 2; p++) {
char XO = p == 0 ? 'x' : 'o';
for (int i = 0; winner == 0 && i < 3; i++) {
if (ttt[i][0] == XO && ttt[i][1] == XO && ttt[i][2] == XO)
winner = XO;
else
if (ttt[0][i] == XO && ttt[1][i] == XO && ttt[2][i] == XO)
winner = XO;
}
if (winner == 0 && ttt[0][0] == XO && ttt[1][1] == XO && ttt[2][2] == XO)
winner = XO;
else
if (winner == 0 && ttt[0][2] == XO && ttt[1][1] == XO && ttt[2][0] == XO)
winner = XO;
}
return winner;
}
int main (void) {
char b[3][3] = {{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'}};
int turn = 0, i, j, loc, type, counter = 0;
char XO, AL;
char theChar = 'A';
char junk ='A';
printf("Type in 1 to play with AL, or 2 to play with another human\n");
scanf("%d", &type);
while (turn <= 9) {
char winner = checkwinner(b);
if (winner == 'x' || winner == 'o') {
printf("%c has won! You get 100 million DOGECOINS! Just enter your debt card information to our website, as well as your checking account and social security number. Go to www.THIS_IS_NOT_A_SCAM.com to get your dogecoins today!\n", winner);
return (0);
} else
if (((b[0][0] == 'x') || (b[0][0] == 'o'))
&& ((b[0][1] == 'x') || (b[0][1] == 'o'))
&& ((b[0][2] == 'x') || (b[0][2] == 'o'))
&& ((b[1][0] == 'x') || (b[1][0] == 'o'))
&& ((b[1][1] == 'x') || (b[1][1] == 'o'))
&& ((b[1][2] == 'x') || (b[1][2] == 'o'))
&& ((b[2][0] == 'x') || (b[2][0] == 'o'))
&& ((b[2][1] == 'x') || (b[2][1] == 'o'))
&& ((b[2][2] == 'x') || (b[2][2] == 'o'))) {
printf("This is a tie.\n");
return (0);
} //<---- missing brace!
if (type == 1) {
counter = counter + 1;
if (counter == 1) { XO = 'x'; }
if (counter == 2) { XO = 'o'; }
if (counter == 3) { XO = 'x'; }
if (counter == 4) { XO = 'o'; }
if (counter == 5) { XO = 'x'; }
if (counter == 6) { XO = 'o'; }
if (counter == 7) { XO = 'x'; }
if (counter == 8) { XO = 'o'; }
if (counter == 9) { XO = 'x'; }
}
if (type == 2) {
XO = 'x';
AL = 'o';
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
b[i][j] = AL;
printArray(b);
}
}
}
theChar = getchar();
putchar(theChar);
printf("Enter number: ");
scanf("%d", &loc);
j = (loc - 1) % 3;
i = (loc - 1) / 3;
if ((b[i][j] == 'x') || (b[i][j] == 'o')) {
printf("That spot has been taken!\n");
return (0);
}
putchar('\n');
junk = getchar();
b[i][j] = XO;
printArray(b);
}
}
void printArray(char thearray[3][3]) {
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%c ", thearray[i][j]);
}
printf("\n");
}
}
Right now I'm trying to finish the AI mode. Rather than just going and finding the first empty space and printing a single 'o' my game prints 9 boards like this:
o 2 3
4 5 6
7 8 9
o o 3
4 5 6
7 8 9
o o o
4 5 6
7 8 9
o o o
o 5 6
7 8 9
o o o
o o 6
7 8 9
o o o
o o o
7 8 9
o o o
o o o
o 8 9
o o o
o o o
o o 9
o o o
o o o
o o o
How do I get the game to stop after printing one 'o', and then letting 'x' pick a move? All help is appreciated.
Your code to find the place for AL to play is incorrect:
if (type == 2) {
XO = 'x';
AL = 'o';
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
b[i][j] = AL;
printArray(b);
}
}
}
You just play every spot on the grid and print it!
Try this instead:
if (type == 2) {
XO = 'x';
AL = 'o';
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (b[i][j] != 'x' && b[i][j] != 'o') {
b[i][j] = AL;
i = j = 2; /* ugly way to exit the nested loops */
}
}
}
printArray(b);
}
But this gaming strategy will be easy to beat!
Also you forget to increment turn, but if you did, you could replace the tedious test for a tie with a simple if (turn == 9).
EDIT: exiting from this nested loop requires more logic... it is better to move the AL game play to a separate function. Furthermore, your logic is flawed: you let AL play if type is 2 instead of 1...
Here is a simplified and corrected version that can play both sides:
#include <stdio.h>
char checkwinner(char b[3][3]) {
for (int i = 0; i < 3; i++) {
if (b[i][0] == b[i][1] && b[i][1] == b[i][2])
return b[i][0];
if (b[0][i] == b[1][i] && b[1][i] == b[2][i])
return b[0][i];
}
if ((b[0][0] == b[1][1] && b[1][1] == b[2][2])
|| (b[0][2] == b[1][1] && b[1][1] == b[2][0])) {
return b[1][1];
}
return 0;
}
void printArray(char b[3][3]) {
for (int i = 0; i < 3; i++) {
printf("%c %c %c\n", b[i][0], b[i][1], b[i][2]);
}
printf("\n");
}
void playAl(char b[3][3], char AL) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (b[i][j] != 'x' && b[i][j] != 'o') {
b[i][j] = AL;
return;
}
}
}
}
int main (void) {
char board[3][3] = {{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'}};
int turn, i, j, loc, type;
printf("What does AL play? (0:none, 1:x, 2:o, 3:both) ");
scanf("%d", &type);
for (turn = 0;; turn++) {
printArray(board);
char winner = checkwinner(board);
if (winner == 'x' || winner == 'o') {
printf("%c has won! Game over\n", winner);
return 0;
}
if (turn == 9) {
printf("This is a tie.\n");
return 0;
}
char XO = "xo"[turn % 2];
if (type & (1 << (turn % 2))) {
/* AL's turn to play */
playAl(board, XO);
continue;
}
for (;;) {
printf("Enter number: ");
if (scanf("%d", &loc) != 1)
return 1;
j = (loc - 1) % 3;
i = (loc - 1) / 3 % 3;
if (board[i][j] != 'x' && board[i][j] != 'o')
break;
printf("This spot is already taken!, try again\n");
}
board[i][j] = XO;
}
}

Resources