Tänkte bygga ett enklare kortspel i java. Har dock problem hur man lättast genomför detta. Jag skulle rekommendera att du "numrerar" korten från 0 till 51. Färg och valör går ju sedan att räkna fram genom modulus och heltalsdivision : Hittade följande kodsnutt på Sun´s javaforum. Till att börja med, innan jag glömmer att skriva om det, är heltalsdivision / i java förutsatt att talen som delas är intar. Jag hade tänkt göra kortspelet som fungerar id e nya javatelfonerna. Ja, om du inte gör en klass Card, bör du nog inte kalla programmet för Shuffle, utan för spelnamnet. Jag håller nog också på den idén, mycket lättare att implementera saker som talonger, högar och andra grejer om man har en separat klass för kortet. Ok, tack Niklas. Det hela blir väldigt enkelt om du gör en klass Card som representarar ett spelkort och en klass Deck som representarar en kortlek och som har en List (el dyl) med de kort som finns i en kortlek. Att blanda innebär då att du stuvar om i listan många gånger (ett par tusen kanske) och när du delar ut plockar du bara från änden. På så vis kan du bara dela ut kort en gång. jag tycker inte att man behöver stuva om flera tusen gånger. Det borde räcka med det som sun själva gör. Dvs gå igenom varje plats i listan och byt ut det kortet med ett slumpvis valt annat kort. Kul idé - jag också!Randomisera spelkort
Vilken metod är bäst att spara korten på, är det en arraylist?
Skulle föreslå att jag bygger upp korthanteringen på följande sätt:
1. Listar alla kort i en tabell
2. Blandar denna tabell
3. Slumpar fram ett kort ur denna tabell.
Problemet som jag ser det det med tabellen är att jag behöver ge korten fyra värden.
1. Deras spelvärde (ex. kung = 10)
2. Deras riktiga värde (ex. kung = 13)
3. Deras unika värde (ex. ruter kung)
4. Är kortet utedelat (ett boolean värde)
Är detta ett rimligt sätt att angripa problemet, och i så fall vilken metod lämpar sig bäst för att spara och randomisera dessa värden?
Tack
AndreasSv: Randomisera spelkort
Valör = kortnummer modulus 13
Färg = kortnummer / 13 (heltalsdivision här)
I Java så jag har för mig att operatorerna är följande (någon annan kan kanske bekräfta detta):
Valör = kortnummer % 13 (returnerar 0 till 12)
Färg = kortnummer \ 13 (returnerar 0 till 3)
När det sedan gäller att hantera korten i t ex "högen" (eller vad man nu kallar det) och "händerna" så funkar ju en vanlig array av heltal bra. T ex kan du ju generera kortleken genom att skapa en array av 52 heltal och lägga in värdena 0 till 51. Blanda sedan genom att slumpa två tal mellan 0 och 51 och byta plats på dessa kort (dvs byta plats på talen på dessa positioner i arrayen). Upprepa proceduren ett par hundra gånger. Enligt mitt lilla testprogram så ger 200 slumpmässiga byten av två kort ett fel på ungefär 2-3%, så perfekt blandat blir det inte då. 300 byten verkade ligga under 1% grovt uppskattat :
<code>
// Generera en sorterad kortlek
for (int i=0;i<52;i++)
tal(i) = i
// Blanda kortleken
for (int i=0;i<300;i++)
{
// OBS! VB-Kod, vet inte hur man slumpar heltal mellan 0 och 51 i Java
x = Int(Rnd * 52)
y = Int(Rnd * 52)
t = tal(x)
tal(x) = tal(y)
tal(y) = t
}
</code>
För att markera ett kort som utdelat kan du ju t ex sätta värdet i arrayen till -1...
Visst kan man tänka sig en mer objektorienterad variant också med några klasser; Kort, Hand, Hög och Enumerator för Färg. Eftersom prestanda antagligen inte är ett jätteproblem i ett kortspel så tycker jag du ska välja den metod som passar din kodstil. Gillar du att koda OO så gör klasser, gillar du att optimera och trimma så kör på arrayen av heltal.Sv: Randomisera spelkort
Koden är för att blanda en kortlek, har ej testat själv, någon som tycker det verkar rimligt?
<code>
import java.util.Random ;
//...
static public int[] makeShuffledDeck() {
Random RNG = new Random() ;
int idx ;
int[] deck = new int[52] ;
// first, place every card in the deck...
for (idx=0; idx < deck.length; idx++) {
deck[idx] = (idx + 1) ;
}
// now shuffle them around randomly:
// for each position in the array,
// swap it with another randomly selected one
//
for (idx=deck.length-1; idx > 0; idx--) {
int other = RNG.nextInt(idx+1) ;
int tmp = deck[idx] ;
deck[idx] = deck[other] ;
deck[other] = tmp ;
}
return deck ;
}
</code>
Tack
AndreasSv: Randomisera spelkort
Sen är jag verkligen inget större fan av "optimeringar" som arraylösningen med heltal som du föreslår såvida man inte ska bygga programmet för mobil eller nån annan beräkningssvag plattform. En kortlek tar verkligen inte mycket och bygger man den i Java bör man utnyttja att språket är OO annars kan man ju alltid göra den i ex C.
Om man sen vill ge sig in och optimera kan man göra det när man ser hur snabbt det blev från början om man har designat sina klasser och interface på ett effektivt sätt.
Jag gjorde ett kortspel för ett par år sen och skapade då en klass Card som hade valör och färg. Sedan används metoder för att tex beräkna det egentliga värdet som ju går att få fram via valören. Med två variabler för det få man redundans.
För att kontrollera hela leken hade jag en klass Deck med metoder för att blanda korten och att ge fylla den hand som anropar den osv.
Metoden för att blanda var precis som Hultan skriver och den fungerar väldigt bra. Det är bara att man kostar på sig att blanda igenom ett par hundra gånger för det går mycket fort.Sv: Randomisera spelkort
Jag hade dock tänkt att själva programmet skulle vara serverbaserat, då telefonen endast är ett grafisktgränsnitt, som innehåller bilder mm. Spelet liggerpå servern.
Hittils har jag byggt randomisering enligt följande:
<code>
import java.util.*;
class Shuffle {
public static void main(String argument[]) {
Random RNG = new Random() ;
int idx ;
int[] deck = new int[52] ;
// first, place every card in the deck...
for (idx=0; idx < deck.length; idx++) {
deck[idx] = (idx + 1) ;
}
// now shuffle them around randomly:
// for each position in the array,
// swap it with another randomly selected one
//
for (idx=deck.length-1; idx > 0; idx--) {
int other = RNG.nextInt(idx+1) ;
int tmp = deck[idx] ;
deck[idx] = deck[other] ;
deck[other] = tmp ;
}
for(int i = 0; i < deck.length; i++) {
System.out.println(deck[i]);
}
int carda = deck[RNG.nextInt(deck.length)];
System.out.println("Random:"+carda);
}
}
</code>
Hur skulle jag bygga upp detta med heltalsdivision ni pratar om, hänger inte riktigt med.
tack
AndreasSv: Randomisera spelkort
Men hur som helst...
Koden för att omvandla ett tal till färg och valör kan du göra så här:
color=cardnr%4;
value=cardnr/4+1;
eller så här:
color=cardnr/13;
value=cardnr%13+1;
Första fallet så numrerar man korten hjärter/klöver/ruter/spader Ess, hjärter/klöver/ruter/spader 2, osv., med andra metoden Hjärter Ess,2,3...13, Klöver Ess, 2,3,...
(Om man använder den ordningen, vill säga)
Då blir color ett tal mellan 0 och 3, där varje tal får representera en färg.Sv: Randomisera spelkort
Har nu fixat så att programmet skriver ut vad det är för kort som slumpats fram.
Detta bygger då på några enkla "if-then-else"-satser.
Skriver ut typ: "A Ace of Spades".
Men jag ställer mig frågande till om hur problemet skall angripas, när det kommer till att reservera redan dutdelade kort, så man kan börja bygga på själva spelet.
Några förslag?
tack
AndreasSv: Randomisera spelkort
Sv: Randomisera spelkort
Sv: Randomisera spelkort
Jag har själv börjat snickra på ett "framework" för detta i VisualBasic.
Hittils finns objekten:
clsCard: (håller reda på grafik, namn mm på alla kort)
clsHand: Håller reda på en spelares "hand" (dvs kort en viss spelare fått)
clsDeck: Håller reda på kortleken, kan "shufflas" och dela ut clsCard-objekt till olika instanser av clsHand.
clsRules: Spelregler, kollar saker som t.ex. "HasPair" vilket tar ett objekt av typen clsHand och returnerar TRUE om spelaren har ett par.
Har inte kommit sådär värst långt än, men om någon annan är intresserad så kan vi ju dela upp arbetet.
Syftet jag hade från början var att skriva en "assistent" som håller reda på utdelade kort och olika sannolikheter för att vinna m.m. - kul att ha på t.ex. on-line pokerspel. Hehe. Men annars kan det ju bli en snygg plattform för alla slags kortspel...
Maila mig om ni vill bidra eller har synpunkter: 018421608(at)telia.com
/Micke