Permalänk
Medlem

hjälp med kortlek! c#

Hej alla!

Jag har börjat med programmering ganska nyligen och är inte alls bra på det(...än). Tanken är att jag ska göra ett väldigt simpelt blackjack-spel. Om någon kan förklara för mig hur man på ett väldigt enkelt sätt kan blanda EN kortlek när man har en "vektor" där jag tilldelat varje index i vektorn som består av 52 st (index?) en färg och en valör. Alltså ett index i vektorn innehåller alltså ett nummer och en färg så att det bildar ett kort. Jag vill nu kunna blanda kortleken med en swap metod och sedan kunna dela ut två kort till mig själv som spelare och kort till en väldig enkelt utvecklad motståndare.

Jag programmerar i C#

Tack på förhand!
n3mo

Permalänk
Medlem

Själv skrivit ett poker program i c++, använde mig av slumptals generator beroende på tid (tog dock bort första slumptalet, ifall om det skulle bli korta tidsintervall) som flyttade vektor positioner slumpmässigt till ett nytt deck. har dock ingen kod att ge dig då jag gjorde detta för över ett år sedan. lycka till!

Visa signatur

Asus UX32VD-R4002V

Permalänk
Medlem

Re: hjälp med kortlek! c#

private List<int> ShuffleCards(List<int> Deck) { Random rnd = new Random(); for (int i = 0; i < Deck.Count; i++) { Deck = Swap(i, rnd.Next(Deck.Count - 1), Deck); } return Deck; } private List<int> Swap(int a, int b, List<int> Deck) { int temp = Deck[a]; Deck[a] = Deck[b]; Deck[b] = temp; return Deck; }

Finns säkert tusen andra (bättre) sätt att göra det på men det där funkar bra till ditt ändamål..

Permalänk
Medlem

Tack för det, jag förstår den första delen och håller på att applicera den till min kod. Frågan är den sista delen kan förklaras och om det finns något annat sätt än att använda "list" då det inte rekommenderas av min handledare.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av n3mo
Tack för det, jag förstår den första delen och håller på att applicera den till min kod. Frågan är den sista delen kan förklaras och om det finns något annat sätt än att använda "list" då det inte rekommenderas av min handledare.

Förstår inte varför din handledare inte gillar generiska samlingar.. men men..
Det funkar lika bra att köra med en vanlig array.

Vad menat du med den sista delen? Swap-metoden eller?

Den byter plats på två element i en lista/array.. Med tanke på hur du formulerade din fråga trodde jag du ville ha en "swap-metod" som bytte plats på två element..

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av n3mo
Tack för det, jag förstår den första delen och håller på att applicera den till min kod. Frågan är den sista delen kan förklaras och om det finns något annat sätt än att använda "list" då det inte rekommenderas av min handledare.

private List<int> Swap(int a, int b, List<int> Deck):

Swap är en funktion som byter plats på position a i listan Deck med position b.

Först skapar den integern temp som får samma värde som position Deck[a] har.
Deck[a] ersätts med värdet i Deck[b].
Deck[b] ersätts med värdet i temp, alltså Deck[a]s tidigare värde.

Funktionen returnerar den modifierade listan Deck.

Temp behövs då följande rader inte gör vad funktionen avser:

Deck[a] = Deck[b]; //Deck[a] får värdet av Deck[b], helt rätt Deck[b] = Deck[a]; //Deck[b] får värdet av Deck[a] som har värdet av Deck[b]

Ett alternativ skulle vara att skapa en klass som har hand om antalet lekar i blandningen, en för att återställa leken, en för att del ut kort. Snabbt ex:

