Are there any problems with my card game code? - static

//Usage: public Static void play()
//Desc: Play the game of OneCard. The game has 2 players. the user and the
// computer.
// The user is dealt 1 card, and so is the computer. The user has the
// option to change the card once. The winner is the player with the
// higher rank card (Ace>King>Queen>...>3>2). The suit is irrelevant.
//Input: The user enters a character (Y/N) signaling whether the user wants
// to change the card.
//Output: The user's card, followed by a message asking if the user wants
// to change the card, followed optionally the user's new card,
// followed by the computer's card, followed by the result of the game,
// followed by a message asking the user if the user wants to play
// again.
import java.util.Scanner;
class OneCard
{
public static void play()
{
Scanner f = new Scanner(System.in);
DeckOfCards d = new DeckOfCards();
String meatbag = d.deal();
String CPU = d.deal();
System.out.printf("Your card: %s " , meatbag);
System.out.print("Change card: (y/n)");
char ch = f.nextLine().charAt(0);
if (ch == 'y' || ch == 'y') meatbag = d.deal();
else ;
findRank(meatbag);
findRank(CPU);
whoWon(meatbag, CPU);
}
public static int findRank(String s)
{
int rank_num= 0;
switch(s)
{
case "Two": rank_num = 2;
break;
case "Three": rank_num = 3;
break;
case "Four": rank_num = 4;
break;
case "Five": rank_num = 5;
break;
case "Six": rank_num = 6;
break;
case "Seven": rank_num = 7;
break;
case "Eight": rank_num = 8;
break;
case "Nine": rank_num = 9;
break;
case "Ten": rank_num = 10;
break;
case "Jack": rank_num = 11;
break;
case "Queen": rank_num = 12;
break;
case "King": rank_num = 13;
break;
case "Ace": rank_num = 14;
break;
}
return rank_num;
}
public static void whoWon(String s1, String s2)
{
System.out.printf("Your card: %s " , s1);
System.out.printf("Dealer's card: %s ", s2);
if(findRank(s1)> findRank(s2)) System.out.println("You won.");
else if (findRank(s1) < findRank(s2)) System.out.println("Dealer won.");
else System.out.println("Draw.");
}
}
I am not sure if I actually made a logical mistake when writing the methods findRank and whoWon. You can assume that class DeckOfCards and method DeckOfCards.deal have been made previous to this code.

There seems to be no logic mistake,
just some stuff you could remove like:
else ;
findRank(meatbag);
findRank(CPU);
Also you might want to change the line
if (ch == 'y' || ch == 'y') meatbag = d.deal();
into
if (ch == 'y' || ch == 'Y') meatbag = d.deal();

Related

Does anybody know a way to make a video game in turbo c where you have an A moving around on the screen?

