You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/lskat/lskat/lskatdoc.cpp

818 lines
17 KiB

/***************************************************************************
lskatdoc.cpp - description
-------------------
begin : Tue May 2 15:47:11 CEST 2000
copyright : (C) 2000 by Martin Heni
email : martin@heni-online.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
// include files for TQt
#include <tqdir.h>
#include <tqfileinfo.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/types.h>
// include files for TDE
#include <tdelocale.h>
// application specific includes
#include "lskatdoc.h"
#include "lskat.h"
#include "lskatview.h"
#include <kcarddialog.h>
TQPtrList<LSkatView> *LSkatDoc::pViewList = 0L;
LSkatDoc::LSkatDoc(TQWidget *parent, const char *name) : TQObject(parent, name)
{
int i;
if(!pViewList)
{
pViewList = new TQPtrList<LSkatView>();
}
pViewList->setAutoDelete(true);
isrunning=0;
wasgame=false;
initrandom();
// Allow translation of playernames
/*
names[0]=i18n("Alice");
names[1]=i18n("Bob");
*/
for (i=0;i<14;i++) cardvalues[i]=0;
cardvalues[(int)Ace]=11;
cardvalues[(int)Ten]=10;
cardvalues[(int)King]=4;
cardvalues[(int)Queen]=3;
cardvalues[(int)Jack]=2;
/*
computerlevel=2;
playedby[1]=KG_INPUTTYPE_INTERACTIVE;
playedby[0]=KG_INPUTTYPE_PROCESS;
// playedby[1]=KG_INPUTTYPE_INTERACTIVE;
*/
isintro=1;
server=false;
port=7432;
host="";
Name="";
remoteswitch=false;
ClearStats();
}
LSkatDoc::~LSkatDoc()
{
}
void LSkatDoc::addView(LSkatView *view)
{
pViewList->append(view);
}
void LSkatDoc::removeView(LSkatView *view)
{
pViewList->remove(view);
}
void LSkatDoc::setAbsFilePath(const TQString &filename)
{
absFilePath=filename;
}
const TQString &LSkatDoc::getAbsFilePath() const
{
return absFilePath;
}
void LSkatDoc::setTitle(const TQString &_t)
{
title=_t;
}
const TQString &LSkatDoc::getTitle() const
{
return title;
}
void LSkatDoc::InitMove(LSkatView *sender,int player,int x,int y)
{
LSkatView *w;
if(pViewList)
{
for(w=pViewList->first(); w!=0; w=pViewList->next())
{
if(w!=sender) w->InitMove(player,x,y);
}
}
}
void LSkatDoc::slotUpdateAllViews(LSkatView *sender)
{
LSkatView *w;
if(pViewList)
{
for(w=pViewList->first(); w!=0; w=pViewList->next())
{
if(w!=sender)
w->repaint();
}
}
}
void LSkatDoc::UpdateViews(int mode)
{
LSkatView *w;
if (IsIntro()) return ;
if(pViewList)
{
for(w=pViewList->first(); w!=0; w=pViewList->next())
{
if (mode & UPDATE_STATUS) w->updateStatus();
}
}
}
bool LSkatDoc::saveModified()
{
return true;
}
void LSkatDoc::closeDocument()
{
deleteContents();
}
bool LSkatDoc::newDocument(TDEConfig * /*config*/,TQString path)
{
int res;
modified=false;
absFilePath=TQDir::homeDirPath();
title=i18n("Untitled");
if (global_debug>1) printf("path=%s\n",path.latin1());
res=LoadBitmap(path);
if (res==0) return false;
return true;
}
bool LSkatDoc::LoadGrafix(TQString path)
{
int res;
res=LoadCards(cardPath);
if (res==0) return false;
res=LoadDeck(deckPath);
if (res==0) return false;
return true;
}
bool LSkatDoc::SetCardDeckPath(TQString deck,TQString card)
{
bool update=false;
if (!deck.isNull() && deck!=deckPath)
{
update=true;
deckPath=deck;
LoadDeck(deckPath);
}
if (!card.isNull() && card!=cardPath)
{
update=true;
cardPath=card;
LoadCards(cardPath);
}
return update;
}
bool LSkatDoc::openDocument(const TQString &filename, const char * /*format*/ /*=0*/)
{
TQFileInfo fileInfo(filename);
title=fileInfo.fileName();
absFilePath=fileInfo.absFilePath();
/////////////////////////////////////////////////
// TODO: Add your document opening code here
/////////////////////////////////////////////////
modified=false;
return true;
}
bool LSkatDoc::saveDocument(const TQString & /*filename*/, const char * /*format*/ /*=0*/)
{
/////////////////////////////////////////////////
// TODO: Add your document saving code here
/////////////////////////////////////////////////
modified=false;
return true;
}
void LSkatDoc::deleteContents()
{
/////////////////////////////////////////////////
// TODO: Add implementation to delete the document contents
/////////////////////////////////////////////////
}
// Called after game ends..give points to players
void LSkatDoc::EvaluateGame()
{
if (score[0]+score[1]!=120)
{
printf("Warning: Score does not end up to 120\n");
}
stat_games[0]++;
stat_games[1]++;
if (score[0]==score[1]) // drawn
{
stat_points[0]++;
stat_points[1]++;
}
else if (score[0]>score[1])
{
stat_won[0]++;
stat_points[0]+=2;
if (score[0]>=90) stat_points[0]++; // Schneider
if (score[0]>=120) stat_points[0]++; // SChwarz
}
else
{
stat_won[1]++;
stat_points[1]+=2;
if (score[1]>=90) stat_points[1]++; // Schneider
if (score[1]>=120) stat_points[1]++; // SChwarz
}
}
void LSkatDoc::EndGame(bool aborted)
{
if (aborted)
{
stat_brk[0]++;
stat_brk[1]++;
}
else
{
startplayer=1-began_game;
}
isrunning=0;
wasgame=true;
}
void LSkatDoc::NewGame()
{
int i,r;
int num[NO_OF_CARDS];
isintro=0;
began_game=startplayer;
for (i=0;i<NO_OF_TILES;i++)
{
cardheight[i]=2;
}
trump=(CCOLOUR)(random(4));
if (global_debug>5) printf("Trump=%d\n",trump);
if (random(8)==0) trump=Grand; // grand
// Fast drawing of random cards
for (i=0;i<NO_OF_CARDS;i++)
{
num[i]=i;
}
for (i=0;i<NO_OF_CARDS;i++)
{
r=random(NO_OF_CARDS-i); // cards available 32-i (+1)
card[i]=num[r];
num[r]=num[NO_OF_CARDS-i-1]; // shift numbers
}
isrunning=1;
movestatus=-1;
currentplayer=startplayer;
laststartplayer=-1;
moveno=0;
computerscore=0;
lock=false;
for (i=0;i<2;i++)
{
score[i]=0;
curmove[i]=-1;
}
}
int LSkatDoc::GetMove(int no) {return curmove[no];}
CCOLOUR LSkatDoc::GetTrump()
{
return trump;
}
void LSkatDoc::SetTrump(CCOLOUR i)
{
trump=i;
}
// pos=0..7, height=2..1..(0 no card left), player=0..1
int LSkatDoc::GetCard(int player, int pos,int height)
{
int i;
if (height==0) return -1;
height=2-height;
i=NO_OF_TILES*player+8*height+pos;
return card[i];
}
// pos=0..7, player=0..1
int LSkatDoc::GetHeight(int player, int pos)
{
int i;
i=8*player+pos;
return cardheight[i];
}
// pos=0..7, player=0..1
void LSkatDoc::SetHeight(int player, int pos,int h)
{
int i;
i=8*player+pos;
cardheight[i]=h;
}
int LSkatDoc::random(int max)
{
double value;
int r;
r=rand();
value=(double)((double)r*(double)max)/(double)RAND_MAX;
return (int)value;
}
void LSkatDoc::initrandom()
{
srand( (unsigned)time( NULL ) ); // randomize
}
bool LSkatDoc::IsRunning() {return isrunning;}
bool LSkatDoc::LegalMove(int p1, int p2)
{
CCOLOUR col1,col2,col3;
CCARD card1,card2,card3;
card1=(CCARD)((p1)/4);
col1=(CCOLOUR)((p1)%4);
card2=(CCARD)((p2)/4);
col2=(CCOLOUR)((p2)%4);
// force trump colour
if (card1==Jack) col1=trump;
if (card2==Jack) col2=trump;
// same colour always ok
if (col1==col2) return true;
// Search for same colour
bool flag=true;
for (int i=0;i<8;i++)
{
int h,c;
h=GetHeight(1-startplayer,i);
if (h==0) continue;
c=GetCard(1-startplayer,i,h);
card3=(CCARD)((c)/4);
col3=(CCOLOUR)((c)%4);
if (card3==Jack) col3=trump;
if (col3==col1)
{
flag=false;
break;
}
}
if (flag) return true;
return false;
}
int LSkatDoc::PrepareMove(int player,int pos)
{
int h,card;
h=GetHeight(player,pos);
if (h==0) return -1; // not possible
if (player!=currentplayer) return -2; // wrong player
card=GetCard(player,pos,h);
// New round
if (currentplayer==startplayer)
{
curmove[0]=-1;
curmove[1]=-1;
}
else
{
if (!LegalMove(curmove[startplayer],card))
{
printf("Illegal move\n");
return -3;
}
}
lock=true;
movestatus=card;
SetHeight(player,pos,h-1);
return 1;
}
int LSkatDoc::MakeMove()
{
lock=false;
curmove[currentplayer]=movestatus;
if (currentplayer==startplayer)
{
moveno++;
currentplayer=1-startplayer;
}
else
{
laststartplayer=startplayer;
if (WonMove(curmove[startplayer],curmove[1-startplayer]))
{
// switch startplayer
startplayer=1-startplayer;
}
else
{
}
currentplayer=startplayer;
score[startplayer]+=CardValue(curmove[0]);
score[startplayer]+=CardValue(curmove[1]);
if (moveno==NO_OF_TILES)
{
EndGame(false);
return 2;
}
}
movestatus=-1;
return 1;
}
int LSkatDoc::CardValue(int card)
{
int card1;
card1=card/4;
return cardvalues[card1];
}
int LSkatDoc::WonMove(int c1,int c2)
{
CCOLOUR col1,col2;
CCARD card1,card2;
card1=(CCARD)((c1)/4);
col1=(CCOLOUR)((c1)%4);
card2=(CCARD)((c2)/4);
col2=(CCOLOUR)((c2)%4);
// Two jacks
if (card1==Jack && card2==Jack)
{
if (col1<col2) return 0;
else return 1;
}
// One Jack wins always
if (card1==Jack) return 0;
if (card2==Jack) return 1;
// higher one wins if same colour
if (col1==col2)
{
if (card1==Ten)
{
if (card2==Ace) return 1;
else return 0;
}
if (card2==Ten)
{
if (card1==Ace) return 0;
return 1;
}
if ((int)card1<(int)card2) return 0;
return 1;
}
// trump wins
if (col1==trump) return 0;
if (col2==trump) return 1;
// first one wins
return 0;
}
int LSkatDoc::GetMoveStatus() {return movestatus;}
void LSkatDoc::SetMoveStatus(int i) { movestatus=i; }
int LSkatDoc::GetCurrentPlayer() {return currentplayer;}
void LSkatDoc::SetCurrentPlayer(int i) {currentplayer=i;}
int LSkatDoc::GetStartPlayer() {return startplayer;}
void LSkatDoc::SetStartPlayer(int i) {startplayer=i;}
void LSkatDoc::SetName(int no, TQString n) { names[no]=n; }
TQString LSkatDoc::GetName(int no) {return names[no];}
int LSkatDoc::GetScore(int no) {return score[no];}
int LSkatDoc::GetMoveNo() {return moveno;}
/*
void LSkatDoc::SetDeckNo(int no) {deckno=no;}
int LSkatDoc::GetDeckNo() {return deckno;}
*/
int LSkatDoc::GetLastStartPlayer() {return laststartplayer;}
KG_INPUTTYPE LSkatDoc::GetPlayedBy(int no) {return playedby[no];}
void LSkatDoc::SetPlayedBy(int no,KG_INPUTTYPE type) {playedby[no]=type;}
int LSkatDoc::GetComputerLevel() {return computerlevel;}
void LSkatDoc::SetComputerLevel(int lev) {computerlevel=lev;}
void LSkatDoc::SetComputerScore(int sc) {computerscore=sc;}
int LSkatDoc::GetComputerScore() {return computerscore;}
void LSkatDoc::SetLock() {lock=true;}
void LSkatDoc::ReleaseLock() {lock=false;}
bool LSkatDoc::IsLocked() {return lock;}
bool LSkatDoc::IsIntro() {return isintro;}
bool LSkatDoc::WasRunning() {return wasgame;}
void LSkatDoc::SetIntro(bool b) {isintro=b;}
int LSkatDoc::LoadBitmap(TQString path)
{
int i;
TQString buf;
if (global_debug>5) printf("Loading bitmaps\n");
for (i=0;i<NO_OF_TRUMPS;i++)
{
buf.sprintf("%st%d.png",path.latin1(),i+1);
if(!mPixTrump[i].load(buf))
{
printf("Fatal error: bitmap %s not found \n",buf.latin1());
}
}
for (i=0;i<3;i++)
{
buf.sprintf("%stype%d.png",path.latin1(),i+1);
if (!mPixType[i].load(buf))
{
printf("Fatal error: bitmap %s not found \n",buf.latin1());
}
}
buf.sprintf("%sbackground.png",path.latin1());
mPixBackground.load(buf);
if (!mPixBackground.load(buf))
{
printf("Fatal error: bitmap %s not found \n",buf.latin1());
}
for (i=0;i<NO_OF_ANIM;i++)
{
buf.sprintf("%s4000%02d.png",path.latin1(),i);
if(!mPixAnim[i].load(buf))
{
printf("Fatal error: bitmap %s not found \n",buf.latin1());
}
}
return 1;
}
int LSkatDoc::LoadCards(TQString path)
{
TQString buf;
for (int i=0;i<NO_OF_CARDS;i++)
{
buf.sprintf("%s%d.png",path.latin1(),i+1);
if(!mPixCard[i].load(buf))
{
printf("Fatal error: bitmap %s not found \n",buf.latin1());
return 0;
}
}
cardsize=mPixCard[0].size();
return 1;
}
int LSkatDoc::LoadDeck(TQString path)
{
if (!mPixDeck.load(path))return 0;
return 1;
}
void LSkatDoc::SetInputHandler(KEInput *i)
{
inputHandler=i;
}
KEInput *LSkatDoc::QueryInputHandler()
{
return inputHandler;
}
int LSkatDoc::SwitchStartPlayer()
{
startplayer=1-startplayer;
return startplayer;
}
bool LSkatDoc::IsServer()
{
return server;
}
void LSkatDoc::SetServer(bool b)
{
server=b;
}
void LSkatDoc::SetHost(TQString h)
{
host=h;
}
void LSkatDoc::SetName(const TQString& n)
{
Name=n;
}
void LSkatDoc::SetPort(short p)
{
port=p;
}
TQString LSkatDoc::QueryHost()
{
return host;
}
short LSkatDoc::QueryPort()
{
return port;
}
TQString LSkatDoc::QueryName() const
{
return Name;
}
int *LSkatDoc::GetCardP()
{
return card;
}
int *LSkatDoc::GetCardHeightP()
{
return cardheight;
}
void LSkatDoc::SetCard(int no,int c)
{
card[no]=c;
}
void LSkatDoc::SetRemoteSwitch(bool b)
{
remoteswitch=b;
}
bool LSkatDoc::IsRemoteSwitch()
{
return remoteswitch;
}
int LSkatDoc::GetStatWon(int no)
{
return stat_won[no];
}
int LSkatDoc::GetStatGames(int no)
{
return stat_games[no];
}
int LSkatDoc::GetStatAborted(int no)
{
return stat_brk[no];
}
int LSkatDoc::GetStatPoints(int no)
{
return stat_points[no];
}
TQString LSkatDoc::GetProcess()
{
return procfile;
}
void LSkatDoc::ClearStats()
{
for (int j=0;j<2;j++)
{
stat_won[j]=0;
stat_points[j]=0;
stat_games[j]=0;
stat_brk[j]=0;
}
}
void LSkatDoc::ReadConfig(TDEConfig *config)
{
TDEConfig emailCfg( "emaildefaults", true );
emailCfg.setGroup( "UserInfo" );
TQString name = emailCfg.readEntry( "FullName" );
if ( name.isEmpty() )
{
struct passwd *pw = getpwuid( getuid() );
if ( pw )
name = TQString::fromLocal8Bit( pw->pw_gecos );
}
config->setGroup("Parameter");
host=config->readEntry("host");
port=(unsigned short)config->readNumEntry("port",7432);
procfile=config->readEntry("process",TQCString("lskatproc"));
Name=config->readEntry("gamename");
names[0]=config->readEntry("Name1",i18n("Alice"));
// names[1]=config->readEntry("Name2",i18n("Bob"));
names[1]=config->readEntry("Name2", name.isEmpty() ? i18n("Bob") : name);
// This is for debug and testing as you can run it from the CVS without
// installing the carddecks !
// For the release version you can remove the aruments to the following two
// functions !!!!
cardPath=config->readPathEntry("cardpath", KCardDialog::getDefaultCardDir());
deckPath=config->readPathEntry("deckpath", KCardDialog::getDefaultDeck());
// Debug only
if (global_debug>3)
printf("cardPath=%s\ndeckPath=%s\n",cardPath.latin1(),deckPath.latin1());
startplayer=config->readNumEntry("Startplayer",0);
if (startplayer>1 || startplayer<0) startplayer=0;
began_game=startplayer;
computerlevel=config->readNumEntry("Level",2);
playedby[0]=(KG_INPUTTYPE)config->readNumEntry("Player1",
(int)KG_INPUTTYPE_PROCESS);
playedby[1]=(KG_INPUTTYPE)config->readNumEntry("Player2",
(int)KG_INPUTTYPE_INTERACTIVE);
stat_won[0]=config->readNumEntry("Stat1W",0);
stat_won[1]=config->readNumEntry("Stat2W",0);
stat_brk[0]=config->readNumEntry("Stat1B",0);
stat_brk[1]=config->readNumEntry("Stat2B",0);
stat_points[0]=config->readNumEntry("Stat1P",0);
stat_points[1]=config->readNumEntry("Stat2P",0);
stat_games[0]=config->readNumEntry("Stat1G",0);
stat_games[1]=config->readNumEntry("Stat2G",0);
}
/** write config file */
void LSkatDoc::WriteConfig(TDEConfig *config)
{
config->setGroup("Parameter");
config->writeEntry("host",host);
config->writeEntry("port",port);
config->writeEntry("process",procfile);
config->writePathEntry("tmppath",picpath);
config->writeEntry("delpath",delpath);
config->writeEntry("Name1",names[0]);
config->writeEntry("Name2",names[1]);
config->writeEntry("gamename",Name);
config->writeEntry("Startplayer",startplayer);
config->writeEntry("Level",computerlevel);
config->writeEntry("Player1",int(playedby[0]));
config->writeEntry("Player2",int(playedby[1]));
config->writeEntry("Stat1W",stat_won[0]);
config->writeEntry("Stat2W",stat_won[1]);
config->writeEntry("Stat1B",stat_brk[0]);
config->writeEntry("Stat2B",stat_brk[1]);
config->writeEntry("Stat1P",stat_points[0]);
config->writeEntry("Stat2P",stat_points[1]);
config->writeEntry("Stat1G",stat_games[0]);
config->writeEntry("Stat2G",stat_games[1]);
config->writePathEntry("cardpath",cardPath);
config->writePathEntry("deckpath",deckPath);
config->sync();
}
#include "lskatdoc.moc"