Multidimensional array in poker program - c

I'm not sure how to make the multidimensional array able to perform the same task as the other three I am supposed to get rid of. Would I just simply replace all the places with the other arrays with just the one Multi? This is especially hard for me since I do not play cards and the logic behind the card game makes no sense to me.
DIRECTIONS
I need to remove the num_in_rank, num_in_suit, and card_exists arrays. Have the program store the cards in a 5 x 2 array instead. Each row of the array will represent a card. For example, if the array is named hand, then hand(0)(0) will store the rank of the first card and hand(0)(1) will store the suit of the first card.
/* Classifies a poker hand */
#include <stdbool.h> /* C99 only */
#include <stdio.h>
#include <stdlib.h>
#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5
/* external variables */
int num_in_rank[NUM_RANKS];
int num_in_suit[NUM_SUITS];
bool straight, flush, four, three;
int pairs; /* can be 0, 1, or 2 */
/* prototypes */
void read_cards(void);
void analyze_hand(void);
void print_result(void);
/**********************************************************
* main: Calls read_cards, analyze_hand, and print_result *
* repeatedly. *
**********************************************************/
int main(void)
{
for (;;) {
read_cards();
analyze_hand();
print_result();
}
}
/**********************************************************
* read_cards: Reads the cards into the external *
* variables num_in_rank and num_in_suit; *
* checks for bad cards and duplicate cards. *
**********************************************************/
void read_cards(void)
{
bool card_exists[NUM_RANKS][NUM_SUITS];
char ch, rank_ch, suit_ch;
int rank, suit;
bool bad_card;
int cards_read = 0;
for (rank = 0; rank < NUM_RANKS; rank++) {
num_in_rank[rank] = 0;
for (suit = 0; suit < NUM_SUITS; suit++)
card_exists[rank][suit] = false;
}
for (suit = 0; suit < NUM_SUITS; suit++)
num_in_suit[suit] = 0;
while (cards_read < NUM_CARDS) {
bad_card = false;
printf("Enter a card: ");
rank_ch = getchar();
switch (rank_ch) {
case '0': exit(EXIT_SUCCESS);
case '2': rank = 0; break;
case '3': rank = 1; break;
case '4': rank = 2; break;
case '5': rank = 3; break;
case '6': rank = 4; break;
case '7': rank = 5; break;
case '8': rank = 6; break;
case '9': rank = 7; break;
case 't': case 'T': rank = 8; break;
case 'j': case 'J': rank = 9; break;
case 'q': case 'Q': rank = 10; break;
case 'k': case 'K': rank = 11; break;
case 'a': case 'A': rank = 12; break;
default: bad_card = true;
}
suit_ch = getchar();
switch (suit_ch) {
case 'c': case 'C': suit = 0; break;
case 'd': case 'D': suit = 1; break;
case 'h': case 'H': suit = 2; break;
case 's': case 'S': suit = 3; break;
default: bad_card = true;
}
while ((ch = getchar()) != '\n')
if (ch != ' ') bad_card = true;
if (bad_card)
printf("Bad card; ignored.\n");
else if (card_exists[rank][suit])
printf("Duplicate card; ignored.\n");
else {
num_in_rank[rank]++;
num_in_suit[suit]++;
card_exists[rank][suit] = true;
cards_read++;
}
}
}
/**********************************************************
* analyze_hand: Determines whether the hand contains a *
* straight, a flush, four-of-a-kind, *
* and/or three-of-a-kind; determines the *
* number of pairs; stores the results into *
* the external variables straight, flush, *
* four, three, and pairs. *
**********************************************************/
void analyze_hand(void)
{
int num_consec = 0;
int rank, suit;
straight = false;
flush = false;
four = false;
three = false;
pairs = 0;
/* check for flush */
for (suit = 0; suit < NUM_SUITS; suit++)
if (num_in_suit[suit] == NUM_CARDS)
flush = true;
/* check for straight */
rank = 0;
while (num_in_rank[rank] == 0) rank++;
for (; rank < NUM_RANKS && num_in_rank[rank] > 0; rank++)
num_consec++;
if (num_consec == NUM_CARDS) {
straight = true;
return;
}
/* check for 4-of-a-kind, 3-of-a-kind, and pairs */
for (rank = 0; rank < NUM_RANKS; rank++) {
if (num_in_rank[rank] == 4) four = true;
if (num_in_rank[rank] == 3) three = true;
if (num_in_rank[rank] == 2) pairs++;
}
}
/**********************************************************
* print_result: Prints the classification of the hand, *
* based on the values of the external *
* variables straight, flush, four, three, *
* and pairs. *
**********************************************************/
void print_result(void)
{
if (straight && flush) printf("Straight flush");
else if (four) printf("Four of a kind");
else if (three &&
pairs == 1) printf("Full house");
else if (flush) printf("Flush");
else if (straight) printf("Straight");
else if (three) printf("Three of a kind");
else if (pairs == 2) printf("Two pairs");
else if (pairs == 1) printf("Pair");
else printf("High card");
printf("\n\n");
}

