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");
}
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;
}
I was trying to make a chess game in c. It is basic. It is for a friend of mine. But I am getting this error when I try to play the game: The error is "stack around the variable 'ch1' was corrupted". I think this is about overloading this ch1 array which is char array(The array in the player1() function). But I don't know where I did overload this variable. Can you guys help me solve this problem ?
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int pwstatus[8] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
int pbstatus[8] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
struct piece {
int color; //0 if white, 1 if black, 2 if empty
int type;//1:pawn, 2:rook, 3:knight, 4:bishop, 5:queen, 6:king, 0 if empty
};
char* pieceToChar(piece piece) {
char *ch = (char*)malloc(5);
if (piece.color == 0)
ch[0] = 'W';
if (piece.color == 1)
ch[0] = 'B';
if (piece.color == 2) {
ch[0] = '0';
ch[1] = ' ';
ch[2] = ' ';
ch[3] = ' ';
ch[4] = '\0';
return ch;
}
if (piece.type == 1)
ch[1] = 'P';
if (piece.type == 2)
ch[1] = 'R';
if (piece.type == 3)
ch[1] = 'K';
if (piece.type == 4)
ch[1] = 'B';
if (piece.type == 5)
ch[1] = 'Q';
if (piece.type == 6)
ch[1] = 'G';
ch[2] = ' ';
ch[3] = ' ';
ch[4] = '\0';
return ch;
}
void assignChar(char* char1, char* char2, int n) {
for (int i = 0; i < n; i++) {
char1[i] = char2[i];
}
}
void charToInt(char* char1, int* int1) {
if (char1[0] == 'A') {
int1[0] = 0;
}
if (char1[0] == 'B') {
int1[0] = 1;
}
if (char1[0] == 'C') {
int1[0] = 2;
}
if (char1[0] == 'D') {
int1[0] = 3;
}
if (char1[0] == 'E') {
int1[0] = 4;
}
if (char1[0] == 'F') {
int1[0] = 5;
}
if (char1[0] == 'G') {
int1[0] = 6;
}
if (char1[0] == 'H') {
int1[0] = 7;
}
if (char1[1] == '1') {
int1[1] = 0;
}
if (char1[1] == '2') {
int1[1] = 1;
}
if (char1[1] == '3') {
int1[1] = 2;
}
if (char1[1] == '4') {
int1[1] = 3;
}
if (char1[1] == '5') {
int1[1] = 4;
}
if (char1[1] == '6') {
int1[1] = 5;
}
if (char1[1] == '7') {
int1[1] = 6;
}
if (char1[1] == '8') {
int1[1] = 7;
}
}
void intToChar(int* int1, char* char1) {
if (int1[0] == 0) {
char1[0] = 'A';
}
if (int1[0] == 1) {
char1[0] = 'B';
}
if (int1[0] == 2) {
char1[0] = 'C';
}
if (int1[0] == 3) {
char1[0] = 'D';
}
if (int1[0] == 4) {
char1[0] = 'E';
}
if (int1[0] == 5) {
char1[0] = 'F';
}
if (int1[0] == 6) {
char1[0] = 'G';
}
if (int1[0] == 7) {
char1[0] = 'H';
}
if (int1[1] == 0) {
char1[1] = '1';
}
if (int1[1] == 1) {
char1[1] = '2';
}
if (int1[1] == 2) {
char1[1] = '3';
}
if (int1[1] == 3) {
char1[1] = '4';
}
if (int1[1] == 4) {
char1[1] = '5';
}
if (int1[1] == 5) {
char1[1] = '6';
}
if (int1[1] == 6) {
char1[1] = '7';
}
if (int1[1] == 7) {
char1[1] = '8';
}
}
char intToCharDif(int integer) {
char ch = '0';
if (integer == 0) {
ch = 'A';
}
if (integer == 1) {
ch = 'B';
}
if (integer == 2) {
ch = 'C';
}
if (integer == 3) {
ch = 'D';
}
if (integer == 4) {
ch = 'E';
}
if (integer == 5) {
ch = 'F';
}
if (integer == 6) {
ch = 'G';
}
if (integer == 7) {
ch = 'H';
}
return ch;
}
struct Board{
piece board[8][8];
Board() {
piece piece;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (i < 2)
piece.color = 0;
if (i > 5)
piece.color = 1;
if (j == 0)
piece.type = 2;
if (j == 1)
piece.type = 3;
if (j == 2)
piece.type = 4;
if (j == 3)
piece.type = 5;
if (j == 4)
piece.type = 6;
if (j == 5)
piece.type = 4;
if (j == 6)
piece.type = 3;
if (j == 7)
piece.type = 2;
if (i > 1 && i < 6) {
piece.color = 2;
piece.type = 0;
}
if (i == 1 || i == 6) {
piece.type = 1;
}
board[i][j] = piece;
}
}
}
void print() {
printf("Chess Board: \n");
char ch[5] = "0000";
for (int i = 8; i >= 0; i--) {
if (i == 8)
printf("8 ");
else if (i == 7)
printf("7 ");
else if (i == 6)
printf("6 ");
else if (i == 5)
printf("5 ");
else if (i == 4)
printf("4 ");
else if (i == 3)
printf("3 ");
else if (i == 2)
printf("2 ");
else if (i == 1)
printf("1 ");
else
printf(" ");
for (int j = 0; j < 8; j++) {
if (i == 0)
break;
assignChar(&ch[0], pieceToChar(board[i - 1][j]), 5);
printf("%s", ch);
}
printf("\n");
}
printf(" A B C D E F G H\n");
}
int pawnMove(int r1, int c1) {
char ch;
int mCount = 0;
printf("Press: ");
if (board[r1][c1].color == 0) {
if (pwstatus[c1] == 1)
{
if (board[r1 + 1][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 + 1);
mCount++;
}
if (board[r1 + 2][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 + 2);
mCount++;
}
}
else
{
if (board[r1 + 1][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d, ", ch, r1 + 1);
mCount++;
}
if (board[r1 + 1][c1 + 1].color == 1) {
ch = intToCharDif(c1 + 1);
printf("%c%d, ", ch, r1 + 1);
mCount++;
}
if (board[r1 + 1][c1 - 1].color == 1) {
ch = intToCharDif(c1 - 1);
printf("%c%d, ", ch, r1 + 1);
mCount++;
}
}
}
else {
if (pbstatus[c1] == 1)
{
if (board[r1 - 1][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 - 1);
mCount++;
}
if (board[r1 - 2][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 - 2);
mCount++;
}
}
else
{
if (board[r1 - 1][c1].color == 2) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 - 1);
mCount++;
}
if (board[r1 - 1][c1 - 1].color == 0) {
ch = intToCharDif(c1 - 1);
printf("%c%d, ", ch, r1 - 1);
mCount++;
}
if (board[r1 - 1][c1 + 1].color == 0) {
ch = intToCharDif(c1 + 1);
printf("%c%d, ", ch, r1 - 1);
mCount++;
}
}
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
int rookMove(int r1, int c1) {
int n;
int mCount = 0;
printf("Press: ");
int color = board[r1][c1].color;
n = c1;
char ch;
while (board[r1][n - 1].color == 2)
{
if (n == 0) { break; }
ch = intToCharDif(n - 1);
printf("%c%d , ", ch, r1);
n--;
mCount++;
}
n = c1;
while (board[r1][n + 1].color == 2 && (n + 1) <= 7)
{
ch = intToCharDif(n + 1);
printf("%c%d , ", ch, r1);
++n;
mCount++;
}
n = r1;
while (board[n - 1][c1].color == 2 && n > -1)
{
ch = intToCharDif(c1);
printf("%c%d , ", ch, n - 1);
--n;
mCount++;
}
n = r1;
while ((board[n + 1][c1].color == 2) && ((n) <= 7))
{
ch = intToCharDif(c1);
printf("%c%d , ", ch, n + 1);
++n;
mCount++;
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
int knightMove(int r1, int c1) {
printf("Press: ");
int color = board[r1][c1].color;
char ch;
int mCount = 0;
if (board[r1 + 2][c1 + 1].color == 2) {
ch = intToCharDif(c1 + 1);
printf("%c%d, ", ch, r1 + 2);
mCount++;
}
if (board[r1 + 2][c1 - 1].color != color) {
ch = intToCharDif(c1 - 1);
if ((c1 - 1) > -1) printf("%c%d, ", ch, r1 + 2);
mCount++;
}
if (board[r1 + 1][c1 + 2].color != color) {
ch = intToCharDif(c1 + 2);
if ((c1 + 2) != 8) printf("%c%d, ", ch, r1 + 1);
mCount++;
}
if (board[r1 - 1][c1 + 2].color != color) {
ch = intToCharDif(c1 + 2);
printf("%c%d, ", ch, r1 - 1);
mCount++;
}
if (board[r1 - 2][c1 - 1].color != color){
ch = intToCharDif(c1 - 1);
if ((c1 - 1) != -1)
printf("%c%d, ", ch, r1 - 2);
mCount++;
}
if (board[r1 - 2][c1 + 1].color != color) {
ch = intToCharDif(c1 + 1);
printf("%c%d, ", ch, r1 - 2);
mCount++;
}
if (board[r1 + 1][c1 - 2].color != color) {
ch = intToCharDif(c1 - 2);
printf("%c%d, ", ch, r1 + 1);
mCount++;
}
if (board[r1 - 1][c1 - 2].color != color){
ch = intToCharDif(c1 - 2);
if ((c1 - 2) != -1)
printf("%c%d, ", ch, r1 - 1);
mCount++;
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
int bishopMove(int r1, int c1) {
int a, b;
printf("Press: ");
int color = board[r1][c1].color;
char ch;
int mCount = 0;
a = 1, b = 1;
while (board[r1 - a][c1 + b].color != color)
{
ch = intToCharDif(c1 + b);
if ((r1 - a) == -1 || (c1 + b) == 8) break;
printf("%c%d , ", ch, r1 - a);
a++;
b++;
mCount++;
}
a = 1, b = 1;
while (board[r1 + a][c1 - b].color != color)
{
ch = intToCharDif(c1 - b);
if ((r1 + a) == 8 || (c1 - b) == -1) break;
printf("%c%d , ", ch, r1 + a);
a++;
b++;
mCount++;
}
a = 1, b = 1;
while (board[r1 + a][c1 + b].color != color)
{
ch = intToCharDif(c1 + b);
if ((r1 + a) == 8 || (c1 + b) == 8) break;
printf("%c%d , ", ch, r1 + a);
a++;
b++;
mCount++;
}
a = 1;
b = 1;
while (board[r1 - a][c1 - b].color != color)
{
ch = intToCharDif(c1 - b);
if ((r1 - a) == -1 || (c1 - b) == -1) break;
printf("%c%d , ", ch, r1 - a);
a++;
b++;
mCount++;
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
int queenMove(int r1, int c1) {
char ch;
int mCount = 0;
int x = 1, y = 1, a, b;
printf("Press: ");
int color = board[r1][c1].color;
while (board[r1][c1 - y].color != color)
{
ch = intToCharDif(c1 - y);
if ((c1 - y) == -1) break;
printf("%c%d , ", ch, r1);
y++;
mCount++;
}
y = 1;
while (board[r1][c1 + y].color != color)
{
ch = intToCharDif(c1 + y);
if ((c1 + y) == 8) break;
printf("%c%d , ", ch, r1);
y++;
mCount++;
}
x = 1;
while (board[r1 - x][c1].color != color)
{
ch = intToCharDif(c1);
if ((r1 - x) == -1) break;
printf("%c%d , ", ch, r1 - x);
x++;
mCount++;
}
x = 1;
while (board[r1 + x][c1].color != color)
{
ch = intToCharDif(c1);
if ((r1 + x) == 8) break;
printf("%c%d , ", ch, r1 + x);
x++;
mCount++;
}
a = 1, b = 1;
while (board[r1 - a][c1 + b].color != color)
{
ch = intToCharDif(c1 + b);
if ((r1 - a) == -1 || (c1 + b) == 8) break;
printf("%c%d , ", ch, r1 - a);
a++;
b++;
mCount++;
}
a = 1, b = 1;
while (board[r1 + a][c1 - b].color != color)
{
ch = intToCharDif(c1 - b);
if ((r1 + a) == 8 || (c1 - b) == -1) break;
printf("%c%d , ", ch, r1 + a);
a++;
b++;
mCount++;
}
a = 1, b = 1;
while (board[r1 + a][c1 + b].color != color)
{
ch = intToCharDif(c1 + b);
if ((r1 + a) == 8 || (c1 + b) == 8) break;
printf("%c%d , ", ch, r1 + a);
a++;
b++;
mCount++;
}
a = 1;
b = 1;
while (board[r1 - a][c1 - b].color != color)
{
ch = intToCharDif(c1 - b);
if ((r1 - a) == -1 || (c1 - b) == -1) break;
printf("%c%d , ", ch, r1 - a);
a++;
b++;
mCount++;
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
int kingMove(int r1, int c1) {
char ch;
int mCount = 0;
int color = board[r1][c1].color;
printf("Press: ");
if (board[r1][c1 + 1].color != color) {
ch = intToCharDif(c1 + 1);
printf("%c%d , ", ch, r1);
mCount++;
}
if (board[r1][c1 - 1].color != color) {
ch = intToCharDif(c1 - 1);
printf("%c%d , ", ch, r1);
mCount++;
}
if (board[r1 + 1][c1].color != color) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 + 1);
mCount++;
}
if (board[r1 - 1][c1].color != color) {
ch = intToCharDif(c1);
printf("%c%d , ", ch, r1 - 1);
mCount++;
}
if (board[r1 + 1][c1 + 1].color != color) {
ch = intToCharDif(c1 + 1);
printf("%c%d , ", ch, r1 + 1);
mCount++;
}
if (board[r1 - 1][c1 - 1].color != color) {
ch = intToCharDif(c1 - 1);
printf("%c%d , ", ch, r1 - 1);
mCount++;
}
if (board[r1 - 1][c1 + 1].color != color) {
ch = intToCharDif(c1 + 1);
printf("%c%d , ", ch, r1 - 1);
mCount++;
}
if (board[r1 + 1][c1 - 1].color != color) {
ch = intToCharDif(c1 - 1);
printf("%c%d , ", ch, r1 + 1);
mCount++;
}
if (mCount == 0)
{
printf(" There is no available move!\nTry different piece!\n");
}
return mCount;
}
void change(char* ch1, char* ch2)
{
int temp1[2] = { 0, 0 };
int temp2[2] = { 0, 0 };
charToInt(ch1, &temp1[0]);
charToInt(ch2, &temp2[0]);
piece tempPiece;
tempPiece.color = 2;
tempPiece.type = 0;
board[temp2[1]][temp2[0]] = board[temp1[1]][temp1[0]];
board[temp1[1]][temp1[0]] = tempPiece;
}
void player1()
{
int p1[2];
char ch1[2];
char ch2[2];
printf("\nPLAYER 1 (W)\n");
again1:
int withMove = 1; //if selected piece has no move this will be 0
printf("Select Piece: \n");
scanf("%s", &ch1[0]);
charToInt(&ch1[0], &p1[0]);
switch (board[p1[1]][p1[0]].type)
{
case 1:
withMove = pawnMove(p1[1], p1[0]);
break;
case 2:
withMove = rookMove(p1[1], p1[0]);
break;
case 3:
withMove = knightMove(p1[1], p1[0]);
break;
case 4:
withMove = bishopMove(p1[1], p1[0]);
break;
case 5:
withMove = queenMove(p1[1], p1[0]);
break;
case 6:
withMove = kingMove(p1[1], p1[0]);
break;
default: printf("Incorrect selection! "); goto again1;
}
if (withMove == 0)
goto again1;
scanf("%s", &ch2[0]);
change(&ch1[0], &ch2[0]);
}
void player2() {
int p1[2];
char ch1[2];
char ch2[2];
printf("\nPLAYER 2 (B)\n");
again1:
int withMove = 1; //if selected piece has no move this will be 0
printf("Select Piece: \n");
scanf("%s", &ch1[0]);
charToInt(&ch1[0], &p1[0]);
switch (board[p1[1]][p1[0]].type)
{
case 1:
withMove = pawnMove(p1[1], p1[0]);
break;
case 2:
withMove = rookMove(p1[1], p1[0]);
break;
case 3:
withMove = knightMove(p1[1], p1[0]);
break;
case 4:
withMove = bishopMove(p1[1], p1[0]);
break;
case 5:
withMove = queenMove(p1[1], p1[0]);
break;
case 6:
withMove = kingMove(p1[1], p1[0]);
break;
default: printf("Incorrect selection! "); goto again1;
}
if (withMove == 0)
goto again1;
scanf("%s", &ch2[0]);
change(&ch1[0], &ch2[0]);
}
};
int main()
{
Board board = Board();
char ch;
printf("\n\tWELCOME TO CHESS GAME");
printf("\n\n\t By Berkay ");
_getch();
system("cls");
int x = 0;
do
{
x++;
system("cls");
board.print();
if ((x % 2) == 0)
{
board.player2();
}
else
{
board.player1();
}
printf(" \n\nPress Enter To Continue ! \n\n ");
ch = _getch();
} while (ch == 13);
}
I am not sure where I did the mistake which causes this error. Is this about the references ?
The code you posted is way too long for a detailed analysis, but I can see that in player1() and player2() you have something like this:
char ch1[2];
...
scanf("%s", &ch1[0]);
I'm just speculating but, if by mistake you input more than just one letter, then ch1 will overflow since it can just accept one letter and the ending \0.
Instead of dealing with char[] or char * for this information where only one character is relevant, maybe should you use only a char?
Or at least should you input this character with "%1s" in order to prevent overflow of char ch1[2]?
Moreover, in charToInt() (which is called a bit after the input) you expect two characters (char1[0] and char1[1]), so maybe you need to declare char ch1[3] and input with "%2s" in order to store two characters and the ending \0.
However, it is difficult to give more precise advice without knowing exactly what happens (and where) when you experience the problem.
Please help... I'm trying to learn C types conversion.
This code works well only converting some hex chars as 1, 2, 3. For others, also changing string or reduce string length, the conversion fails...
I'll put the code below... Anyone can explain me where the code is wrong?
Thanks in advance!
#include <stdio.h>
int a2v(char c)
{
if ((c >= '0') && (c <= '9'))
{
return c - '0';
}
if ((c >= 'a') && (c <= 'f'))
{
return c - 'a' + 10;
}
else return 0;
}
char v2a(int c)
{
const char hex[] = "0123456789abcdef";
return hex[c];
}
char *unhexlify(char *hstr)
{
char *bstr = malloc((strlen(hstr) / 2) + 1);
char *pbstr = bstr;
for (int i = 0; i < strlen(hstr); i += 2)
{
*pbstr++ = (a2v(hstr[i]) << 4) + a2v(hstr[i + 1]);
}
*pbstr++ = '\0';
return bstr;
}
char *hexlify(char *bstr)
{
char *hstr = malloc((strlen(bstr) * 2) + 1);
char *phstr = hstr;
for (int i = 0; i < strlen(bstr); i++)
{
*phstr++ = v2a((bstr[i] >> 4) & 0xFF);
*phstr++ = v2a((bstr[i]) & 0xFF);
}
*phstr++ = '\0';
return hstr;
}
int main()
{
char *title = "... Trying to convert hex into binary string and back again ?! ...";
printf("%s\n\n", title);
char *input = "0123456789abcdef\0";
printf("Original: %s (%d)\n\n", input, (int)strlen(input));
char *input_bin = unhexlify(input);
printf("Bin: %s (%d)\n\n", input_bin, (int)strlen(input_bin));
char *input_hex = hexlify(input_bin);
printf("Hex: %s (%d)\n\n", input_hex, (int)strlen(input_hex));
system("pause");
return 0;
}
Updated Version of #Kevin's answer:
int a2v(char c) {
if ((c >= '0') && (c <= '9')) return c - '0';
if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10;
if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10;
else return 0;
}
char v2a(int c) {
const char hex[] = "0123456789abcdef";
return hex[c];
}
char *hexlify(char *bstr) {
char *hstr=malloc((strlen(bstr)*2)+1);
bzero(hstr,(strlen(bstr)*2)+1);
char *phstr=hstr;
for(int i=0; i<strlen(bstr);i++) {
*phstr++ =v2a((bstr[i]>>4)&0x0F);
*phstr++ =v2a((bstr[i])&0x0F);
}
*phstr++ ='\0';
return hstr;
}
char *hexlifyn(char *bstr, uint str_len) {
char *hstr=malloc((str_len*2)+1);
bzero(hstr,(str_len*2)+1);
char *phstr=hstr;
for(int i=0; i<str_len;i++) {
*phstr++ =v2a((bstr[i]>>4)&0x0F);
*phstr++ =v2a((bstr[i])&0x0F);
}
*phstr++ ='\0';
return hstr;
}
char *unhexlify(char *hstr) {
char *bstr=malloc((strlen(hstr)/2)+1);
bzero(bstr,(strlen(hstr)/2)+1);
char *pbstr=bstr;
for(int i=0;i<strlen(hstr); i += 2)
*pbstr++ =(a2v(hstr[i])<<4)+a2v(hstr[i+1]);
*pbstr++ ='\0';
return bstr;
}
char *unhexlifyn(char *hstr, uint str_len) {
char *bstr=malloc((str_len/2)+1);
bzero(bstr,(str_len/2)+1);
char *pbstr=bstr;
for(int i=0;i<str_len; i += 2)
*pbstr++ =(a2v(hstr[i])<<4)+a2v(hstr[i+1]);
*pbstr++ ='\0';
return bstr;
}
Thank you!
Based on chux's answer, the mistake was into hexlify function:
*phstr++ = v2a((bstr[i] >> 4) & 0x0F);
*phstr++ = v2a((bstr[i]) & 0x0F);
Masks was wrong! I will study much more!
PS = I added some code in order to handle NULL binary character (0), that truncates string.
#include <stdio.h>
int a2v(char c)
{
if ((c >= '0') && (c <= '9'))
{
return c - '0';
}
if ((c >= 'a') && (c <= 'f'))
{
return c - 'a' + 10;
}
else return 0;
}
char v2a(int c)
{
const char hex[] = "0123456789abcdef";
return hex[c];
}
char *unhexlify(char *hstr)
{
char *bstr = malloc((strlen(hstr) / 2) + 1);
char *pbstr = bstr;
for (int i = 0; i < strlen(hstr); i += 2)
{
char c = (a2v(hstr[i]) << 4) + a2v(hstr[i + 1]);
if (c == 0) {
*pbstr++ = -128;
} else {
*pbstr++ = c;
}
}
*pbstr++ = '\0';
return bstr;
}
char *hexlify(char *bstr)
{
char *hstr = malloc((strlen(bstr) * 2) + 1);
char *phstr = hstr;
for (int i = 0; i < strlen(bstr); i++)
{
if (bstr[i] == -128)
{
*phstr++ = '0';
*phstr++ = '0';
} else {
*phstr++ = v2a((bstr[i] >> 4) & 0x0F);
*phstr++ = v2a((bstr[i]) & 0x0F);
}
}
*phstr++ = '\0';
return hstr;
}
int main()
{
printf("... Trying to convert hex into binary string and back again ?! ...\n\n");
char *input = "070790ca8fd8058b455f13dd698a4eed028cb0efc13907f681604676d69e57affe299aae7c91fd000000005271266004e4cd7f52548153f8f78b76840aeca16e91bac0ebeb4d74ff3ce3c901\0";
char *input_bin = unhexlify(input);
char *input_hex = hexlify(input_bin);
printf("Input: %s (%d)\n\n", input, strlen(input));
printf("Output: %s (%d)\n\n", input_hex, strlen(input_hex));
if (strcmp(input, input_hex) == 0)
{
printf("Input and output are EQUALS !\n\n");
} else {
printf("Input and output are NOT EQUALS !\n\n");
}
system("pause");
return 0;
}
Regards, Kevin