class cardPool{ int numOfDecks; vector<list<deck> > currentPool; bool shuffleDeck(); card getCardFromDeck(); //Skicka ett kort från leken tills //Det inte längre finns några kort. bool changeNumOfDecks(int); //Ändra antalet kortlekar int cardLeft(); //Antalet kort som finns kvar }

Då kan du få en klass som du kan använda i alla dina kortspelprogram, ex. för texas holdem kan du köra något i stil med:

//Ge spelare kort for(int i = 0; i<players; i++){ playerListOfCards[i].add(crdpl.getCardFromDeck()); playerListOfCards[i].add(crdpl.getCardFromDecK()); } //Ge floppen kort for(int i = 0; i<3; i++) flopListOfCards.add(crdpl.getCardFromDeck());

Nu blir jag lite sugen på att bygga en sån klass själv!
Hade varit kul!

Visa signatur

Cat funeral! Cat funeral!
>>> 112383 <<<

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av pscs3
Text..

Bra beskrivning och förtydligande av mitt exempel..

Håller absolut med om att det är en bra idé att ha en kortleksklass. Väldigt smidigt om man vill återvända den i framtiden..

Permalänk
Medlem

okej, tack så mycket för svaren! jag hör av mig om jag kommer över fler problem nu ska här kodas!

Permalänk
Medlem

Det brukar duga ganska bra att blanda med en sortering efter slumpdata. I detta fallet Guidar.
Det borde vara lite snabbare än swapmethoden också.

//Skapa lista List<int> Deck = new List<int>(); for (int i = 0; i < 52; i++) { Deck.Add(i); } //Sortera/blanda listan Deck = Deck.OrderBy(a => Guid.NewGuid()).ToList<int>();

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Zorin
Det brukar duga ganska bra att blanda med en sortering efter slumpdata. I detta fallet Guidar.
Det borde vara lite snabbare än swapmethoden också.

//Skapa lista List<int> Deck = new List<int>(); for (int i = 0; i < 52; i++) { Deck.Add(i); } //Sortera/blanda listan Deck = Deck.OrderBy(a => Guid.NewGuid()).ToList<int>();

Kan jag hålla med om, dock tror jag det där är lite för avancerat för TS. Och dessutom tolkade jag frågan som att det skulle vara en swapmetod..

Men som sagt din metod är ju bättre!

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Zorin
Det brukar duga ganska bra att blanda med en sortering efter slumpdata. I detta fallet Guidar.
Det borde vara lite snabbare än swapmethoden också.

//Skapa lista List<int> Deck = new List<int>(); for (int i = 0; i < 52; i++) { Deck.Add(i); } //Sortera/blanda listan Deck = Deck.OrderBy(a => Guid.NewGuid()).ToList<int>();

Testade lite med stopwatch bara för skojs skull och slumpad sortering ligger kring 0,23 ms medan den första swap ligger kring 0,80 ms så det var en hyffsad skillnad.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av HRN
Testade lite med stopwatch bara för skojs skull och slumpad sortering ligger kring 0,23 ms medan den första swap ligger kring 0,80 ms så det var en hyffsad skillnad.

Snabbare visst, men det uppfyller inte kraven TS hade!
Han hade till och med strukit under swap-metod..

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Kalle87
Snabbare visst, men det uppfyller inte kraven TS hade!
Han hade till och med strukit under swap-metod..

Sant, men jag var bara nyfiken på att se om det var någon signifikant skillnad. Jag kanske borde markerat med "Off topic"

Kan tillägga (nu när jag ändå satt och testade) att om man använder random.Next() så klockar jag den till ca 0,19 ms. Next kan iofs ge dubletter men jag är tveksam till att det skulle påverka utfallet på en så liten mängd.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av HRN
Sant, men jag var bara nyfiken på att se om det var någon signifikant skillnad. Jag kanske borde markerat med "Off topic"

Kan tillägga (nu när jag ändå satt och testade) att om man använder random.Next() så klockar jag den till ca 0,19 ms. Next kan iofs ge dubletter men jag är tveksam till att det skulle påverka utfallet på en så liten mängd.

Det är ju intressant att det ändå skiljer så pass mycket. Det visar ju på hur viktigt det är att optimera kod vid lite mer avancerade program..

Permalänk
Medlem

Kan tilläggas att jag skrev min implementation när jag skulle göra slumptester på en kortlek. (simulera en många miljoner lång session av patiensen 123) Jag använde ett färdigt bibliotek för kortleken men dess blandningsalgoritm var för långsam. Genom att byta ut den fick jag ner mitt test på en kortlek (blanda och genomföra det test jag skulle) till helt okej tider. Den metod som fanns i biblioteket var en ovan nämnda swap men som standard gjorde 5000 swapningar. För att få ner tiden sänkte jag antalet men vid 2000 swapnigar blev mitt testresultat odugligt (och fortfarande för långsamt) och jag misstänkte att kortlekarna inte blev blandade ordentligt. (Vilket även var en punkt som dök upp som möjlig felkälla och som kunde påverka resultatet för det jag skulle testa)
Jag skulle villa påstå att 54 swapningar är ett för lågt antal för att bli en "bra" blandad kortlek. För trådskaparen har det troligen ingen betydelse.

PS. Jag såg inte att TS efterfrågade just swap-metoden förens efter att jag postat.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Zorin
Kan tilläggas att jag skrev min implementation när jag skulle göra slumptester på en kortlek. (simulera en många miljoner lång session av patiensen 123) Jag använde ett färdigt bibliotek för kortleken men dess blandningsalgoritm var för långsam. Genom att byta ut den fick jag ner mitt test på en kortlek (blanda och genomföra det test jag skulle) till helt okej tider. Den metod som fanns i biblioteket var en ovan nämnda swap men som standard gjorde 5000 swapningar. För att få ner tiden sänkte jag antalet men vid 2000 swapnigar blev mitt testresultat odugligt (och fortfarande för långsamt) och jag misstänkte att kortlekarna inte blev blandade ordentligt. (Vilket även var en punkt som dök upp som möjlig felkälla och som kunde påverka resultatet för det jag skulle testa)
Jag skulle villa påstå att 54 swapningar är ett för lågt antal för att bli en "bra" blandad kortlek. För trådskaparen har det troligen ingen betydelse.

PS. Jag såg inte att TS efterfrågade just swap-metoden förens efter att jag postat.

Det spelar nog ingen roll hur många gånger man blandar om man använder den förstnämnda swap-metoden eftersom den inte ger en jämt fördelad representation av tänkbara permutationer. Man kan nog blanda sig galen utan att få ett bra resultat (om man är lite petig ). Om det är viktigt med en väl blandad kortlek så är nog nedanstående metod bättre.

private void ShuffleCards(List<int> deck) { for (int i = deck.Count - 1; i > 0; i--) { Swap(i, _random.Next(i + 1), deck); } }

Permalänk
Medlem

Om man har nyligen börjat med programmering så funkar metoden ovan rätt bra tycker jag..

Men visst, det är absolut inte nån optimal metod, OM man ska va petig..

Permalänk
Medlem

Visst gör den det! Men även om man är ny inom programmering så kan det vara intressant att veta att det finns flera sätt att lösa en uppgift (även om man explicit ber om en swap ) och att det alltid kan vara bra att tänka till en extra gång

Personligen tycker jag att det kan var kul med trådar som har enkla frågor men spinner vidare och blir lite mer djupgående

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av HRN
Visst gör den det! Men även om man är ny inom programmering så kan det vara intressant att veta att det finns flera sätt att lösa en uppgift (även om man explicit ber om en swap ) och att det alltid kan vara bra att tänka till en extra gång

Personligen tycker jag att det kan var kul med trådar som har enkla frågor men spinner vidare och blir lite mer djupgående

Absolut, det håller jag med om!

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Zorin
Det brukar duga ganska bra att blanda med en sortering efter slumpdata. I detta fallet Guidar.
Det borde vara lite snabbare än swapmethoden också.

//Skapa lista List<int> Deck = new List<int>(); for (int i = 0; i < 52; i++) { Deck.Add(i); } //Sortera/blanda listan Deck = Deck.OrderBy(a => Guid.NewGuid()).ToList<int>();

Intressant nog använder du (edit) nästan samma metod att slumpa ordningen som var uppe på IDG idag: http://www.idg.se/2.1085/1.298975/tabbe-fran-microsoft-placer... Microsoft använder den för att sortera i vilket ordning webläsarna ska visas i windows innan man valt en default.

edit: om [s] hade funkar här hade jag gjort en sådan här
Tyvärr är det en väldigt dålig metod att sortera på som ändå är väldigt spridd på nätet. Resultatet beror på hur OrderBy-funktionen är implementerad, och det är inte något man ska lita på, man vill ju inte att koden ska bete sig annorlunda för att någon kommer på en snabbare OrderBy liksom (eller som i fallet med webläsarna, att olika webläsare ger olika svar).

Permalänk

Snyggt vore också om man gjorde det till en extension method, då kan man använda det på alla generiska listor

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av vb
Intressant nog använder du samma metod att slumpa ordningen som var uppe på IDG idag: http://www.idg.se/2.1085/1.298975/tabbe-fran-microsoft-placer... Microsoft använder den för att sortera i vilket ordning webläsarna ska visas i windows innan man valt en default.

Tyvärr är det en väldigt dålig metod att sortera på som ändå är väldigt spridd på nätet. Resultatet beror på hur OrderBy-funktionen är implementerad, och det är inte något man ska lita på, man vill ju inte att koden ska bete sig annorlunda för att någon kommer på en snabbare OrderBy liksom (eller som i fallet med webläsarna, att olika webläsare ger olika svar).

Såg artikeln om det som drabbat Microsoft. Dock klarar sig mitt fall från det problemet. Även om jag nu i efterhand får erkänna att jag utan att göra någon djupdykning i det förutsatte att Linqs OrderBy skapade keyvaluepairs som den behöll under sorteringen (och därmed undviker den miss MS har gjort).
Och självklart får ska man vara medveten om att om man manipulerar koden med egna sorteringar eller jämförelser så är inte koden "bergsäker".

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Zorin
Såg artikeln om det som drabbat Microsoft. Dock klarar sig mitt fall från det problemet. Även om jag nu i efterhand får erkänna att jag utan att göra någon djupdykning i det förutsatte att Linqs OrderBy skapade keyvaluepairs som den behöll under sorteringen (och därmed undviker den miss MS har gjort).
Och självklart får ska man vara medveten om att om man manipulerar koden med egna sorteringar eller jämförelser så är inte koden "bergsäker".

D'oh!

Du har såklart rätt, jag som inte tänkte efter tillräckligt, får skylla på att det var sent när jag skrev inlägget I det här fallet kan man vara hyfsat säker på sin sak.

Permalänk
Medlem
Skrivet av Kalle87:

private List<int> ShuffleCards(List<int> Deck) { Random rnd = new Random(); for (int i = 0; i < Deck.Count; i++) { Deck = Swap(i, rnd.Next(Deck.Count - 1), Deck); } return Deck; } private List<int> Swap(int a, int b, List<int> Deck) { int temp = Deck[a]; Deck[a] = Deck[b]; Deck[b] = temp; return Deck; }

Finns säkert tusen andra (bättre) sätt att göra det på men det där funkar bra till ditt ändamål..

Tjena!

Har du lust att förklara vad den här raden gör: Deck = Swap(i, rnd.Next(Deck.Count - 1), Deck); ? Varför tar man -1?

Permalänk
Medlem
Skrivet av mhj:

Tjena!

Har du lust att förklara vad den här raden gör: Deck = Swap(i, rnd.Next(Deck.Count - 1), Deck); ? Varför tar man -1?

List.Count returnerar antalet element i listan och eftersom listan är noll-indexerad (dvs första värdet i listan ligger på index [0]) så måste man använda -1 för att undvika att hamna utanför listan.

Visa signatur

Lian Li 6070B / Asus P8P67 B3 / Intel Core i5 2500K @ 4.5GHz
Corsair Vengance 8GB 1600MHz / Asus GTX780 / Corsair TX650V2