to help you visualize it first define the multidimensional array, then use constants to access the indexes
ie.
//you could also use namespaces and enums or static class variables, const is simpler
const int RANK = 0; //or CARD_RANK if ambiguous/conflicting
const int SUIT = 1; //or CARD_SUIT if ambiguous
int cards[5][2]; //first index is card, second index is data about the card
//access first card's suit
int temp = cards[0][SUIT];
Assuming the program runs already, and all you need to do is this, then just do it and everything will work. The game seems to be poker or a variation btw.

Related

substitution cipher: can't acknowledge nonrepeating characters

I'm having a problem with CS50's substitution cipher problem. I'm stuck on how to validate the key. Whenever I pass a 26 character key as a command-line argument, the program outputs "you must not repeat any characters" even when the key doesn't have any. My program correctly checks for the length of the key and the presence of a command-line argument. It just doesn't acknowledge a valid nonrepeating key.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
bool validateKey(char key[]);
string substitute(char key[], string plaintext);
int main(int argc, string argv[]) {
if(strlen(argv[1]) == 26) { //key typed after prgm name will be used to encrypt data
if(validateKey(argv[1])) {
string plaintext = get_string("Plaintext: ");
string ciphertext = substitute(argv[1], plaintext);
printf("Ciphertext: %s", ciphertext);
}
}
else if(argv[1] == NULL) {
printf("Usage: ./substitution key\n");
}
else {
printf("Key must contain 26 characters.\n");
}
}
bool validateKey(char key[]) {
for(int i = 0; i < 26; i++) {
if(!isalpha(key[i])) {
printf("Key must only contain alphabetic characters.\n");
return false;
}
}
/*
an array of counters to keep track of how many times a letter occurs in the cipher
each counter should be set to 1 if key doesn't have repeating letters
*/
int cntr[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 26; i++) {
key[i] = islower(key[i]); //make all the letters in the key lowercase to make it easier to work with
switch(key[i]) {
case 'a':
cntr[0] += 1;
case 'b':
cntr[1] += 1;
case 'c':
cntr[2] += 1;
case 'd':
cntr[3] += 1;
case 'e':
cntr[4] += 1;
case 'f':
cntr[5] += 1;
case 'g':
cntr[6] += 1;
case 'h':
cntr[7] += 1;
case 'i':
cntr[8] += 1;
case 'j':
cntr[9] += 1;
case 'k':
cntr[10] += 1;
case 'l':
cntr[11] += 1;
case 'm':
cntr[12] += 1;
case 'n':
cntr[13] += 1;
case 'o':
cntr[14] += 1;
case 'p':
cntr[15] += 1;
case 'q':
cntr[16] += 1;
case 'r':
cntr[17] += 1;
case 's':
cntr[18] += 1;
case 't':
cntr[19] += 1;
case 'u':
cntr[20] += 1;
case 'v':
cntr[21] += 1;
case 'w':
cntr[22] += 1;
case 'x':
cntr[23] += 1;
case 'y':
cntr[24] += 1;
case 'z':
cntr[25] += 1;
}
}
for(int i = 0; i < 26; i++) {
if(cntr[i] != 1) {
printf("Key must not contain repeated characters.\n");
return false;
}
}
return true;
}
string substitute(char key[]) {
return "";
}
The "minimal" fix is to add a break after each increment, so your case 'a' doesn't execute the code for case 'b' and onwards. You'd also need to change the islower call to tolower (otherwise all your key values just become 0 and 1).
That said, the switch statement itself is already ridiculously overlong, and should really just be simplified to the one-liner:
cntr[tolower(key[i]) - 'a'] += 1;
which is safe, since you've already checked all the input characters pass isalpha.

