Avatar billede Spotgun Seniormester
30. december 2006 - 12:01 Der er 6 kommentarer og
1 løsning

Random og sandsynlighed i spil

Jeg har gang i et hobbyprojekt med at omdanne et brætspil til en computerbaseret udgave.

I brætspillet kan man trække nogle kort, og jeg skal selvfølgelig have samme mulighed i computerspillet. Der er ialt 84 kort fordelt på følgende typer (sandsynlighed for at trække kortet står i parentesen):

Venstre: 18 kort (21,43%)
Højre: 18 kort (21.43%)
1 frem: 18 kort (21.43%)
2 frem: 12 kort (14,29%)
3 frem: 6 kort (7,14%)
1 tilbage: 6 kort (7,14%)
U-vending: 6 kort (7,14%)

Hvordan får jeg omsat det til en stump C# kode, så jeg kan trække et tilfældigt kort, vel at mærke med ovenstående sandsynlighed in mente?
Avatar billede driis Nybegynder
30. december 2006 - 12:22 #1
Det kan du gøre ved at have en tilsvarende stak kort i programmet, og trække herfra.
F.eks. ved en List<Card>, hvor kort er en klasse du definierer.
Avatar billede driis Nybegynder
30. december 2006 - 12:36 #2
Eksempel:

using System;
using System.Collections.Generic;

namespace DrawCards
{
    public class CardStack
    {
        private Random rand = new Random();
        private List<Card> cards = new List<Card>(84);
       
        public CardStack()
        {
            InitializeStack();
        }

        private void InitializeStack()
        {
            cards.AddRange(Card.GetCards("Left", 18));
            cards.AddRange(Card.GetCards("Right", 18));
            cards.AddRange(Card.GetCards("1 fw", 18));
            cards.AddRange(Card.GetCards("2 fw", 12));
            cards.AddRange(Card.GetCards("3 fw", 6));
            cards.AddRange(Card.GetCards("1 back", 6));           
            cards.AddRange(Card.GetCards("U-Turn", 6));
        }
       
        public Card DrawCard()
        {
            int idx = rand.Next(cards.Count);
            return cards[idx];
        }
       
    }

    public class Card
    {
        public Card(string name)
        {
            this.name = name;
        }
       
        public static Card[] GetCards(string name, int count)
        {
            Card[] cards = new Card[count];
            for (int i = 0; i < count; i++)
                cards[i] = new Card(name);

            return cards;
        }

        private string name;
       
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override string ToString()
        {
            return Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return obj.GetHashCode() == GetHashCode();
        }
    }
}
Avatar billede Spotgun Seniormester
30. december 2006 - 12:37 #3
Perfekt, det skulle lige være til at arbejde med. Stik mig et svar, så får du nogle point...
Avatar billede driis Nybegynder
30. december 2006 - 12:37 #4
Det kan så anvendes således:

using System;
using System.Collections.Generic;

namespace DrawCards
{
    class Program
    {
        private const int count = 10000;

        static void Main(string[] args)
        {
            Console.WriteLine("Drawing {0} cards...", count);
           
            CardStack stack = new CardStack();
            Dictionary<Card, int> cardCount = new Dictionary<Card, int>(count);           
            for(int i = 0 ; i < count ; i++ )
            {
                Card c = stack.DrawCard();
                if (!cardCount.ContainsKey(c))
                    cardCount.Add(c, 1);
                else
                    cardCount[c]++;
            }

            Console.WriteLine("Results:");
            int total = 0;
            double totalPercentage = 0;
            foreach(Card c in cardCount.Keys)
            {
                double percentage = (double)cardCount[c]/count;
                Console.WriteLine("{0}\t{1}\t{2:0.00} %", c, cardCount[c],percentage * 100);
                total += cardCount[c];
                totalPercentage += percentage;
            }
            Console.WriteLine(new string('-', 80));
            Console.WriteLine("Total\t{0}\t{1:0.00} %", total, totalPercentage * 100);
        }
    }
}

Procentsatserne er ikke 100% korrekte, netop fordi de er trukket tilfældigt. Hvis du lader count i testprogrammet være større, vil procentsatserne blive endnu tættere på det forventede resultat.
Avatar billede driis Nybegynder
30. december 2006 - 12:38 #5
Svar, i øvrigt ;-)
Avatar billede md_craig Nybegynder
30. december 2006 - 13:27 #6
Du skal lige være obs på hvordan du trækker kortene...

i det eksempel givet her, så svarer det til at du trækker et kort, ligger det tilbage og blander stakken...

Hvis det istedet foregår som så mange andre brætspil, med at du trækker et kort, ligger det fra, trækker et kort ligger det fra... osv til stakken er tom, og så blander det der... så skal der lige ændres i det du har nu...
Avatar billede Spotgun Seniormester
30. december 2006 - 15:47 #7
Det har jeg såmænd taget højde for :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester