Pseudocode und Implementationsansätze

Entwicklungsrichtlinien

/**********************************************************************

*

*

*

* Parameters: Parameter erläutern

*

* Result: Rückgabewert erläutern, insbesondere Fehlercodes

*

* Version: Dummy/Prototype/PreAlpha/Alpha/Beta/Release

*

* Description:

* Kurzbeschreibung der Funktion, alles was neben den Kommentaren

* in der Funktion nützlich wäre

* um den Code zu verstehen und was man wissen sollte, wenn man den

* Code ueberhaupt nicht betrachtet.

*

**********************************************************************/

Klassen

Team

Announcement

GameType

Rule

GameValues

Language

CardValue

CardColor

Card

Trick

Player

Ai

Human

Game

GamePoints

GamePointsTable

Party

Die Grafik

Mischen der Karten

Code der PreAlphaversion:

for (i = 12 * Number_of_Players; i > 0; i--)

{

int r; // random variable (number of cards, still to count)

r = int((double(rand()) / RAND_MAX) * i);

if (r == i) r = i - 1;

r += 1;

int n; // Number of the selected card (in the end)

for (n = 0; r > 0; n++)

{

if (!used[n]) {

r--;

if (r == 0) break;

}

Cards[i - 1] = TCard(InttoCardColor(n / 12), InttoCardValue(n % 12));

used[n] = true;

}

Kartenüberprüfung für Stiche

Nur für Standardregeln und Herz Zehnen sind nicht Trumpf.

Code der PreAlphaversion:

bool Trick::IsValid(const TCard& c, const THand& h) const

{

if (act_Card==0) return true;

if (act_Card>3) {

cerr<<"Trick Overflow: IsValid\n";

return false;

}

// Color is equal to first Color in trick: bingo

// and first color is no trump picture

if (c.GetColor()==Cards[0].GetColor() &&

c.GetValue()!=Jack &&

c.GetValue()!=Queen &&

Cards[0].GetValue()!=Jack &&

Cards[0].GetValue()!=Queen) return true;

// attend Trump

if (Cards[0].GetColor()==Diamond ||

Cards[0].GetValue()==Jack ||

Cards[0].GetValue()==Queen)

{

if (c.GetColor()==Diamond) return true;

if (c.GetValue()==Jack) return true;

if (c.GetValue()==Queen) return true;

if (h.hasTrump())

{

return false;

} else return true;

}

// on Hand is no card of this color: Bingo

if (Cards[0].GetValue()!=Jack &&

Cards[0].GetValue()!=Queen &&

Cards[0].GetColor()!=Diamond &&

!h.ExistsColor(Cards[0].GetColor()))

{

return true;

}

// what a shame

return false;

}

Gewinnerermittlung eines Stiches

Nur für Standardregeln und Herz Zehnen sind nicht Trumpf.

Code der PreAlphaversion:

int Trick::WinnerIs(bool Output)

{

int winner=0;

TCard* best=&(Cards[0]);

for(int i=1;i

{

// table of yet made comparisons

//

// Q = queen

// J = jack

// D = diamond

// C = color

//

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | | | |

// J | | | |

// D | | | |

// C | | | |

// Trumpcolor jabs each other color

if (best->GetColor()!=Diamond &&

(Cards[i].GetColor()==Diamond || Cards[i].GetValue()==Jack || Cards[i].GetValue()==Queen) &&

best->GetValue()!=Jack && best->GetValue()!=Queen)

{

winner=i;

best=&(Cards[i]);

continue;

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | | | | x

// J | | | | x

// D | | | | x

// C | | | |

// Queen jabs Jacks

if (best->GetValue()==Jack && Cards[i].GetValue()==Queen)

{

winner=i;

best=&(Cards[i]);

continue;

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | | x | | x

// J | | | | x

// D | | | | x

// C | | | |

// Higher Jack jabs lower

if (best->GetValue()==Jack && Cards[i].GetValue()==Jack)

{

if (best->GetColor()

winner=i;

best=&(Cards[i]);

continue;

}

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | | x | | x

// J | | x | | x

// D | | | | x

// C | | | |

// Higher Queen jabs lower

if (best->GetValue()==Queen && Cards[i].GetValue()==Queen)

{

winner=i;

best=&(Cards[i]);

continue;

}

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | x | x | | x

// J | | x | | x

// D | | | | x

// C | | | |

// Jack jabs no Queen

if(best->GetValue()==Queen && Cards[i].GetValue()==Jack)

{

continue;

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | x | x | | x

// J | x | x | | x

// D | x | | | x

// C | x | | |

// Diamond is jabbed by Jacks and Queens

if (best->GetColor()==Diamond && ( Cards[i].GetValue()==Jack ||

Cards[i].GetValue()==Queen))

{

winner=i;

best=&(Cards[i]);

continue;

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | x | x | x | x

// J | x | x | x | x

// D | x | | | x

// C | x | | |

if (best->GetValue() == Jack)

continue;

if ( (best->GetColor() == Diamond) &&

(Cards[i].GetColor() != Diamond))

continue;

// highest Card of a Color jabs all lower

if (best->GetColor()==Cards[i].GetColor()&&

best->GetValue()!=Jack &&

best->GetValue()!=Queen)

{

// Nine is jabbed by everything except Nine

if (best->GetValue()==Nine && Cards[i].GetValue()!=Nine)

{

winner=i;

best=&(Cards[i]);

continue;

}

// only King and Nine jabs King not

if (best->GetValue()==King &&

Cards[i].GetValue()!=Nine &&

Cards[i].GetValue()!=King)

{

winner=i;

best=&(Cards[i]);

continue;

}

// only Ace jabs ten

if (best->GetValue()==Ten &&

Cards[i].GetValue()!=Nine &&

Cards[i].GetValue()!=King &&

Cards[i].GetValue()!=Ten)

{

winner=i;

best=&(Cards[i]);

continue;

}

}

// i\best| Q | J | D | C

// ------+---+---+---+---

// Q | x | x | x | x

// J | x | x | x | x

// D | x | | x | x

// C | x | | | x

}

return winner;

}

Die Stichdatenbank

Die Datensätze werden in einem Feld gespeichert.

Erzeugung der Datenbank:

Code der PreAlphaversion:

TCard c[4];

for(int w=0;w<24;w++)

for (int x=0;x<24;x++)

for (int y=0;y<24;y++)

for (int z=0;z<24;z++)

{

c[0]=TCard(InttoCardColor(w/6),InttoCardValue(2*(w%6)));

c[1]=TCard(InttoCardColor(x/6),InttoCardValue(2*(x%6)));

c[2]=TCard(InttoCardColor(y/6),InttoCardValue(2*(y%6)));

c[3]=TCard(InttoCardColor(z/6),InttoCardValue(2*(z%6)));

Tricks[w*24*24*24+x*24*24+y*24+z]=TTrick(c);

}

Hierbei sind die Kartenfarbe von 0=Karo bis 3=Kreuz codiert und Die KartenWerte sind 0=Neun, 2=Zehn, 4=As, 6=Bube, 8=Dame und 10=König

Ein Zugriff erfolgt dann wie folgt:

Code der PreAlphaversion:

int mod=24*24*24;

// computation of startposition for Database

for(i = 0; i < CardsInTrick; i++)

{

startpos+=mod*(6*T.GetCard(i).GetColor()+CardValuetoInt(T.GetCard(i).GetValue()/2);

mod=mod/24;

}

Wobei CardValueToInt genau obige Zahlen liefert

Die Berechnung für Gewinnaussicht einer Karte:

Lässt sich als gewichtete Summe aller Punkte der Stiche darstellen, die diese Karte gewinnt, von diesen werden alle Punkte der Stiche abgezogen, die durch diese Karte verloren werden.

Auswerten eines imaginären Spielbaumes

Code der PreAlphaversion:

// add next card to Trick or Evaluate Trick if oll cards played

void PlayTree::calc_one( TTrick T, THand all[Number_of_Players],int depth, int pl, int start,THand h[Number_of_Players])

{

int z,w,i,i1;

TCard c;

THand h2[Number_of_Players];

TTrick T2;

THand h3;

if (T.GetActCard()==Number_of_Players) {

// Evaluate Trick

w=T.WinnerIs(false);

// modify Win_Probality for choosen Card with number start

if (w==pl) {

Win_Prob[start]+=T.GetPoints();

} else {

Win_Prob[start]-=T.GetPoints();

}

// sort hands for next trick to calculate some tricks in the future

for (z=0;z

h2[z]=all[(w+z)%Number_of_Players];

// a little bit statitistic

numbertricks2[start]+=1;

// Calculate next TTrick

calc_Tricks(TTrick(),h2,depth,w,start);

} else {

// Add one Card to T

//by first call find the cards of my hand i'am allowed to play

if (start==-1 || T.GetActCard()==0) {

h[0]=T.GetValidCards(all[0]);

}

// remember my hand before i play a card

h3=h[T.GetActCard()];

for ( i = 0; i < h[T.GetActCard()].GetCardsNumber() ; i++ ) {

T2=T;

c=h[T2.GetActCard()].GetCard(i);

T2=T2+h[T2.GetActCard()].PlayCard(i);

// first call but not last

if ((start==-1 || T.GetActCard()==0) && T2.GetActCard()!=Number_of_Players) {

// modify hands of all other players

for (i1=1;i1

h[i1]=T2.GetValidCards(all[i1]);

}

// add one Card to Trick

calc_one(T2,all,depth,pl,all[T.GetActCard()].GetPos(c),h);

} else {

// add one Card to Trick

calc_one(T2,all,depth,pl,start,h);

}

// restore my hand

h[T.GetActCard()]=h3;

}

}

}

int PlayTree::calc_Tricks(TTrick T,THand all[Number_of_Players],int depth,int pl)

{

if (depth>0) {

depth--;

THand all2[Number_of_Players];

for (int i = 0; i < Number_of_Players; i++)

all2[i] = all[i];

calc_one(T,all,depth,pl,-1,all2);

}

return 0;

}

Stand 3. November 2001