Why my converter doesn't count the last digit?

This program is about converting Roman number to decimal number. The program can convert the alphabet to number but it can not process the last roman digit. I think my flow is alright but the output is not right. Can any body give me a helping hand?
#include <stdint.h>
#include <stdio.h>
#include <string.h>
int roman_to_int(const char s[], int length) {
// Please complete the function body
int ans = 0, value[length];
for (int i = 0; i < length; i++) {
switch (s[i]) {
case 'I': value[i] = 1; break;
case 'V': value[i] = 5; break;
case 'X': value[i] = 10; break;
case 'L': value[i] = 50; break;
case 'C': value[i] = 100; break;
case 'D': value[i] = 500; break;
case 'M': value[i] = 1000; break;
}
}
for (int i = 0; i < length - 1; i++) {
if (value[i] >= value[i+1])
ans += value[i];
else {
ans = ans + value[i+1] - value[i];
i++;
}
}
return ans;
}
int main() {
char roman_num[] = "III";
char roman_num_2[] = "CXXIII";
char roman_num_3[] = "MMMCDLIX";
printf("roman_to_int(%s) = %d\n", roman_num,
roman_to_int(roman_num, strlen(roman_num)));
printf("roman_to_int(%s) = %d\n", roman_num_2,
roman_to_int(roman_num_2, strlen(roman_num_2)));
printf("roman_to_int(%s) = %d\n", roman_num_3,
roman_to_int(roman_num_3, strlen(roman_num_3)));
}
You should add the value of the last roman digit after the end of the second loop.
As an alternative, you could make value on entry longer than n and set the last entry to 0 so you won't need the make a special case of the last roman digit.
Note that you should also handle the case of unrecognised roman digits: either by ignoring them or by returning an error code, such as a negative value -1.
It is also simpler for roman_to_int to take a null terminated C string and compute the length there.
Here is a modified version:
#include <stdio.h>
#include <string.h>
int roman_to_int(const char s[]) {
// Please complete the function body
int length = strlen(s);
int ans = 0, value[length + 1];
for (int i = 0; i < length; i++) {
switch (s[i]) {
case 'I': value[i] = 1; break;
case 'V': value[i] = 5; break;
case 'X': value[i] = 10; break;
case 'L': value[i] = 50; break;
case 'C': value[i] = 100; break;
case 'D': value[i] = 500; break;
case 'M': value[i] = 1000; break;
default: return -1;
}
}
value[length] = 0;
for (int i = 0; i < length; i++) {
if (value[i] >= value[i + 1])
ans += value[i];
else
ans -= value[i];
}
return ans;
}
int main() {
char roman_num[] = "III";
char roman_num_2[] = "CXXIII";
char roman_num_3[] = "MMMCDLIX";
char roman_num_4[] = "MMMCDLIZ"; // error
printf("roman_to_int(%s) = %d\n", roman_num, roman_to_int(roman_num));
printf("roman_to_int(%s) = %d\n", roman_num_2, roman_to_int(roman_num_2));
printf("roman_to_int(%s) = %d\n", roman_num_3, roman_to_int(roman_num_3));
printf("roman_to_int(%s) = %d\n", roman_num_4, roman_to_int(roman_num_4));
return 0;
}

