summaryrefslogtreecommitdiffstats
path: root/lskat/lskatproc
diff options
context:
space:
mode:
Diffstat (limited to 'lskat/lskatproc')
-rw-r--r--lskat/lskatproc/KChildConnect.cpp124
-rw-r--r--lskat/lskatproc/KChildConnect.h45
-rw-r--r--lskat/lskatproc/KConnectTypes.h38
-rw-r--r--lskat/lskatproc/KEMessage.cpp326
-rw-r--r--lskat/lskatproc/KEMessage.h66
-rw-r--r--lskat/lskatproc/KInputChildProcess.cpp106
-rw-r--r--lskat/lskatproc/KInputChildProcess.h57
-rw-r--r--lskat/lskatproc/KMessageEntry.cpp98
-rw-r--r--lskat/lskatproc/KMessageEntry.h44
-rw-r--r--lskat/lskatproc/Makefile.am13
-rw-r--r--lskat/lskatproc/docs/Makefile.am4
-rw-r--r--lskat/lskatproc/docs/en/Makefile.am4
-rw-r--r--lskat/lskatproc/lskatproc.cpp596
-rw-r--r--lskat/lskatproc/lskatproc.h104
-rw-r--r--lskat/lskatproc/main.cpp28
-rw-r--r--lskat/lskatproc/templates/cpp_template16
-rw-r--r--lskat/lskatproc/templates/header_template16
17 files changed, 1685 insertions, 0 deletions
diff --git a/lskat/lskatproc/KChildConnect.cpp b/lskat/lskatproc/KChildConnect.cpp
new file mode 100644
index 00000000..0308a3f0
--- /dev/null
+++ b/lskat/lskatproc/KChildConnect.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ KChildConnect.cpp - description
+ -------------------
+ begin : Tue May 2 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 <stdio.h>
+#include "KChildConnect.h"
+
+#include "KChildConnect.moc"
+
+KChildConnect::KChildConnect()
+ : QObject(0,0)
+{
+ input_pending=false;
+ inputbuffer="";
+}
+
+KChildConnect::~KChildConnect()
+{
+}
+
+KR_STATUS KChildConnect::QueryStatus()
+{
+ return KR_OK;
+}
+
+// Communication with process
+bool KChildConnect::SendMsg(KEMessage *msg)
+{
+ QString sendstring=msg->ToString();
+ // Debug only
+ if (msg->HasKey(QCString("KLogSendMsg")))
+ {
+ char *p;
+ int size;
+ FILE *fp;
+ msg->GetData(QCString("KLogSendMsg"),p,size);
+ if (p && (fp=fopen(p,"a")) )
+ {
+ fprintf(fp,"------------------------------------\n");
+ fprintf(fp,"%s", sendstring.utf8().data());
+ fclose(fp);
+ }
+ }
+ // end debug only
+ return Send(sendstring);
+}
+
+// Send string to parent
+bool KChildConnect::Send(QString str)
+{
+ if (!str || str.length()<1) return true; // no need to send crap
+ printf("%s",str.latin1());
+ fflush(stdout);
+ return true;
+}
+
+void KChildConnect::Receive(QString input)
+{
+ // Cut out CR
+ int len,pos;
+ QString tmp;
+
+
+ // Call us recursive until there are no CR left
+ len=KEMESSAGE_CR.length();
+ pos=input.find(KEMESSAGE_CR);
+ if (pos>0)
+ {
+ tmp=input.left(pos);
+ if (tmp.length()>0) Receive(tmp); // CR free
+ input=input.right(input.length()-pos-len);
+ if (input.length()>0) Receive(input);
+ return ;
+ }
+
+// printf(" ---> KChildConnect::Receive: '%s'\n",(const char *)input);
+ if (input==QString(KEMESSAGE_HEAD) && !input_pending)
+ {
+ input_pending=true;
+ inputcache.clear();
+ return ;
+ }
+ if (!input_pending) return ; // ignore
+ if (input!=QString(KEMESSAGE_TAIL))
+ {
+ inputcache.append(input.latin1());
+ return;
+ }
+ input_pending=0;
+
+ KEMessage *msg=new KEMessage;
+ char *it;
+ for (it=inputcache.first();it!=0;it=inputcache.next())
+ {
+ msg->AddString(QCString(it));
+ }
+
+// printf("+- CHILDprocess:: GOT MESSAGE::Emmiting slotReceiveMsg\n");
+ emit signalReceiveMsg(msg,ID);
+
+ delete msg;
+}
+
+void KChildConnect::SetID(int id)
+{
+ ID=id;
+}
+int KChildConnect::QueryID()
+{
+ return ID;
+}
+
diff --git a/lskat/lskatproc/KChildConnect.h b/lskat/lskatproc/KChildConnect.h
new file mode 100644
index 00000000..9cad1a5d
--- /dev/null
+++ b/lskat/lskatproc/KChildConnect.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ KChildConnect.h - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+
+#ifndef _KCHILDCONNECT_H_
+#define _KCHILDCONNECT_H_
+
+#include <qobject.h>
+#include <qstrlist.h>
+#include "KEMessage.h"
+
+
+class KChildConnect: public QObject
+{
+ Q_OBJECT
+
+ protected:
+ QStrList inputcache;
+ bool input_pending;
+ QString inputbuffer;
+ int ID;
+
+ public:
+ KChildConnect();
+ ~KChildConnect();
+ void Receive(QString input);
+ int QueryID();
+ void SetID(int id);
+
+ virtual bool SendMsg(KEMessage *msg);
+ virtual bool Send(QString str);
+ virtual KR_STATUS QueryStatus();
+
+ public slots:
+
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+#endif
diff --git a/lskat/lskatproc/KConnectTypes.h b/lskat/lskatproc/KConnectTypes.h
new file mode 100644
index 00000000..12e9561a
--- /dev/null
+++ b/lskat/lskatproc/KConnectTypes.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ KConnectTypes.h - description
+ -------------------
+ begin : Sun Apr 9 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. *
+ * *
+ ***************************************************************************/
+#ifndef _KCONNECTTYPES_H_
+#define _KCONNECTTYPES_H_
+
+enum KGM_TYPE {KGM_TYPE_INVALID=0,KGM_TYPE_SHORT=1,KGM_TYPE_LONG=2,
+ KGM_TYPE_FLOAT=3,KGM_TYPE_DATA=4};
+
+enum KG_INPUTTYPE {
+ KG_INPUTTYPE_INVALID=0,
+ KG_INPUTTYPE_INTERACTIVE=1,
+ KG_INPUTTYPE_PROCESS=2,
+ KG_INPUTTYPE_REMOTE=3};
+
+enum KR_STATUS {
+ KR_NO_SOCKET=-2,
+ KR_WAIT_FOR_CLIENT=-1,
+ KR_INVALID=0,
+ // >0 OK
+ KR_OK=1,
+ KR_CLIENT=2,
+ KR_SERVER=3
+ };
+#endif
diff --git a/lskat/lskatproc/KEMessage.cpp b/lskat/lskatproc/KEMessage.cpp
new file mode 100644
index 00000000..db598573
--- /dev/null
+++ b/lskat/lskatproc/KEMessage.cpp
@@ -0,0 +1,326 @@
+/***************************************************************************
+ KEMessage.cpp - description
+ -------------------
+ begin : Tue May 2 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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "KEMessage.h"
+
+void KEMessage::AddEntry(QString key,KMessageEntry *entry)
+{
+ // printf(" AddingEntry: %s with data field %p\n",(char *)key,entry->QueryData());
+ if (!entry) return ;
+ dict.insert(key,entry);
+ keys.append(key.latin1());
+}
+
+void KEMessage::AddDataType(QString key,int size,const char *data,KGM_TYPE type)
+{
+// printf("AddDataType for %s size=%d\n",(const char *)key,size);
+ if (size<=0) return ;
+ KMessageEntry *entry=new KMessageEntry;
+ entry->SetType(type);
+ entry->CopyData(size,data);
+ AddEntry(key,entry);
+}
+
+void KEMessage::AddData(QString key,short data)
+{
+ AddDataType(key,sizeof(short),(char *)&data,KGM_TYPE_SHORT);
+}
+
+void KEMessage::AddData(QString key,long data)
+{
+ AddDataType(key,sizeof(long),(char *)&data,KGM_TYPE_LONG);
+}
+
+void KEMessage::AddData(QString key,float data)
+{
+ AddDataType(key,sizeof(float),(char *)&data,KGM_TYPE_FLOAT);
+}
+
+void KEMessage::AddData(QString key,const char *data,int size)
+{
+ if (size<0) size=strlen(data)+1; // +1 for 0 Byte
+ AddDataType(key,size,data,KGM_TYPE_DATA);
+}
+
+KGM_TYPE KEMessage::QueryType(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return (KGM_TYPE)0;
+ return entry->QueryType();
+}
+
+bool KEMessage::HasKey(QString key)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,short &s)
+{
+ short *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_SHORT) return false;
+ // printf("GetShortData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(short *)entry->QueryData();
+ s=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,long &l)
+{
+ long *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_LONG) return false;
+ result=(long *)entry->QueryData();
+ l=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,float &f)
+{
+ float *result;
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_FLOAT) return false;
+ // printf("GetFloatData: %p for %s\n",entry->QueryData(),(char *)key);
+ result=(float *)entry->QueryData();
+ f=*result;
+ return true;
+}
+
+bool KEMessage::GetData(QString key,char * &c,int &size)
+{
+ KMessageEntry *entry;
+ entry=dict.find(key);
+ if (!entry) return false;
+ if (entry->QueryType()!=KGM_TYPE_DATA) return false;
+ c=entry->QueryData();
+ size=entry->QuerySize();
+ return true;
+}
+
+QString KEMessage::EntryToString(char *key,KMessageEntry *entry)
+{
+ QString s,tmp;
+ int size,i;
+ KGM_TYPE type;
+ char *data;
+ s=QCString("");
+ if (!entry) return s;
+ size=entry->QuerySize();
+ type=entry->QueryType();
+ data=entry->QueryData();
+
+ // Key
+ /*
+ tmp.sprintf("%s%s%d%s%d%s",
+ key,KEMESSAGE_SEP,
+ size,KEMESSAGE_SEP,
+ (int)type,KEMESSAGE_SEP);
+ */
+ tmp=QCString(key);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",size);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+ tmp.sprintf("%d",(int)type);
+ s+=tmp;
+ s+=KEMESSAGE_SEP;
+
+
+ // We ignore the type of data and process them all as
+ // byte sequence
+ for (i=0;i<size;i++)
+ {
+ // Convert to 4 bit value ... someone can improves
+ tmp.sprintf("%c%c",
+ 'a'+(data[i]&15),
+ 'a'+((data[i]>>4)&15));
+ s+=tmp;
+ }
+ s+=KEMESSAGE_CR;
+
+ return s;
+}
+
+QString KEMessage::StringToEntry(QString str,KMessageEntry *entry)
+{
+ int pos,oldpos,cnt,len;
+ QString key,size,type,data;
+ const char *p;
+ char *q;
+ char c;
+
+ len=KEMESSAGE_SEP.length();
+
+ if (!entry) return QString();
+ pos=str.find(KEMESSAGE_SEP,0);
+ if (pos<0) return QString(); // wrong format
+ key=str.left(pos);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ size=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_SEP,oldpos+len);
+ if (pos<0) return QString(); // wrong format
+ type=str.mid(oldpos+len,pos-oldpos-len);
+
+
+ data=str.right(str.length()-pos-len);
+
+
+ cnt=size.toInt();
+ entry->SetType((KGM_TYPE)type.toInt());
+
+ // I hope this works with unicode strings as well
+ p=data.latin1();
+ q=(char *)calloc(data.length()/2,sizeof(char));
+ if (!q) return QString();
+ for(pos=0;pos<cnt;pos++)
+ {
+ if (pos*2+1>(int)data.length()) return QString(); // SEVERE ERROR
+ c=*(p+2*pos)-'a' | ((*(p+2*pos+1)-'a')<<4);
+ q[pos]=c;
+ }
+ entry->CopyData(cnt,q);
+
+ free(q);
+ return key;
+}
+
+QString KEMessage::ToString()
+{
+ QString s;
+ KMessageEntry *entry;
+ char *it;
+ s=KEMESSAGE_HEAD+KEMESSAGE_CR;
+ for (it=keys.first();it!=0;it=keys.next())
+ {
+ entry=dict.find(QCString(it));
+ s+=EntryToString(it,entry);
+ }
+ s+=KEMESSAGE_TAIL+KEMESSAGE_CR;
+ return s;
+}
+
+bool KEMessage::AddString(QString s)
+{
+ // break s into key,size and data
+ QString key;
+ KMessageEntry *entry=new KMessageEntry;
+ key=StringToEntry(s,entry);
+ if (!key) return false;
+ AddEntry(key,entry);
+ return true;
+}
+bool KEMessage::AddStringMsg(QString str)
+{
+ bool result;
+ QString data;
+ int pos,oldpos,len;
+
+ len=KEMESSAGE_CR.length();
+
+ pos=str.find(KEMESSAGE_CR);
+ if (pos<0) return false; // wrong format
+ if (str.left(pos)!=(KEMESSAGE_HEAD)) return false; // wrong message
+
+ do
+ {
+ oldpos=pos;
+ pos=str.find(KEMESSAGE_CR,oldpos+len);
+ if (pos<0) return false; // wrong format
+ data=str.mid(oldpos+len,pos-oldpos-len);
+ if (data!=(KEMESSAGE_TAIL))
+ {
+ result=AddString(data);
+ if (!result) return false; // wrong format
+ }
+ }while(data!=(KEMESSAGE_TAIL));
+
+ return result;
+}
+
+void KEMessage::RemoveAll()
+{
+ keys.clear();
+ dict.clear();
+}
+
+void KEMessage::Remove(QString key)
+{
+ keys.remove(key.latin1());
+ dict.remove(key);
+}
+
+uint KEMessage::QueryNumberOfKeys()
+{
+ return keys.count();
+}
+QStrList *KEMessage::QueryKeys()
+{
+ return &keys;
+}
+
+KEMessage::~KEMessage()
+{
+ // printf("Deleteing KEMessage %p\n",this);
+}
+KEMessage::KEMessage()
+{
+ // printf("KEMessage construct %p\n",this);
+ dict.setAutoDelete(true);
+}
+KEMessage::KEMessage(KEMessage &msg)
+{
+ // printf("KEMessage copy constructor from %p to %p\n",&msg,this);
+ *this=msg;
+}
+KEMessage &KEMessage::operator=(KEMessage &msg)
+{
+ // KEMessage *newmsg=new KEMessage;
+ KMessageEntry *entry;
+ KMessageEntry *newentry;
+ char *it;
+ // printf("Assigning = KEMessage from %p to %p\n",&msg,this);
+ for (it=msg.keys.first();it!=0;it=msg.keys.next())
+ {
+ entry=msg.dict.find(QCString(it));
+ newentry=new KMessageEntry;
+ *newentry=*entry;
+ AddEntry(QCString(it),newentry);
+
+ }
+ // return *newmsg;
+ return *this;
+}
diff --git a/lskat/lskatproc/KEMessage.h b/lskat/lskatproc/KEMessage.h
new file mode 100644
index 00000000..0a1913cc
--- /dev/null
+++ b/lskat/lskatproc/KEMessage.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ KEMessage.h - description
+ -------------------
+ begin : Tue May 2 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. *
+ * *
+ ***************************************************************************/
+#ifndef _KEMESSAGE_H_
+#define _KEMESSAGE_H_
+
+#include <string.h>
+#include <qstring.h>
+#include <qstrlist.h>
+#include <qdict.h>
+#include "KMessageEntry.h"
+
+#define KEMESSAGE_HEAD QString(QCString("BEGIN_V1000"))
+#define KEMESSAGE_TAIL QString(QCString("END_V1000"))
+#define KEMESSAGE_CR QString(QCString("\n"))
+#define KEMESSAGE_SEP QString(QCString(":::"))
+
+class KEMessage
+{
+ private:
+ QStrList keys;
+ QDict<KMessageEntry> dict;
+
+ protected:
+ void AddEntry(QString key,KMessageEntry *entry);
+ public:
+ QStrList *QueryKeys();
+ uint QueryNumberOfKeys();
+ void AddDataType(QString key,int size,const char *data,KGM_TYPE type);
+ void AddData(QString key,short data);
+ void AddData(QString key,long data);
+ void AddData(QString key,float data);
+ void AddData(QString key,const char *data,int size=-1);
+ bool GetData(QString key,short &s);
+ bool GetData(QString key,long &l);
+ bool GetData(QString key,float &f);
+ bool GetData(QString key,char * &c,int &size);
+ bool HasKey(QString key);
+ void Remove(QString key);
+ KGM_TYPE QueryType(QString key);
+ QString ToString();
+ QString EntryToString(char *key,KMessageEntry *entry);
+ QString StringToEntry(QString str,KMessageEntry *entry);
+ bool AddString(QString s);
+ bool AddStringMsg(QString str);
+ void RemoveAll();
+ ~KEMessage();
+ KEMessage();
+ KEMessage(KEMessage &msg);
+ KEMessage &operator=(KEMessage &msg);
+};
+
+#endif
diff --git a/lskat/lskatproc/KInputChildProcess.cpp b/lskat/lskatproc/KInputChildProcess.cpp
new file mode 100644
index 00000000..a821aa7a
--- /dev/null
+++ b/lskat/lskatproc/KInputChildProcess.cpp
@@ -0,0 +1,106 @@
+/***************************************************************************
+ KInputChildProcess.cpp - description
+ -------------------
+ begin : Tue May 2 2000
+ copyright : (C) 2000 by Martin Heni
+ email : martin@heni-online.de
+ ***************************************************************************/
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <qstring.h>
+
+#include "KInputChildProcess.h"
+#include "KInputChildProcess.moc"
+
+
+KInputChildProcess::~KInputChildProcess()
+{
+ delete buffer;
+ delete childConnect;
+}
+KInputChildProcess::KInputChildProcess(int size_buffer)
+ : QObject(0,0)
+{
+ buffersize=size_buffer;
+ if (buffersize<1) buffersize=1024;
+ buffer=new char[buffersize];
+ inputbuffer="";
+ terminateChild=false;
+}
+bool KInputChildProcess::exec()
+{
+ int pos;
+ QString s;
+
+ childConnect=new KChildConnect;
+ if (!childConnect) return false;
+ connect(childConnect,SIGNAL(signalReceiveMsg(KEMessage *,int)),
+ this,SLOT(slotReceiveMsg(KEMessage *,int)));
+ do
+ {
+ // Wait for input
+ if (feof(stdin))
+ {
+ sleep(1);
+ continue;
+ }
+
+ if (!fgets(buffer,buffersize,stdin) )
+ {
+ continue;
+ }
+ s=buffer;
+ s=inputbuffer+s;
+ // printf("ChildABC '%s'\n",(const char *)s);
+ // fflush(stdout);
+ pos=s.findRev(KEMESSAGE_CR);
+ if (pos<0)
+ {
+ inputbuffer=s;
+ }
+ else if (pos+KEMESSAGE_CR.length()==s.length())
+ {
+ // CR at the end...calling receive
+ childConnect->Receive(s);
+ }
+ else
+ {
+ inputbuffer=s.right(s.length()-pos-KEMESSAGE_CR.length());
+ s=s.left(pos+KEMESSAGE_CR.length());
+ // printf("s='%s' in='%s'\n",(const char *)s,(const char *)inputbuffer);
+ childConnect->Receive(s);
+ }
+ }while(!terminateChild);
+ return true;
+}
+
+void KInputChildProcess::Terminate()
+{
+ terminateChild=true;
+}
+bool KInputChildProcess::IsTerminated()
+{
+ return terminateChild;
+}
+
+bool KInputChildProcess::ReceiveMsg(KEMessage *msg,int id)
+{
+ return false;
+}
+void KInputChildProcess::slotReceiveMsg(KEMessage *msg,int id)
+{
+ if (!ReceiveMsg(msg,id)) // made for virtual override
+ {
+ // otherwise emit signal
+ emit signalReceiveMsg(msg,id);
+ }
+}
+bool KInputChildProcess::SendMsg(KEMessage *msg)
+{
+ if (childConnect) return childConnect->SendMsg(msg);
+ return false;
+}
+
+
diff --git a/lskat/lskatproc/KInputChildProcess.h b/lskat/lskatproc/KInputChildProcess.h
new file mode 100644
index 00000000..b4694df5
--- /dev/null
+++ b/lskat/lskatproc/KInputChildProcess.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ KInputChildProcess.h - description
+ -------------------
+ begin : Tue May 2 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. *
+ * *
+ ***************************************************************************/
+#ifndef _KINPUTCHILDPROCESS_H_
+#define _KINPUTCHILDPROCESS_H_
+
+#include <qobject.h>
+#include "KEMessage.h"
+#include "KChildConnect.h"
+
+
+class KInputChildProcess : public QObject
+{
+ Q_OBJECT
+
+ private:
+ char *buffer;
+ QString inputbuffer;
+ int buffersize;
+ bool terminateChild;
+ protected:
+ KChildConnect *childConnect;
+
+ public:
+ KInputChildProcess(int size_buffer=4096);
+ ~KInputChildProcess();
+ bool exec();
+ virtual bool ReceiveMsg(KEMessage *msg,int id);
+ // Forward calls to childconnect
+ bool SendMsg(KEMessage *msg);
+ // Immediately kills child's exec !
+ void Terminate();
+ bool IsTerminated();
+
+
+ public slots:
+ void slotReceiveMsg(KEMessage *msg,int id);
+
+ signals:
+ void signalReceiveMsg(KEMessage *msg,int id);
+};
+
+
+#endif
diff --git a/lskat/lskatproc/KMessageEntry.cpp b/lskat/lskatproc/KMessageEntry.cpp
new file mode 100644
index 00000000..e91f645a
--- /dev/null
+++ b/lskat/lskatproc/KMessageEntry.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ KMessageEntry.cpp - description
+ -------------------
+ begin : Tue May 2 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. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ FILENAME| - description
+ -------------------
+ begin : Tue Apr 4 2000
+ copyright : (C) |1995-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 <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "KMessageEntry.h"
+
+
+void KMessageEntry::SetType(KGM_TYPE t)
+{
+ type=t;
+}
+
+KGM_TYPE KMessageEntry::QueryType()
+{
+ return type;
+}
+
+int KMessageEntry::QuerySize()
+{
+ return size;
+}
+
+char * KMessageEntry::QueryData()
+{
+ return data;
+}
+
+bool KMessageEntry::CopyData(int s,const char *c)
+{
+ if (s<1) return false;
+ data=(char *)calloc(s,1);
+ if (!data) return false;
+ // printf(" MessageEntry Copy Data to calloc %p\n",data);
+ memcpy(data,c,s);
+ size=s;
+ return true;
+}
+
+KMessageEntry::KMessageEntry()
+{
+ // printf("KMessageEntry construct %p\n",this);
+ size=0;
+ type=(KGM_TYPE)0;
+ data=(char *)0;
+}
+
+KMessageEntry::KMessageEntry(KMessageEntry &entry)
+{
+ // printf("KMessageEntry copy constructor from %p to %p\n",&entry,this);
+ *this=entry;
+}
+KMessageEntry &KMessageEntry::operator=(KMessageEntry &entry)
+{
+ // printf("KMessageEntry operator= from %p to %p\n",&entry,this);
+ SetType(entry.type);
+ CopyData(entry.size,entry.data);
+ return *this;
+}
+
+KMessageEntry::~KMessageEntry()
+{
+ // printf("MessageEntry destructor %p\n",this);
+ // printf(" MessageEntry free %p\n",data);
+ if (data) free(data);
+ data=(char *)0;
+}
+
diff --git a/lskat/lskatproc/KMessageEntry.h b/lskat/lskatproc/KMessageEntry.h
new file mode 100644
index 00000000..947ce1ff
--- /dev/null
+++ b/lskat/lskatproc/KMessageEntry.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ KMessageEntry.h - description
+ -------------------
+ begin : Tue May 2 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. *
+ * *
+ ***************************************************************************/
+#ifndef _KMESSAGEENTRY_H_
+#define _KMESSAGEENTRY_H_
+
+#include <string.h>
+#include "KConnectTypes.h"
+
+
+
+class KMessageEntry
+{
+ private:
+ int size;
+ KGM_TYPE type;
+ char *data;
+
+ public:
+ void SetType(KGM_TYPE t);
+ KGM_TYPE QueryType();
+ int QuerySize();
+ char *QueryData();
+ bool CopyData(int s,const char *c);
+ KMessageEntry();
+ KMessageEntry(KMessageEntry &entry);
+ KMessageEntry &operator=(KMessageEntry &entry);
+ ~KMessageEntry();
+};
+
+#endif
diff --git a/lskat/lskatproc/Makefile.am b/lskat/lskatproc/Makefile.am
new file mode 100644
index 00000000..4f99375b
--- /dev/null
+++ b/lskat/lskatproc/Makefile.am
@@ -0,0 +1,13 @@
+bin_PROGRAMS = lskatproc
+
+lskatproc_SOURCES = lskatproc.cpp KChildConnect.cpp KInputChildProcess.cpp KEMessage.cpp KMessageEntry.cpp main.cpp
+
+lskatproc_LDADD = $(LIB_KFILE)
+
+# set the include path for X, qt and KDE
+INCLUDES= $(all_includes)
+
+METASOURCES = AUTO
+
+# the library search path.
+lskatproc_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/lskat/lskatproc/docs/Makefile.am b/lskat/lskatproc/docs/Makefile.am
new file mode 100644
index 00000000..271bd418
--- /dev/null
+++ b/lskat/lskatproc/docs/Makefile.am
@@ -0,0 +1,4 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/lskat/lskatproc/docs/en/Makefile.am b/lskat/lskatproc/docs/en/Makefile.am
new file mode 100644
index 00000000..271bd418
--- /dev/null
+++ b/lskat/lskatproc/docs/en/Makefile.am
@@ -0,0 +1,4 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+
+####### kdevelop will overwrite this part!!! (end)############
diff --git a/lskat/lskatproc/lskatproc.cpp b/lskat/lskatproc/lskatproc.cpp
new file mode 100644
index 00000000..c1fdcfba
--- /dev/null
+++ b/lskat/lskatproc/lskatproc.cpp
@@ -0,0 +1,596 @@
+/***************************************************************************
+ lskatproc.cpp - description
+ -------------------
+ begin : Sun Apr 9 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 <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "lskatproc.h"
+
+#define MIN_TIME 1000 // usec
+
+// ------------ class game ---------------------------------
+lgame::lgame()
+{
+ int i;
+ 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;
+ curmove[0]=-1;
+ curmove[1]=-1;
+ score[0]=0;
+ score[1]=0;
+ level=0;
+ endgame=false;
+ for (i=0;i<NO_OF_CARDS;i++) played[i]=0;
+}
+
+lgame::lgame(lgame &game)
+{
+ *this=game;
+}
+
+lgame &lgame::operator=(lgame &game)
+{
+ int i;
+ currentplayer=game.currentplayer;
+ startplayer=game.startplayer;
+ trump=game.trump;
+ movenumber=game.movenumber;
+ score[0]=game.score[0];
+ score[1]=game.score[1];
+ curmove[0]=game.curmove[0];
+ curmove[1]=game.curmove[1];
+ for (i=0;i<NO_OF_CARDS;i++) played[i]=game.played[i];
+ for (i=0;i<NO_OF_CARDS;i++) card[i]=game.card[i];
+ for (i=0;i<16;i++) cardheight[i]=game.cardheight[i];
+ endgame=game.endgame;
+ level=game.level;
+ return *this;
+}
+
+int lgame::MakeMove(int c,int pos)
+{
+ int h;
+ curmove[currentplayer]=c;
+ h=GetHeight(currentplayer,pos);
+ if (currentplayer==startplayer)
+ {
+ movenumber++;
+ SetHeight(currentplayer,pos,h-1);
+ currentplayer=1-startplayer;
+ }
+ else
+ {
+ if (!LegalMove(curmove[startplayer],c)) return -1;
+ SetHeight(currentplayer,pos,h-1);
+ if (WonMove(curmove[startplayer],curmove[1-startplayer]))
+ {
+ // switch startplayer
+ startplayer=1-startplayer;
+ }
+ currentplayer=startplayer;
+ score[startplayer]+=CardValue(curmove[0]);
+ score[startplayer]+=CardValue(curmove[1]);
+
+ if (movenumber==NO_OF_TILES)
+ {
+ endgame=true;
+ return 2;
+ }
+ }
+ return 1;
+}
+
+void lgame::Init()
+{
+ int player,i,h,j,card;
+ // check what cards are played
+ for (player=0;player<2;player++)
+ {
+ for (i=0;i<8;i++)
+ {
+ h=GetHeight(player,i);
+ for (j=h;j<2;j++)
+ {
+ card=GetCard(player,i,j+1);
+ if (card>=0) played[card]=1;
+ }
+ }
+ }
+}
+
+// Add value of both cards to the score of startplayer
+void lgame::AddScore(int c1,int c2)
+{
+ score[startplayer]+=CardValue(c1);
+ score[startplayer]+=CardValue(c2);
+}
+// Switch the startplayer
+void lgame::SwitchStartplayer()
+{
+ startplayer=1-startplayer;
+}
+
+// pos=0..7, player=0..1
+void lgame::SetHeight(int player, int pos,int h)
+{
+ int i;
+ i=8*player+pos;
+ cardheight[i]=h;
+}
+bool lgame::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 lgame::CardValue(int card)
+{
+ int card1;
+
+ card1=card/4;
+ return cardvalues[card1];
+}
+int lgame::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;
+
+}
+// pos=0..7, height=2..1..(0 no card left), player=0..1
+int lgame::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 lgame::GetHeight(int player, int pos)
+{
+ int i;
+ i=8*player+pos;
+ return cardheight[i];
+}
+
+// Returns a value for the given side
+// applies all rules
+int lgame::Subvalue(int side)
+{
+ int sc,card;
+ int i,h,c;
+ CCOLOUR col1;
+ CCARD card1;
+ int trum1;
+ int jack1;
+ int havecol[4];
+ bool haveten[4];
+ bool haveace[4];
+ bool havejack[4];
+
+ sc=0;
+ trum1=0;
+ for (i=0;i<4;i++)
+ {
+ havecol[i]=false;
+ haveten[i]=false;
+ haveace[i]=false;
+ havejack[i]=false;
+ }
+ jack1=0;
+ for (i=0;i<8;i++)
+ {
+ h=GetHeight(side,i);
+ c=GetCard(side,i,h);
+ if (c<0) continue;
+
+ card1=(CCARD)((c)/4);
+ col1=(CCOLOUR)((c)%4);
+
+ if (col1==trump) trum1++;
+ havecol[(int)col1]++;
+ if (card1==Ten)
+ {
+ haveten[(int)col1]=true;
+ }
+ else if (card1==Ace)
+ {
+ haveace[(int)col1]=true;
+ }
+ else if (card1==Jack)
+ {
+ havejack[(int)col1]=true;
+ jack1++;
+ }
+ if (col1!=trump)
+ {
+ if (card1==Seven) sc-=60;
+ if (card1==Eight) sc-=50;
+ if (card1==Nine) sc-=40;
+ if (card1==Queen) sc-=10;
+ }
+ }
+ for (i=0;i<4;i++)
+ {
+ if (havecol[i]==0 && i!=trump) sc+=1000;
+ if (havecol[i]>5) sc+=800;
+
+ if (haveten[i]&&havecol[i]<2)
+ {
+ card=8*i+Ace;
+ if (!played[card] && !haveace[i]) sc-=2500; // free ten
+ }
+ if (haveace[i]) sc+=1500; // ace
+ if (havejack[i])
+ {
+ if (trump==Grand) sc+=4000+300*(4-i);
+ else sc+=2700+100*(4-i);
+ }
+ }
+ // evaluate
+ sc+=trum1*2500;
+ if (trum1==0) sc-=7000;
+ else if (trum1==1) sc-=5000;
+ return sc;
+}
+
+int lgame::Value(int player)
+{
+ int sc;
+ sc=0;
+
+ // Someone won?
+ if (score[0]>90) sc+=90000;
+ else if (score[0]>60) sc+=70000;
+ else if (score[0]==60) sc+=40000;
+
+ if (score[1]>90) sc-=90000;
+ else if (score[1]>60) sc-=70000;
+ else if (score[1]==60) sc-=40000;
+
+ // Reward points
+ sc+=(score[0]-score[1])*650;
+
+ // Calulate cards
+ sc+=Subvalue(0);
+ sc-=Subvalue(1);
+
+ // random
+ sc+=random(500)-250;
+
+ if (player==1) return -sc;
+ return sc;
+}
+
+
+// -------------class lskatproc ----------------------------
+lskatproc::lskatproc()
+ : KInputChildProcess(4096)
+{
+
+ initrandom();
+}
+
+lskatproc::~lskatproc(){
+}
+
+
+
+bool lskatproc::ReceiveMsg(KEMessage* msg,int id)
+{
+// time_t timee,timea;
+short x,y;
+
+ SendDebug("Receiv Msg");
+ // end of process
+ if (msg->HasKey(QCString("Terminate")))
+ {
+ Terminate();
+ }
+ // Init of process
+ if (msg->HasKey(QCString("Init")))
+ {
+ // No init necessary
+ }
+ // Make a move
+ if (msg->HasKey(QCString("Cards")))
+ {
+ SendDebug("Process HasKey(Cards)");
+ // new game object
+ lgame game;
+ // extract data from message
+ game.ExtractGame(msg);
+ game.Init(); // must be AFTER ExtractGame
+
+ // Debug stuff only
+ sprintf(buf,"Trump=%d move=%d sc1=%d sc2=%d",
+ game.trump,game.curmove[1-game.currentplayer],game.score[0],game.score[1]);
+ SendDebug(buf);
+
+ if (game.currentplayer==0 && game.startplayer==0)
+ sprintf(buf,"+++ Computer ACTS as player ONE\n");
+ else if (game.currentplayer==0 && game.startplayer==1)
+ sprintf(buf,"+++ Computer REACTS as player ONE\n");
+ else if (game.currentplayer==1 && game.startplayer==1)
+ sprintf(buf,"+++ Computer ACTS as player TWO\n");
+ else
+ sprintf(buf,"+++ Computer REACTS as player TWO\n");
+ SendDebug(buf);
+
+ // fills data
+ x=0;y=0;
+ GetComputerMove(game,x,y,0);
+ sprintf(buf,"Computer move player=%d x=%d y=%d",game.currentplayer,x,y);
+ SendDebug(buf);
+
+
+ // report move
+ msg->RemoveAll();
+ msg->AddData(QCString("Move"),game.currentplayer);
+ msg->AddData(QCString("MoveX"),x);
+ msg->AddData(QCString("MoveY"),y);
+
+ //timee=time(0);
+ // Sleep a minimum amount to slow down moves
+ //if ( 1000*(timee-timea) < MIN_TIME) usleep((MIN_TIME-1000*(timee-timea)));
+ SendDebug("Sending move back to main");
+
+ if (!IsTerminated()) SendMsg(msg);
+ fflush(stdout); // I do not know why it is needed..send does it too?
+ }
+
+ return true;
+}
+
+
+/* --------------------------------------------------------------------------- */
+/* Computer Routinen */
+/* --------------------------------------------------------------------------- */
+
+// extract game from msg
+int lgame::ExtractGame(KEMessage *msg)
+{
+ int i;
+ short tmp;
+ char *p;
+ int size;
+
+ msg->GetData(QCString("Startplayer"),startplayer);
+ msg->GetData(QCString("CurrentPlayer"),currentplayer);
+ msg->GetData(QCString("Cards"),p,size);
+ msg->GetData(QCString("Level"),level);
+ level--; // start with level 0
+ for (i=0;i<NO_OF_CARDS;i++)
+ {
+ card[i]=((int *)p)[i];
+ }
+ msg->GetData(QCString("Height"),p,size);
+ for (i=0;i<NO_OF_TILES;i++)
+ {
+ cardheight[i]=((int *)p)[i];
+ }
+ msg->GetData(QCString("Trump"),tmp);
+ trump=(CCOLOUR)tmp;
+ short mm;
+ msg->GetData(QCString("CurrentMove"),mm);
+ curmove[1-currentplayer]=(int)mm;
+ curmove[currentplayer]=-1;
+ msg->GetData(QCString("No"),movenumber);
+ msg->GetData(QCString("Sc1"),score[0]);
+ msg->GetData(QCString("Sc2"),score[1]);
+ return 1;
+}
+
+long lgame::random(long max)
+{
+double value;
+int r;
+ r=rand();
+ value=(double)((double)r*(double)max)/(double)RAND_MAX;
+ return (long)value;
+}
+
+void lskatproc::initrandom()
+{
+ srand( (unsigned)time( NULL ) ); // randomize
+}
+
+
+int lskatproc::GetComputerMove(lgame game,short &x,short &y,int rek)
+{
+ int i,maxvalue,maxmove,h,c;
+ //short oldscore;
+ bool startflag;
+ int startplayer;
+ int value;
+ lgame cgame;
+ char sbuf[100];
+ short mx,my;
+
+
+ for (i=0;i<2*rek;i++) sbuf[i]=' ';
+ sbuf[2*rek]=0;
+
+ x=0;
+ y=0;
+ if (game.currentplayer==game.startplayer) startflag=true;
+ else startflag=false;
+
+ startplayer=game.startplayer;
+
+ maxmove=0;
+ maxvalue=LOWERT;
+
+ sprintf(buf,"%s:Prepareing computer move (cur=%d) startflag=%d",
+ sbuf,game.currentplayer,startflag);
+ //SendDebug(buf);
+ for (i=0;i<8;i++)
+ {
+ sprintf(buf,"%s:Checking for card %d of player %d\n",sbuf,i,game.currentplayer);
+ // SendDebug(buf);
+ cgame=game;
+ h=cgame.GetHeight(cgame.currentplayer,i);
+ if (h<1)
+ {
+ sprintf(buf,"%s:i=%d:: no cards left",sbuf,i);
+ // SendDebug(buf);
+ continue; // no cards left
+ }
+ c=cgame.GetCard(cgame.currentplayer,i,h);
+ if (cgame.MakeMove(c,i)<0)
+ {
+ sprintf(buf,"%s:i=%d:: no legal move c1=%d c2=%d",
+ sbuf,i,cgame.curmove[cgame.startplayer],c);
+ // SendDebug(buf);
+ continue; // wrong card
+ }
+ if (!startflag) // we are second
+ {
+ sprintf(buf,"LEVEL %d %d",cgame.level,rek);
+ SendDebug(buf);
+ // Still recursion necessary and game not yet ended?
+ if (rek<2*cgame.level && !cgame.endgame)
+ {
+ // If we have the same startplayer the movesequence
+ // is not switched and we can take the negative value
+ // otherwise we play again, and have to take the poitiv value
+ if (cgame.startplayer==startplayer)
+ {
+ value=-GetComputerMove(cgame,mx,my,rek+1);
+ // if (value==-LOWERT) value=LOWERT; // no move possible
+ }
+ else
+ value=GetComputerMove(cgame,mx,my,rek+1);
+ }
+ else // evaluate position
+ {
+ value=cgame.Value(1-startplayer);
+ }
+ }
+ else // we are first player
+ {
+ // Alwayss the other player moves now
+ value=-GetComputerMove(cgame,mx,my,rek+1);
+ }
+
+ sprintf(buf,"%s:i=%d:: Value=%d",sbuf,i,value);
+ SendDebug(buf);
+
+ if (value>maxvalue)
+ {
+ maxvalue=value;
+ maxmove=i;
+ }
+ }
+ x=maxmove%4;
+ y=maxmove/4;
+ return maxvalue;
+}
+
+void lskatproc::SendDebug(const char *s)
+{
+ KEMessage *msg=new KEMessage;
+ msg->AddData(QCString("Debug"),s);
+// msg->AddData("KLogSendMsg","debug.log");
+// DEBUG
+// SendMsg(msg);
+// printf("%s\n",s);
+
+ delete msg;
+}
diff --git a/lskat/lskatproc/lskatproc.h b/lskat/lskatproc/lskatproc.h
new file mode 100644
index 00000000..b5840461
--- /dev/null
+++ b/lskat/lskatproc/lskatproc.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ lskatproc.h - description
+ -------------------
+ begin : Sun Apr 9 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef LSKATPROC_H
+#define LSKATPROC_H
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+#include "KInputChildProcess.h"
+
+/**
+ *@author Martin Heni
+ */
+
+
+
+#define LOWERT -999999999L
+#define SIEG_WERT 9999999L
+
+
+#define START_REK 1 // (0) 1:Nur Stellungsbewertung bei Level 1
+ // 0:Level 1 schon eine Rekursion
+
+typedef enum {Club=0,Spade=1,Heart=2,Diamond=3,Grand=4} CCOLOUR;
+typedef enum {Ace=0,King=1,Queen=2,Jack=3,Ten=4,Nine=5,Eight=6,Seven=7} CCARD;
+#define NO_OF_CARDS 32
+#define NO_OF_TILES 16
+#define NO_OF_TRUMPS 5
+
+class lgame
+{
+ public:
+ lgame();
+ lgame(lgame &game);
+ lgame &operator=(lgame &game);
+
+ int WonMove(int c1,int c2);
+ int CardValue(int card);
+ bool LegalMove(int p1, int p2);
+ void SetHeight(int player, int pos,int h);
+ int GetHeight(int player, int pos);
+ int GetCard(int player, int pos,int height);
+ int Value(int player);
+ void AddScore(int c1,int c2);
+ void SwitchStartplayer();
+ int MakeMove(int c,int pos);
+ void Init();
+ long random(long max);
+ int Subvalue(int side);
+ int ExtractGame(KEMessage *msg);
+
+ short currentplayer;
+ short startplayer;
+ int card[NO_OF_CARDS];
+ int cardheight[16];
+ int cardvalues[14];
+ short score[2];
+ CCOLOUR trump;
+ short movenumber;
+ int curmove[2];
+ bool endgame;
+ int played[NO_OF_CARDS]; // cards already played
+ short level;
+};
+
+
+class lskatproc : public KInputChildProcess
+{
+
+private:
+
+public:
+ lskatproc();
+ ~lskatproc();
+
+ virtual bool ReceiveMsg(KEMessage *msg,int id);
+
+
+ void initrandom();
+ int GetComputerMove(lgame game,short &x,short &y,int rek);
+ void SendDebug(const char *s);
+
+ private:
+ char buf[1024];
+};
+
+#endif
diff --git a/lskat/lskatproc/main.cpp b/lskat/lskatproc/main.cpp
new file mode 100644
index 00000000..d25cd8c9
--- /dev/null
+++ b/lskat/lskatproc/main.cpp
@@ -0,0 +1,28 @@
+/***************************************************************************
+ main.cpp - description
+ -------------------
+ begin : Sun Apr 9 22:56:15 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 <stdio.h>
+#include "lskatproc.h"
+
+
+
+
+int main(int argc, char *argv[])
+{
+ lskatproc mComm;
+ return mComm.exec() ? 0 : 1;
+}
diff --git a/lskat/lskatproc/templates/cpp_template b/lskat/lskatproc/templates/cpp_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskatproc/templates/cpp_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
diff --git a/lskat/lskatproc/templates/header_template b/lskat/lskatproc/templates/header_template
new file mode 100644
index 00000000..6afef5d4
--- /dev/null
+++ b/lskat/lskatproc/templates/header_template
@@ -0,0 +1,16 @@
+/***************************************************************************
+ |FILENAME| - description
+ -------------------
+ begin : |DATE|
+ copyright : (C) |YEAR| by |AUTHOR|
+ email : |EMAIL|
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/