I am trying to make a game with ms-dos called find the key.
What i am struggling with is using graphics.h to move an ASCII character move over a red screen using keyboard input.
Here is a snippet of my source code:
if (cn == 1) {
initgraph(&gd, &gm,"C:\\TC\\BGI");
settextstyle(DEFAULT_FONT,HORIZ_DIR,3);
setbkcolor(RED);
setcolor(BLACK);
outtextxy(100+i,100,"a");
while (getch() != '\033') { // if the first value is esc
getch(); // skip the [
switch(getch()) { // the real value
case 'D':
moveleft();
case 'A':
// code for arrow down
break;
case 'W':
// code for arrow right
break;
case 'S':
// code for arrow left
break;
}
}
Here is the moveleft() Function:
void moveleft() {
int i;
int j;
for( i = 0 ; i <= 420 ; i = i + 10, j++ ){
outtextxy(100+i,100,"a");
setcolor(j);
delay(100);
if( i == 420 )
break;
if ( j == 15 )
j = 2;
cleardevice(); // clear screen
}
}

Switch statement is skipped after two iterations of while loop

I am writing a state machine for an Arduino project to parse an input string from Serial1 input. I have a switch statement in a while loop that advances the state:
char * tok = strtok(instr, " \r\n"); //instr is the input string
int state = 0;
int targx = 0, targy = 0;
while (tok)
{
// State machine:
// 0: start parsing
// 1: N2 command, parse prediction
// 2: Correct prediction, parse targx
// 3: Parse targy
// 4: Target parsing complete
// 1000: Wrong prediction / unknown command
switch (state)
{
case 0:
if (strcmp(tok, "N2") == 0) state = 1;
else if (strcmp(tok, "PANGAIN") == 0) state = 5;
else if (strcmp(tok, "TILTGAIN") == 0) state = 7;
else state = 1000;
break;
case 1:
//Look for a person
int i = strlen(tok) - 1;
while(i >= 0 && tok[i] != ':') {i--;}
if (i >= 0) tok[i] = '\0';
Serial.print("Here's what it saw: ");
Serial.print(tok);
Serial.print("\n");
if (strcmp(tok, "person") == 0)
{
state = 2;
Serial.println(state);
}
else state = 1000;
break;
case 2:
Serial.println("Inside case 2");
targx = atoi(tok);
Serial.print("Targx = ");
Serial.print(targx, DEC);
Serial.println("");
state = 3;
break;
case 3:
targy = atoi(tok);
Serial.print("Targy = ");
Serial.print(targy, DEC);
Serial.println("");
state = 4;
break;
default:
break;
}
// Move to the next token:
tok = strtok(0, " \r\n");
Serial.println(tok);
}
The problem I'm having so far is it will get to case 1 and correctly identify that "person" is in the token and set the state to 2 but on every iteration of the while loop after that, it just skips the switch statement entirely. Here's what the output looks like for one input string:
Input String: N2 person:66 -1297 -538 2431 1331
> person:66
> Here's what it saw: person
> 2
> -1297
> -538
> 2431
> 1331
Can anyone tell me why the switch statement is being bypassed entirely after case 1 is hit? Any and all help is appreciated!
Your if else statement in case 1 is not correct.
The first if should be like this
if (i >= 0) {tok[i] = '\0';}
You are missing the brackets.
And the else statement should also be included in brackets like this.
if (strcmp(tok, "person") == 0)
{
state = 2;
Serial.println(state);
}
else
{
state = 1000;
}
Or if it is just one line of code like yours, you could write it in a separate line.
if (strcmp(tok, "person") == 0)
{
state = 2;
Serial.println(state);
}
else
state = 1000;
Otherwise it will assign value 1000 to state, that's why the for loop would skip all the switch cases.
My English is not very good. Hope you understand it.

Creating Tic-Tac-Toe in C - array not showing changes, not returning error messages

I am trying to create a tic-tac-toe game in C.
My instructions are as follows:
Write a C program that lets two people play tic-tac-toe. Use a global array: char ttt[3][3]; to represent the board state, and globals for the player (a char to hold X or O or whatever you characters you want), i and j integers for indexes, and an integer to count the number of moves completed. Show the game board for each move two characters for the players with a key for the user to type one character or digit to say what spot to take in the board. At the end of a game, say who won or that it is a tie. Have at least the functions to print the board, get a valid move, and check for a win; do use printf, scanf, if-else, switch (to find indexes into ttt) while, for.
My code is as follows:
#include <stdio.h>
#include <conio.h>
// Global array for the board
char ttt[3][3] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'}
};
void PrintTheBoard() { // Print the board as it currently is
printf("| %c | | %c | | %c |\n", ttt[0][0], ttt[0][1], ttt[0][2]);
printf("| %c | | %c | | %c |\n", ttt[1][0], ttt[1][1], ttt[1][2]);
printf("| %c | | %c | | %c |\n", ttt[2][0], ttt[2][1], ttt[2][2]);
}
// Check for a win
int CheckForWin() {
// Checks for horizontal win conditions
if (ttt[0][0] == ttt[0][1] && ttt[0][1] == ttt[0][2])
return 1;
else if (ttt[1][0] == ttt[1][1] && ttt[1][1] == ttt[1][2])
return 1;
else if (ttt[2][0] == ttt[2][1] && ttt[2][1] == ttt[2][2])
return 1;
// Checks for vertical wins
else if (ttt[0][0] == ttt[1][0] && ttt[1][0] == ttt[2][0])
return 1;
else if (ttt[0][1] == ttt[1][1] && ttt[1][1] == ttt[2][1])
return 1;
else if (ttt[0][2] == ttt[1][2] && ttt[1][2] == ttt[2][2])
return 1;
// Checks for diagonal wins
else if (ttt[0][0] == ttt[1][1] && ttt[1][1] == ttt[2][2])
return 1;
else if (ttt[0][2] == ttt[1][1] && ttt[1][1] == ttt[2][0])
return 1;
else if (ttt[0][0] != '1' && ttt[0][1] != '2' && ttt[0][2] != '3' &&
ttt[1][0] != '4' && ttt[1][1] != '5' && ttt[1][2] != '6' &&
ttt[2][0] != '7' && ttt[2][1] != '8' && ttt[2][2] != '9')
return 2;
else
return 0;
}
int main() { // The function below gets a move, validates it, and keep tracks of the # of moves made.
int choice;
int player = 1;
int i;
int counter = 0;
char mark;
int isValid;
// Gets user input
do {
PrintTheBoard();
player = (player % 2) ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
// Determines what mark to make, depending on the current player by way of "if current player is player 1, use X, otherwise, use O"
mark = (player == 1) ? 'X' : 'O';
/*
The below switch function is a bit convoluted. Depending on the value of the "choice" variable (1-9, chosen by the active player
and corresponding to a position on the board), the value is checked for position validity by checking if the position in the
array corresponding to the choice still has its original numeral value, which indicates the spot is not taken.
If it still has that original value, the position is assigned an X or an O depending on the current player.
If the spot is taken, indicated by the value not being equal to its original numeral, the player is told that the position is
invalid.
If the player does not choose a valid case, the player is informed of this and told what to do.
*/
switch(choice) {
case 1:
if (ttt[0][0] == '1') {
ttt[0][0] = mark;
}
break;
case 2:
if (ttt[0][1] == '2') {
ttt[0][1] = mark;
}
break;
case 3:
if (ttt[0][2] == '3') {
ttt[0][2] = mark;
}
break;
case 4:
if (ttt[1][0] == '4') {
ttt[1][0] = mark;
}
break;
case 5:
if (ttt[1][1] == '5') {
ttt[1][1] = mark;
}
break;
case 6:
if (ttt[1][2] == '6') {
ttt[1][2] = mark;
}
break;
case 7:
if (ttt[2][0] == '7') {
ttt[2][0] = mark;
}
break;
case 8:
if (ttt[2][1] == '8') {
ttt[2][1] = mark;
}
break;
case 9:
if (ttt[2][2] == '9') {
ttt[2][2] = mark;
}
break;
default:
printf("Invalid input. Please choose and type a number 1-9 corresponding to a position that is not already taken.\n");
printf("Press any key to continue.\n");
player--;
getch();
}
i = CheckForWin();
if (i != 1 && i != 2)
player++;
} while (i == 0);
PrintTheBoard();
if (i == 1)
printf("Player %d wins!", player);
else
printf("The game is a draw!");
}
My issue is that the error message is not printed when the two players choose the same spot. The program then goes to the next players turn, effectively skipping the player who chose an occupied spot. The player who occupied the spot in question keeps the spot.
Furthermore, I don't really understand how to use i and j integers to fill out the indexes. When I try code blocks previously used for this, tons of errors show up.
Thanks for any help.
Try adding an extra boolean variable and moving the error message outside of the switch:
int okay = 0;
switch (choice) {
case 1:
if (ttt[0][0] == '1') {
ttt[0][0] = mark;
okay = 1;
}
break;
case 2:
if (ttt[0][1] == '2') {
ttt[0][1] = mark;
okay = 1;
}
break;
case 3:
if (ttt[0][2] == '3') {
ttt[0][2] = mark;
okay = 1;
}
break;
case 4:
if (ttt[1][0] == '4') {
ttt[1][0] = mark;
okay = 1;
}
break;
case 5:
if (ttt[1][1] == '5') {
ttt[1][1] = mark;
okay = 1;
}
break;
case 6:
if (ttt[1][2] == '6') {
ttt[1][2] = mark;
okay = 1;
}
break;
case 7:
if (ttt[2][0] == '7') {
ttt[2][0] = mark;
okay = 1;
}
break;
case 8:
if (ttt[2][1] == '8') {
ttt[2][1] = mark;
okay = 1;
}
break;
case 9:
if (ttt[2][2] == '9') {
ttt[2][2] = mark;
okay = 1;
}
break;
}
if (! okay) {
printf("Invalid input. Please choose and type a number 1-9 corresponding to a position that is not already taken.\n");
printf("Press any key to continue.\n");
player--;
getch();
}
With a bit of trickery, we can make this a bit more compact:
int savemark = mark;
switch (choice) {
case 1:
if (ttt[0][0] == '1') {
ttt[0][0] = mark++;
}
break;
case 2:
if (ttt[0][1] == '2') {
ttt[0][1] = mark++;
}
break;
case 3:
if (ttt[0][2] == '3') {
ttt[0][2] = mark++;
}
break;
case 4:
if (ttt[1][0] == '4') {
ttt[1][0] = mark++;
}
break;
case 5:
if (ttt[1][1] == '5') {
ttt[1][1] = mark++;
}
break;
case 6:
if (ttt[1][2] == '6') {
ttt[1][2] = mark++;
}
break;
case 7:
if (ttt[2][0] == '7') {
ttt[2][0] = mark++;
}
break;
case 8:
if (ttt[2][1] == '8') {
ttt[2][1] = mark++;
}
break;
case 9:
if (ttt[2][2] == '9') {
ttt[2][2] = mark++;
}
break;
}
if (mark == savemark) {
printf("Invalid input. Please choose and type a number 1-9 corresponding to a position that is not already taken.\n");
printf("Press any key to continue.\n");
player--;
getch();
}
You mentioned that you must use a switch but expressed the desire to see the more compact solution. So, here's a way:
int okay = 0;
do {
if (choice < 1)
break;
if (choice > 9)
break;
choice -= 1;
if (ttt[choice / 3][choice % 3] == ('1' + choice)) {
ttt[choice / 3][choice % 3] = mark;
okay = 1;
}
} while (0);
if (! okay) {
printf("Invalid input. Please choose and type a number 1-9 corresponding to a position that is not already taken.\n");
printf("Press any key to continue.\n");
player--;
getch();
}

