首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >纸牌大战

纸牌大战
EN

Code Review用户
提问于 2018-09-19 05:58:48
回答 2查看 4.7K关注 0票数 6

我是一个初学者程序员,寻找我的简单战争卡游戏程序,我所做的评论。每个玩家得到一副牌,你一次抽一张牌,然后比较2。最高值获胜。这样做,直到比赛结束,谁得到最多的分数,谁就赢。如有任何建议,敬请谅解!谢谢你花时间看这个!

代码语言:javascript
复制
enum Suit
{
    Hearts,
    Diamonds,
    Spades,
    Clovers
}

enum Face
{
    Two,
    Three,
    Four,    
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace
}

// MAKING WAR CARD GAME

class Program
{
    public static bool isPlaying = true;
    public static Player human = new Player();
    public static Player cpu = new Player();
    public static int round = 1;
    static void Main(string[] args)
    {
        GameFlow.Start(human, cpu);
        while (isPlaying)
        {
            for (int i = 0; i < 52; i++)
            {
                GameFlow.Gameplay(human, cpu, round);
                round++;
            }

            round = 1;
            GameFlow.Ending(human, cpu);
        }
    }
}
class Player
{
    public string name = "CPU";
    public Card currentCard = new Card(); // the current card in play
    public int wins = 0 , drawCount = 0;
    public Deck myDeck = new Deck();

    public void DrawOne()
    {
        currentCard = myDeck.CurrentlyInDeck[drawCount];
        drawCount++;
        if (drawCount == 52)
        {
            drawCount = 0;
        }
    }

    public void SetName()
    {
        while (name == "CPU" || name == "")
        {
            Console.WriteLine("What is your name human?");
            name = Console.ReadLine();
            if(name == "CPU" || name == "")
            {
                Console.WriteLine("Invalid name!! Try a real name you assclown!");
                Console.ReadLine();
            }
            Console.Clear();
        }
    }
class Card
{
    public Suit suit;
    public Face face;

    public void PrintCard()
    {
        Console.Write("{0} of {1}", face, suit);
    }
}
class Deck
{
    public List<Card> CurrentlyInDeck;

    public void GenerateDeck() // Must use this to populate deck
    {
        CurrentlyInDeck = new List<Card>(52);
        int place = 0; // tracks which card number
        for (int i = 0; i < 4; i++)
        {
            for (int f = 0; f < 13; f++)
            {
                Card card = new Card();
                CurrentlyInDeck.Add(card);
                CurrentlyInDeck[place].suit = (Suit)i;
                CurrentlyInDeck[place].face = (Face)f;
                place++;
            }
        }
    }

    private static readonly Random rand = new Random();

    public void Shuffle() 
    {
        Card holder = new Card();
        int random;

        for (int i = 0; i < 52; i++)
        {
            random = rand.Next(0, 51);
            holder = CurrentlyInDeck[i];
            CurrentlyInDeck[i] = CurrentlyInDeck[random];
            CurrentlyInDeck[random] = holder;
        }
    }

    public void PrintDeck() // prints all cards in the deck , used for testing
    {
        foreach (var card in CurrentlyInDeck)
        {
            card.PrintCard();
        }
    }
}
static class Create
{
    public static void Name(Player a)
    {
        a.SetName();
    }

    public static void TheirDecks(Player hum , Player cpu)
    {
        hum.myDeck.GenerateDeck();
        cpu.myDeck.GenerateDeck();

        hum.myDeck.Shuffle();
        cpu.myDeck.Shuffle();
    }
}
static class GameFlow
{
    static public void Start(Player hum, Player cpu) //Creates initial situation 
    {
        Words.Begin();
        Create.TheirDecks(hum, cpu);
        Create.Name(hum);
    }

    static public void ShuffleDecks(Player hum, Player cpu)
    {
        hum.myDeck.Shuffle();
        cpu.myDeck.Shuffle();
    }

    static public void DrawCards(Player hum, Player cpu) // changes the current card
    {
        hum.DrawOne();
        cpu.DrawOne();
    }

    static public void Gameplay(Player hum, Player cpu, int round) // The normal gameplay loop
    {
        GameFlow.DrawCards(hum, cpu);
        Words.Template(hum, cpu, round);
        GameFlow.CheckWin(hum, cpu);
    }

    static public void Ending(Player hum, Player cpu) // Once all the cards have been played
    {
        string answer = "";
        bool correctForm = false;
        Words.LastWords(hum, cpu);
        while (!correctForm)
        {
            Console.WriteLine("Would you like to play again? Enter y for yes or n for no.");
            answer = Console.ReadLine();
            answer = answer.ToLower();

            if(answer != "y" && answer != "n")
            {
                Console.WriteLine("Thats not a valid option you idiot!");
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
                Console.Clear();
                Words.LastWords(hum, cpu);
            }

            if(answer == "y" || answer == "n")
            {
                correctForm = true;
            }
        }

        if (answer == "y")
        {
            PlayingAgain(hum ,cpu);
            Console.Clear();
        }

        if (answer == "n")
        {
            Console.WriteLine("Thanks for playing!");
            Console.WriteLine("Press enter to exit.");
            Environment.Exit(0);
        }
    }

    static public void PlayingAgain(Player hum , Player cpu)
    {
        ShuffleDecks(hum, cpu);
        hum.wins = 0;
        cpu.wins = 0;
    }

