iT邦幫忙

0

C# 兩個Array每個位置比較

小弟製作了一個猜數字的小遊戲(3A1B)
規則:玩家輸入4個不重複數字,
若數字對了且位置對了則A+1,
若數字對了但位置錯了則B+1

遊戲開始自動生成4個數字
依序存入myArray(1個數字存1個位置)

ex 5278 myArray[0]=5 ,myArray[1]=2 ....

玩家輸入四個數字
依序存入UserAyyar
存入方法同myArray

目前是用兩個for迴圈的方式
一個一個去抓出是否錯誤

A = 0;
B = 0;

for (int i = 0; i < 4; i++)
{
    if (myArray[i].ToString() == UserArray[i].ToString())
    {
        A += 1;
    }

    for (int j = 0; j < 4; j++)
    { 
        if(i!=j)
        {
            if (myArray[i].ToString() == UserArray[j].ToString())
            {
                B += 1;
            }
        }
    }
}

想詢問
是否有更有效率的比較方法??

https://drive.google.com/open?id=1hsVVRTsYo6GKNfM01-QZQLd9L4AtjoWr
此連結為小遊戲程式
用VS2013 WindowForm製作
包在.zip內

2 個回答

2
小魚
iT邦大師 1 級 ‧ 2019-10-01 11:39:30
最佳解答

4個數字而已差異不大,
或許也可以考慮用Dictionary ?
只是我覺得殺雞焉用牛刀...

看更多先前的回應...收起先前的回應...

感謝回答
這個方法沒見過
未來可以應用到

小魚 iT邦大師 1 級 ‧ 2019-10-01 15:18:40 檢舉

如果你給我原檔我可以幫你改成這種方式,
試看看有沒有比較快,
不過這種功能應該本來就花不到多少時間吧...

小魚
https://drive.google.com/open?id=1xHuyjLZc1L8hV-UVI5WSuufeUFd_twhP
這是整個方案

對阿很簡易的小遊戲
估計根本察覺不出效率的差別
不過學會了未來應用在大資料上
可能就很有幫助了

小魚 iT邦大師 1 級 ‧ 2019-10-01 15:47:06 檢舉

我把Form1.cs改成這樣

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 猜數字小遊戲
{
    public partial class Form1 : Form
    {
        bool IsWin = false;
        int FailCount = 0;
        int A = 0;
        int B = 0;
        //答案
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();
        //使用者輸入的
        ArrayList UserArray = new ArrayList();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            clearUI();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            clearUI();
        }

        private void clearUI()
        {
            label1.Visible = false;
            label1.Text = "答案是:";
            IsWin = false;
            FailCount = 0;
            A = 0;
            B = 0;
            textBox1.Clear();
            label3.Visible = false;
            myDictionary.Clear();
            UserArray.Clear();
            listBox1.Items.Clear();
            int number = 0;
            System.Random num = new Random();

            //初始化答案物件
            myDictionary.Clear();
            //前面是數字,後面是位置,預設值是0
            for (int i = 0; i < 10; i++)
                myDictionary.Add(i, 0);

            for (int i = 0; i < 4; i++)
            {
                do
                {
                    number = num.Next(0, 10);
                }
                //初始化答案
                while (myDictionary[number] != 0);
                myDictionary[number] = i + 1;
                label1.Text += number.ToString();
            }


        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Ans();
        }


        private void Ans()
        {
            UserArray.Clear();


            if (!IsWin)
            {
                #region 檢核
                if (textBox1.Text.Count() != 4)
                {
                    MessageBox.Show("只可以輸入四個數字,請重新輸入!!");
                    textBox1.Clear();
                    textBox1.Focus();
                    return;
                }
                try
                {
                    var TES = Convert.ToInt32(textBox1.Text);
                }
                catch (Exception e)
                {
                    MessageBox.Show("只可以輸入數字,請重新輸入!!");
                    textBox1.Clear();
                    textBox1.Focus();
                    return;
                }
                for (int i = 0; i < 4; i++)
                {
                    UserArray.Add(textBox1.Text.Substring(i, 1));
                }
                if (UserArray[0] + "" == UserArray[1] + "" || UserArray[0] + "" == UserArray[2] + "" ||
                    UserArray[0] + "" == UserArray[3] + "" || UserArray[1] + "" == UserArray[2] + "" ||
                    UserArray[1] + "" == UserArray[3] + "" || UserArray[2] + "" == UserArray[3] + "")
                {
                    MessageBox.Show("不可以輸入重複數字,請重新輸入!!");
                    textBox1.Clear();
                    textBox1.Focus();
                    return;
                }
                #endregion

                FailCount += 1;

                A = 0;
                B = 0;

                for (int i = 0; i < 4; i++)
                {
                    //該數字的位置
                    int value = myDictionary[Convert.ToInt32(UserArray[i])] - 1;
                    if (value == i)
                        A += 1;
                    else if (value >= 0)
                        B += 1;
                }
                label3.Text = A.ToString() + " A " + B.ToString() + " B ";
                label3.Visible = true;
                listBox1.Items.Add(textBox1.Text + " " + label3.Text);
                listBox1.Focus();
                listBox1.TopIndex = FailCount - 1;
                textBox1.Focus();
                textBox1.Clear();
                if (A == 4)
                {
                    IsWin = true;
                    MessageBox.Show("恭喜你,嘗試了" + FailCount.ToString() + "次,終於成功了!!");
                    label1.Visible = true;
                    listBox1.Items.Add("遊戲破關");
                    listBox1.Items.Add("請選擇'再玩一次'或'離開'");
                }
            }
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                button3.Focus();
                button3_Click(sender, e);
            }
        }


    }
}

