I have seen questions related to Craps, but they were related to python and Java. I hope someone familiar with C# can help me. The code below is meant to simulate the game of craps. The code mostly works, except for one issue.
I suppose I should briefly explain the game. Two 6 sided dice are rolled. If the result is a 7 or 11. The player or "shooter" wins automatically. If a 2, 3, or 12 is rolled, the shooter loses automatically. However, if another number is rolled, that number becomes the "point". The shooter rolls again until either they roll the point again or a 7. If the point is rerolled the shooter wins. If a 7 is rolled, this time it is a loss.
So, the problem is that this code still gives wins or losses automatically for 2, 3, 11, and 12 after the first roll. For example: The shooter rolls a 6. 6 becomes the point and the shooter rolls again. If the shooter rolls a 3 this code marks this result as a loss when it should just keep rolling until a 6 or 7 is rolled. This incorrect end happens whenever a 2, 3, 11, or 12 is rolled after the first roll. Any help on correcting the logic of this code would be greatly appreciated. Thanks Also, I hope this question is formatted correctly. Please let me know if it is not.
class Craps
{
const int dieSides = 6;
int roll;
//const int repeatGame = 1000;
Random random = new Random();
public void RollDice()
{
int die1 = 0;
int die2 = 0;
die1 = random.Next(1, 7);
die2 = random.Next(1, 7);
roll = die1 + die2;
//Console.WriteLine("The shooter roled: {0}", roll);
}
public void PlayCraps()
{
RollDice();
Console.WriteLine("The shooter roled: {0}", roll);
int gameStatus = 0;
int point = roll;
int numRolls = 1;
if (roll != 7 || roll != 11 || roll != 2 || roll != 3 || roll != 12)
{
Console.WriteLine("The point is: {0}", point);
}
while (gameStatus < 1)
{
if (roll == 7 || roll == 11)
{
Console.WriteLine("You won!");
gameStatus++;
break;
}
else if (roll == 2 || roll == 3 || roll == 12)
{
Console.WriteLine("You lost.");
gameStatus++;
break;
}
else
{
while (point != roll || roll != 7)
{
RollDice();
if (roll == point)
{
Console.WriteLine("The shooter roled: {0}", roll);
Console.WriteLine("You won!");
numRolls++;
gameStatus++;
break;
}
if (roll == 7)
{
Console.WriteLine("The shooter roled: {0}", roll);
Console.WriteLine("You lost");
numRolls++;
gameStatus++;
break;
}
else
{
numRolls++;
Console.WriteLine("The shooter roled: {0}", roll);
break;
}
}
}
}
Console.WriteLine("This game was {0} roll(s)", numRolls);
}
static void Main(string[] args)
{
Craps NewGame = new Craps();
NewGame.PlayCraps();
Console.ReadLine();
}
}
User pm100 commented saying that the final break returned the code back to the outer loop and that this was causing the error. Removing this fixed the issue described in my question. There may be other errors or ways to improve this code, but that comment solved the particular focus of this question.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
ok so im pretty new to programming and am trying to make a game where i roll random ints for the dice inside of a loop and i want to be able to subtract the results of the dice roll from a value for the enemy's Hp and have that value carry over throughout the loop until the hp value equals zero then break the loop and end the game. I have tried declaring an int for the value, but i cant figure out how to save the damage dealt from the previous dice roll loop. Can anyone point me in the right direction to do this?
Edit:
forgot to add the code whoops.
This is my crappy code
class Program
{
static void Main(string[] args)
{
Program.hit();
}
static void hit()
{
bool enemyAlive = true;
while (enemyAlive)
{
Random rnd = new Random();
int roll20 = rnd.Next(1, 21);
int roll6 = rnd.Next(1, 7);
int rollCrt = rnd.Next(1, 7);
int critDmg = roll6 + rollCrt + 4;
if (roll20 == 20)
{
WriteLine($"\nyou rolled. { roll20} CRIT!!");
WriteLine($"you deal. {roll6} + {rollCrt} + 4 = {critDmg} damage.");
//currentEhp = enemyHp - critDmg;
// WriteLine(currentEhp);
}
else if (roll20 <= 14)
{
WriteLine($"\nyou rolled. {roll20} you miss");
}
else if (roll20 >= 15)
{
WriteLine($"\nyou rolled. {roll20} you hit");
WriteLine($"you deal. {roll6} damage");
//currentEhp = enemyHp - roll6;
// WriteLine(currentEhp);
}
ReadLine();
}
}
}
Declare the int variable outside of the loop and subtract from within the loop.
For example:
int hp = 100;
// I'm guessing this is the dice roll loop
for (int i = 0; i < NumOfTimes; i++)
{
if (hp <= 0)
break;
DiceRoll();
hp -= ValueOfDiceRoll;
}
I am trying to make a program for a game of pig where there user enters a point total to play for and then takes turns with a computer player until one player reaches the point total. For the human turn the player rolls and if they roll 2-6 then they can use r to roll again or h to hold. when hold is selected it adds up the total points and goes to the next turn. If 1 is rolled then they get 0 points for the round and it goes to the computers turn. For some reason when I select h to hold it just keeps going and when it does end the points don't get added up. Not sure how to fix this
any help would be appericated
static int pigRoll()
{
Random random = new Random();
int die1 = 0;
die1 = random.Next(1, 6);
Console.WriteLine($"You rolled {die1}");
return die1;
}
static double humanTurn()
{
double pointTotal = 0;
string gameSelect = null;
var pigDiceRoll = 0;
Console.WriteLine("It's your turn");
do
{
pigDiceRoll = pigRoll();
if (pigDiceRoll != 1)
{
Console.WriteLine("r to roll or h to hold (r/h)");
gameSelect = Console.ReadLine();
pointTotal = pointTotal + pigDiceRoll;
}
else if(pigDiceRoll ==1)
{
pointTotal = 0;
}
} while (gameSelect != "r" || pigDiceRoll != 1);
Console.WriteLine($"Your turn point total is {pointTotal}");
return pointTotal;
}
The while statement should read:
while (gameSelect == "r" && pigDiceRoll != 1)
This translates to keep looping while the user wants to roll again and they didn't roll a 1.
Alternatively you could use:
while (!(gameSelect != "r" || pigDiceRoll == 1))
Both are logically the same, but the first is probably easier to read.
I have to alter this in order for more than one player to be available. Do I change something in the Player class? Or do I create a new class for all Players? I am on the right track? Here is the code so far:
namespace Blackjack
{
class Program
{
static Player[] players = new Player[5];
static int pointer = 0;
class PlayingCard
{
public string Suit;
public int Value;
public int Points;
// Alternate Constructor with 2 parameters - Int for Suit, Int for Value
// We use this in the generateDeck() function
public PlayingCard(int s, int v)
{
Value = v; // Sets the Value of the card to the value of v (The second argument)
switch (s) // Case statement based on the value of s
{
case 1: // If s == 1, then set the Suit to Clubs
Suit = "♣";
break;
case 2: // If s == 2, then set the Suit to Diamonds
Suit = "♦";
break;
case 3: // If s == 3, then set the Suit to Hearts
Suit = "♥";
break;
case 4: // If s == 4, then set the Suit to Spades
Suit = "♠";
break;
}
if (Value > 10)
{
Points = 10;
}
else if (Value == 1) // If it's an ace
{
Points = 11; // Set the points to 11
}
else
{
Points = Value;
}
}
}
class Player
{
public PlayingCard[] hand;
public int cardsInHand;
public int points;
public string name;
public Player()
{
hand = new PlayingCard[5];
cardsInHand = 0;
points = 0;
}
}
static void Main(string[] args)
{
onePlayer();
Console.ReadLine();
}
// Generates the deck of 52 cards
static PlayingCard[] generateDeck()
{
PlayingCard[] deck = new PlayingCard[52]; // Declares an array of PlayingCards with a size of 52
int counter = 0; // Tells us where to save the next value into the array
// Nested for loop to generate all 52 cards - 4 possible suits with 13 possible values each
for (int suit = 1; suit < 5; suit++) // Loop through the 4 possible suits
{
for (int value = 1; value < 14; value++) // Loop through the 13 possible values
{
deck[counter] = new PlayingCard(suit, value); // Generate new card and store it in the deck
counter++; // Increment the counter
}
}
return deck; // Returns the completed deck
}
// Procedure to shuffle the deck of cards
static void shuffleDeck(ref PlayingCard[] deck)
{
Random rnd = new Random(); // Creates new Random object
PlayingCard temp; // Creates a variable for temporarily storing a PlayingCard
int num; // Creates an integer variable for storing the randomly generated numbers
for (int i = 0; i < deck.Length; i++) // Loop through each index in the array
{
num = rnd.Next(0, deck.Length); // Generate random num between 0 & 51
// Swap the contents of deck[i] and deck[num]
temp = deck[i];
deck[i] = deck[num];
deck[num] = temp;
}
// As deck is passed by reference, we do not need to return it to the main program
// The changes will have automatically been applied to the deck in the main program
}
static void outputCard(PlayingCard card)
{
switch (card.Value) // Case statement based on the value of card
{
// Case for 1 - "The Ace of ..."
case 1:
Console.WriteLine("The Ace of {0}", card.Suit);
break;
// Case for 11 - "The Jack of ..."
case 11:
Console.WriteLine("The Jack of {0}", card.Suit);
break;
// Case for 12 - "The Queen of ..."
case 12:
Console.WriteLine("The Queen of {0}", card.Suit);
break;
// Case for 13 - "The King of ..."
case 13:
Console.WriteLine("The King of {0}", card.Suit);
break;
// Case for everything else
default:
Console.WriteLine("The {0} of {1}", card.Value, card.Suit);
break;
}
}
// Output the details of a card using symbols - eg/ A♠
// Used to output the player's hand on the same line (See outputHand procedure below)
static void outputCardSymbol(PlayingCard card)
{
switch (card.Value) // Case statement based on the value of card
{
// Case for 1 - "The Ace of ..."
case 1:
Console.Write("A{0} ", card.Suit);
break;
// Case for 11 - "The Jack of ..."
case 11:
Console.Write("J{0} ", card.Suit);
break;
// Case for 12 - "The Queen of ..."
case 12:
Console.Write("Q{0} ", card.Suit);
break;
// Case for 13 - "The King of ..."
case 13:
Console.Write("K{0} ", card.Suit);
break;
// Case for everything else
default:
Console.Write("{0}{1} ", card.Value, card.Suit);
break;
}
}
// Outputs all of the cards in a player's hand along with their point total
static void outputHand(Player player)
{
// Print "Current Hand: "
Console.Write("Current Hand: ");
// Loop through all cards in hand
for (int i = 0; i < player.cardsInHand; i++)
{
outputCardSymbol(player.hand[i]);
}
Console.WriteLine("Current points: {0}.", player.points);
}
static void drawCard(PlayingCard[] deck, ref Player player)
{
PlayingCard nextCard = deck[pointer];
// Add the next card in the deck to the player's hand
if (player.cardsInHand < 5)
{
player.hand[player.cardsInHand] = nextCard;
// Increment the number of cards in the player's hand
player.cardsInHand++;
// Add the point value of the new card to the player's total
player.points += nextCard.Points;
// Output the details of the card
//outputCard(nextCard);
// Increment the pointer
pointer++;
}
}
// Check if the player has exceeded 21 points
// Output the player's point total
static bool checkPoints(Player player)
{
// Output the player's point total
//Console.WriteLine("Current Points: {0}", player.points);
// Check if the player is bust
if (player.points > 21)
{
Console.WriteLine("Bust!");
return false;
}
// Return true if the player is still alive
return true;
}
// Compare the player & the dealer
static void calculateWinner(Player player, Player dealer)
{
// Player wins if...
if (dealer.points > 21 || player.cardsInHand == 5 && dealer.cardsInHand != 5)
{
Console.WriteLine("{0} Wins!", player.name);
}
// The game ends in a draw if...
else if (dealer.points == player.points)
{
Console.WriteLine("Draw!");
}
// Otherwise, the dealer has won
else if (dealer.points == 21 && player.points != 21 || player.cardsInHand < 5)
{
Console.WriteLine("{0} wins", dealer.points);
}
else if (player.cardsInHand == 5 && dealer.cardsInHand == 5)
{
if (player.points > dealer.points)
{
Console.WriteLine("{0} wins! 5 card trick: higher than dealers. ", player.name);
}
else if (player.points == dealer.points)
{
Console.WriteLine("It's a draw! 5 card trick: same! ");
}
Console.WriteLine("{0} wins! 5 card trick: less than dealers. ", dealer.name);
}
}
// Checks if the player has any aces with a point value of 11 (high)
// If the player is about to go bust, change the ace to a point value of 1 (low)
// Then update the player's score
static void checkAces(ref Player player)
{
bool changed = false; // Flags up if we've changed an ace already
if (player.points > 21)
{
for (int i = 0; i < player.cardsInHand; i++)
{
if (player.hand[i].Points == 11 && changed == false) // If it's a high ace
{
player.hand[i].Points = 1; // Change it to a low ace
player.points -= 10; // Take 10 away from player's points
changed = true;
}
}
}
}
static void onePlayer()
{
string playAgain = "Undefined";
do
{
// Generate the deck of cards & shuffle it
PlayingCard[] deck = generateDeck();
shuffleDeck(ref deck);
// Create the two player objects
Player player = new Player();
Console.Write("Please enter your name: ");
player.name = Console.ReadLine();
Player dealer = new Player();
Console.Write("Please enter a name for the dealer: ");
dealer.name = Console.ReadLine();
// Draw the first two cards for the Player
drawCard(deck, ref player);
drawCard(deck, ref player);
checkAces(ref player); // Call checkAces to see if we can stop player going bust
outputHand(player);
checkPoints(player); // Output the player's point total
bool alive = true;
string choice = "Undefined";
while (alive == true && choice != "STICK")
{
Console.Write("Hit or Stick? ");
choice = Console.ReadLine().ToUpper();
if (choice == "HIT") // If the user asks to hit then...
{
drawCard(deck, ref player);
// If player still has a valid point total, alive will remain true
// If the player is now bust, alive will become false and the loop will exit
checkAces(ref player); // Call checkAces to see if we can stop player going bust
outputHand(player);
alive = checkPoints(player);
}
}
// If the player isn't bust, it's time for the dealer's turn
if (alive == true)
{
bool dealerAlive = true;
Console.WriteLine();
Console.WriteLine("*** Dealer's Turn ***");
drawCard(deck, ref dealer);
drawCard(deck, ref dealer);
checkAces(ref dealer); // Call checkAces to see if we can stop dealer going bust
outputHand(dealer);
checkPoints(dealer);
while (dealerAlive == true)
{
Console.WriteLine("Press Enter to Continue");
Console.ReadLine();
// Draw the dealer's next card and check if they are still alive
drawCard(deck, ref dealer);
checkAces(ref dealer); // Call checkAces to see if we can stop dealer going bust
outputHand(dealer);
dealerAlive = checkPoints(dealer);
}
}
// Calculate & output the winner
calculateWinner(player, dealer);
Console.Write("Do you want to play again? Y/N ");
playAgain = Console.ReadLine().ToUpper();
} while (playAgain == "Y");
}
}
}
Add each player to a List<Player> as this will keep each Player object to allow more than just two players as you can include the Dealer as a Player.
Also try to seperate your class rather than having multiple internal classes. It makes an easier read and makes navigation easier.
Player.cs
namespace Blackjack
{
public class Player
{
public PlayingCard[] hand;
public int cardsInHand;
public int points;
public string name;
public Player()
{
hand = new PlayingCard[5];
cardsInHand = 0;
points = 0;
}
}
}
Your game also has one slight problem, the dealer sticks from 17
How do I repeat this code/game if the player gets the answer wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Random RandomGenerator = new Random();// random number generator
Console.WriteLine("i have thought of a number between 1 and 100");//display message
//
//
int IN_RandomNum = RandomGenerator.Next(1, 100); //the range
//loop 10 times
for (int i = 0; i < 10; i++) //for loop created
{
int IN_Guess; //guessing integer
Console.Write("{0} turns left, enter your next guess>", 10 - i);//number of turns players has
//
IN_Guess = Convert.ToInt32(Console.ReadLine()); //string to number
//Now check if guess is same as generated
if (IN_Guess == IN_RandomNum)//if guess is equal to generated number
{
Console.WriteLine("correct in {0} turns", i + 1); //if guessed correctly
break; //breaking code
}
else if (IN_Guess > IN_RandomNum) //if guess is higher than generated number
{
Console.WriteLine("Too high");// if guessed number is too high
}
else //then...
{
Console.WriteLine("Too low"); // if guessed number is too low
} if (i==8) //on last turn display this message
{
Console.WriteLine("*YOU ONLY HAVE 1 GUESS LEFT!*"); //display this message
}
}
Console.WriteLine("please press enter to quit"); //display message
Console.ReadLine();//keeps application open until enter button hit
}
}
}
Please help because i really cant figure out where to put the while loop...ive ran out of ideas
You would need to wrap everything in a while loop.
When it exits the for loop you have, it doesn't matter if they win or lose you go back to the top and start again, generating a new random number.
Before reading the code below, see my suggestion above and attempt it yourself, see if you can crack it
Something like this:
static void Main(string[] args)
{
Random RandomGenerator = new Random();// random number generator
while (true)
{
Console.WriteLine("i have thought of a number between 1 and 100");//display message
bool guessedCorrect = false;
int IN_RandomNum = RandomGenerator.Next(1, 100); //the range
//loop 10 times
for (int i = 0; i < 10; i++) //for loop created
{
int IN_Guess; //guessing integer
Console.Write("{0} turns left, enter your next guess>", 10 - i);//number of turns players has
//
IN_Guess = Convert.ToInt32(Console.ReadLine()); //string to number
//Now check if guess is same as generated
if (IN_Guess == IN_RandomNum)//if guess is equal to generated number
{
Console.WriteLine("correct in {0} turns", i + 1); //if guessed correctly
guessedCorrect = true;
break; //breaking code
}
else if (IN_Guess > IN_RandomNum) //if guess is higher than generated number
{
Console.WriteLine("Too high");// if guessed number is too high
}
else //then...
{
Console.WriteLine("Too low"); // if guessed number is too low
}
if (i == 8) //on last turn display this message
{
Console.WriteLine("*YOU ONLY HAVE 1 GUESS LEFT!*"); //display this message
}
}
if (guessedCorrect)
{
Console.WriteLine("Good job... Lets try again");
}
else
{
Console.WriteLine("Better luck next timer... here we go");
}
}
}
P.S. I lost every time i tried, your game is too hard :-(
I am trying to assigned a Enemy enemy class instance to a random newenemy instance.
For example:
public Enemy GetEnemy()
{
Random rand = new Random();
Enemy newenemy = new Enemy(string.Empty, 0, 0, 0, 0, 0);
if (Main.level == 1)
{
int z = rand.Next(0, 2);
if (z == 0)
{
newenemy = new Enemy("Chicken", 50, 0, 4, 11, 32);
}
else if (z == 1)
{
newenemy = new Enemy("Common Goblin", 67, 0, 8, 14, 36);
}
else if (z == 2)
{
newenemy = new Enemy("Rabbit", 50, 0, 15, 25, 9);
}
}
return newenemy;
}
Which is then used in my Battle function: (I'll post some cause it is somewhat long)
if (whathappen == 2 || whathappen == 4 || whathappen == 6 || whathappen == 8 || whathappen == 10) //battle code
{
Console.Write("You were engaged by the enemy! \nYou are fighting an enemy {0}\n", GetEnemy().name);
while (Main.health > 0 || GetEnemy().health > 0)
{
Console.Write("1) Attack With Weapon ");
int choose;
int.TryParse(Console.ReadLine(), out choose);
if (choose == 1)
{
int miss = r.Next(0, 6);
if (miss < 6)
{
int totaldamage = (r.Next(0, Main.RHand.damage) + r.Next(0, Main.LHand.damage)) - GetEnemy().armor;
GetEnemy().health -= totaldamage;
Console.WriteLine("You attack the {0} with a {1} and deal {2} damage!", GetEnemy().name, Main.RHand.name, totaldamage);
Console.WriteLine("The {0} has {1} health remaning!", GetEnemy().name, GetEnemy().health);
However, when I am testing my game, no enemy is assigned during the battle and I don't understand why. This is the output:
You were engaged by the enemy!
You are fighting an enemy! (The enemy name should come after enemy)
You attack the (name should be here again) with a Bronze Dagger and deal 15 damage!
Can anyone explain why this is happeneing?
There's a few problems with your code:
Based on your description of your problem, my guess is that Main.level is not equal to 1
You're not quite using Random.Next correctly: Random.Next(0, 2) will never equal 2
But even after you fix those problems, you have a bigger issue that you're creating way too many instances of your Enemy and you aren't saving them anywhere.
Every time you call your GetEnemy() method you're making a brand new instance of your class, accessing one property on it, then it's getting discarded. You are attempting to maintain the state of your enemy, you will need to save the instance you create and reuse it, e.g.:
Enemy enemy = GetEnemy();
while (Main.health > 0 || enemy.health > 0)
{
.
.
.
}