    static public void CheckWin(Player hum , Player cpu)
    {
        Console.WriteLine("");
        if ((int)hum.currentCard.face > (int)cpu.currentCard.face)
        {
            hum.wins++;
            Console.WriteLine();
            Console.WriteLine("You win this one! Nice!");
            Console.WriteLine("Press enter to keep going.");
            Console.ReadLine();
            Console.Clear();
        }

        else if ((int)hum.currentCard.face < (int)cpu.currentCard.face)
        {
            cpu.wins++;
            Console.WriteLine();
            Console.WriteLine("Looks like the CPU won this one. You suck!");
            Console.WriteLine("Press enter to keep going.");
            Console.ReadLine();
            Console.Clear();
        }

        else
        {
            Console.WriteLine();
            Console.WriteLine("Its a draw!");
            Console.WriteLine("Press enter to keep going.");
            Console.ReadLine();
            Console.Clear();
        }
    }
}
static class Words // The dialogue of the program
{
    public static void Begin()
    {
        Console.WriteLine("Hello , welcome to war!");
        Console.WriteLine("The rules are simple. Its you vs a cpu");
        Console.WriteLine("You each pull 1 card from your decks and see which is highest.");
        Console.WriteLine("Your card will be the one under your name , while the other is the CPUs.");
        Console.WriteLine("The one with the most points at the end wins all the glory!");
        Console.WriteLine("Understand?");
        Console.WriteLine("Press enter if you're ready for the showdown.");
        Console.ReadLine();
        Console.Clear();
    }

    public static void Template(Player hum , Player cpu , int round) //Prints the normal screen
    {
        int distance = 17; //distance between the 2 names
        Console.Write("{0} wins = {1}", hum.name, hum.wins);
        Console.Write("          R{0}", round);
        distance -= hum.name.Length;
        while (distance > 0)
        {
            Console.Write(" ");
            distance--;
        }
        Console.Write("{0} wins = {1}" , cpu.name , cpu.wins);
        Console.WriteLine();
        Console.WriteLine();
        hum.currentCard.PrintCard();
        Console.Write("     vs     ");
        cpu.currentCard.PrintCard();
    }

    public static void LastWords(Player hum , Player cpu)
    {
        Console.WriteLine("Thats all the cards!");
        Console.WriteLine("So this is the final score: {0} = {1} and {2} = {3}" , hum.name, hum.wins, cpu.name, cpu.wins);

        if(hum.wins > cpu.wins)
        {
            Console.WriteLine("You have beaten the CPU in this game of luck!!!! Congrats!!!");
        }

        else if(cpu.wins > hum.wins)
        {
            Console.WriteLine("The CPU has detroyed you and everything you have loved. Congrats!!!");
        }

        else
        {
            Console.WriteLine("Oh my! Its a draw. You both are equal warriors of luck.");
        }
    }
}
EN

回答 2

Code Review用户

发布于 2018-09-20 10:07:04

另一个答案已经提到了费舍-耶茨洗牌,这绝对是您想要使用的。我想我会把你的洗牌分解一下,让你知道它为什么有缺陷。

这是我认为是整个互联网上最好的网页之一,它有一个关于洗牌的章节,你可能会觉得有趣:迈克的可视化算法

迈克还创建了这个资源:它会洗牌吗?转到这个页面并将选择更改为“天真的交换(i↦随机)”,这就是您已经实现的。它会告诉你洗牌是相当有偏见的:

如果这还不够糟糕的话,你会意外地增加了一种额外的偏见。我已经将您的算法翻译为JS,并为您运行了它:

你看到右下角那个深紫色的正方形了吗?这表明了对最后一个元素的非常负面的偏见。让我们来看看为什么:

代码语言:javascript
复制
public void Shuffle() 
{
    Card holder = new Card();
    int random;

    for (int i = 0; i < 52; i++)
    {
        random = rand.Next(0, 51); // !!!
        holder = CurrentlyInDeck[i];
        CurrentlyInDeck[i] = CurrentlyInDeck[random];
        CurrentlyInDeck[random] = holder;
    }
}

Random.Next的文档说(强调我的):

大于或等于minValue且小于maxValue的32位有符号整数;也就是说,返回值的范围包括minValue,而不是maxValue。

这意味着您只生成0到50之间的随机数。这意味着您永远不能在原来的位置得到最后一项,因为它只在循环的最后一次迭代中被交换。这对洗牌来说是很糟糕的。

票数 8
EN

Code Review用户

发布于 2018-09-21 17:20:33

让我补充一点其他人似乎没有提到过的东西。您不应该使用公共字段,除非它是常量或只读的,而是应该使用公共属性。例如,考虑一下Card类,但是您对其他类感到内疚。

代码语言:javascript
复制
class Card
{
    public Suit suit;
    public Face face;

    public void PrintCard()
    {
        Console.Write("{0} of {1}", face, suit);
    }
}

我希望看到:

  • 显式访问修饰符
  • 只读属性而不是字段
  • 属性名应该是PascalCased。
  • 方法名PrintCard可以简化为Print,但实际上可以是ToStringName属性。

因此,这将改写为:

代码语言:javascript
复制
public class Card
{
    public Suit Suit { get; }
    public Face Face { get; }

    public Card(Face face, Suit suit)
    {
        Face = face;
        Suit = suit; 
    }

    public string Name => $"{Face}{Suit}";
    public override string ToString() => Name;
}

您不需要根据神奇的数字或甲板大小来填充它们。而是直接设置它们。示例:

代码语言:javascript
复制
public void GenerateDeck()
{
    CurrentlyInDeck = new List<Card>();  // Not concerned with count.
    var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>().ToList();
    var faces = Enum.GetValues(typeof(Face)).Cast<Face>().ToList();
    foreach (var suit in suits)
    {
        foreach (var face in faces)
        {
            CurrentlyInDeck.Add(new Card(face, suit));
        }
    }
}
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/203971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档