測試了一下
https://ithelp.ithome.com.tw/upload/images/20191001/20105694ZSvNkq2HUo.png

測試了一下
似乎會有題目出現重複數字的狀況
以及

myDictionary.Clear();
            for (int i = 0; i < 10; i++)
                myDictionary.Add(i, 0);

            for (int i = 0; i < 4; i++)
            {
                do
                {
                    number = num.Next(0, 10);
                }
                while (myDictionary[i] != 0);
                myDictionary[number] = i + 1;
                label1.Text += number.ToString();
            }

跑這段有機率出現while出不來的狀況?


更新
似乎是我Code寫錯
thx

小魚 iT邦大師 1 級 ‧ 2019-10-02 13:33:08 檢舉

忽然發現前後不一樣
你把 myDictionary[i] 改成 myDictionary[number] 應該就好了...
/images/emoticon/emoticon01.gif

p.s. 我發現我沒有寫錯,
你是複製貼上的嗎?
/images/emoticon/emoticon39.gif

3
米歐
iT邦新手 4 級 ‧ 2019-10-01 12:40:11

改成這樣呢?

for (int i = 0; i < 4; i++)
{
    int index = Array.IndexOf(myArray, UserArray[i]);
    if(index > -1)
    {
        if(index == i)
        {
            A += 1;
        }
        else
        {
            B += 1;
        }
    }
}
看更多先前的回應...收起先前的回應...
小魚 iT邦大師 1 級 ‧ 2019-10-01 12:52:12 檢舉

看起來好像可以優.

YoChen iT邦新手 2 級 ‧ 2019-10-01 13:16:19 檢舉

如果是考慮效率的話,複雜度是不變的,還是會到n^2
不過倒是簡潔不少~XDD

for (int i = 0; i < 4; i++)
{
    int index = myArray.IndexOf(UserArray[i]);
    if(index > -1)
    {
        if(index == i)
        {
            A += 1;
        }
        else
        {
            B += 1;
        }
    }
}

樓主的語法調整一下
這樣才可以執行~

確實簡潔多了xD
請問如果用Linq的方法呢?

米歐 iT邦新手 4 級 ‧ 2019-10-01 14:43:18 檢舉

哈哈,我沒有實際執行過 XD

我要發表回答

立即登入回答