Why does my C program print out the same output no matter what I put for the input?

I'm new to C and I've been working on this homework problem for about 2 hours to no avail. I'm attempting to create a program that takes an alphabetic phone number (ie; CALLATT or 1-800-COL-LECT) and turns it into the number form (2255288 or 1-800-265-5328). No matter what I put for input, though, I always get -4197680 for my output.
int main(void){
int c=0, len, a[len];
char n[len];
printf("Enter phone number: \n");
scanf("%c", n);
len = sizeof(n) / sizeof(n[0]);
while (len > c){
if (n[c] == 'A' || n[c] == 'B' || n[c] == 'C'){
a[c] = 2;
c++;
}
else if (n[c] == 'D' || n[c] == 'E' || n[c] == 'F'){
a[c] = 3;
c++;
}
else if (n[c] == 'G' || n[c] == 'H' || n[c] == 'I'){
a[c] = 4;
c++;
}
else if (n[c] == 'J' || n[c] == 'L' || n[c] == 'L'){
a[c] = 5;
c++;
}
else if (n[c] == 'M' || n[c] == 'N' || n[c] == 'O'){
a[c] = 6;
c++;
}
else if (n[c] == 'P' || n[c] == 'Q' || n[c] == 'R' || n[c] == 'S'){
a[c] = 7;
c++;
}
else if (n[c] == 'T' || n[c] == 'U' || n[c] == 'V'){
a[c] = 8;
c++;
}
else if (n[c] == 'W' || n[c] == 'X' || n[c] == 'Y' || n[c] == 'Z'){
a[c] = 9;
c++;
}
else {
a[c] = n[c];
c++;
}
}
printf("%d\n", a);
return 0;
}
EDIT: Revised. There were many comments pointing out problems, here is my answer which works with a reasonable length phone number. It skips any non-dialing characters, such as '-' which is not part of a phone number.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void){
int k, d, e, len;
char dial[20], entry[20] = {0};
printf("Enter phone number: ");
fgets(entry, 19, stdin);
len = strlen(entry);
d = 0; // dial string index of output
for (e=0; e<len; e++) { // entry string index of input
k = entry[e];
switch (toupper(k)) {
case 'A': case 'B': case 'C': dial[d++] = '2'; break;
case 'D': case 'E': case 'F': dial[d++] = '3'; break;
case 'G': case 'H': case 'I': dial[d++] = '4'; break;
case 'J': case 'K': case 'L': dial[d++] = '5'; break;
case 'M': case 'N': case 'O': dial[d++] = '6'; break;
case 'P': case 'Q': case 'R': case 'S': dial[d++] = '7'; break;
case 'T': case 'U': case 'V': dial[d++] = '8'; break;
case 'W': case 'X': case 'Y': case 'Z': dial[d++] = '9'; break;
default:
if (isdigit(k) || k=='*' || k=='#') dial[d++] = k;
}
}
dial[d] = 0; // terminate string
printf("Dial %s\n", dial);
return 0;
}
Here is some code:
char buf[32];
sscanf("%31s", buf);
size_t i;
for (i = 0; i < sizeof(buf) && buf[i]; ++i)
{
switch (buf[i])
{
case 'A': case 'B': case 'C':
buf[i] = '2'; break; // Note: character literal, not integer
case 'D': case 'E': case 'F':
buf[i] = '3'; break;
....
}
}
printf("%s", buf);
If you have a Posix-compliant library, you can use dynamic allocation:
char *buf;
scanf("%ms", &buf); //scanf would allocate memory
for (i = 0; buf[i]; ++i)
{
.....
}
printf("%s", buf);
free(buf);
There are so many problems in your code, it will almost need a re-write to make it work. I think you should start something small. Make sure it works before adding more functionality. I would suggest dividing the code in main into three sections -- reading the phone number, converting phone number and printing the converted phone number.
Here's a skeletal program that captures those three steps.
#define SIZE 50
void readPhoneNumber(char phoneNumber[])
{
}
void convertTextToNumber(char phoneNumber[], char dialedNumber[])
{
}
void printPhoneNumber(char phoneNumber[])
{
}
int main(void)
{
char phoneNumber[SIZE];
char dialedNumber[SIZE];
readPhoneNumber(phoneNumber);
convertTextToNumber(phoneNumber, dialedNumber);
printPhoneNumber(dialedNumber);
}
Now, you can start fleshing out the functions. For example, readPhoneNumber can be implemented as:
void readPhoneNumber(char phoneNumber[])
{
printf("Enter phone number: \n");
fgets(phoneNumber, SIZE, stdin);
}
printPhoneNumber can be implemented as:
void printPhoneNumber(char phoneNumber[])
{
printf("%s\n", phoneNumber);
}
I'll leave you to work out the implementation of convertTextToNumber.
Here you have undefined behavior, len is not initialized.
int c=0, len, a[len];
char n[len];
Use instead a constant value instead, i bet the phone number in your country has some kind of maximum length.
This way to read from the keyboard is not recommended, scanf does not check for length of string so you can do a faceroll on the keyboard and your program will crash. Instead use fgets( ) to read from stdin then go through the string char by char skipping the included \n
printf("Enter phone number: \n");
scanf("%c", n);
This makes no sense, you calculate the sizeof n i.e. of the integer that holds n. If you want the length of the string use strlen( n ); btw try to use more descriptive variable names.
len = sizeof(n) / sizeof(n[0]);
Instead of
while (len > c){
why not use a normal for-loop ? you seem to increment c++ everywhere.
this here will not do what you expect it to do
printf("%d\n", a);
but you assign 'a' integers e.g.
a[c] = 2;
printf can not magically print a number of your array, instead you want to print out is a string with the numbers. the ascii value of a digit is 48 + digit. e.g. '0' is 48, by knowing this have a character buffer and add the ascii values to it. make sure it ends with \0 which is end of string. then print out the string
buf[c++] = 48 + digit;
...
buf[c] = '\0';
puts( buf );

Code loops when character entered in C

This is mostly out of curiosity to why this is happening as it doesn't matter in my case. If I type in an invalid number it properly goes to the repeat label and asks me to enter a number again, but if i enter in a character like 'f' it will loop endlessly and not stop. Why is this?
The array and all variables here are of type int.
repeat:
printf("Enter number of available space, you are %c: ", userXO);
scanf("%d", user);
switch (*user)
{
case 1: if (spaces[0][0] == 49){ spaces[0][0] = userXO;}else goto repeat; break;
case 2: if (spaces[0][1] == 50){ spaces[0][1] = userXO;}else goto repeat; break;
case 3: if (spaces[0][2] == 51){ spaces[0][2] = userXO;}else goto repeat; break;
case 4: if (spaces[1][0] == 52){ spaces[1][0] = userXO;}else goto repeat; break;
case 5: if (spaces[1][1] == 53){ spaces[1][1] = userXO;}else goto repeat; break;
case 6: if (spaces[1][2] == 54){ spaces[1][2] = userXO;}else goto repeat; break;
case 7: if (spaces[2][0] == 55){ spaces[2][0] = userXO;}else goto repeat; break;
case 8: if (spaces[2][1] == 56){ spaces[2][1] = userXO;}else goto repeat; break;
case 9: if (spaces[2][2] == 57){ spaces[2][2] = userXO;}else goto repeat; break;
default: goto repeat; break;
}
scanf("%d", user); tries to read a number, finds a char(f), leaves it in the buffer and ends. The loop then loops around and executes scanf("%d", user); again. And again...
Here is how I would have written what you did:
int rc, user;
char buf[100];
for (;;) // repeat until explicitly broken out of
{
printf ("Enter number of available space; you are %c: ", userXO);
if (!fgets (buf, sizeof buf, stdin)) /* end of file or i/o error? */
break;
rc = sscanf(buf, "%d", &user);
if (rc != 1) /* other than one parsed input item is an error */
{
printf ("invalid number; try again\n");
continue;
}
/*
* this switch has the odd property of potentially
* doing all 9 cases for case 1, 8 cases for case 2, etc.
* Maybe explicit breaks for success are needed?
*/
switch (user)
{
case 1: if (spaces[0][0] == 49) spaces[0][0] = userX0; else continue;
case 2: if (spaces[0][1] == 50) spaces[0][1] = userX0; else continue;
case 3: if (spaces[0][2] == 51) spaces[0][2] = userX0; else continue;
case 4: if (spaces[1][0] == 52) spaces[1][0] = userX0; else continue;
case 5: if (spaces[1][1] == 53) spaces[1][1] = userX0; else continue;
case 6: if (spaces[1][2] == 54) spaces[1][2] = userX0; else continue;
case 7: if (spaces[2][0] == 55) spaces[2][0] = userX0; else continue;
case 8: if (spaces[2][1] == 56) spaces[2][1] = userX0; else continue;
case 9: if (spaces[2][2] == 57) spaces[2][2] = userX0; else continue;
default: continue;
}
break; /* if valid case(s) taken, exits loop */
}
As you can see, there is no need for a label or a goto. Also the code is more compact.

Resources