更新於 2024/11/01閱讀時間約 13 分鐘

系統開發-撲克牌由小到大排序

    撲克牌已經洗牌且發牌,若要繼續下一回合牌局,我們可以使用new Card[52]整副牌重新建立,記得index要歸零。

    Card[] cards = new Card[52];    //一副牌52張
    int index = 0;

    for (int i = 0; i < suits.Length; i++) //四種花色
    {
    for (int j = 1; j <= 13; j++) //一種花色13張牌1-13
    {
    cards[index] = new Card(suits[i], j); //初始化
    cards[index].Seq = index; //加上撲克牌的順序
    index++;
    }
    }

    但這裡我們使用另一種作法,將已經亂掉的牌重新由小到大排序後,即可重複利用

    Default.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    洗牌前:<br />
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    <br />
    <br />
    洗牌後:<br />
    <asp:Label ID="Label2" runat="server" Text=""></asp:Label>
    <br /><br />
    復原排序到洗牌前:<br />
    <asp:Label ID="Label3" runat="server" Text=""></asp:Label>
    <br /><br />
    可按F5或重新載入更新畫面,每次洗牌後結果都會不一樣
    </div>
    </form>
    </body>
    </html>

    Default.aspx.cs

    public partial class _Default : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {
    string[] suits = { "S", "H", "D", "C" }; //"S黑桃" , "H紅心" , "D方塊" , "C梅花"

    Card[] cards = new Card[52]; //一副牌52張
    int index = 0;

    for (int i = 0; i < suits.Length; i++) //四種花色
    {
    for (int j = 1; j <= 13; j++) //一種花色13張牌1-13
    {
    cards[index] = new Card(suits[i], j); //初始化
    cards[index].Seq = index; //加上撲克牌的順序
    index++;
    }
    }

    //洗牌前
    for (int i = 0; i < cards.Length; i++)
    {
    if (i % 13 == 0) //13張牌排成一行
    {
    Label1.Text += $"<br>{cards[i].ToString()}"; //換行
    }
    else
    {
    //Label1.Text += $",{cards[i].ToString()}"; //Card class預設顯示方式
    Label1.Text += $",{cards[i].Suit}{cards[i].Rank}"; //自訂顯示方式
    }
    }

    //洗牌
    Shuffle(cards);

    //洗牌後
    for (int i = 0; i < cards.Length; i++)
    {
    if (i % 13 == 0) //13張牌排成一行
    {
    Label2.Text += $"<br>{cards[i].ToString()}"; //換行
    }
    else
    {
    //Label1.Text += $",{cards[i].ToString()}"; //Card class預設顯示方式
    Label2.Text += $",{cards[i].ToString()}"; //自訂顯示方式
    }
    }

    //復原順序
    BubbleSort(cards);

    //復原後
    //洗牌後
    for (int i = 0; i < cards.Length; i++)
    {
    if (i % 13 == 0) //13張牌排成一行
    {
    Label3.Text += $"<br>{cards[i].ToString()}"; //換行
    }
    else
    {
    Label3.Text += $",{cards[i].ToString()}"; //自訂顯示方式
    }
    }
    }

    //洗牌
    void Shuffle(Card[] cards)
    {
    Random rand = new Random();

    for(int i=0; i<cards.Length; i++)
    {
    int j = rand.Next(cards.Length); //// 產生一個隨機索引 0-52

    //例如:
    // i=0, j=12,表示第一張牌 (cards[0] 黑桃1) 與第13張牌 (cards[12]黑桃13) 互換
    // 互換後的結果為,第一張牌 (cards[0] 黑桃13,第13張牌 (cards[12]黑桃1)
    // 一直換52次(每一個位置的牌都換一次)
    Swap(cards, i, j);
    }
    }

    //陣列中兩個元素交換,河內塔做法
    void Swap(Card[] cards, int i, int j)
    {
    Card tmp = cards[i];
    cards[i] = cards[j];
    cards[j] = tmp;
    }

    //將撲克牌順序由小到大排序
    void BubbleSort(Card[] cards)
    {
    for (int i = 0; i < cards.Length; i++)
    {
    for (int j = 0; j < cards.Length-1; j++)
    {
    if (cards[j].Seq > cards[j+1].Seq) //反過來就是由大到小排序
    {
    Swap(cards, j, j+1);
    }
    }
    }
    }
    }

    class Card
    {
    public string Suit { get; set; }
    public int Rank { get; set; }
    public int Seq { get; set; } //新增順序,用來排序撲克牌

    // Card建構函數
    public Card(string suit, int rank)
    {
    this.Suit = suit; //花色
    this.Rank = rank; //點數
    }

    // 覆寫ToString()方法來顯示卡片訊息
    public override string ToString()
    {
    string suitName = "";

    switch (Suit)
    {
    case "S":
    suitName = "黑桃";
    break;
    case "H":
    suitName = "紅心";
    break;
    case "D":
    suitName = "方塊";
    break;
    case "C":
    suitName = "梅花";
    break;
    }

    return $"{suitName}{Rank}";
    }
    }

    執行結果:


    此遊戲開發到此階段,基本已經架構完成(包含流程、物件建立與使用),之後只剩下加上遊戲的玩法(邏輯判斷)與操作介面即可以完成。

    也就是說學會前幾篇文章,即可開發類似的遊戲,你可能會想說有這麼簡單嗎? 是的,就是這麼簡單,舉幾個簡單應用的例子

    • 亂數玩家姓名(random)
    • 技能擊中機率
    • 打完怪後掉落物品(亂數獎勵)
    • 單抽SSR英雄(設定比例+洗牌+陣列第一個元素)
    • 十連抽SSR英雄(設定比例+洗牌+陣列前十個元素)
    • 抽禮物刷新
    • 商店物品刷新+排序
    • 關卡怪物刷新+排序

    以上類似的基本應用加上不同的使用者介面與邏輯玩法,即可設計出一款遊戲。


    分享至
    成為作者繼續創作的動力吧!
    © 2024 vocus All rights reserved.