Problem with input and output to and from .txt file

My homework is to calculate the resistance in Ohms of a resistor give a text file with information about the resistor. Using this text file, I calculate the resistance and print it to another text file. When I run this code I get a debug error "Run-Time check failure #3-T" and no output to the file. Can you tell me where I am going wrong?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<math.h>
int col_to_num(char color, int choice) {
int num;
switch (color) {
case 'B':if (choice == 1) num = 0;
else if (choice == 2) num = 1;
else if (choice == 3)num = 6;
case 'b':if (choice == 1) num = 0;
else if (choice == 2) num = 1;
else if (choice == 3)num = 6;
case 'G':if (choice == 1) num = 5;
else if (choice == 2) num = 8;
else if (choice == 3)num = -1;
case 'g':if (choice == 1) num = 5;
else if (choice == 2) num = 8;
else if (choice == 3)num = -1;
case 'R':num = 2;
case 'r':num = 2;
case 'O':num = 3;
case 'o':num = 3;
case 'Y':num = 4;
case 'y':num = 4;
case 'V':num = 7;
case 'v':num = 7;
case 'W':num = 9;
case 'w':num = 9;
case 'S':num = 10;
case 's':num = 10;
}
return num;
}
int main() {
double resistance, thirdband;
char color1, color2, color3;
int val1, val2, val3;
FILE *inp, *outp;
inp = fopen("resistorcolor.txt", "r");
outp = fopen("resistorvalue.txt", "w");
if (inp == NULL) {
printf("The input file does not exist\n");
}
else {
while (fscanf(inp, "%c %d %c %d %c %d%*c", &color1, &val1, &color2, &val2, &color3, &val3) != EOF) {
if (col_to_num(color3, val3) == -1)thirdband = .01;
if (col_to_num(color3, val3) == 10)thirdband = .01;
if (col_to_num(color3, val3) == 0)thirdband = 1;
if (col_to_num(color3, val3) == 1)thirdband = 10;
if (col_to_num(color3, val3) == 2)thirdband = 100;
if (col_to_num(color3, val3) == 3)thirdband = 1000;
if (col_to_num(color3, val3) == 4)thirdband = 10000;
if (col_to_num(color3, val3) == 5)thirdband = 100000;
if (col_to_num(color3, val3) == 6)thirdband = 1000000;
resistance = ((col_to_num(color1, val1) * 10) + col_to_num(color2, val2))*thirdband;
fprintf(outp, "%.2lf Ohm", resistance);
thirdband = 0;
}
fclose(outp);
}
return 0;
}
Run-Time check failure #3 mean something was used without being initialized. There is more information which you are not seeing. The error message should be "Run-Time check failure #3: The variable 'XXX' is being used without being initialized", where XXX is a variable in your code.
In any case you have a lot of uninitialized variables, those should be initialized to some default value:
double resistance = 0.0, thirdband = 0.0;
char color1 = 0, color2 = 0, color3 = 0;
int val1 = 0, val2 = 0, val3 = 0;
FILE *inp = nullptr, *outp = nullptr;
and for the function:
int col_to_num(char color, int choice) {
int num = -1;
Most likely it is int num from the col_to_num function, which will never hit a case if you didn't pass in one of those values. You need to break to exit the switch statement, usually after your condition is hit, however you can group cases together by not breaking allowing you to easily do the same action for different cases. Think of it as falling through starting at the case that is matched. You also need a default case to handle if no cases are matched like this:
int col_to_num(char color, int choice) {
int num = -1;
switch (color) {
case 'B':
case 'b':
if (choice == 1) num = 0;
else if (choice == 2) num = 1;
else if (choice == 3)num = 6;
break;
case 'G':
case 'g':
if (choice == 1) num = 5;
else if (choice == 2) num = 8;
else if (choice == 3)num = -1;
break;
case 'R':
case 'r':
num = 2;
break;
case 'O':
case 'o':
num = 3;
break;
case 'Y':
case 'y':
num = 4;
break;
case 'V':
case 'v':
num = 7;
break;
case 'W':
case 'w':
num = 9;
break;
case 'S':
case 's':
num = 10;
break;
default:
printf("Invalid input: %c\n", color);
}
return num;
}
perhaps you got a wrong understanding of switch case. You need to include break statement after every case if not added, all the cases will run whatever the input may be. And second thing is, you have to initialize the variables before using them. Hope that helps. Cheers !! Feel free to ask any doubts.

Classifying Poker Hands [ROYAL FLUSH IS FAILING]

I was following programming projects from the book C programming: A Modern Approach and I have incorporated 2 questions into my program but failed to achieve the 3rd that is to finding a royal flush hand.
This is what I have done so far:
/* Classifies a poker hand */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5
#define ROYAL_FLUSH ('A' || 'a' || 'K' || 'k' || 'Q' || 'q' || 'J' || 'j' || 'T' || 't')
#define ACE_LOW (('A' || 'a') && '2' && '3' && '4' && '5')
/* external variables */
/* int ROYAL_FLUSH[8, 9, 10, 11, 12]
int num_in_rank[NUM_RANKS];
int num_in_suit[NUM_SUITS]; */
bool royal_flush, ace_low, straight, flush, four, three;
int pairs; /* can be 0, 1 or 2 */
/* Prototypes */
int read_cards(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]);
int analyze_hand(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS]);
void print_result(void);
int main(void)
{
int num_in_rank[NUM_RANKS];
int num_in_suit[NUM_SUITS];
for(;;) {
read_cards(num_in_rank, num_in_suit);
analyze_hand(num_in_rank, num_in_suit);
print_result();
}
}
int read_cards(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS])
{
bool card_exists[NUM_RANKS][NUM_SUITS];
char ch, rank_ch, suit_ch;
int rank, suit;
bool bad_card;
int cards_read = 0;
for (rank = 0; rank < NUM_RANKS; rank++) {
num_in_rank[rank] = 0;
for (suit = 0; suit < NUM_SUITS; suit++)
card_exists[rank][suit] = false;
}
for (suit = 0; suit < NUM_SUITS; suit++)
num_in_suit[suit] = 0;
while (cards_read < NUM_CARDS) {
bad_card = false;
printf("Enter a card: ");
rank_ch = getchar();
switch (rank_ch) {
case '0': exit(EXIT_SUCCESS);
case '2': rank = 0; break;
case '3': rank = 1; break;
case '4': rank = 2; break;
case '5': rank = 3; break;
case '6': rank = 4; break;
case '7': rank = 5; break;
case '8': rank = 6; break;
case '9': rank = 7; break;
case 't': case 'T': rank = 8; break;
case 'j': case 'J': rank = 9; break;
case 'q': case 'Q': rank = 10; break;
case 'k': case 'K': rank = 11; break;
case 'a': case 'A': rank = 12; break;
default: bad_card = true;
}
suit_ch = getchar();
switch (suit_ch) {
case 'c': case 'C': suit = 0; break;
case 'd': case 'D': suit = 1; break;
case 'h': case 'H': suit = 2; break;
case 's': case 'S': suit = 3; break;
default: bad_card = true;
}
while ((ch = getchar()) != '\n')
if (ch != ' ') bad_card = true;
if (bad_card)
printf("Bad card; ignored.\n");
else if (card_exists[rank][suit])
printf("Duplicate card; ignored.\n");
else {
num_in_rank[rank]++;
num_in_suit[suit]++;
card_exists[rank][suit] = true;
cards_read++;
}
}
return 0;
}
int analyze_hand(int num_in_rank[NUM_RANKS], int num_in_suit[NUM_SUITS])
{
int num_consec = 0;
int rank, suit;
royal_flush = false;
straight = false;
ace_low = false;
flush = false;
four = false;
three = false;
pairs = 0;
/*check for royal flush */
/* int arr[5] = {8, 9, 10, 11, 12};
int i; */
if (flush)
for (rank = 0; rank < NUM_RANKS; rank++)
if (num_in_rank[rank] == ROYAL_FLUSH)
continue;
else
break;
royal_flush = true;
/* check for flush */
for (suit = 0; suit < NUM_SUITS; suit++)
if (num_in_suit[suit] == NUM_CARDS)
flush = true;
/* check for ace-low straight */
for (rank = 0; rank < NUM_RANKS; rank++)
if (num_in_rank[rank] == ACE_LOW)
ace_low = true;
/* check for straight */
rank = 0;
while (num_in_rank[rank] == 0) rank++;
for (; rank < NUM_RANKS && num_in_rank[rank] > 0; rank++)
num_consec++;
if (num_consec == NUM_CARDS) {
straight = true;
return 0;
}
/* check for 4 of a kind, 3 of a kind and pairs */
for (rank = 0; rank < NUM_RANKS; rank++) {
if (num_in_rank[rank] == 4)
four = true;
if (num_in_rank[rank] == 3)
three = true;
if (num_in_rank[rank] == 2)
pairs++;
}
return 0;
}
void print_result(void)
{
if (royal_flush && flush && straight)
printf("\nRoyal Flush");
else if (straight && flush && royal_flush == false)
printf("\nStraight Flush");
else if (four)
printf("\nFour of a kind");
else if (three && pairs == 1)
printf("\nFull House");
else if (flush)
printf("\nFlush");
else if (straight)
printf("\nStraight");
else if (ace_low)
printf("\nAce-low straight");
else if (three)
printf("\nThree of a kind");
else if (pairs == 2)
printf("\nTwo Pairs");
else if (pairs == 1)
printf("\nPair");
else
printf("\nHigh card");
printf("\n\n");
}
My code prints out Royal Flush when the inputted cards are not even royal flush cards but are actually flush cards.
I am new to c so please go easy on the criticism.
Language: c99 ; Compiler: gcc
This:
if (num_in_rank[rank] == ROYAL_FLUSH)
which is the same as this:
if (num_in_rank[rank] == ('A' || 'a' || 'K' || 'k' || 'Q' || 'q' || 'J' || 'j' || 'T' || 't'))
Does not do what you think it does. It does not compare num_in_rank[rank] against each of A, a, etc. What is does is perform a logical OR first between A and a, then a logical OR of that result with K, etc.
You need to compare your variable against each of those individually.
You could do this:
if ((num_in_rank[rank] == 'A') || (num_in_rank[rank] == 'a') || ...
Or this:
char in_royal[] = { 'A', 'a', ... };
for (i=0;i<sizeof(in_royal);i++) {
if (num_in_rank[rank] == in_royal[i]) {
...
There's also an issue with how this is laid out:
if (flush)
for (rank = 0; rank < NUM_RANKS; rank++)
if (num_in_rank[rank] == ROYAL_FLUSH)
continue;
else
break;
royal_flush = true;
The last line is outside of the if block, and you won't capture the case you want. Make sure to use braces:
if (flush) {
royal_flush = true;
for (rank = 0; rank < NUM_RANKS; rank++) {
if ((num_in_rank[rank] == 'A') || (num_in_rank[rank] == 'a') || ...) {
continue;
} else {
royal_flush = false;
break;
}
}
}
As an improvement, rather than checking for all cards in a royal flush individually, just check for an ace. That along with the separate checks for straight and flush (which aren't currently in your code) will capture that. Then you can do this:
if (straight && flush && has_ace)
printf("\nRoyal Flush");

C pointers in reversi games

I want to that this function after than player 1 puts position program chack where on the left is player's 1 pawn and all of opponent's paws between player's 1 two pawns turning on 'X', like in reversi games.
This is whole unfinished code:
#include<stdio.h>
#define SIZE 7
char board[SIZE][SIZE];
char letter;
int number;
void make_board(char tab[SIZE][SIZE]){
int w,k;
for(w=0; w < SIZE; w++){
for(k=0; k < SIZE; k++){
tab[w][k] = '.';
}
}
tab[0][0] = 'X';
tab[1][0] = '1';
tab[2][0] = '2';
tab[3][0] = '3';
tab[4][0] = '4';
tab[5][0] = '5';
tab[6][0] = '6';
tab[0][1] = 'A';
tab[0][2] = 'B';
tab[0][3] = 'C';
tab[0][4] = 'D';
tab[0][5] = 'E';
tab[0][6] = 'F';
tab[4][4] = 'X';
tab[4][3] = 'O';
tab[3][4] = 'O';
tab[3][3] = 'X';
}
char draw_board(char tab[SIZE][SIZE]){
int w, k;
for(w=0; w < SIZE; w++){
for(k=0; k < SIZE; k++){
printf("%2c", tab[w][k]);
}
printf("\n");
}
}
int translate(char letter){
int letter_to_number;
switch(letter){
case 'A':
case 'a':
letter_to_number = 1;
break;
case 'B':
case 'b':
letter_to_number = 2;
break;
case 'C':
case 'c':
letter_to_number = 3;
break;
case 'D':
case 'd':
letter_to_number = 4;
break;
case 'E':
case 'e':
letter_to_number = 5;
break;
}
return letter_to_number;
}
int finished(char tab[SIZE][SIZE]){ // looking '.' in array
int i,j;
for(i=1;i<=SIZE;i++){
for(j=1;j<=SIZE;j++){
if(tab[i][j]=='.'){
return 1;
}else{
return 0; // if don't find any '.' game is finish
}
}
}
}
void hit(char tab[SIZE][SIZE], int player ){
int i,j;
int *poz1, *poz2;
printf("Call out a letter and a number of a row and column on the grid:\n");
scanf(" %c %d", &letter, &number);
i=translate(letter);
poz1=&tab[number][i];
if(tab[number][i]=='.'){
if(player==1){
*poz1='X';
for(poz1-1;*poz1=='X';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
*poz2='X';}
}else{
*poz1='O';
for(poz1-1;*poz1=='O';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
poz2='O';}
}
}else{
printf("On this place already is pawn\n");
}
draw_board(board);
getchar();
}
int main(){
int i,j,k, pg1=0, pg2=0, player=1;
make_board(board);
draw_board(board);
do{
if(player==1){
printf("Player 1\n");
hit(board, gracz);
k=finished(board);
gracz=2;
}else{
printf("Player 2\n");
hit(board, gracz);
k=finished(board);
player=1;
}
}while(k==1);
for(i=1;i<=SIZE;i++){
for(j=1;j<=SIZE;j++){
if(board[i][j]=='X'){
pg1++;
}else{
pg2++;
}
}
}
if(pg1>pg2){
printf("Player 1 wins");
}else{
printf("Player 2 wins");
}
return 0;
}
Bit buggy code:
poz1=&tab[number][i];
if(tab[number][i]=='.'){
if(player==1){
*poz1='X';
for(poz1-1;*poz1=='X';poz1--){
poz2=&poz1;}
poz1=&tab[number][i];
for(poz2;poz2<=poz1;poz2++){
*poz2='X';}
How can you asgn &pos1 to pos2. For this you need pointer to a pointer, i.e, pos 2 should be declared as **pos2.
Also, what do you want to achieve by looping over poz1 (set 'X' earlier)?
Anyhow, some cleanup to your code:
if(tab[number][i]=='.'){
if(player==1){ //considering player 1 is 'X'
// Loop to the left till you find opponent's piece or come to edge.
for(j=i-1;tab[number][j]=='O' && j!=0 ;j--)
;
// Validation check
if(i-j <=1 || tab[number][j] != 'X');
//Invalid move
return 1;
else
// convert all the opponents pieces between two of yours piece
for(k=i;k>j;k--)
tab[number][k] = 'X';
The above part of code is informative only..this will check if the move is valid for left side..and if valid convert the opponents pieces.. you need to understand this and put similar logic for "Right", "Diagonal" etc to complete the reversi game.

Resources