diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/AUTHORS b/retroshare-gui/src/gui/plugins/qcheckers_plugin/AUTHORS new file mode 100644 index 000000000..fd88dae2a --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/AUTHORS @@ -0,0 +1,7 @@ +Andi Peredri +Artur Wiebe + +Contributors: + Sebastien Prud'homme + Guillaume Bedot french translations + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/ChangeLog b/retroshare-gui/src/gui/plugins/qcheckers_plugin/ChangeLog new file mode 100644 index 000000000..bf066f66c --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/ChangeLog @@ -0,0 +1,70 @@ +2005-12-29 Artur Wiebe + * toplevel.cc, view.h: Removed unused slots. + * Renamed info to histrory. + * history.cc: Removed useless code. + +2005-12-19 Artur Wiebe + * KCheckers 0.8 released. + * Added support for free men placement at the beginning of the game. + * Added multiple undos/redos: free movement in move history. + * Removed network code: there will be network in the next version. + * See below for more changes since 0.6. + +2005-09-09 Artur Wiebe + * KCheckers 0.7 is done - will not be released. + * Ported to Qt 4.0. So watch out for more bugs. + * Added basic Theme support. + * Improved thread termination. + * Redesigned GUI. + * echeckers.cc: Fixed bug: man reaching the king row became king and + continued move. + * Improved PDN support. Can now re-play games. + +2005-04-11 Artur Wiebe + * KCheckers 0.6 released. + * New game mode: Human vs. Human. + * Added Info widget next to game's board. + * Added different board sizes. + * Rewrote menubar and toolbar code. + * Rewrote network code. + * Fixed some bugs, introduced new. + +2004-08-08 Artur Wiebe + * KCheckers 0.5 released. + * Machine thinks in a thread now. + * Added Internationalization support. + * Added Network support. + * Altered GUI interface to match KDE specifications. + * Extended Preview in File Open Dialog. + * Various improvements. + +2003-01-15 Andi Peredri + * KCheckers 0.4 released. + * Added support for Portable Draughts Notation database format. + * Added saving, loading and restarting of game. + * Added PDN preview widget. + * Added 20 PDN compositions. + * Added game information box. + * Various improvements. + +2002-06-10 Andi Peredri + * KCheckers 0.3 released. + * Ported to Qt 3. + * Added toolbar. + * Added green theme of the board. + * Added undo of last move. + * Added auto saving of settings. + * Added optional notation of the board. + +2002-03-10 Andi Peredri + * KCheckers 0.2 released. + * Ported to pure Qt. + * KCheckers engine improvements. + * Added support of english checkers. + * Added wooden theme of the board. + * Added auto change of the men's color. + * Added on-line description of the play's rules. + +2002-01-15 Andi Peredri + * Initial Release. + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/FAQ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/FAQ new file mode 100644 index 000000000..63df0fbcd --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/FAQ @@ -0,0 +1,49 @@ +What is my IP address? +---------------------- +Run ifconfig and loop for the eth0/ppp0/ippp0 entry. The second line starts +with "inet addr". That's your IP address! + + +How to create a themes? +----------------------- +There are two places you can put your own theme directories: +$SHARE/themes or $HOME/.kcheckers/themes. $SHARE is /usr/local/kcheckers on +default. simply create a directory there that contains the following files: + tile1.png - unused tiles. + tile2.png - where men are placed. + frame.png - around selected man. + manblack.png - + manwhite.png - + kingblack.png - + kingwhite.png - + theme - the first line should be the default/english name + - of the theme. This will be used if the correct locale + - name should not be found. + - Locale specific names can be provided with the + - following syntax: [locale]=Theme Name. + - Example theme file: + - Line 1) This is a default theme name + - Line 2) [de_DE]=Das ist Deutsch + - Line 2) [en]=This is English +Directory name will be shown as theme name. All pictures are the same size. + + +My theme is not loaded. Why? +---------------------------- +Start kcheckers in a x-terminal. Watch out for errors otherwise send me your +compressed theme directory. + + +PDN. +---- +Because draught is a fast (compared to chess) game there are less situations +one will save a game. Nevertheless, this is possible in kcheckers. + +Now, imagine you want to see how a match on the last WCM was played. You simply +open the PDN file, select the game you are interested in from the list and +click move after a move and watch how the men on the board are moved. + +If you want to continue a game at certain position, no problem, click on the +"Continue" button in toolbar. But consider who is next on turn, what kind of +game (against computer or human) you are playing. + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.cpp b/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.cpp new file mode 100644 index 000000000..c63ef98d6 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.cpp @@ -0,0 +1,33 @@ +//#include +//#include +//#include + +#include "QcheckersPlugin.h" +#include "toplevel.h" + +QString +QcheckersPlugin::pluginDescription() const +{ + QString res; + res = "A QCheckers plugin" ; + + return res; +} + +QString +QcheckersPlugin::pluginName() const +{ + return "QCheckers" ; +} + +QWidget* +QcheckersPlugin::pluginWidget(QWidget * parent ) +{ + myTopLevel* top = new myTopLevel(); + + return top; + +} + + +Q_EXPORT_PLUGIN2(qcheckers_plugin, QcheckersPlugin) diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.h new file mode 100644 index 000000000..957b22c3c --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/QcheckersPlugin.h @@ -0,0 +1,27 @@ +#ifndef _HWA_PLUGIN_H_ +#define _HWA_PLUGIN_H_ + +#include + +#include +#include + +#include + +#include + +class QcheckersPlugin: public QObject, public PluginInterface +{ + Q_OBJECT + Q_INTERFACES(PluginInterface) + + public slots: + + virtual QString pluginDescription() const ; + virtual QString pluginName() const ; + + virtual QWidget* pluginWidget(QWidget * parent = 0) ; + +}; + +#endif diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/README b/retroshare-gui/src/gui/plugins/qcheckers_plugin/README new file mode 100644 index 000000000..a1f9620c1 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/README @@ -0,0 +1,83 @@ + + KCheckers is a Qt-based checkers board game. + + Requirements: Qt 3.0 + + Installation: Read INSTALLS for more information. + + Information: If you find any bugs, send a report to wibix@gmx.de. + For further information and recent versions of KCheckers, + please visit it's Homepage at + + http://kcheckers.org + http://kcheckers.wibix.de + + Usage: Read FAQ for more information. + + PDN Format: For storing the positions of games KCheckers uses the + Portable Draughts Notation (PDN) database format. It is + used by many other checkers programs, and is becoming + the standard way to swap games. + + PDN is based on the Portable Game Notation (PGN) standard + which is widely used for Chess. + + For details see http://www.chessandcheckers.com/pdn.htm + + ----------------------------------------------------------------------- + PDN File: [Event "Game 1"] + [Black "Nemet,A"] + [White "Terens,B"] + [Date "11.05.2002"] + [Result "1-0"] + [GameType "21"] + [SetUp "1"] + [FEN "W:WK4,28:BK11,19."] + + 1. 4-8 11x4 2. 28-24 19x28 {black win...} 1-0 + + ----------------------------------------------------------------------- + Results: 1-0 White wins + 0-1 Black wins + 1/2-1/2 Drawn game + * Unfinished game + + ----------------------------------------------------------------------- + Game Types: 0: Chess + 1: Chinese chess + 2-19: Future chess expansion + 20: International draughts + 21: English draughts + 22: Italian draughts + 23: American pool + 24: Spanish draughts + 25: Russian draughts + 26: Brazilian draughts + 27: Canadian draughts + 28: Portugese draughts + 29-49: Future draughts expansion + 50: Othello + + ----------------------------------------------------------------------- + FEN: If a game starts from a set-up position, a Forsyth-Edwards + Notation (FEN) header is given with the position. + + W Turn + :W White pieces + K4 King on field 4 + 28 Man on field 28 + :B Black pieces + + ----------------------------------------------------------------------- + Rules: Board BackCapture MoveKing TakeMax + International 10x10 + >1 + + English 8x8 kings 1 - + Italian 8x8 kings 1 + + American pool 8x8 + >1 - + Spanish 8x8 kings >1 + + Russian 8x8 + >1 - + Brasilian 8x8 + >1 + + Canadian 12x12 + >1 + + + ----------------------------------------------------------------------- + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.cc new file mode 100644 index 000000000..7b20f1d92 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.cc @@ -0,0 +1,364 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include + +#include "board.h" +#include "common.h" +#include "pdn.h" +#include "echeckers.h" +#include "rcheckers.h" +/* +#include "newgamedlg.h" + +#include "player.h" +#include "humanplayer.h" +#include "computerplayer.h" +*/ + + +myBoard::myBoard(QWidget* parent) + : QFrame(parent) +{ + /* + * board & info + */ + setFrameStyle(QFrame::Box|QFrame::Plain); + for(int i=0; i<64; i++) + m_fields[i] = new Field(this, i); + + QGridLayout* grid = new QGridLayout(this); + grid->setSpacing(0); + grid->setMargin(0); + for(int i=0; i<4; i++) { + for(int k=0; k<4; k++) { + grid->addWidget(m_fields[i*8+k+32], i*2, k*2 ); + grid->addWidget(m_fields[i*8+k ], i*2, k*2+1); + grid->addWidget(m_fields[i*8+k+4 ], i*2+1,k*2 ); + grid->addWidget(m_fields[i*8+k+36], i*2+1,k*2+1); + } + } + + for(int i=0; i<32; i++) + connect(m_fields[i], SIGNAL(click(int)), + this, SIGNAL(fieldClicked(int))); + + + /* + * game init + */ + m_game = 0; + + xpmPat1 = 0; + xpmPat2 = 0; + xpmFrame= 0; + xpmManBlack = 0; + xpmManWhite = 0; + xpmKingBlack= 0; + xpmKingWhite= 0; +} + + +myBoard::~myBoard() +{ + if(m_game) + delete m_game; +} + + +void myBoard::setTheme(const QString& path, bool set_white) +{ + // delete them later. + QPixmap* p1 = xpmManWhite; + QPixmap* p2 = xpmManBlack; + QPixmap* p3 = xpmKingWhite; + QPixmap* p4 = xpmKingBlack; + QPixmap* p5 = xpmPat1; + QPixmap* p6 = xpmPat2; + QPixmap* p7 = xpmFrame; + + if(path == DEFAULT_THEME) { + // just in case no themes installed. + xpmPat1 = new QPixmap(":/icons/theme/tile1.png"); + xpmPat2 = new QPixmap(":/icons/theme/tile2.png"); + xpmFrame= new QPixmap(":/icons/theme/frame.png"); + xpmManBlack = new QPixmap(":/icons/theme/manblack.png"); + xpmManWhite = new QPixmap(":/icons/theme/manwhite.png"); + xpmKingBlack= new QPixmap(":/icons/theme/kingblack.png"); + xpmKingWhite= new QPixmap(":/icons/theme/kingwhite.png"); + } else { + xpmPat1 = new QPixmap(path+"/"THEME_TILE1); + xpmPat2 = new QPixmap(path+"/"THEME_TILE2); + xpmFrame= new QPixmap(path+"/"THEME_FRAME); + xpmManBlack + = new QPixmap(path+"/"THEME_MANBLACK); + xpmManWhite + = new QPixmap(path+"/"THEME_MANWHITE); + xpmKingBlack + = new QPixmap(path+"/"THEME_KINGBLACK); + xpmKingWhite + = new QPixmap(path+"/"THEME_KINGWHITE); + } + + setColorWhite(set_white); + + for(int i=0; i<32; i++) + m_fields[i]->setPattern(xpmPat2); + for(int i=32; i<64; i++) + m_fields[i]->setPattern(xpmPat1); + for(int i=0; i<32; i++) + m_fields[i]->setFrame(xpmFrame); + + setFixedSize(xpmMan1->width()*8 + 2*frameWidth(), + xpmMan1->height()*8 + 2*frameWidth()); + + if(m_game) + do_draw(); + + // now delete. + if(p1) delete p1; + if(p2) delete p2; + if(p3) delete p3; + if(p4) delete p4; + if(p5) delete p5; + if(p6) delete p6; + if(p7) delete p7; +} + + +void myBoard::reset() +{ + int new_board[32]; + + for(int i=0; i<12; i++) + new_board[i]=MAN2; + for(int i=12; i<20; i++) + new_board[i]=FREE; + for(int i=20; i<32; i++) + new_board[i]=MAN1; + + // reset frames. + for(int i=0; i<32; i++) + m_fields[i]->showFrame(false); + + if(m_game) + m_game->setup(new_board); + + do_draw(); +} + + +void myBoard::adjustNotation(bool bottom_is_white) +{ + if(!m_game) + return; + + QString notation = (m_game->type()==ENGLISH + ? ENOTATION : QString(RNOTATION).toUpper()); + + if(bottom_is_white) { + for(int i=0; i<32; i++) + m_fields[i]->setLabel(notation.mid(i*2,2).trimmed()); + } else { + for(int i=0; i<32; i++) + m_fields[i]->setLabel(notation.mid(62-i*2,2).trimmed()); + } +} + + +void myBoard::do_draw() +{ + for(int i=0; i<32; i++) { + switch(m_game->item(i)) { + case MAN1: + m_fields[i]->setPicture(xpmMan1); + break; + case MAN2: + m_fields[i]->setPicture(xpmMan2); + break; + case KING1: + m_fields[i]->setPicture(xpmKing1); + break; + case KING2: + m_fields[i]->setPicture(xpmKing2); + break; + default: + m_fields[i]->setPicture(NULL); + } + } +} + + +void myBoard::setColorWhite(bool b) +{ + if(b) { + xpmMan1 = xpmManWhite; + xpmMan2 = xpmManBlack; + xpmKing1= xpmKingWhite; + xpmKing2= xpmKingBlack; + } else { + xpmMan1 = xpmManBlack; + xpmMan2 = xpmManWhite; + xpmKing1= xpmKingBlack; + xpmKing2= xpmKingWhite; + } +} + +void myBoard::setNotation(bool s, bool above) +{ + for(int i=0; i<32; i++) + m_fields[i]->showLabel(s, above); +} + +/* +void myBoard::do_move(const QString& move) +{ + qDebug() << __PRETTY_FUNCTION__; + if(!m_current->isHuman()) { + add_log(myBoard::Warning, tr("It's not your turn.")); + return; + } + + int from_num, to_num; + if(extract_move(move, &from_num, &to_num)) { + slot_click(from_num); + slot_click(to_num); + } else + add_log(myBoard::Warning, tr("Syntax error. Usage: /from-to")); +} + */ + + + +bool myBoard::convert_move(const QString& move_orig, int* from_num, int* to_num) +{ + QString move = move_orig.toUpper().replace('X', '-'); + QString from; + QString to; + int sect = move.count('-'); + + *from_num = *to_num = -1; + + from = move.section('-', 0, 0); + to = move.section('-', sect, sect); + + if(from!=QString::null && to!=QString::null) { + for(int i=0; i<32; i++) { + if(m_fields[i]->label()==from) + *from_num = m_fields[i]->number(); + if(m_fields[i]->label()==to) + *to_num = m_fields[i]->number(); + } + + if(*from_num>=0 && *to_num>=0) + return true; + } + + return false; +} + + +void myBoard::setNotationFont(const QFont& f) +{ + setFont(f); + for(int i=0; i<32; i++) + m_fields[i]->fontUpdate(); +} + + +void myBoard::setGame(int rules) +{ + if(m_game) + delete m_game; + + if(rules==ENGLISH) { + m_game = new ECheckers(); + } else { + m_game = new RCheckers(); + } + + reset(); +} + + +void myBoard::selectField(int field_num, bool is_on) +{ + for(int i=0; i<32; i++) { + if(i==field_num) + m_fields[i]->showFrame(is_on); + else + m_fields[i]->showFrame(false); + } +} + + +QString myBoard::doMove(int from_num, int to_num, bool white_player) +{ + bool bottom_player = (white_player && (xpmMan1==xpmManWhite)) + || (!white_player && (xpmMan1==xpmManBlack)); + + int from_pos = from_num; + int to_pos = to_num; + + if(!bottom_player) { + from_pos = 31-from_pos; + to_pos = 31-to_pos; + m_game->fromString(m_game->toString(true)); + } + if(!m_game->go1(from_pos, to_pos)) { + return QString::null; + /* + qDebug() << __PRETTY_FUNCTION__ + << from_pos << "," << to_pos + << " could not move."; + */ + } + if(!bottom_player) { + m_game->fromString(m_game->toString(true)); + } + + do_draw(); + + return QString("%1?%3") + .arg(m_fields[from_num]->label()) + .arg(m_fields[to_num]->label()); +} + + +bool myBoard::doMove(const QString& move, bool white_player) +{ + int from_pos, to_pos; + if(convert_move(move, &from_pos, &to_pos)) { + doMove(from_pos, to_pos, white_player); + return true; + } + return false; +} + + +void myBoard::doFreeMove(int from, int to) +{ + int old_to = m_game->item(to); + int old_from = m_game->item(from); + m_game->setItem(to, old_from); + m_game->setItem(from, old_to); + do_draw(); +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.h new file mode 100644 index 000000000..2273761b1 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/board.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + + +#include + +#include "field.h" +#include "checkers.h" + + +class myBoard : public QFrame +{ + Q_OBJECT + +public: + myBoard(QWidget* parent); + ~myBoard(); + + // returns coded move string: from_pos_string?to_pos_string + QString doMove(int from_pos, int to_pos, bool white_player); + // coded move. + bool doMove(const QString& move, bool white_player); + // + void doFreeMove(int from, int to); + + void selectField(int field_num, bool is_on); + + void setTheme(const QString& theme_path, bool set_white); + + void setNotation(bool enabled, bool show_above); + void setNotationFont(const QFont& f); + + void setColorWhite(bool); + void reset(); + void adjustNotation(bool bottom_is_white); + + void setGame(int rules); + + bool whiteIsNext() const; + + int type() const { return m_game->type(); } + // TODO + const Checkers* game() const { return m_game; } + +signals: + void fieldClicked(int); + +private: + bool convert_move(const QString&, int* from, int* to); + void do_draw(); + +private: + Field* m_fields[64]; + + QPixmap* xpmPat1; + QPixmap* xpmPat2; + QPixmap* xpmFrame; + + QPixmap* xpmMan1; + QPixmap* xpmMan2; + QPixmap* xpmKing1; + QPixmap* xpmKing2; + + QPixmap* xpmManBlack; + QPixmap* xpmManWhite; + QPixmap* xpmKingBlack; + QPixmap* xpmKingWhite; + + Checkers* m_game; +}; + + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.cc new file mode 100644 index 000000000..b3dd35489 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.cc @@ -0,0 +1,451 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +// +// KCheckers Engine + +// +// Internal: External: +// +// Board = 54 Fields: Board = 32 Fields: +// +// | 06 07 08 09| MAN2 | 00 01 02 03| +// |11 12 13 14 | |04 05 06 07 | +// | 17 18 19 20| | 08 09 10 11| +// |22 23 24 25 | |12 13 14 15 | +// | 28 29 30 31| | 16 17 18 19| +// |33 34 35 36 | |20 21 22 23 | +// | 39 40 41 42| | 24 25 26 27| +// |44 45 46 47 | MAN1 |28 29 30 31 | + +#include +#include + +#include + +#include "checkers.h" + + +int Checkers::internal(int external) const +{ + const int i[]={6,7,8,9,11,12,13,14,17,18,19,20,22,23,24,25, + 28,29,30,31,33,34,35,36,39,40,41,42,44,45,46,47}; + return i[external]; +} + + +/* +int Checkers::external(int internal) const +{ + const int i[]={ + -1,-1,-1,-1,-1,-1,0,1,2,3, // 0-9 internal + -1,4,5,6,7,-1,-1,8,9,10, // 10-19 + 11,-1,12,13,14,15,-1,-1,16,17, // 20-29 + 18,19,-1,20,21,22,23,-1,-1,24, // 30-39 + 25,26,27,-1,28,29,30,31,-1,-1, // 40-49 + -1,-1,-1,-1}; // 50-53 + return i[internal]; +} +*/ + + +Checkers::Checkers() +{ + for(int i=0;i<54;i++) board[i] = NONE; + + for(int i=0; i<12; i++) board[internal(i)] = MAN2; + for(int i=12; i<20; i++) board[internal(i)] = FREE; + for(int i=20; i<32; i++) board[internal(i)] = MAN1; + + levelmax = 2; + + srand(time(0)); // Seed the random number generator +} + + +bool Checkers::setup(int setupboard[]) +{ + /*aw - caused problems + int sum1=0; // Sum of MAN1 & KING1 + int sum2=0; // Sum of MAN2 & KING2 + + for(int i=0; i<32; i++) { + switch(setupboard[i]) { + case MAN1: + case KING1: sum1++; break; + case MAN2: + case KING2: sum2++; break; + + case FREE: break; + + default: return false; + } + } + + if(sum1>12 || sum1==0 || sum2>12 || sum2==0) + return false; + + for(int i=0; i<4; i++) + if(setupboard[i]==MAN1) return false; + + for(int i=28; i<32; i++) + if(setupboard[i]==MAN2) return false; + */ + + for(int i=0; i<32; i++) + board[internal(i)] = setupboard[i]; + + return true; +} + + +/////////////////////////////////////////////////// +// +// Player Functions +// +/////////////////////////////////////////////////// + + +bool Checkers::checkMove1() const +{ + for(int i=6;i<48;i++) + if(checkMove1(i)) + return true; + return false; +} + + +bool Checkers::checkMove1(int i) const +{ + switch(board[i]) { + case MAN1: + if(board[i-6]==FREE) return true; + if(board[i-5]==FREE) return true; + break; + case KING1: + if(board[i-6]==FREE) return true; + if(board[i-5]==FREE) return true; + if(board[i+5]==FREE) return true; + if(board[i+6]==FREE) return true; + } + return false; +} + + +//////////////////////////////////////////////////// +// +// Computer Functions +// +//////////////////////////////////////////////////// + + +void Checkers::go2() +{ + // + level=0; + for(int i=6;i<48;i++) + bestboard[i] = board[i]; + turn(); + for(int i=6;i<48;i++) + board[i] = bestboard[i]; + ; +} + + +void Checkers::turn(int& resMax, bool capture) +{ + if(levelresMax) { + resMax=res; + if(level==1) { + for(int i=6;i<48;i++) bestboard[i]=board[i]; + bestcounter=1; + } + } else if(res==resMax && level==1) { + bestcounter++; + if((rand()%bestcounter)==0) { + for(int i=6;i<48;i++) bestboard[i]=board[i]; + } + } + + if(capture) { + if(f12) board[12]=NONE; + if(f13) board[13]=NONE; + if(f14) board[14]=NONE; + if(f17) board[17]=NONE; + if(f18) board[18]=NONE; + if(f19) board[19]=NONE; + if(f23) board[23]=NONE; + if(f24) board[24]=NONE; + if(f25) board[25]=NONE; + if(f28) board[28]=NONE; + if(f29) board[29]=NONE; + if(f30) board[30]=NONE; + if(f34) board[34]=NONE; + if(f35) board[35]=NONE; + if(f36) board[36]=NONE; + if(f39) board[39]=NONE; + if(f40) board[40]=NONE; + if(f41) board[41]=NONE; + } + } + else if(resMax<0) resMax=0; +} + + +bool Checkers::checkMove2() const +{ + for(int i=6;i<48;i++) { + switch(board[i]) { + case MAN2: + if(board[i+5]==FREE) return true; + if(board[i+6]==FREE) return true; + break; + case KING2: + if(board[i-6]==FREE) return true; + if(board[i-5]==FREE) return true; + if(board[i+5]==FREE) return true; + if(board[i+6]==FREE) return true; + } + } + return false; +} + + +int Checkers::turn() +{ + int resMax=(level-levelmax)*10; + level++; + + if(checkCapture2()) { + for(int i=6; i<48; i++) { + switch(board[i]) { + case MAN2: + manCapture2(i, resMax); + break; + case KING2: + kingCapture2(i,UL,resMax); + kingCapture2(i,UR,resMax); + kingCapture2(i,DL,resMax); + kingCapture2(i,DR,resMax); + } + } + + } else if(checkMove2()) { + for(int i=6;i<48;i++) { + switch(board[i]) { + case MAN2: + if(board[i+5]==FREE) { // down left + board[i]=FREE; + if(i>38) + board[i+5]=KING2; + else + board[i+5]=MAN2; + turn(resMax); + board[i+5]=FREE; + board[i]=MAN2; + } + if(board[i+6]==FREE) { // down right + board[i]=FREE; + if(i>38) + board[i+6]=KING2; + else + board[i+6]=MAN2; + turn(resMax); + board[i+6]=FREE; + board[i]=MAN2; + } + break; + case KING2: + kingMove2(i,resMax); + break; + } + } + + } else ; + + level--; + return resMax; +} + + +QString Checkers::toString(bool rotate) const +{ + int fields[32]; + int it; + + for(int i=0; i<32; i++) { + it = item(i); + if(rotate) + fields[31-i] = (~it&7)-1; + else + fields[i] = it; + } + + QString str; + for(int i=0; i<32; i++) + str += QString("").sprintf("%.2u", fields[i]); + + return str; +} + + +bool Checkers::fromString(const QString& str) +{ + int fields[32]; + + for(int i=0; i<32; i++) + fields[i] = str.mid(i*2, 2).toInt(); + + // apply + if(!setup(fields)) { + qDebug() << "Checkers::fromString:" << str; + return false; + } + + return true; +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.h new file mode 100644 index 000000000..c9381e533 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/checkers.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef CHECKERS_H +#define CHECKERS_H + + +#include + + +// do not change - hard coded +#define NONE 0 +#define MAN1 1 +#define KING1 2 +#define FREE 3 +#define KING2 4 +#define MAN2 5 +#define FULL 6 + +#define UL -6 +#define UR -5 +#define DL 5 +#define DR 6 + + +class Checkers +{ +public: + Checkers(); + virtual ~Checkers() {} + + bool setup(int setupboard[]); + virtual bool go1(int from, int to)=0; + + void go2(); + + void setSkill(int i) { levelmax=i; }; + int skill() const { return levelmax; } + virtual int type() const = 0; + + int item(int i) const { return board[internal(i)]; } + void setItem(int i, int item) { board[internal(i)] = item; } + + // string representation of the game board. + // set rotate to switch player sides. + QString toString(bool rotate) const; + bool fromString(const QString&); + + // checks for a capture/move for particular stone in external + // representation. human player only. + bool canCapture1(int i) { return checkCapture1(internal(i)); } + bool canMove1(int i) { return checkMove1(internal(i)); } + + bool checkMove1() const; + bool checkMove2() const; + virtual bool checkCapture1() const = 0; + virtual bool checkCapture2() const = 0; + +protected: + bool checkMove1(int) const; + virtual bool checkCapture1(int) const = 0; + + int level; // Current level + int levelmax; // Maximum level + + int turn(); + void turn(int&, bool capture=false); + + int to; + int board[54]; + int bestboard[54]; + int bestcounter; + + virtual void kingMove2(int,int &)=0; + + virtual bool manCapture2(int,int &)=0; + virtual bool kingCapture2(int,int,int &)=0; + + virtual bool manCapture1(int,int,bool &)=0; + virtual bool kingCapture1(int,int,bool &)=0; + + int internal(int) const; // Return internal board position +}; + + +#endif diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/common.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/common.h new file mode 100644 index 000000000..8b34655f5 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/common.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + + +#define APPNAME "QCheckers" +#define VERSION "0.8.1" +#define EXT "pdn" + + +#define HOMEPAGE "http://kcheckers.org" +#define COPYRIGHT "(c) 2002-2003, Andi Peredri (andi@ukr.net)
" \ + "(c) 2004-2005, Artur Wiebe (wibix@gmx.de)" +#define CONTRIBS "Sebastien Prud'homme (prudhomme@laposte.net)
" \ + "Guillaume Bedot (guillaume.bedot@wanadoo.fr)" + +/* !!! Do not change PREFIX variable name, please. !!! */ +/* !!! It is used in qcheckers.pro. !!! */ +#define PREFIX "/usr/local" +#define USER_PATH ".kcheckers" // in $HOME +#define THEME_DIR "themes/" + +// some keys for QSettings +#define CFG_KEY "/"APPNAME"/" + +// +#define DEFAULT_THEME "Default" +// +#define THEME_TILE1 "tile1.png" +#define THEME_TILE2 "tile2.png" +#define THEME_FRAME "frame.png" +#define THEME_MANBLACK "manblack.png" +#define THEME_MANWHITE "manwhite.png" +#define THEME_KINGBLACK "kingblack.png" +#define THEME_KINGWHITE "kingwhite.png" +#define THEME_FILE "theme" + +// +#define MAX_TILE_SIZE 64 + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.cc new file mode 100644 index 000000000..0d9539847 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.cc @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include + +#include "computerplayer.h" +#include "pdn.h" +#include "rcheckers.h" +#include "echeckers.h" +#include "checkers.h" + + +myComputerPlayer::myComputerPlayer(const QString& name, bool white, int skill) + : myPlayer(name, white) +{ + m_game = 0; + m_thread = 0; + m_skill = skill; +} + + +myComputerPlayer::~myComputerPlayer() +{ + if(m_thread) { + m_thread->stop(); + // delete m_thread + } + delete m_game; +} + + +void myComputerPlayer::yourTurn(const Checkers* g) +{ + if(m_thread) + qDebug("myComputerPlayer::yourTurn: a thread exists."); + + // first create it. + if(!m_game || m_game->type()!=g->type()) { + delete m_game; + if(g->type()==RUSSIAN) + m_game = new RCheckers(); + else + m_game = new ECheckers(); + } + + m_game->setSkill(m_skill); + m_game->fromString(g->toString(false)); + + m_thread = new myThread(this, m_game); + m_thread->start(); +} + + +void myComputerPlayer::stop() +{ + if(m_thread) { + m_thread->stop(); + } +} + + +void myComputerPlayer::customEvent(QEvent* ev) +{ + if(ev->type() == QEvent::MaxUser) { + m_thread->wait(); + + delete m_thread; + m_thread = 0; + + emit moveDone(m_game->toString(false)); + } +} + + + +/**************************************************************************** + * + * + ***************************************************************************/ +void myThread::run() +{ + m_game->go2(); + if(!m_aborted) { + QEvent* ev = new QEvent(QEvent::MaxUser); + QApplication::postEvent(m_player, ev); + } else + qDebug("thread.aborted.done."); +} + + +void myThread::stop() +{ + m_aborted = true; + m_game->setSkill(0); +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.h new file mode 100644 index 000000000..553389f3a --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/computerplayer.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _COMPUTERPLAYER_H_ +#define _COMPUTERPLAYER_H_ + + +#include + +#include "player.h" + + +class myThread; + + +class myComputerPlayer : public myPlayer +{ + Q_OBJECT + +public: + myComputerPlayer(const QString& name, bool white, int skill); + ~myComputerPlayer(); + + virtual void yourTurn(const Checkers* game); + virtual void stop(); + + // need this to process thread's events + virtual void customEvent(QEvent*); + +private: + myThread* m_thread; + Checkers* m_game; + int m_skill; +}; + + + +/****************************************************************************/ +class myThread : public QThread { +public: + myThread(myComputerPlayer* p, Checkers* g) + : m_player(p), m_game(g), m_aborted(false) {} + + virtual void run(); + + void stop(); + + Checkers* game() const { return m_game; } + +private: + myComputerPlayer* m_player; + Checkers* m_game; + bool m_aborted; +}; + + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/copying b/retroshare-gui/src/gui/plugins/qcheckers_plugin/copying new file mode 100644 index 000000000..c7aea1896 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/copying @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.cc new file mode 100644 index 000000000..362e59e1b --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.cc @@ -0,0 +1,423 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +// aw?1 - due to english rules a man reaching the king-row becomes a king +// and the is complete. +// +// English Checkers + + +#include "echeckers.h" + + +/////////////////////////////////////////////////// +// +// Player Functions +// +/////////////////////////////////////////////////// + + +bool ECheckers::go1(int from, int field) +{ + from=internal(from); + field=internal(field); + + to=field; + + if(checkCapture1()) { + bool capture=false; + + switch(board[from]) { + case MAN1: + if(manCapture1(from, UL, capture)) return true; + if(manCapture1(from, UR, capture)) return true; + return false; + case KING1: + if(kingCapture1(from, UL, capture)) return true; + if(kingCapture1(from, UR, capture)) return true; + if(kingCapture1(from, DL, capture)) return true; + if(kingCapture1(from, DR, capture)) return true; + return false; + } + + } else { + switch(board[from]) { + case MAN1: + if((to==(from-6))||(to==(from-5))) { + board[from]=FREE; + if(to<10) + board[to]=KING1; + else + board[to]=MAN1; + return true; + } + return false; + case KING1: + if((to==(from-6))||(to==(from-5)) || + (to==(from+5))||(to==(from+6)) ) { + board[from]=FREE; + board[to]=KING1; + return true; + } + return false; + } + } + + return false; +} + + +bool ECheckers::checkCapture1() const +{ + for(int i=6;i<48;i++) + if(checkCapture1(i)) + return true; + + return false; +} + + +bool ECheckers::checkCapture1(int i) const +{ + switch(board[i]) { + case MAN1: + // forward-left + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + // forward-right + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + break; + + case KING1: + // forward-left + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + // forward-right + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + // backward-left + if(board[i+5]==MAN2 || board[i+5]==KING2) + if(board[i+10]==FREE) return true; + // backward-right + if(board[i+6]==MAN2 || board[i+6]==KING2) + if(board[i+12]==FREE) return true; + } + + return false; +} + + +/* ORIG FUNC aw??? +bool ECheckers::checkCapture1() +{ + for(int i=6;i<48;i++) { + switch(board[i]) { + case MAN1: + // forward-left + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + // forward-right + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + break; + + case KING1: + // forward-left + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + // forward-right + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + // backward-left + if(board[i+5]==MAN2 || board[i+5]==KING2) + if(board[i+10]==FREE) return true; + // backward-right + if(board[i+6]==MAN2 || board[i+6]==KING2) + if(board[i+12]==FREE) return true; + } + } + + return false; +} +*/ + + +// Return TRUE if a course of the player true +// Return FALSE if a course of the player incorrect + +bool ECheckers::manCapture1(int from, int direction, bool& capture) +{ + int i=from+direction; + + if(board[i]==MAN2 || board[i]==KING2) { + int k=i+direction; + if(board[k]==FREE) { + bool next=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + + // become a king! + if(k<10) { + board[k]=KING1; + /*aw?1 + if(kingCapture1(k, direction+11, next)) { + board[i]=FREE; + return true; + } + */ + } else { + board[k]=MAN1; + if(manCapture1(k,UL,next)) {board[i]=FREE; return true;} + if(manCapture1(k,UR,next)) {board[i]=FREE; return true;} + } + + //?? make move here, too??? + if((!next) && k==to) {board[i]=FREE; return true;}// move success + + // move failed, restore + board[k]=FREE; + board[i]=save; + board[from]=MAN1; + capture=true; + } + } + + return false; +} + + +bool ECheckers::kingCapture1(int from, int direction, bool& capture) +{ + int i=from+direction; + if(board[i]==MAN2 || board[i]==KING2) + { + int k=i+direction; + if(board[k]==FREE) + { + bool next=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + board[k]=KING1; + + if(direction==UL || direction==DR) { + if(kingCapture1(k,UR,next)) {board[i]=FREE;return true;} + if(kingCapture1(k,DL,next)) {board[i]=FREE;return true;} + } else { + if(kingCapture1(k,UL,next)) {board[i]=FREE;return true;} + if(kingCapture1(k,DR,next)) {board[i]=FREE;return true;} + } + if(kingCapture1(k,direction,next)) {board[i]=FREE;return true;} + + if((!next) && k==to) {board[i]=FREE;return true;}// move ok + + // move failed, restore + board[k]=FREE; + board[i]=save; + board[from]=KING1; + capture=true; + } + } + return false; +} + + +//////////////////////////////////////////////////// +// +// Computer Functions +// +//////////////////////////////////////////////////// + + +void ECheckers::kingMove2(int from, int& resMax) +{ + board[from]=FREE; + + int i=from-6; + if(board[i]==FREE) { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + + i=from-5; + if(board[i]==FREE) { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + + i=from+5; + if(board[i]==FREE) { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + + i=from+6; + if(board[i]==FREE) { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + + board[from]=KING2; +} + + +bool ECheckers::checkCapture2() const +{ + for(int i=6;i<48;i++) + { + switch(board[i]) + { + case MAN2: + if(board[i+5]==MAN1 || board[i+5]==KING1) + if(board[i+10]==FREE) return true; + if(board[i+6]==MAN1 || board[i+6]==KING1) + if(board[i+12]==FREE) return true; + break; + case KING2: + if(board[i-6]==MAN1 || board[i-6]==KING1) + if(board[i-12]==FREE) return true; + if(board[i-5]==MAN1 || board[i-5]==KING1) + if(board[i-10]==FREE) return true; + if(board[i+5]==MAN1 || board[i+5]==KING1) + if(board[i+10]==FREE) return true; + if(board[i+6]==MAN1 || board[i+6]==KING1) + if(board[i+12]==FREE) return true; + } + } + return false; +} + + +// Return TRUE if it is possible to capture +// Return FALSE if it is impossible to capture +bool ECheckers::manCapture2(int from, int& resMax) +{ + bool capture=false; + + // try left-down + int i=from+5; + if(board[i]==MAN1 || board[i]==KING1) { + int k=from+10; + if(board[k]==FREE) { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + + // become a king! + if(from>32) { + board[k]=KING2; + // aw?1 + turn(resMax, true); //aw??? + //aw??if(!kingCapture2(k, UL, resMax)) turn(resMax, true); + } else { + board[k]=MAN2; + if(!manCapture2(k, resMax)) turn(resMax, true); + } + + // restore + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + // now right-down + i=from+6; + if(board[i]==MAN1 || board[i]==KING1) { + int k=from+12; + if(board[k]==FREE) { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + + // become a king! + if(from>32) { + board[k]=KING2; + // aw?1 + turn(resMax, true); // aw??? + //aw???if(!kingCapture2(k,UR,resMax)) turn(resMax,true); + } else { + board[k]=MAN2; + if(!manCapture2(k,resMax)) turn(resMax,true); + } + + // restore + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + if(capture) return true; + return false; +} + + +bool ECheckers::kingCapture2(int from, int direction, int &resMax) +{ + int i=from+direction; + if(board[i]==MAN1 || board[i]==KING1) + { + int k=i+direction; + if(board[k]==FREE) + { + bool capture=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + + board[k]=KING2; + if(direction==UL || direction==DR) { + if(kingCapture2(k,UR,resMax)) capture=true; + if(kingCapture2(k,DL,resMax)) capture=true; + } else { + if(kingCapture2(k,UL,resMax)) capture=true; + if(kingCapture2(k,DR,resMax)) capture=true; + } + if(kingCapture2(k,direction,resMax)) capture=true; + + if(!capture) turn(resMax,true); + board[k]=FREE; + + //restore + resMax++; + board[i]=save; + board[from]=KING2; + return true; + } + } + return false; +} + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.h new file mode 100644 index 000000000..89d1da551 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/echeckers.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef ECHECKERS_H +#define ECHECKERS_H + +#include "checkers.h" +#include "pdn.h" + + +class ECheckers:public Checkers +{ +public: + virtual bool go1(int,int); + + + virtual int type() const { return ENGLISH; } + + virtual bool checkCapture1() const; + virtual bool checkCapture2() const; + +protected: + virtual bool checkCapture1(int) const; + +private: + void kingMove2(int,int &); + + bool manCapture1(int,int,bool &); + bool kingCapture1(int,int,bool &); + + bool manCapture2(int,int &); + bool kingCapture2(int,int,int &); + +}; + +#endif diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.cc new file mode 100644 index 000000000..6006a5537 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.cc @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include + +#include "field.h" +#include "common.h" + + +Field::Field(QWidget* parent,int i) + : QWidget(parent) +{ + pixmap = new QPixmap(MAX_TILE_SIZE, MAX_TILE_SIZE); + + m_number=i; + + m_pattern=NULL; + m_checker=NULL; + m_frame=NULL; + + show_frame = false; + + m_show_label = true; +} + + +void Field::paintEvent(QPaintEvent*) +{ + QPainter p(this); + + p.drawPixmap(0, 0, *pixmap); + + p.end(); +} + + +void Field::mousePressEvent(QMouseEvent* me) +{ + if(me->button() != Qt::LeftButton) + return; + emit click(m_number); +} + + +void Field::draw() +{ + QPainter paint; + paint.begin(pixmap); + paint.setFont(font()); + + if(m_pattern) + paint.drawPixmap(0, 0, *m_pattern); + + // notation + paint.setPen(Qt::white); + QRect not_rect = paint.boundingRect(2, 2, 0, 0, Qt::AlignLeft, m_label); + if(m_show_above) { + if(m_checker) + paint.drawPixmap(0, 0, *m_checker); + if(m_show_label) { + paint.fillRect(not_rect, Qt::black); + paint.drawText(not_rect, Qt::AlignTop|Qt::AlignLeft, m_label); + } + } else { + if(m_show_label) + paint.drawText(not_rect, Qt::AlignTop|Qt::AlignLeft, m_label); + if(m_checker) + paint.drawPixmap(0, 0, *m_checker); + } + + if(show_frame) + paint.drawPixmap(0, 0, *m_frame); + + paint.end(); + update(); +} + + +void Field::setFrame(QPixmap* xpm) +{ + m_frame = xpm; +} + + +void Field::showFrame(bool b) +{ + if(show_frame != b) { + show_frame = b; + draw(); + } +} + + +void Field::setPicture(QPixmap* xpm) +{ + if(m_checker!=xpm) { + m_checker = xpm; + draw(); + } +} + + +void Field::setPattern(QPixmap* xpm) +{ + if(m_pattern != xpm) { + m_pattern = xpm; + draw(); + } +} + + +void Field::setLabel(const QString& str) +{ + if(m_label!=str) { + m_label=str; + draw(); + } +} + + +void Field::showLabel(bool s, bool a) +{ + if(s!=m_show_label || a!=m_show_above) { + m_show_above = a; + m_show_label = s; + draw(); + } +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.h new file mode 100644 index 000000000..8e62d8af0 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/field.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef FIELD_H +#define FIELD_H + +#include +#include + + +class Field : public QWidget +{ + Q_OBJECT + +public: + Field(QWidget*, int num); + + const QString& label() const { return m_label; } + void setLabel(const QString&); + void showLabel(bool s, bool above); + + void showFrame(bool); + void setFrame(QPixmap*); + void setPicture(QPixmap*); + void setPattern(QPixmap*); + + int number() const { return m_number; } + + void fontUpdate() { draw(); } + +signals: + void click(int); + +protected: + + void paintEvent(QPaintEvent*); + void mousePressEvent(QMouseEvent*); + +private: + void draw(); + + int m_number; + + // pixmap = pattern + label + picture + frame; + + QPixmap* m_frame; + QPixmap* m_checker; + QPixmap* m_pattern; + + QString m_label; + bool m_show_label; + bool m_show_above; + + QPixmap* pixmap; + + bool show_frame; +}; + +#endif + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.cc new file mode 100644 index 000000000..22303cffc --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.cc @@ -0,0 +1,514 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include "history.h" +#include "common.h" + + + +#define COL_TAG_NR 0 // m_tags, this col is hidden. +#define COL_TAG_NAME 1 +#define COL_TAG_VAL 2 + +#define COL_MOVE_NR 0 // m_movelist +#define COL_MOVE 1 +#define COL_MOVE_COMM 2 + + +myHistory::myHistory(QWidget* parent) + : QFrame(parent) +{ + setFixedWidth(240); + + m_gamelist = new QComboBox(this); + connect(m_gamelist, SIGNAL(activated(int)), + this, SLOT(slot_game_selected(int))); + + m_taglist = new QTreeWidget(this); + m_taglist->setColumnCount(3); + m_taglist->header()->hide(); + m_taglist->setColumnHidden(COL_TAG_NR, true); +// m_taglist->header()->setStretchLastSection(true); +// m_taglist->header()->setResizeMode(QHeaderView::Stretch); + m_taglist->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + connect(m_taglist, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), + this, SLOT(slot_modify_tag(QTreeWidgetItem*, int))); + + m_movelist = new QTreeWidget(this); + m_movelist->setColumnCount(3); + m_movelist->header()->setStretchLastSection(true); + m_movelist->header()->setMovable(false); + m_movelist->setRootIsDecorated(false); + QStringList header; + header << "#" << tr("Move") << tr("Comment"); + m_movelist->setHeaderLabels(header); + // + connect(m_movelist, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), + this, SLOT(slot_modify_comment(QTreeWidgetItem*, int))); + connect(m_movelist, + SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), + this, + SLOT(slot_move(QTreeWidgetItem*, QTreeWidgetItem*))); + + // history + /* + gameUndo = new QAction(QIcon(":/icons/undo.png"), tr("&Undo"), this); + connect(gameUndo, SIGNAL(triggered()), m_view, SLOT(slotUndo())); + + gameRedo = new QAction(QIcon(":/icons/redo.png"), tr("&Redo"), this); + connect(gameRedo, SIGNAL(triggered()), m_view, SLOT(slotRedo())); + + gameContinue = new QAction(QIcon(":/icons/continue.png"), + tr("&Continue"), this); + connect(gameContinue, SIGNAL(triggered()), m_view, SLOT(slotContinue())); + + + */ + m_mode_icon = new QLabel(this); + m_mode_icon->setFrameStyle(QFrame::Panel | QFrame::Sunken); + + m_undo = new QToolButton(this); + m_undo->setIcon(QIcon(":/icons/undo.png")); + m_undo->setToolTip(tr("Undo")); + connect(m_undo, SIGNAL(clicked()), this, SLOT(slot_undo())); + + m_redo = new QToolButton(this); + m_redo->setIcon(QIcon(":/icons/redo.png")); + m_redo->setToolTip(tr("Redo")); + connect(m_redo, SIGNAL(clicked()), this, SLOT(slot_redo())); + + m_cont = new QToolButton(this); + m_cont->setIcon(QIcon(":/icons/continue.png")); + m_cont->setToolTip(tr("Continue")); + connect(m_cont, SIGNAL(clicked()), this, SLOT(slot_continue())); + + m_current = new QLabel(this); + + QHBoxLayout* history = new QHBoxLayout(); + history->addWidget(m_mode_icon); +//TODO history->addStretch(); + history->addWidget(m_undo); + history->addWidget(m_redo); + history->addWidget(m_cont); + history->addStretch(); + history->addWidget(m_current); + + // layout + QVBoxLayout* vb = new QVBoxLayout(this); + vb->setMargin(0); + vb->addWidget(m_gamelist, 0); + vb->addWidget(m_taglist, 2); + vb->addWidget(m_movelist, 4); + vb->addLayout(history); + + /* + * other stuff + */ + m_pdn = new Pdn(); + m_disable_moves = false; + // + m_paused = true; // little hack ensures a mode change. + m_freeplace = false; + set_mode(false); +} + + +myHistory::~myHistory() +{ + delete m_pdn; +} + + +void myHistory::clear() +{ + m_gamelist->clear(); + m_pdn->clear(); + m_taglist->clear(); + m_movelist->clear(); +} + + +void myHistory::setTag(PdnGame::Tag tag, const QString& val) +{ + QTreeWidgetItem* item = 0; + QList item_list = m_taglist->findItems( + tag_to_string(tag), Qt::MatchExactly, COL_TAG_NAME); + if(item_list.count()) { + if(item_list.count() == 1) + item = item_list[0]; + else + qDebug() << __PRETTY_FUNCTION__ << "ERR"; + } + + if(item) { + item->setText(COL_TAG_VAL, val); + } else { + item = new QTreeWidgetItem(m_taglist); + item->setText(COL_TAG_NR, QString::number(tag)); + item->setText(COL_TAG_NAME, tag_to_string(tag)); + item->setText(COL_TAG_VAL, val); + } + + if(tag==PdnGame::Type) { + item->setText(COL_TAG_VAL, val + " (" + + typeToString(QString("%1").arg(val).toInt()) + + ")"); + } + + m_game->set(tag, val); +//TODO m_taglist->resizeColumnToContents(COL_TAG_NAME); +} + + +QString myHistory::getTag(PdnGame::Tag tag) +{ + QList item_list = m_taglist->findItems( + tag_to_string(tag), Qt::MatchExactly, COL_TAG_NAME); + if(item_list.count() == 1) + return item_list[0]->text(COL_TAG_VAL); + return ""; +} + + +QString myHistory::tag_to_string(PdnGame::Tag tag) +{ + switch(tag) { + case PdnGame::Date: return /*tr(*/"Date";//); + case PdnGame::Site: return /*tr(*/"Site";//); + case PdnGame::Type: return /*tr(*/"Type";//); + case PdnGame::Event: return /*tr(*/"Event";//); + case PdnGame::Round: return /*tr(*/"Round";//); + case PdnGame::White: return /*tr(*/"White";//); + case PdnGame::Black: return /*tr(*/"Black";//); + case PdnGame::Result: return /*tr(*/"Result";//); + } + + return "Site"; // FIXME +} + + +void myHistory::appendMove(const QString& text, const QString& comm) +{ + m_disable_moves = true; + + QTreeWidgetItem* new_item = new QTreeWidgetItem(m_movelist); + new_item->setText(COL_MOVE, text); + new_item->setText(COL_MOVE_COMM, comm); + + int move_nr = (m_movelist->topLevelItemCount() - 2) / 2; + PdnMove* m = m_game->getMove(move_nr); + + if(m_movelist->topLevelItemCount()%2) { + m->m_second = text; + m->m_comsecond = comm; + } else { + new_item->setText(COL_MOVE_NR, QString("%1.").arg(move_nr+1)); + m->m_first = text; + m->m_comfirst = comm; + } + + m_movelist->setCurrentItem(new_item); + m_movelist->scrollToItem(new_item); + + // TODO + m_movelist->resizeColumnToContents(COL_MOVE_NR); + + m_disable_moves = false; +} + + +void myHistory::slot_modify_comment(QTreeWidgetItem* item, int) +{ + if(!item || item==m_movelist->topLevelItem(0) || m_paused) + return; + + bool ok; + QString new_text = QInputDialog::getText(this, tr("Set Comment"),//FIXME + tr("Comment")+":", QLineEdit::Normal, item->text(COL_MOVE_COMM), + &ok); + if(!ok) + return; + + new_text.remove('{'); + new_text.remove('}'); + if(new_text != item->text(COL_MOVE_COMM)) { + // gui + item->setText(COL_MOVE_COMM, new_text); + + // pdn + int index = m_movelist->indexOfTopLevelItem(item); + PdnMove* move = m_game->getMove((index - 1) / 2); + if(index%2==1) + move->m_comfirst = new_text; + else + move->m_comsecond = new_text; + } +} + + +void myHistory::slot_modify_tag(QTreeWidgetItem* item, int/* col*/) +{ + if(!item || m_paused) + return; + + PdnGame::Tag tag =(PdnGame::Tag)item->text(COL_TAG_NR).toUInt(); + if(tag==PdnGame::Type) { + return; + } + + bool ok; + QString new_text = QInputDialog::getText(this, tr("Set Tag"),//FIXME + tr("Tag")+":", QLineEdit::Normal, item->text(COL_TAG_VAL), &ok); + if(!ok) + return; + + new_text.remove('"'); + new_text.remove('['); + new_text.remove(']'); + + if(new_text != item->text(COL_TAG_VAL)) { + item->setText(COL_TAG_VAL, new_text); + m_game->set(tag, new_text); + if(tag==PdnGame::Event) + m_gamelist->setItemText(m_gamelist->currentIndex(), + new_text); + } +} + + +bool myHistory::openPdn(const QString& filename, QString& log_text) +{ + if(!m_pdn->open(filename, this, tr("Reading file..."), log_text)) { + set_mode(false); + return false; + } + + set_mode(true); + + m_gamelist->clear(); + m_movelist->clear(); + m_taglist->clear(); + + QProgressDialog progress(this); + progress.setModal(true); + progress.setLabelText(tr("Importing games...")); + progress.setRange(0, m_pdn->count()); + progress.setMinimumDuration(0); + + for(int i=0; icount(); ++i) { + if((i%10)==0) + progress.setValue(i); + m_gamelist->insertItem(i, m_pdn->game(i)->get(PdnGame::Event)); + } + + slot_game_selected(0); + + return true; +} + + +bool myHistory::savePdn(const QString& fn) +{ + return m_pdn->save(fn); +} + + +void myHistory::slot_game_selected(int index) +{ + if(index>=m_pdn->count()) { + qDebug() << __PRETTY_FUNCTION__ << "Index" << index + << "out of range >=" << m_pdn->count(); + return; + } + + m_game = m_pdn->game(index); + m_movelist->clear(); + + QTreeWidgetItem* root = new QTreeWidgetItem(m_movelist); + for(int i=0; imovesCount(); ++i) { + PdnMove* m = m_game->getMove(i); + + appendMove(m->m_first, m->m_comfirst); + if(m->m_second.length()) + appendMove(m->m_second, m->m_comsecond); + } + + setTag(PdnGame::Site, m_game->get(PdnGame::Site)); + setTag(PdnGame::Black, m_game->get(PdnGame::Black)); + setTag(PdnGame::White, m_game->get(PdnGame::White)); + setTag(PdnGame::Result, m_game->get(PdnGame::Result)); + setTag(PdnGame::Date, m_game->get(PdnGame::Date)); + setTag(PdnGame::Site, m_game->get(PdnGame::Site)); + setTag(PdnGame::Type, m_game->get(PdnGame::Type)); + setTag(PdnGame::Round, m_game->get(PdnGame::Round)); + setTag(PdnGame::Event, m_game->get(PdnGame::Event)); + + // signal to view + if(m_paused && !m_freeplace) { + emit previewGame(m_game->get(PdnGame::Type).toInt()); + } + + m_movelist->setCurrentItem(root); + slot_move(root, 0); +} + + +void myHistory::newPdn(const QString& event, bool freeplace) +{ + m_freeplace = freeplace; + m_paused = !m_freeplace; // FIXME - needed to force view update. + set_mode(m_freeplace); + + PdnGame* game = m_pdn->newGame(); + game->set(PdnGame::Event, event); + + int index = m_gamelist->count(); + m_gamelist->insertItem(index, event); + m_gamelist->setCurrentIndex(index); + + slot_game_selected(index); +} + + +QString myHistory::typeToString(int type) +{ + switch(type) { + case ENGLISH: return tr("English draughts"); + case RUSSIAN: return tr("Russian draughts"); + }; + return tr("Unknown game type"); +} + + +void myHistory::set_mode(bool paused) +{ + if(m_paused != paused) { + m_paused = paused; + + if(m_paused) { + if(m_freeplace) { + m_mode_icon->setPixmap(QPixmap(":/icons/freeplace.png")); + m_mode_icon->setToolTip(tr("Free Placement Mode")); + } else { + m_mode_icon->setPixmap(QPixmap(":/icons/paused.png")); + m_mode_icon->setToolTip(tr("Paused Mode")); + } + } else { + m_mode_icon->setPixmap(QPixmap(":/icons/logo.png")); + m_mode_icon->setToolTip(tr("Play Mode")); + } + + m_gamelist->setEnabled(m_paused); + //FIXME m_movelist->setEnabled(yes); + + emit newMode(m_paused, m_freeplace); + } +} + + +void myHistory::slot_move(QTreeWidgetItem* item, QTreeWidgetItem*) +{ + // update history buttons. + bool curr_is_first = + (m_movelist->topLevelItem(0) == m_movelist->currentItem()); + bool curr_is_last = + (m_movelist->indexOfTopLevelItem(m_movelist->currentItem()) + == m_movelist->topLevelItemCount()-1); + + m_undo->setEnabled(!curr_is_first); + m_redo->setEnabled(!curr_is_last); + m_cont->setEnabled(m_paused); + + + // process + if(!item || !m_paused || m_disable_moves) + return; + + do_moves(); +} + + +void myHistory::history_undo(bool move_backwards) +{ + int next = m_movelist->indexOfTopLevelItem(m_movelist->currentItem()) + + (move_backwards ? -1 : +1); + + if(next>=0 && nexttopLevelItemCount()) + m_movelist->setCurrentItem(m_movelist->topLevelItem(next)); +} + + +void myHistory::do_moves() +{ + QString moves; + QTreeWidgetItem* item = m_movelist->currentItem(); + for(int i=0; itopLevelItemCount(); ++i) { + QTreeWidgetItem* cur = m_movelist->topLevelItem(i); + moves += cur->text(COL_MOVE) + MOVE_SPLIT; + if(m_movelist->topLevelItem(i)==item) + break; + } + emit applyMoves(moves); +} + + +void myHistory::delete_moves() +{ + int curr = m_movelist->indexOfTopLevelItem(m_movelist->currentItem()); + while(m_movelist->topLevelItemCount() > curr+1) { + delete m_movelist->topLevelItem( + m_movelist->topLevelItemCount()-1); + } +} + + +void myHistory::slot_undo() +{ + set_mode(true); + history_undo(true); + do_moves(); +} + +void myHistory::slot_redo() +{ + set_mode(true); + history_undo(false); + do_moves(); +} + + +void myHistory::slot_continue() +{ + delete_moves(); + set_mode(false); +} + + +void myHistory::slotWorking(bool b) +{ + setEnabled(!b); +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.h new file mode 100644 index 000000000..8ca495fd4 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/history.h @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef _HISTORY_H_ +#define _HISTORY_H_ + + +#include +#include +#include +#include +#include + +#include "pdn.h" + + +#define MOVE_SPLIT '#' + + +class myHistory : public QFrame +{ + Q_OBJECT + +public: + myHistory(QWidget* parent); + ~myHistory(); + + void newPdn(const QString& event, bool freeplace); + bool openPdn(const QString& filename, QString& log_text); + bool savePdn(const QString& fn); + + void clear(); + + bool isPaused() const { return m_paused; } + bool isFreePlacement() const { return m_freeplace; } + + void setTag(PdnGame::Tag, const QString& val); + QString getTag(PdnGame::Tag); + + void appendMove(const QString& move, const QString& comment); + // FIXME - provide a function that returns who is next, black or white. + int moveCount() const { return m_movelist->topLevelItemCount()-1; } + + static QString typeToString(int type); + + void setCurrent(const QString& t) { m_current->setText(t); } + +signals: + void previewGame(int game_type); + void applyMoves(const QString& moves); + void newMode(bool paused, bool freeplace); + +public slots: + void slotWorking(bool); + +private slots: + void slot_move(QTreeWidgetItem*, QTreeWidgetItem*); + void slot_game_selected(int index); + void slot_modify_tag(QTreeWidgetItem* item, int col); + void slot_modify_comment(QTreeWidgetItem* item, int col); + + void slot_undo(); + void slot_redo(); + void slot_continue(); + +private: + QString tag_to_string(PdnGame::Tag); + void set_mode(bool); + + void do_moves(); + void history_undo(bool move_backwards); + void delete_moves(); + + +private: + QTreeWidget* m_taglist; + QTreeWidget* m_movelist; + QComboBox* m_gamelist; + Pdn* m_pdn; + PdnGame* m_game; + + bool m_paused; + bool m_freeplace; + bool m_disable_moves; + + QToolButton* m_undo; + QToolButton* m_redo; + QToolButton* m_cont; + + QLabel* m_mode_icon; + QLabel* m_current; +}; + + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.cc new file mode 100644 index 000000000..31e50a108 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.cc @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include "humanplayer.h" +#include "rcheckers.h" +#include "echeckers.h" +#include "pdn.h" + + +myHumanPlayer::myHumanPlayer(const QString& name, bool white, + bool second_player) + : myPlayer(name, white) +{ + selected = false; + + m_second = second_player; + m_game = 0; +} + + +myHumanPlayer::~myHumanPlayer() +{ +} + + +void myHumanPlayer::yourTurn(const Checkers* g) +{ + if(!m_game || m_game->type()!=g->type()) { + delete m_game; + if(g->type()==RUSSIAN) + m_game = new RCheckers(); + else + m_game = new ECheckers(); + } + + // synchronize + m_game->fromString(g->toString(m_second)); +} + + +bool myHumanPlayer::fieldClicked(int field_num, bool* select, QString& errmsg) +{ + if(m_second) + field_num = 31 - field_num; + + switch(m_game->item(field_num)) { + case MAN1: + case KING1: + if(m_game->checkCapture1() && !m_game->canCapture1(field_num)) { + errmsg = tr("You must capture."); //TODO better text. + return false; + } + if(!m_game->canCapture1(field_num) && !m_game->canMove1(field_num)) { + errmsg = tr("Cannot move this."); //TODO better text. + return false; + } + + // Player (re)selects + from = field_num; + fromField = field_num; + selected = true; + *select = true; + return true; + break; + + case FREE: + if(!selected) + return true; + + if(!go(field_num)) + return false; // incorrect course + + // move done - unselect + if(selected) + *select = false; + selected = false; + + emit moveDone(m_game->toString(m_second)); + break; + + default: + break; + } + + return true; +} + + +bool myHumanPlayer::go(int to) +{ + return m_game->go1(from, to); +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.h new file mode 100644 index 000000000..807f6bc91 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/humanplayer.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _HUMANPLAYER_H_ +#define _HUMANPLAYER_H_ + +#include "player.h" + +#include + + +class myHumanPlayer : public myPlayer +{ + Q_OBJECT + +public: + // when playing player vs. player on same computer. the second + // player must invert some things. + myHumanPlayer(const QString& name, bool white, bool second_player); + ~myHumanPlayer(); + + virtual void yourTurn(const Checkers* game); + virtual bool fieldClicked(int fieldnumber, bool*, QString& err_msg); + virtual void stop() {} + + virtual bool isHuman() const { return true; } + + +public slots: +// virtual void getReady() { emit readyToPlay(); } + +private: + bool go(int fieldnumber); + +private: + bool m_second; + + Checkers* m_game; + bool selected; + + int from; // on Checkers board + int fromField; // on GUI board +}; + + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.qm b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.qm new file mode 100644 index 000000000..50c459474 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.qm differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.ts b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.ts new file mode 100644 index 000000000..2dd665fc6 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_de.ts @@ -0,0 +1,611 @@ + + + myHistory + + Move + Zug + + + Comment + Kommentar + + + Undo + Rückgängig + + + Redo + Wiederholen + + + Continue + Fortsetzen + + + Set Comment + Setze Kommentar + + + Set Tag + Setze Tag + + + Tag + Tag + + + Reading file... + Lese Datei... + + + Importing games... + Importiere Spiele... + + + English draughts + Englische Regeln + + + Russian draughts + Russische Regeln + + + Unknown game type + Unbekannter Spieltyp + + + Free Placement Mode + Platzieren-Modus + + + Paused Mode + Pause-Modus + + + Play Mode + Spiel-Modus + + + + myHumanPlayer + + You must capture. + Sie müssen Schlagen. + + + Unmovable. + Unbewegbar. + + + you must capture + Sie müssen Schlagen + + + unmovable + unbewegbar + + + Cannot move this. + Kann nicht bewegen. + + + + myInfo + + Move + Zug + + + Comment + Kommentar + + + White + Weiß + + + Black + Schwarz + + + English draughts + Englische Regeln + + + Russian draughts + Russische Regeln + + + Unknown game type + Unbekannter Spieltyp + + + Importing games... + Importiere Spiele... + + + Reading file... + Lese Datei... + + + Continue + Fortsetzen + + + Previous + Zurück + + + Next + Vor + + + Undo + Rückgängig + + + Redo + Wiederholen + + + Set Comment + Setze Kommentar + + + Set Tag + Setze Tag + + + Free Placement Mode + Platzieren-Modus + + + Paused Mode + Pause-Modus + + + Play Mode + Spiel-Modus + + + Tag + Tag + + + + myNewGameDlg + + New Game + Neues Spiel + + + Rules + Regeln + + + Skill + Schwierigkeitsgrad + + + Beginner + Anfänger + + + Novice + Novize + + + Average + Durchschnitt + + + Good + Gut + + + Expert + Experte + + + Master + Meister + + + Accept + Akzeptieren + + + Address: + Adresse: + + + Servername: + Servername: + + + Serverinfo: + Serverinfo: + + + &Start + &Starten + + + &Cancel + A&bbrechen + + + Wait... + Warte... + + + Waiting for client to connect... + Warte auf Netzwerkspieler... + + + Waiting for server to accept... + Warte auf Serverbestätigung... + + + Server denied. + Server lehnt ab. + + + Connection aborted. + Verbindung getrennt. + + + Human + Mensch + + + Player One + Spieler Eins + + + White + Weiß + + + Player Two + Spieler Zwei + + + Computer + Computer + + + Network - New Game + Netzwerk - Neues Spiel + + + Network - Join Game + Netzwerk - Spiel betreten + + + Server + Server + + + Could not create a game on the server. + Konnte kein Spiel auf dem Server erstellen. + + + Could not join the game. + Konnte dem Spiel nicht beitreten. + + + Client connected. + Mit dem Client verbunden. + + + Client disconnected. + Client hat sich verabschiedet. + + + Free Men Placement + Freies Platzieren der Figuren + + + + myTopLevel + + &New... + &Neu... + + + CTRL+N + File|New + CTRL+N + + + &Next Round + &Nächste Runde + + + &Stop + &Stopp + + + &Undo Move + &Zug rückgängig + + + CTRL+Z + File|Undo + CTRL+Z + + + &Information + &Information + + + &Open... + &Öffnen... + + + CTRL+O + File|Open + CTRL+O + + + &Save... + &Speichern... + + + CTRL+S + File|Save + CTRL+S + + + &Quit + &Beenden + + + CTRL+Q + File|Quit + CTRL+Q + + + &Show Notation + &Zeige Notation + + + &Green Board + &Grünes Brett + + + &Marble Board + &Rotes Brett + + + &Wooden Board + &Hölzernes Brett + + + &Console + &Konsole + + + What's This + Was ist das + + + SHIFT+F1 + Help|WhatsThis + SHIFT+F1 + + + &Rules of Play + &Spielregeln + + + F1 + Help|Help + F1 + + + About &Qt + Über &Qt + + + &Game + &Spiel + + + &View + &Ansicht + + + &Settings + &Einstellungen + + + &Help + &Hilfe + + + Error + Fehler + + + &Close + &Schließen + + + Save Game + Spiel speichern + + + Could not save: + Konnte nicht speichern: + + + Open Game + Spiel laden + + + Could not load: + Konnte nicht öffnen: + + + Game Info + Spielinfo + + + Rules of Play + Spielregeln + + + About + Über + + + Current game will be lost if you continue. +Do you really want to discard it? + Das aktuelle Spiel geht verloren, wenn Sie fortfahren. +Wollen sie es wirklich verwerfen? + + + Abort Game? + Spiel abbrechen? + + + <p>In the beginning of game you have 12 checkers (men). White always moves first. The men move forward only. The men can capture:<ul><li>by jumping forward only (english rules);<li>by jumping forward or backward (russian rules).</ul><p>A man which reaches the far side of the board becomes a king. The kings move forward or backward:<ul><li>to one square only (english rules);<li>to any number of squares (russian rules).</ul><p>The kings capture by jumping forward or backward. Whenever a player is able to make a capture he must do so. + <p>Sie beginnen mit 12 Steinen. Weiß beginnt das Spiel. Sie können die Steine nur nach vorne bewegen. Diese können andere Steine schlagen:<ul><li>indem sie nur nach vorne springen (Englische Regeln);<li>indem sie sowohl nach vorn als auch nach hinten springen (Russische Regeln).</ul><p>Ein Stein der die gegenüberliegende Seite erreicht, wird zur Dame.Die Dame bewegt sich sowohl vorwärts als auch rückwärts:<ul><li>immer nur ein Feld pro Zug (Englische Regeln);<li>beliebig viele Felder pro Zug (Russische Regeln).</ul><p>Die Dame kann vor-/ und rückwärts schlagen. Schlagen ist Pflicht. + + + &Confirm aborting current game + &Bestätige Abbrechen des laufenden Spiels + + + &Open console on new messages + &Öffne Konsole beim Entreiffen neues Nachrichten + + + &Small board + &Kleines Brett + + + &Big board + &Großes Brett + + + &About + &Über + + + Show notation &above + Zeige Notation &über + + + &Notation font... + &Notationsschrift... + + + <p>In the beginning of game you have 12 checkers (men). The men move forward only. The men can capture:<ul><li>by jumping forward only (english rules);<li>by jumping forward or backward (russian rules).</ul><p>A man which reaches the far side of the board becomes a king. The kings move forward or backward:<ul><li>to one square only (english rules);<li>to any number of squares (russian rules).</ul><p>The kings capture by jumping forward or backward. Whenever a player is able to make a capture he must do so. + <p>Sie beginnen mit 12 Steinen. Sie können die Steine nur nach vorne bewegen. Diese können andere Steine schlagen:<ul><li>indem sie nur nach vorne springen (Englische Regeln);<li>indem sie sowohl nach vorn als auch nach hinten springen (Russische Regeln).</ul><p>Ein Stein der die gegenüberliegende Seite erreicht, wird zur Dame.Die Dame bewegt sich sowohl vorwärts als auch rückwärts:<ul><li>immer nur ein Feld pro Zug (Englische Regeln);<li>beliebig viele Felder pro Zug (Russische Regeln).</ul><p>Die Dame kann vor-/ und rückwärts schlagen. Schlagen ist Pflicht. + + + File already exists. +Do you really want to override it? + Die Datei existiert bereits. +Wollen Sie sie wirklich überschreiben? + + + Clear &log on new round + Lösche &Log bei Rundenbeginn + + + Shift+/ + Shift+/ + + + Show notation &above men + Zeige Notation &über Spielsteinen + + + &Toolbar + &Toolleiste + + + + myView + + Go! + Los! + + + Game aborted. + Spiel abgebrochen. + + + Connection closed. + Verbundung getrennt. + + + Drawn game. + Unentschieden. + + + Invalid move. + Ungültiger Zug. + + + Waiting for opponent to move... + Warte auf Gegenspieler... + + + White wins! + Weiß gewinnt! + + + Black wins! + Schwarz gewinnt! + + + White + Weiß + + + Black + Schwarz + + + Invalid move + Ungültiger Zug + + + It's not your turn. + Du bist nicht am Zug. + + + opponent + Gegner + + + Warning! Some errors occured. + Warnung! Es sind Fehler aufgetreten. + + + Preview mode + Vorschau-Modus + + + Syntax error. Usage: /from-to + Syntaxfehler. Gebrauch: /von-nach + + + Saved: + Gespeichert: + + + Opened: + Geöffnet: + + + Play mode + Spiel-Modus + + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.qm b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.qm new file mode 100644 index 000000000..769e705ae Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.qm differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.ts b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.ts new file mode 100644 index 000000000..068641a70 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_fr.ts @@ -0,0 +1,570 @@ + + + myHistory + + Move + Déplacer + + + Comment + Commentaire + + + Undo + Annuler + + + Redo + Refaire + + + Continue + Continuer + + + Set Comment + Définir le Commentaire + + + Set Tag + Définir le Tag + + + Tag + Tag + + + Reading file... + Lecture du fichier en cours... + + + Importing games... + Importe les jeux... + + + English draughts + Dames anglaises + + + Russian draughts + Dames russes + + + Unknown game type + Type de jeu inconnu + + + Free Placement Mode + Mode de Placement Libre + + + Paused Mode + Mode Pause + + + Play Mode + Mode Jeu + + + + myHumanPlayer + + Go! + Commencer ! + + + Incorrect course. + Mouvement impossible. Peut-être une capture est-elle possible ? + + + You must capture. + Vous devez capturer. + + + Cannot move this. + Impossible de déplacer cet élément. + + + + myInfo + + Move + Déplacer + + + Comment + Commentaire + + + Undo + Annuler + + + Redo + Refaire + + + Continue + Continuer + + + Set Comment + Définir le Commentaire + + + Set Tag + Définir le Tag + + + Reading file... + Lecture du fichier en cours... + + + Importing games... + Importe les jeux... + + + English draughts + Dames anglaises + + + Russian draughts + Dames russes + + + Unknown game type + Type de jeu inconnu + + + Free Placement Mode + Mode de Placement Libre + + + Paused Mode + Mode Pause + + + Play Mode + Mode Jeu + + + Tag + Tag + + + + myNewGameDlg + + New Game + Nouveau Jeu + + + Against CPU on this PC + Contre l'ordinateur local + + + Against Human on Network - New Game + Contre un humain en réseau - Nouvelle partie + + + Against Human on Network - Join Game + Contre un humain en réseau - Joindre une partie + + + Rules + Règles + + + English + Anglaises + + + Russian + Russes + + + Skill + Niveau de difficulté + + + Beginner + Débutant + + + Novice + Novice + + + Average + Moyen + + + Good + Bon + + + Expert + Expert + + + Master + Maître + + + Server IP: + IP du serveur: + + + Pick free port + Prendre un port libre + + + &Start + &Commencer + + + &Cancel + &Annuler + + + Human + Humain + + + Player One + Joueur Un + + + White + Blancs + + + Player Two + Joueur Deux + + + Computer + Ordinateur + + + Free Men Placement + Placement des Pions Libre + + + + myTopLevel + + &New... + &Nouveau... + + + CTRL+N + File|New + CTRL+N + + + &Next Round + Niveau &Suivant + + + &Stop + &Arrêter + + + &Undo Move + &Annuler le mouvement + + + CTRL+Z + File|Undo + CTRL+Z + + + &Information + &Information + + + &Open... + &Ouvrir... + + + CTRL+O + File|Open + CTRL+O + + + &Save... + &Enregistrer... + + + CTRL+S + File|Save + CTRL+S + + + &Quit + &Quitter + + + CTRL+Q + File|Quit + CTRL+Q + + + &Show Notation + &Afficher la notation + + + &Green Board + &Plateau vert + + + &Marble Board + &Plateau marbré + + + &Wooden Board + &Plateau en bois + + + What's This + Qu'est ce que c'est ? + + + SHIFT+F1 + Help|WhatsThis + SHIFT+F1 + + + &Rules of Play + &Règles du jeu + + + F1 + Help|Help + F1 + + + &About + À &propos + + + About &Qt + À propos de &Qt + + + &Game + &Jeu + + + &View + &Afficher + + + &Settings + &Configurer KCheckers + + + &Help + &Aide + + + Error + Erreur + + + &Close + &Fermer + + + Save Game + Enregistrer la Partie + + + Could not save: + Impossible d'enregistrer : + + + Open Game + Charger une Partie + + + Could not load: + Impossible d'ouvrir: + + + Game Info + Informations sur la partie + + + Rules of Play + Règles de jeu + + + About + À propos + + + Quit Game? + Quitter la partie ? + + + Current game will be lost if you continue. +Do you really want to discard it? + La partie en cours sera perdue si vous continuez. +Voulez-vous vraiment l'abandonner ? + + + Abort Game? + Abandonner la partie ? + + + &Confirm aborting current game + &Confirmer l'abandon de la partie + + + &About + &À Propos + + + Show notation &above men + Afficher la notation &au dessus des pions + + + Clear &log on new round + Nettoyer le &log au niveau niveau + + + &Notation font... + Fonte pour la &notation... + + + &Toolbar + &Barre d'outils + + + <p>In the beginning of game you have 12 checkers (men). The men move forward only. The men can capture:<ul><li>by jumping forward only (english rules);<li>by jumping forward or backward (russian rules).</ul><p>A man which reaches the far side of the board becomes a king. The kings move forward or backward:<ul><li>to one square only (english rules);<li>to any number of squares (russian rules).</ul><p>The kings capture by jumping forward or backward. Whenever a player is able to make a capture he must do so. + <p>Au début vous avez 12 pions. Les pions peuvent se déplacer uniquement en avant. Ils peuvent capturer :<ul><li>en sautant en avant seulement (règles anglaises),<li>en sautant en avant ou en arrière (règles russes).</ul><p>Un pion qui arrive du côté adverse du plateau devient une dame. Les dames peuvent se déplacer en avant ou en arrière :<ul><li>d'une seule case (règles anglaises),<li>de plusieurs cases (règles russes).</ul><p>Les dames peuvent capturer en sautant en avant ou en arrière. Quand une capture est possible, elle doit obligatoirement être exécutée. + + + + + myView + + Go! + Commencer ! + + + You have lost. Game over. + Vous avez perdu. Fin de la partie. + + + Congratulation! You have won! + Félicitations ! Vous avez gagné ! + + + I am thinking... + Je pense... + + + Waiting network player to move... + En attente du mouvement du joueur distant... + + + Incorrect course. + Mouvement impossible. Peut-être une capture est-elle possible ? + + + Waiting for network player to connect... + En attente de la connexion du joueur distant... + + + Waiting for server to reply... + En attente de la réponse du serveur... + + + Game aborted. + Partie abandonnée. + + + ENGLISH rules. + Règles ANGLAISES. + + + RUSSIAN rules. + Règles RUSSES. + + + +New Network Game + +Nouvelle partie en réseau + + + +Join Network Game + +Rejoindre une partie en réseau + + + Unknown rules. Playing current rules: + Règles inconnues. Adopte les règles courantes : + + + Unknown skill. Keeping current skill: + Niveau inconnu. Conserve le niveau courant : + + + Player + Le joueur + + + is played by KCheckers with current skill: + est controllé par KCheckers avec le niveau courant : + + + This is not implemented yet. + Ceci n'est pas encore implémenté. + + + Please consider Information mismatch. + Veuillez considérer que les informations sont discordantes. + + + Russian + Russes + + + Drawn game. + Match nul. + + + Invalid move. + Mouvement invalide. + + + White wins! + Les blancs gagnent ! + + + Black wins! + Les noirs gagnent ! + + + opponent + adversaire + + + Opened: + Ouvert : + + + Warning! Some errors occured. + Attention ! Des erreurs sont survenues. + + + Saved: + Enregistré : + + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_ru.ts b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_ru.ts new file mode 100644 index 000000000..222ecdbff --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/i18n/kcheckers_ru.ts @@ -0,0 +1,545 @@ + + + PdnPreview + + White + Белые + + + Black + Черные + + + Open board only + Показывать доску + + + No preview available. + Предпросмотр невозможен. + + + English draughts + Английские чекерсы + + + Russian draughts + Русские шашки + + + Unknown game type + Правила неизвестны + + + + myConsole + + Clear + Очистить + + + Save + Сохранить + + + Save Console + Сохранить команды + + + + myHumanPlayer + + You must capture. + Вы должны бить. + + + Unmovable. + Нет хода. + + + Cannot move this. + Нет хода. + + + + myInfo + + White + Белые + + + Black + Черные + + + English draughts + Английские чекерсы + + + Russian draughts + Русские шашки + + + Unknown game type + Правила неизвестны + + + Importing games... + + + + Reading file... + + + + Continue + + + + Move + + + + Comment + + + + Undo + + + + Redo + + + + Set Comment + + + + Set Tag + + + + Free Placement Mode + + + + Paused Mode + + + + Play Mode + + + + Tag + + + + + myNewGameDlg + + New Game + Новая игра + + + Rules + Правила + + + Skill + Уровень + + + Beginner + Подготовительный + + + Novice + Начальный + + + Average + Средний + + + Good + Сложный + + + Expert + Эксперт + + + Master + Мастер + + + Accept + Принять + + + Address: + Адрес: + + + Servername: + Имя сервера: + + + Serverinfo: + Информация о сервере: + + + &Start + &Старт + + + &Cancel + &Отмена + + + Wait... + Подождите... + + + Waiting for client to connect... + Ожидание связи с клиентом... + + + Waiting for server to accept... + Ожидание ответа от сервера... + + + Server denied. + Сервер недоступен. + + + Connection aborted. + Связь прервана. + + + Human + Человек + + + Player One + Первый игрок + + + White + Белые + + + Player Two + Второй игрок + + + Computer + Компьютер + + + Network - New Game + Сеть - Новая игра + + + Network - Join Game + Сеть - Присоединиться + + + Server + Сервер + + + Client + Клиент + + + Could not create a game on the server. + Невозможно запустить игру на сервере. + + + Could not join the game. + Невозможно присоединиться к игре. + + + Client connected. + Связь с клиентом установлена. + + + Client disconnected. + Связь с клиентом разорвана. + + + Free Men Placement + + + + + myTopLevel + + &New... + &Новая... + + + CTRL+N + File|New + CTRL+N + + + &Next Round + &Следующая партия + + + &Stop + &Стоп + + + &Undo Move + &Ход назад + + + CTRL+Z + File|Undo + CTRL+Z + + + &Information + &Информация + + + &Open... + &Открыть... + + + CTRL+O + File|Open + CTRL+O + + + &Save... + &Сохранить... + + + CTRL+S + File|Save + CTRL+S + + + &Quit + &Выход + + + CTRL+Q + File|Quit + CTRL+Q + + + &Show Notation + &Показать нотацию + + + &Green Board + &Зеленая доска + + + &Marble Board + &Мраморная доска + + + &Wooden Board + &Деревянная доска + + + &Console + &Консоль + + + What's This + Что это + + + SHIFT+F1 + Help|WhatsThis + SHIFT+F1 + + + &Rules of Play + &Правила игры + + + F1 + Help|Help + F1 + + + About &Qt + О &Qt + + + &Game + &Игра + + + &View + &Вид + + + &Settings + &Настройки + + + &Help + &Справка + + + Error + Ошибка + + + &Close + &Закрыть + + + Save Game + Сохранить игру + + + Could not save: + Невозможно сохранить: + + + Open Game + Открыть игру + + + Could not load: + Невозможно открыть: + + + Game Info + Информация об игре + + + Rules of Play + Правила игры + + + About + О программе + + + Current game will be lost if you continue. +Do you really want to discard it? + Текущая игра будет прервана. +Вы действительно этого хотите? + + + Abort Game? + Прервать игру? + + + <p>In the beginning of game you have 12 checkers (men). White always moves first. The men move forward only. The men can capture:<ul><li>by jumping forward only (english rules);<li>by jumping forward or backward (russian rules).</ul><p>A man which reaches the far side of the board becomes a king. The kings move forward or backward:<ul><li>to one square only (english rules);<li>to any number of squares (russian rules).</ul><p>The kings capture by jumping forward or backward. Whenever a player is able to make a capture he must do so. + <p>В начале игры у вас есть 12 пешек. Белые всегда начинают. Пешки могут ходить только вперед. Пешки могут бить:<ul><li>только вперед (английские правила);<li>вперед и назад (русские правила).</ul><p>Пешка, достигающая противоположного края доски, становится дамкой. Дамки ходят вперед и назад:<ul><li>только на соседние поля (английские правила);<li>на любое количество клеток (русские правила).</ul><p>Дамки могут бить и вперед и назад. Если игрок может бить, то он обязан это сделать. + + + + &Confirm aborting current game + &Подтвердите прерывание текущей игры + + + &Open console on new messages + &Открытие консоли для сообщений + + + &Small board + &Маленькая доска + + + &Big board + &Большая доска + + + &About + &О программе + + + &Notation font... + + + + <p>In the beginning of game you have 12 checkers (men). The men move forward only. The men can capture:<ul><li>by jumping forward only (english rules);<li>by jumping forward or backward (russian rules).</ul><p>A man which reaches the far side of the board becomes a king. The kings move forward or backward:<ul><li>to one square only (english rules);<li>to any number of squares (russian rules).</ul><p>The kings capture by jumping forward or backward. Whenever a player is able to make a capture he must do so. + <p>В начале игры у вас есть 12 пешек. Пешки могут ходить только вперед. Пешки могут бить:<ul><li>только вперед (английские правила);<li>вперед и назад (русские правила).</ul><p>Пешка, достигающая противоположного края доски, становится дамкой. Дамки ходят вперед и назад:<ul><li>только на соседние поля (английские правила);<li>на любое количество клеток (русские правила).</ul><p>Дамки могут бить и вперед и назад. Если игрок может бить, то он обязан это сделать. + + + Clear &log on new round + + + + Show notation &above men + + + + &Toolbar + + + + + myView + + Go! + Ваш ход! + + + Game aborted. + Игра прервана. + + + Connection closed. + Соединение закрыто. + + + Drawn game. + Затявнушаяся игра. + + + Invalid move. + Неверный ход. + + + Waiting for opponent to move... + Ожидание хода противника... + + + White wins! + Выиграли белые! + + + Black wins! + Выиграли черные! + + + White + Белые + + + Black + Черные + + + opponent + противник + + + Warning! Some errors occured. + + + + Saved: + + + + Opened: + + + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/Thumbs.db b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/Thumbs.db new file mode 100644 index 000000000..7a46fc41d Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/Thumbs.db differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/biglogo.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/biglogo.png new file mode 100644 index 000000000..a4b052a34 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/biglogo.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/clear.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/clear.png new file mode 100644 index 000000000..66d96d85c Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/clear.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/console.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/console.png new file mode 100644 index 000000000..ef1fb8979 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/console.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/context.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/context.png new file mode 100644 index 000000000..e8e6b4d45 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/context.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/continue.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/continue.png new file mode 100644 index 000000000..4d069e52a Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/continue.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/dialog.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/dialog.png new file mode 100644 index 000000000..c5630c6ba Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/dialog.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/down.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/down.png new file mode 100644 index 000000000..9990d86d4 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/down.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/exit.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/exit.png new file mode 100644 index 000000000..363c9b4c3 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/exit.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/fileopen.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/fileopen.png new file mode 100644 index 000000000..e4bdb3df1 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/fileopen.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/filesave.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/filesave.png new file mode 100644 index 000000000..869209e31 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/filesave.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/freeplace.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/freeplace.png new file mode 100644 index 000000000..5ec4b060c Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/freeplace.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/info.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/info.png new file mode 100644 index 000000000..36524824b Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/info.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/logo.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/logo.png new file mode 100644 index 000000000..16facdd15 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/logo.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/next.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/next.png new file mode 100644 index 000000000..93fa94c81 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/next.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/paused.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/paused.png new file mode 100644 index 000000000..9d4b7d911 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/paused.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/redo.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/redo.png new file mode 100644 index 000000000..defa358de Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/redo.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/stop.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/stop.png new file mode 100644 index 000000000..ea7ddcdad Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/stop.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/Thumbs.db b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/Thumbs.db new file mode 100644 index 000000000..2a36d81d2 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/Thumbs.db differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/frame.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/frame.png new file mode 100644 index 000000000..669aa8d71 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/frame.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingblack.png new file mode 100644 index 000000000..b6a596a4f Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingwhite.png new file mode 100644 index 000000000..64fc42f1a Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/kingwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manblack.png new file mode 100644 index 000000000..32372efee Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manwhite.png new file mode 100644 index 000000000..6262d38f1 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/manwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile1.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile1.png new file mode 100644 index 000000000..843fa0043 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile1.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile2.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile2.png new file mode 100644 index 000000000..c415b4d0d Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/theme/tile2.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/undo.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/undo.png new file mode 100644 index 000000000..3ad9e865c Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/undo.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/up.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/up.png new file mode 100644 index 000000000..27f475c89 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/icons/up.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/main.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/main.cc new file mode 100644 index 000000000..f3dede268 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/main.cc @@ -0,0 +1,49 @@ +#include +#include +#include +#include +//#include + + +#include "toplevel.h" +#include "common.h" + + +int main(int argc, char *argv[]) +{ + QApplication app(argc,argv); +// app.setStyle(new QPlastiqueStyle); + + qDebug() + << "Your Locale:" << QLocale::system().name() << endl + << "Prefix path:" << PREFIX; + + // Qt translations + QTranslator qt_tr; + if(qt_tr.load("qt_" + QLocale::system().name())) + app.installTranslator(&qt_tr); + else + qDebug() << "Loading Qt translations failed."; + + // App translations + QTranslator app_tr; + if(app_tr.load("kcheckers_" + QLocale::system().name(), + PREFIX"/share/kcheckers")) + app.installTranslator(&app_tr); + else + qDebug() << "Loading KCheckers translations failed."; + + myTopLevel* top = new myTopLevel(); + top->show(); + + // command line + if(app.argc()==2) + top->open(app.argv()[1]); + + int exit = app.exec(); + + delete top; + return exit; +} + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.cc new file mode 100644 index 000000000..d13af8f1c --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.cc @@ -0,0 +1,324 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include + +#include +#include + +#include "newgamedlg.h" +#include "pdn.h" +#include "common.h" +#include "history.h" + +#include "player.h" + + +#define BEGINNER 2 +#define NOVICE 4 +#define AVERAGE 6 +#define GOOD 7 +#define EXPERT 8 +#define MASTER 9 + +#define CFG_SKILL CFG_KEY"Skill" +#define CFG_RULES CFG_KEY"Rules" +#define CFG_WHITE CFG_KEY"White" +#define CFG_PLAYER1 CFG_KEY"Player1" +#define CFG_PLAYER2 CFG_KEY"Player2" + + +myNewGameDlg::myNewGameDlg(QWidget* parent) + : QDialog(parent) +{ + setModal(true); + setWindowTitle(tr("New Game")+QString(" - "APPNAME)); + + + /* + * buttons, options. + */ + start_button = new QPushButton(tr("&Start"), this); + start_button->setDefault(true); + connect(start_button, SIGNAL(clicked()), this, SLOT(slot_start())); + + QPushButton* cn = new QPushButton(tr("&Cancel"), this); + connect(cn, SIGNAL(clicked()), this, SLOT(slot_reject())); + + // TODO - better text + m_freeplace = new QCheckBox(tr("Free Men Placement"), this); + + QHBoxLayout* buttons_layout = new QHBoxLayout(); + buttons_layout->addWidget(m_freeplace); + buttons_layout->addStretch(); + buttons_layout->addWidget(start_button); + buttons_layout->addWidget(cn); + + + /* + * global layout. + */ + QHBoxLayout* players_layout = new QHBoxLayout(); + players_layout->addWidget(create_player_one()); + players_layout->addWidget(create_player_two()); + + QVBoxLayout* global_layout = new QVBoxLayout(this); + global_layout->addLayout(players_layout); + global_layout->addLayout(buttons_layout); +} + + +myNewGameDlg::~myNewGameDlg() +{ +} + + +QWidget* myNewGameDlg::create_human_options() +{ + QFrame* frm = new QFrame(); + QVBoxLayout* frm_layout = new QVBoxLayout(frm); + frm_layout->addWidget(new QLabel("No options available.")); + frm_layout->addStretch(); + + return frm; +} + + +QWidget* myNewGameDlg::create_player_one() +{ + m_player_one.box = new QGroupBox(tr("Player One"), this); + + // name + m_player_one.name = new QLineEdit(m_player_one.box); + + // rules group box + m_player_one.rules = new QGroupBox(tr("Rules"), m_player_one.box); + m_player_one.rule_english = new QRadioButton( + myHistory::typeToString(ENGLISH), m_player_one.rules); + m_player_one.rule_russian = new QRadioButton( + myHistory::typeToString(RUSSIAN), m_player_one.rules); + + QVBoxLayout* rules_layout = new QVBoxLayout(m_player_one.rules); + rules_layout->addWidget(m_player_one.rule_english); + rules_layout->addWidget(m_player_one.rule_russian); + + // play white men? + m_player_one.white = new QCheckBox(tr("White"), m_player_one.box); + + // layout + QVBoxLayout* vb1_layout = new QVBoxLayout(m_player_one.box); + vb1_layout->addWidget(m_player_one.name); + vb1_layout->addWidget(m_player_one.rules); + vb1_layout->addWidget(m_player_one.white); + + return m_player_one.box; +} + + +QWidget* myNewGameDlg::create_player_two() +{ + m_player_two.box = new QGroupBox(tr("Player Two"), this); + + // name + m_player_two.name = new QLineEdit(m_player_two.box); + + // options + m_player_two.options = new QTabWidget(m_player_two.box); + m_player_two.options->insertTab(COMPUTER, create_computer_options(), tr("Computer")); + m_player_two.options->insertTab(HUMAN, create_human_options(), tr("Human")); + connect(m_player_two.options, SIGNAL(currentChanged(int)), + this, SLOT(slot_game(int))); + + /* + * frame layout + */ + QVBoxLayout* frm_layout = new QVBoxLayout(m_player_two.box); + frm_layout->addWidget(m_player_two.name); + frm_layout->addWidget(m_player_two.options); + + return m_player_two.box; +} + + +QWidget* myNewGameDlg::create_computer_options() +{ + QFrame* frm = new QFrame(); + + // skills + QGroupBox* skills = new QGroupBox(tr("Skill"), frm); + m_player_two.computer.skills[BEGINNER] = new QRadioButton(tr("Beginner"), + skills); + m_player_two.computer.skills[NOVICE] = new QRadioButton(tr("Novice"), + skills); + m_player_two.computer.skills[AVERAGE] = new QRadioButton(tr("Average"), + skills); + m_player_two.computer.skills[GOOD] = new QRadioButton(tr("Good"), + skills); + m_player_two.computer.skills[EXPERT] = new QRadioButton(tr("Expert"), + skills); + m_player_two.computer.skills[MASTER] = new QRadioButton(tr("Master"), + skills); + + QGridLayout* skills_layout = new QGridLayout(skills); + int row = 0; + int col = 0; + foreach(QRadioButton* rb, m_player_two.computer.skills) { + skills_layout->addWidget(rb, row++, col); + connect(rb, SIGNAL(clicked()), this, SLOT(slot_skills())); + if(row > 2) { + row = 0; + col = 1; + } + } + + // layout + QHBoxLayout* frm_layout = new QHBoxLayout(frm); + frm_layout->addWidget(skills); + + return frm; +} + + +void myNewGameDlg::slot_reject() +{ + reject(); +} + + +void myNewGameDlg::slot_start() +{ + accept(); +} + + +void myNewGameDlg::slot_skills() +{ + QRadioButton* skill = 0; + foreach(QRadioButton* rb, m_player_two.computer.skills) { + if(rb->isChecked()) { + skill = rb; + break; + } + } + + if(skill) + m_player_two.name->setText("*"+skill->text()+"*"); +} + + +void myNewGameDlg::slot_game_start(int id) +{ + slot_game(id); + slot_start(); +} + + +void myNewGameDlg::slot_game(int id) +{ + start_button->setEnabled(true); + m_player_one.box->setEnabled(true); + m_player_two.options->setEnabled(true); + + if(m_player_two.last_game_index==HUMAN) { + m_cfg_player2 = m_player_two.name->text(); + } + + m_player_two.last_game_index = id; + + switch(id) { + case COMPUTER: + m_player_two.name->setReadOnly(true); + slot_skills(); + + m_player_one.rules->setEnabled(true); + m_player_one.white->setEnabled(true); + break; + + case HUMAN: + m_player_two.name->setReadOnly(false); + m_player_two.name->setText(m_cfg_player2); + + m_player_one.rules->setEnabled(true); + m_player_one.white->setEnabled(true); + break; + + default: + qDebug() << __PRETTY_FUNCTION__ << "ERR"; + break; + } +} + + +void myNewGameDlg::writeSettings(QSettings* cfg) +{ + cfg->setValue(CFG_SKILL, skill()); + cfg->setValue(CFG_RULES, rules()); + cfg->setValue(CFG_WHITE, m_player_one.white->isChecked()); + + cfg->setValue(CFG_PLAYER1, m_player_one.name->text()); + cfg->setValue(CFG_PLAYER2, m_cfg_player2); +} + + +void myNewGameDlg::readSettings(QSettings* cfg) +{ + int skills = cfg->value(CFG_SKILL, BEGINNER).toInt(); + QMap::iterator it; + it = m_player_two.computer.skills.find(skills); + if(it != m_player_two.computer.skills.end()) + it.value()->setChecked(true); + else + m_player_two.computer.skills[BEGINNER]->setChecked(true); + slot_skills(); + + int rules = cfg->value(CFG_RULES, ENGLISH).toInt(); + if(rules == ENGLISH) + m_player_one.rule_english->setChecked(true); + else + m_player_one.rule_russian->setChecked(true); + + m_player_one.white->setChecked(cfg->value(CFG_WHITE, false).toBool()); + + m_player_one.name->setText(cfg->value(CFG_PLAYER1, + getenv("USER")).toString()); + m_cfg_player2 = cfg->value(CFG_PLAYER2, "Player2").toString(); +} + + +int myNewGameDlg::skill() const +{ + QMap::const_iterator it; + it = m_player_two.computer.skills.begin(); + for(; it!=m_player_two.computer.skills.end(); ++it) { + if(it.value()->isChecked()) + return it.key(); + } + + qDebug() << __PRETTY_FUNCTION__ << "No skill selected."; + return BEGINNER; +} + + +int myNewGameDlg::rules() const +{ + if(m_player_one.rule_english->isChecked()) + return ENGLISH; + return RUSSIAN; +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.h new file mode 100644 index 000000000..22b4dc34a --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/newgamedlg.h @@ -0,0 +1,116 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _NEWGAMEDLG_H_ +#define _NEWGAMEDLG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define COMPUTER 0 +#define HUMAN 1 + + +class myPlayer; + + +class myNewGameDlg : public QDialog +{ + Q_OBJECT + +public: + myNewGameDlg(QWidget* parent); + ~myNewGameDlg(); + + // playing against the computer + int rules() const; + // return HUMAN/COMPUTER + int opponent() const { return m_player_two.options->currentIndex(); } + // + int skill() const; + // + bool freePlacement() const { return m_freeplace->isChecked(); } + + // + const QString name() const { return m_player_one.name->text(); } + bool isWhite() const { return m_player_one.white->isChecked(); } + const QString opponentName() const { return m_player_two.name->text(); } + + // for settings + void writeSettings(QSettings*); + void readSettings(QSettings*); + +private slots: + void slot_game(int id); // ListWidget + void slot_game_start(int id); + void slot_skills(); + + void slot_reject(); + void slot_start(); + +private: + QWidget* create_player_one(); + QWidget* create_player_two(); + + QWidget* create_human_options(); + QWidget* create_computer_options(); + +private: + struct player_one_struct { + QGroupBox* box; + QLineEdit* name; + QGroupBox* rules; + QRadioButton* rule_english; + QRadioButton* rule_russian; + QCheckBox* white; + }; + struct player_one_struct m_player_one; + + struct player_two_struct { + QGroupBox* box; + QLineEdit* name; + int last_game_index; + QTabWidget* options; + // human options + // computer options + struct computer_stuct { + QMap skills; + }; + struct computer_stuct computer; + }; + struct player_two_struct m_player_two; + + QCheckBox* m_freeplace; + QPushButton* start_button; + + QString m_cfg_player2; +}; + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.cc new file mode 100644 index 000000000..01d32f269 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.cc @@ -0,0 +1,541 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include +#include + +#include "checkers.h" +#include "pdn.h" + + +#define PLAYER true +#define COMPUTER false + +#define END_OF_MOVELINE "@." + + +Pdn::Pdn() +{ +} + + +Pdn::~Pdn() +{ + qDeleteAll(m_database); + m_database.clear(); +} + + +bool Pdn::open(const QString& filename, QWidget* parent, + const QString& label, QString& text_to_log) +{ + qDeleteAll(m_database); + m_database.clear(); + + QFile file(filename); + if(!file.open(QFile::ReadOnly)) return false; + + QTextStream ts(&file); + + QString str1, str2; + + QProgressDialog progress(parent); + progress.setModal(true); + progress.setLabelText(label); + progress.setRange(0, file.size()); + progress.setMinimumDuration(0); + + unsigned int line_nr = 1; + unsigned int game_started = 1; + bool in_tags = false; + while(!ts.atEnd()) { + str1 = ts.readLine().trimmed(); + if(ts.atEnd()) + str2 += str1; + + if((str1.length() && str1[0]=='[') || ts.atEnd()) { + if(!in_tags) { + // tags begin again, so a game is ended. + if(str2.length()) { + if((m_database.count()%10)==0) + progress.setValue(file.pos()); + + QString log_txt; + PdnGame* game = new PdnGame(str2, log_txt); + m_database.append(game); + + if(log_txt.length()) { + text_to_log + += QString("%1. game begins at line %2:\n") + .arg(m_database.count()) + .arg(game_started); + text_to_log += log_txt; + } + + game_started = line_nr; + str2=""; + } + + in_tags = true; + } + } else { + if(in_tags) + in_tags = false; + } + + str2.append(str1+"\n"); + + if(progress.wasCanceled()) + break; + + line_nr++; + } + + file.close(); + + return true; +} + + +bool Pdn::save(const QString& filename) +{ + QFile file(filename); + if(!file.open(QFile::WriteOnly)) + return false; + + QTextStream ts(&file); + + foreach(PdnGame* game, m_database) { + ts << game->toString() << endl << endl; + } + + file.close(); + return true; +} + + + +PdnGame* Pdn::newGame() +{ + QString log_txt; // here: ignore TODO + PdnGame* game = new PdnGame("", log_txt); + m_database.append(game); + return game; +} + + +/*************************************************************************** + * * + * * + ***************************************************************************/ +PdnMove::PdnMove(QString line) +{ + if(line[0]=='{') { + qDebug("a move must not begin with a comment."); + return; + } + + // first move. + m_first = line.section(' ', 0, 0); + line = line.mid(m_first.length()).trimmed(); + + // check for a first comment. + if(line[0]=='{') { + int end = line.indexOf('}', 1); + if(end>=0) { + m_comfirst = line.mid(1, end-1); + line.remove(0, end+1); + line = line.trimmed(); + } else + qDebug("no comment ending of the first comment."); + } + + // second move. + m_second = line.section(' ', 0, 0); + line = line.mid(m_second.length()).trimmed(); + + // check for a second comment. + if(line[0]=='{') { + int end = line.indexOf('}', 1); + if(end>=0) + m_comsecond = line.mid(1, end-1); + else + qDebug("no comment ending of the second comment."); + } +} + + +/*************************************************************************** + * * + * * + ***************************************************************************/ +PdnGame::PdnGame(const QString& game_string, QString& log_txt) +{ + white = PLAYER; + for(int i=0; i<12; i++) + board[i]=MAN2; + for(int i=20; i<32; i++) + board[i]=MAN1; + + if(!parse(game_string, log_txt)) { + qDebug(" errors occured while processing game."); // TODO + } +} + + +PdnGame::~PdnGame() +{ + qDeleteAll(m_moves); + m_moves.clear(); +} + + +QString PdnGame::get(Tag tag) const +{ + switch(tag) { + case Date: return pdnDate; + case Site: return pdnSite; + case Type: return pdnType; + case Event: return pdnEvent; + case Round: return pdnRound; + case White: return pdnWhite; + case Black: return pdnBlack; + default: return pdnResult; + } +} + + +void PdnGame::set(Tag tag, const QString& string) +{ + switch(tag) { + case Date: pdnDate=string; break; + case Site: pdnSite=string; break; + case Type: pdnType=string; break; + case Event: pdnEvent=string;break; + case Round: pdnRound=string;break; + case White: pdnWhite=string;break; + case Black: pdnBlack=string;break; + default: pdnResult=string; + } +} + + +bool PdnGame::parse_moves(const QString& line) +{ + qDeleteAll(m_moves); + m_moves.clear(); + + QStringList list = line.split(' '); + + QString current_move; + int move_num = 0; + bool in_comment = false; + foreach(QString str, list) { + if(str.startsWith("{")) + in_comment = true; + if(str.endsWith("}")) + in_comment = false; + + if(str.endsWith(".") && !in_comment) { + if(str!=END_OF_MOVELINE) { + if((move_num+1) != str.mid(0, str.length()-1).toInt()) { + qDebug() << "Move num expected:" << move_num+1 + << "received:" << str; + return false; + } + move_num++; + } + + current_move = current_move.trimmed(); + if(current_move.length()) { + m_moves.append(new PdnMove(current_move)); + current_move = ""; + } + continue; + } + + if(str.isEmpty()) + current_move += " "; + else + current_move += str + " "; + } + + return true; +} + + +bool PdnGame::parse(const QString& pdngame, QString& log_txt) +{ + QString fen; + QString moves; + int num = pdngame.count("\n"); // Number of lines + + for(int i=0; i<=num; i++) { + QString line = pdngame.section('\n',i ,i); + if(!line.length()) + continue; + + if(line.startsWith("[")) { + line.remove(0, 1); + line = line.trimmed(); + + if(line.startsWith("GameType")) pdnType=line.section('"',1,1); + else if(line.startsWith("FEN")) fen=line.section('"',1,1); + else if(line.startsWith("Date")) pdnDate=line.section('"',1,1); + else if(line.startsWith("Site")) pdnSite=line.section('"',1,1); + else if(line.startsWith("Event")) pdnEvent=line.section('"',1,1); + else if(line.startsWith("Round")) pdnRound=line.section('"',1,1); + else if(line.startsWith("White")) pdnWhite=line.section('"',1,1); + else if(line.startsWith("Black")) pdnBlack=line.section('"',1,1); + else if(line.startsWith("Result")) pdnResult=line.section('"',1,1); + else ; // Skip other unsupported tags + + } else { + moves += " " + line; + } + } + + // parse move section. + if(moves.endsWith(pdnResult)) + moves.truncate(moves.length()-pdnResult.length()); + else { + log_txt += " +Different result at the end of the movelist:\n" + + QString(" \"%1\" expected, got \"%2\"\n") + .arg(pdnResult) + .arg(moves.right(pdnResult.length())); + + // need to remove the incorrect result. + if(moves.endsWith(" *")) { + log_txt += " => Ignoring \" *\" from the end.\n"; + moves.truncate(moves.length()-2); + } else { + int pos = moves.lastIndexOf('-') - 1; + bool skip_ws = true; + for(int i=pos; i>=0; i--) { + if(moves[i]==' ') { + if(!skip_ws) { + log_txt += " => Ignoring \"" + + moves.right(moves.length()-i-1) + + "\" from the end.\n", + moves.truncate(i+1); + break; + } + } else { + skip_ws = false; + } + } + } + } + + if(!parse_moves(moves+" "END_OF_MOVELINE)) { // :) + log_txt += "\n +parsing moves failed."; + return false; + } + + // Translation of the GameType tag + switch(pdnType.toInt()) { + case ENGLISH: + case RUSSIAN: + break; + default: +// log_txt += "\n +setting game type to english."; + pdnType.setNum(ENGLISH); + break; + } + + // Parsing of the Forsyth-Edwards Notation (FEN) tag + if(fen.isNull()) + return true; + + fen=fen.trimmed(); + + for(int i=fen.indexOf(" "); i!=-1; i=fen.indexOf(" ")) + fen=fen.remove(i,1); + + if(fen.startsWith("W:W")) + white=PLAYER; + else if(fen.startsWith("B:W")) + white=COMPUTER; + else + return false; + + QString string = fen.mid(3).section(":B",0,0); + if(!parse(string, white)) + return false; + + string=fen.section(":B",1,1); + if(string.endsWith(".")) + string.truncate(string.length()-1); + if(!parse(string, !white)) + return false; + + return true; +} + + +bool PdnGame::parse(const QString& str, bool side) +{ + QString notation; + + if(pdnType.toInt() == ENGLISH) + notation=QString(ENOTATION); + else + notation=QString(RNOTATION); + + QStringList sections = str.split(","); + foreach(QString pos, sections) { + bool king=false; + + if(pos.startsWith("K")) { + pos=pos.remove(0,1); + king=true; + } + if(pos.length()==1) + pos.append(' '); + if(pos.length()!=2) + return false; + + int index = notation.indexOf(pos); + if(index%2) + index=notation.indexOf(pos,index+1); + if(index == -1) + return false; + + if(white==COMPUTER) + index=62-index; + + if(side==PLAYER) + board[index/2]=(king ? KING1 : MAN1); + else + board[index/2]=(king ? KING2 : MAN2); + } + return true; +} + + +PdnMove* PdnGame::getMove(int i) +{ + if(im_moves.count()) + qDebug("PdnGame::getMove(%u) m_moves.count()=%u", + i, m_moves.count()); + + PdnMove* m = new PdnMove(""); + m_moves.append(m); + return m; +} + + +QString PdnGame::toString() +{ + QString fen; + QString moves; + + /* + * fen + */ + if(!movesCount()) { + qDebug("FEN tag with lots of errors."); + QString string1; + QString string2; + QString notation; + + if(pdnType.toInt() == ENGLISH) + notation=QString(ENOTATION); + else + notation=QString(RNOTATION); + + for(int i=0; i<32; i++) { + int index=i*2; + if(white==COMPUTER) index=62-index; + + QString pos; + + switch(board[i]) { + case KING1: + pos.append('K'); + case MAN1: + pos.append(notation.mid(index,2).trimmed()); + if(string1.length()) string1.append(','); + string1.append(pos); + break; + case KING2: + pos.append('K'); + case MAN2: + pos.append(notation.mid(index,2).trimmed()); + if(string2.length()) string2.append(','); + string2.append(pos); + default: + break; + } + } + if(white==PLAYER) + fen.append("W:W"+string1+":B"+string2+"."); + else + fen.append("B:W"+string2+":B"+string1+"."); + } + + /* + * moves + */ + unsigned int count = 1; + foreach(PdnMove* move, m_moves) { + moves += QString("%1. %2 %3%4%5\n") + .arg(count) + .arg(move->m_first) + .arg(move->m_comfirst.length() ? "{"+move->m_comfirst+"} " : "") + .arg(move->m_second) + .arg(move->m_comsecond.length() ? " {"+move->m_comsecond+"}" : ""); + count++; + } + + + /* + * create format and write tags+fen+moves. + */ + QString str; + + if(pdnEvent.length()) str.append("[Event \""+pdnEvent+"\"]\n"); + if(pdnSite.length()) str.append("[Site \"" +pdnSite +"\"]\n"); + if(pdnDate.length()) str.append("[Date \"" +pdnDate +"\"]\n"); + if(pdnRound.length()) str.append("[Round \""+pdnRound+"\"]\n"); + if(pdnWhite.length()) str.append("[White \""+pdnWhite+"\"]\n"); + if(pdnBlack.length()) str.append("[Black \""+pdnBlack+"\"]\n"); + + if(fen.length()) { + str.append("[SetUp \"1\"]\n"); + str.append("[FEN \""+fen+"\"]\n\n"); + } + + str.append("[Result \""+pdnResult+"\"]\n"); + str.append("[GameType \""+pdnType+"\"]\n"); + str.append(moves); + str.append(pdnResult+"\n"); + + return str; +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.h new file mode 100644 index 000000000..8110fd655 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/pdn.h @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef PDN_H +#define PDN_H + + +#include +#include + + +#define ENOTATION "1 2 3 4 5 6 7 8 9 1011121314151617181920212223242526272829303132" +//#define ENOTATION "32313029282726252423222120191817161514131211109 8 7 6 5 4 3 2 1 " +#define RNOTATION "b8d8f8h8a7c7e7g7b6d6f6h6a5c5e5g5b4d4f4h4a3c3e3g3b2d2f2h2a1c1e1g1" + +#define ENGLISH 21 +#define RUSSIAN 25 + + +class PdnMove; +class PdnGame; + + +// Portable Draughts Notation Format File parser +class Pdn +{ +public: + Pdn(); + virtual ~Pdn(); + + int count() const { return m_database.count(); } + PdnGame* game(int i) { return m_database.at(i); } + PdnGame* newGame(); + + void clear() { m_database.clear(); } + // parent is needed to display a progress dialog. + bool open(const QString& filename, QWidget* parent, + const QString& label, QString& text_to_log); + bool save(const QString& filename); + +private: + QList m_database; +}; + + +/* + * m_first, m_second are mandatary. + * comments are optional. + */ +class PdnMove +{ +public: + PdnMove(QString whole_line_of_move); + + QString m_first, m_comfirst; + QString m_second, m_comsecond; +}; + + +/* + * represents each game in a pdn-file. + */ +class PdnGame +{ +public: + PdnGame(const QString& game_string, QString& text_to_log); + ~PdnGame(); + + enum Tag { Date, Site, Type, Event, Round, White, Black,Result }; + + int item(int i) const { return board[i]; } + void setItem(int i, int set) { board[i]=set; } + + bool isWhite() const { return white; } + void setWhite(bool set) { white=set; } + + void set(Tag tag, const QString& string); + QString get(Tag tag) const; + + int movesCount() const { return m_moves.count(); } + PdnMove* getMove(int i); + PdnMove* addMove(); + void clearMoves() { m_moves.clear(); } + + QString toString(); + +private: + bool parse(const QString& game_string, QString& log_txt); + bool parse(const QString& string, bool side); + bool parse_moves(const QString& moves_line); + +private: + bool white; + int board[32]; + QString pdnDate; + QString pdnSite; + QString pdnType; + QString pdnEvent; + QString pdnRound; + QString pdnWhite; + QString pdnBlack; + QString pdnResult; + QList m_moves; +}; + + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/player.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/player.h new file mode 100644 index 000000000..eb62f8f79 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/player.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PLAYER_H_ +#define _PLAYER_H_ + +#include + + +class Checkers; +class Field; + + +class myPlayer : public QObject +{ + Q_OBJECT + +public: + myPlayer(const QString& name, bool white) + : m_name(name), m_white(white), m_opponent(0) {} + + // information + bool isWhite() const { return m_white; } + void setWhite(bool b) { m_white = b; } + // + const QString& name() const { return m_name; } + void setName(const QString& n) { m_name = n; } + // + virtual bool isHuman() const { return false; } + + // + virtual void yourTurn(const Checkers* game) = 0; + // return false on incorrect course. + // set select to true to select the select, or unselect. + // QString contains error msg. + virtual bool fieldClicked(int, bool*,QString&) { return true; } + // computerplayer terminates his thinking thread. + // humanplayer + // networkplayer disconnects from the server. + virtual void stop() = 0; + + void setOpponent(myPlayer* o) { m_opponent=o; } + myPlayer* opponent() const { return m_opponent; } + +signals: + // emitted when move is done, provides the complete board converted to + // string. + void moveDone(const QString&); + +private: + QString m_name; + bool m_white; + + myPlayer* m_opponent; +}; + + +#endif diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.pro b/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.pro new file mode 100644 index 000000000..f1effd4b6 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.pro @@ -0,0 +1,59 @@ +#=== this part is common (similar) for all plugin projects ===================== +TEMPLATE = lib +CONFIG += plugin debug + +# this is directory, where PluginInterface.h is located +INCLUDEPATH += ../ + +# and, the result (*.so or *.dll) should appear in this directory +DESTDIR = ../bin +OBJECTS_DIR = temp/obj +RCC_DIR = temp/qrc +UI_DIR = temp/ui +MOC_DIR = temp/moc + + +# the name of the result file; +TARGET = $$qtLibraryTarget(qdiagram_plugin) + +HEADERS += ../PluginInterface.h \ + QCheckersPlugin.h +SOURCES += QCheckersPlugin.cpp + +#=============================================================================== + +HEADERS += pdn.h \ + checkers.h echeckers.h rcheckers.h \ + field.h toplevel.h view.h history.h board.h \ + newgamedlg.h \ + common.h \ + player.h humanplayer.h computerplayer.h + + +SOURCES += pdn.cc \ + checkers.cc echeckers.cc rcheckers.cc \ + field.cc toplevel.cc view.cc history.cc board.cc \ + newgamedlg.cc \ + humanplayer.cc computerplayer.cc + +RESOURCES = qcheckers.qrc + + +TARGET = qcheckers +#PREFIX = $$system(grep 'define PREFIX' common.h | cut -d'"' -f2) +#SHARE_PATH = $$system(grep 'define SHARE_PATH' common.h | cut -d'"' -f2) + +TRANSLATIONS = i18n/kcheckers_de.ts i18n/kcheckers_fr.ts +# i18n/kcheckers_ru.ts + +target.path = $$PREFIX/bin +INSTALLS += target + + +# +# This hack is needed for i18n support. +# +share.path += $$PREFIX/share/kcheckers +share.files += kcheckers.pdn COPYING AUTHORS ChangeLog README themes i18n/* +INSTALLS += share + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.qrc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.qrc new file mode 100644 index 000000000..74bccb5f3 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/qcheckers.qrc @@ -0,0 +1,29 @@ + + + icons/biglogo.png + icons/fileopen.png + icons/filesave.png + icons/stop.png + icons/dialog.png + icons/undo.png + icons/redo.png + icons/exit.png + icons/info.png + icons/next.png + icons/context.png + icons/logo.png + icons/paused.png + icons/freeplace.png + icons/clear.png + icons/continue.png + + icons/theme/frame.png + icons/theme/kingwhite.png + icons/theme/manwhite.png + icons/theme/tile2.png + icons/theme/kingblack.png + icons/theme/manblack.png + icons/theme/tile1.png + + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.cc new file mode 100644 index 000000000..c24ba138d --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.cc @@ -0,0 +1,553 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +// +// Russian Checkers + + +#include "rcheckers.h" + + +/////////////////////////////////////////////////// +// +// Player Functions +// +/////////////////////////////////////////////////// + + +bool RCheckers::go1(int from,int field) +{ + from=internal(from); + field=internal(field); + + to=field; + + if(checkCapture1()) + { + bool capture=false; + switch(board[from]) + { + case MAN1: + if(manCapture1(from,UL,capture)) return true; + if(manCapture1(from,UR,capture)) return true; + if(manCapture1(from,DL,capture)) return true; + if(manCapture1(from,DR,capture)) return true; + return false; + case KING1: + if(kingCapture1(from,UL,capture)) return true; + if(kingCapture1(from,UR,capture)) return true; + if(kingCapture1(from,DL,capture)) return true; + if(kingCapture1(from,DR,capture)) return true; + return false; + } + } + else + { + switch(board[from]) + { + case MAN1: + if((to==(from-6))||(to==(from-5))) + { + board[from]=FREE; + if(to<10) board[to]=KING1; + else board[to]=MAN1; + return true; + } + return false; + case KING1: + for(int i=from-6;;i-=6) + { + if(i==to) + { + board[from]=FREE; + board[to]=KING1; + return true; + } + else if(board[i]==FREE) continue; + else break; + } + for(int i=from-5;;i-=5) + { + if(i==to) + { + board[from]=FREE; + board[to]=KING1; + return true; + } + else if(board[i]==FREE) continue; + else break; + } + for(int i=from+5;;i+=5) + { + if(i==to) + { + board[from]=FREE; + board[to]=KING1; + return true; + } + else if(board[i]==FREE) continue; + else break; + } + for(int i=from+6;;i+=6) + { + if(i==to) + { + board[from]=FREE; + board[to]=KING1; + return true; + } + else if(board[i]==FREE) continue; + else break; + } + return false; + } + } + return false; +} + + + +bool RCheckers::checkCapture1() const +{ + for(int i=6;i<48;i++) + if(checkCapture1(i)) + return true; + + return false; +} + + +bool RCheckers::checkCapture1(int i) const +{ + switch(board[i]) + { + case MAN1: + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + if(board[i+5]==MAN2 || board[i+5]==KING2) + if(board[i+10]==FREE) return true; + if(board[i+6]==MAN2 || board[i+6]==KING2) + if(board[i+12]==FREE) return true; + break; + case KING1: + int k; + for(k=i-6;board[k]==FREE;k-=6); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k-6]==FREE) return true; + + for(k=i-5;board[k]==FREE;k-=5); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k-5]==FREE) return true; + + for(k=i+5;board[k]==FREE;k+=5); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k+5]==FREE) return true; + + for(k=i+6;board[k]==FREE;k+=6); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k+6]==FREE) return true; + } + + return false; +} + + +/* ORIG func aw +bool RCheckers::checkCapture1() +{ + for(int i=6;i<48;i++) + { + switch(board[i]) + { + case MAN1: + if(board[i-6]==MAN2 || board[i-6]==KING2) + if(board[i-12]==FREE) return true; + if(board[i-5]==MAN2 || board[i-5]==KING2) + if(board[i-10]==FREE) return true; + if(board[i+5]==MAN2 || board[i+5]==KING2) + if(board[i+10]==FREE) return true; + if(board[i+6]==MAN2 || board[i+6]==KING2) + if(board[i+12]==FREE) return true; + break; + case KING1: + int k; + for(k=i-6;board[k]==FREE;k-=6); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k-6]==FREE) return true; + + for(k=i-5;board[k]==FREE;k-=5); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k-5]==FREE) return true; + + for(k=i+5;board[k]==FREE;k+=5); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k+5]==FREE) return true; + + for(k=i+6;board[k]==FREE;k+=6); + if(board[k]==MAN2 || board[k]==KING2) + if(board[k+6]==FREE) return true; + } + } + return false; +} +*/ + + +// Return TRUE if a course of the player true +// Return FALSE if a course of the player incorrect + +bool RCheckers::manCapture1(int from,int direction,bool &capture) +{ + int i=from+direction; + if(board[i]==MAN2 || board[i]==KING2) + { + int k=i+direction; + if(board[k]==FREE) + { + bool next=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + + if(k<10) + { + board[k]=KING1; + if(kingCapture1(k,direction+11,next)) + { + board[i]=FREE; + return true; + } + } + else + { + board[k]=MAN1; + if(direction==UL || direction==DR) + { + if(manCapture1(k,UR,next)) {board[i]=FREE;return true;} + if(manCapture1(k,DL,next)) {board[i]=FREE;return true;} + } + else + { + if(manCapture1(k,UL,next)) {board[i]=FREE;return true;} + if(manCapture1(k,DR,next)) {board[i]=FREE;return true;} + } + if(manCapture1(k,direction,next)) {board[i]=FREE;return true;} + } + + if((!next) && k==to) {board[i]=FREE;return true;} + + board[k]=FREE; + board[i]=save; + board[from]=MAN1; + capture=true; + } + } + return false; +} + + +bool RCheckers::kingCapture1(int from,int direction,bool &capture) +{ + int i; + for(i=from+direction;board[i]==FREE;i+=direction); + + if(board[i]==MAN2 || board[i]==KING2) + { + int k=i+direction; + if(board[k]==FREE) + { + bool next=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + + for(;board[k]==FREE;k+=direction) + { + board[k]=KING1; + if(direction==UL || direction==DR) + { + if(kingCapture1(k,UR,next)) {board[i]=FREE;return true;} + if(kingCapture1(k,DL,next)) {board[i]=FREE;return true;} + } + else + { + if(kingCapture1(k,UL,next)) {board[i]=FREE;return true;} + if(kingCapture1(k,DR,next)) {board[i]=FREE;return true;} + } + board[k]=FREE; + } + + board[k-=direction]=KING1; + if(kingCapture1(k,direction,next)) {board[i]=FREE;return true;} + board[k]=FREE; + + if(!next) + for(;k!=i;k-=direction) + if(k==to) {board[i]=FREE;board[k]=KING1;return true;} + + board[i]=save; + board[from]=KING1; + capture=true; + } + } + return false; +} + + +//////////////////////////////////////////////////// +// +// Computer Functions +// +//////////////////////////////////////////////////// + + +void RCheckers::kingMove2(int from,int &resMax) +{ + board[from]=FREE; + for(int i=from-6;board[i]==FREE;i-=6) + { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + for(int i=from-5;board[i]==FREE;i-=5) + { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + for(int i=from+5;board[i]==FREE;i+=5) + { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + for(int i=from+6;board[i]==FREE;i+=6) + { + board[i]=KING2; + turn(resMax); + board[i]=FREE; + } + board[from]=KING2; +} + + +bool RCheckers::checkCapture2() const +{ + for(int i=6;i<48;i++) + { + switch(board[i]) + { + case MAN2: + if(board[i-6]==MAN1 || board[i-6]==KING1) + if(board[i-12]==FREE) return true; + if(board[i-5]==MAN1 || board[i-5]==KING1) + if(board[i-10]==FREE) return true; + if(board[i+5]==MAN1 || board[i+5]==KING1) + if(board[i+10]==FREE) return true; + if(board[i+6]==MAN1 || board[i+6]==KING1) + if(board[i+12]==FREE) return true; + break; + case KING2: + int k; + for(k=i-6;board[k]==FREE;k-=6); + if(board[k]==MAN1 || board[k]==KING1) + if(board[k-6]==FREE) return true; + + for(k=i-5;board[k]==FREE;k-=5); + if(board[k]==MAN1 || board[k]==KING1) + if(board[k-5]==FREE) return true; + + for(k=i+5;board[k]==FREE;k+=5); + if(board[k]==MAN1 || board[k]==KING1) + if(board[k+5]==FREE) return true; + + for(k=i+6;board[k]==FREE;k+=6); + if(board[k]==MAN1 || board[k]==KING1) + if(board[k+6]==FREE) return true; + } + } + return false; +} + + +// Return TRUE if it is possible to capture +// Return FALSE if it is impossible to capture + +bool RCheckers::manCapture2(int from,int &resMax) +{ + bool capture=false; + + int i=from-6; + if(board[i]==MAN1 || board[i]==KING1) + { + int k=from-12; + if(board[k]==FREE) + { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + board[k]=MAN2; + resMax--; + if(!manCapture2(k,resMax)) turn(resMax,true); + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + i=from-5; + if(board[i]==MAN1 || board[i]==KING1) + { + int k=from-10; + if(board[k]==FREE) + { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + board[k]=MAN2; + resMax--; + if(!manCapture2(k,resMax)) turn(resMax,true); + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + i=from+5; + if(board[i]==MAN1 || board[i]==KING1) + { + int k=from+10; + if(board[k]==FREE) + { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + if(from>32) + { + board[k]=KING2; + if(!kingCapture2(k,UL,resMax)) turn(resMax,true); + } + else + { + board[k]=MAN2; + if(!manCapture2(k,resMax)) turn(resMax,true); + } + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + i=from+6; + if(board[i]==MAN1 || board[i]==KING1) + { + int k=from+12; + if(board[k]==FREE) + { + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + if(from>32) + { + board[k]=KING2; + if(!kingCapture2(k,UR,resMax)) turn(resMax,true); + } + else + { + board[k]=MAN2; + if(!manCapture2(k,resMax)) turn(resMax,true); + } + resMax++; + board[k]=FREE; + board[i]=save; + board[from]=MAN2; + capture=true; + } + } + + if(capture) return true; + return false; +} + + +bool RCheckers::kingCapture2(int from,int direction,int &resMax) +{ + int i; + for(i=from+direction;board[i]==FREE;i+=direction); + + if(board[i]==MAN1 || board[i]==KING1) + { + int k=i+direction; + if(board[k]==FREE) + { + bool capture=false; + int save=board[i]; + board[from]=FREE; + board[i]=NONE; + resMax--; + + for(;board[k]==FREE;k+=direction) + { + board[k]=KING2; + if(direction==UL || direction==DR) + { + if(kingCapture2(k,UR,resMax)) capture=true; + if(kingCapture2(k,DL,resMax)) capture=true; + } + else + { + if(kingCapture2(k,UL,resMax)) capture=true; + if(kingCapture2(k,DR,resMax)) capture=true; + } + board[k]=FREE; + } + + board[k-=direction]=KING2; + if(kingCapture2(k,direction,resMax)) capture=true; + board[k]=FREE; + + if(!capture) + for(;k!=i;k-=direction) + { + board[k]=KING2; + turn(resMax,true); + board[k]=FREE; + } + + resMax++; + board[i]=save; + board[from]=KING2; + return true; + } + } + return false; +} + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.h new file mode 100644 index 000000000..dcb11a6f4 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/rcheckers.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef RCHECKERS_H +#define RCHECKERS_H + +#include "checkers.h" +#include "pdn.h" + + +class RCheckers:public Checkers +{ + +public: + virtual bool go1(int,int); + + + virtual int type() const { return RUSSIAN; } + + virtual bool checkCapture1() const; + virtual bool checkCapture2() const; + +protected: + virtual bool checkCapture1(int) const; + +private: + + void kingMove2(int,int &); + + bool manCapture1(int,int,bool &); + bool kingCapture1(int,int,bool &); + + bool manCapture2(int,int &); + bool kingCapture2(int,int,int &); + +}; + +#endif + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/Thumbs.db b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/Thumbs.db new file mode 100644 index 000000000..7be7db106 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/Thumbs.db differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/frame.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/frame.png new file mode 100644 index 000000000..4c65e86d5 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/frame.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingblack.png new file mode 100644 index 000000000..b6a596a4f Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingwhite.png new file mode 100644 index 000000000..64fc42f1a Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/kingwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manblack.png new file mode 100644 index 000000000..32372efee Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manwhite.png new file mode 100644 index 000000000..6262d38f1 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/manwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/theme b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/theme new file mode 100644 index 000000000..120b87409 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/theme @@ -0,0 +1 @@ +Marble diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile1.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile1.png new file mode 100644 index 000000000..5e41ce8e3 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile1.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile2.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile2.png new file mode 100644 index 000000000..94f4d42a0 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/marble/tile2.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/frame.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/frame.png new file mode 100644 index 000000000..932e11319 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/frame.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingblack.png new file mode 100644 index 000000000..856878b34 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingwhite.png new file mode 100644 index 000000000..e50d6ddf8 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/kingwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manblack.png new file mode 100644 index 000000000..0963e2911 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manwhite.png new file mode 100644 index 000000000..09fea5f20 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/manwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/theme b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/theme new file mode 100644 index 000000000..5aaa68e8c --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/theme @@ -0,0 +1 @@ +Simple Big diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile1.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile1.png new file mode 100644 index 000000000..54e0f001d Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile1.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile2.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile2.png new file mode 100644 index 000000000..9091400a9 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_big/tile2.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/frame.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/frame.png new file mode 100644 index 000000000..f7e8e4e18 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/frame.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingblack.png new file mode 100644 index 000000000..e6ce1c2bf Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingwhite.png new file mode 100644 index 000000000..7cf9614b1 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/kingwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manblack.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manblack.png new file mode 100644 index 000000000..92bc5e29f Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manblack.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manwhite.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manwhite.png new file mode 100644 index 000000000..54ac91600 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/manwhite.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/theme b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/theme new file mode 100644 index 000000000..bddb41245 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/theme @@ -0,0 +1 @@ +Simple Small diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile1.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile1.png new file mode 100644 index 000000000..1f5f4b269 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile1.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile2.png b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile2.png new file mode 100644 index 000000000..63f60d237 Binary files /dev/null and b/retroshare-gui/src/gui/plugins/qcheckers_plugin/themes/simple_small/tile2.png differ diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.cc new file mode 100644 index 000000000..c7048045f --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.cc @@ -0,0 +1,574 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pdn.h" +#include "toplevel.h" +#include "newgamedlg.h" +#include "view.h" +#include "common.h" + +#define CFG_THEME_PATH CFG_KEY"ThemePath" +#define CFG_FILENAME CFG_KEY"Filename" +#define CFG_KEEPDIALOG CFG_KEY"ShowKeepDialog" +#define CFG_NOTATION CFG_KEY"Notation" +#define CFG_NOT_ABOVE CFG_KEY"NotationAbove" +#define CFG_NOT_FONT CFG_KEY"NotationFont" +#define CFG_CLEAR_LOG CFG_KEY"ClearLogOnNewRound" + + +myTopLevel::myTopLevel() +{ + setWindowTitle(APPNAME); + setWindowIcon(QIcon(":/icons/biglogo.png")); + + m_newgame = new myNewGameDlg(this); + make_central_widget(); + make_actions(); + restore_settings(); + + /* + * new computer game. + */ + m_view->newGame(m_newgame->rules(), m_newgame->freePlacement(), + m_newgame->name(), + m_newgame->isWhite(), m_newgame->opponent(), + m_newgame->opponentName(), m_newgame->skill()); + + if(layout()) + layout()->setSizeConstraint(QLayout::SetFixedSize); +} + + +void myTopLevel::make_actions() +{ + // game menu actions + gameNew = new QAction(QIcon(":/icons/logo.png"), tr("&New..."), this); + gameNew->setShortcut(tr("CTRL+N", "File|New")); + connect(gameNew, SIGNAL(triggered()), this, SLOT(slot_new_game())); + + gameNextRound = new QAction(QIcon(":/icons/next.png"), + tr("&Next Round"), this); + connect(gameNextRound, SIGNAL(triggered()), + this, SLOT(slot_next_round())); + + gameStop = new QAction(QIcon(":/icons/stop.png"), tr("&Stop"), this); + connect(gameStop, SIGNAL(triggered()), m_view, SLOT(slotStopGame())); + + gameOpen = new QAction(QIcon(":/icons/fileopen.png"), tr("&Open..."), + this); + gameOpen->setShortcut(tr("CTRL+O", "File|Open")); + connect(gameOpen, SIGNAL(triggered()), this, SLOT(slot_open_game())); + + gameSave = new QAction(QIcon(":/icons/filesave.png"), tr("&Save..."), + this); + gameSave->setShortcut(tr("CTRL+S", "File|Save")); + connect(gameSave, SIGNAL(triggered()), this, SLOT(slot_save_game())); + + QAction* gameQuit = new QAction(QIcon(":/icons/exit.png"), tr("&Quit"), + this); + gameQuit->setShortcut(tr("CTRL+Q", "File|Quit")); + connect(gameQuit, SIGNAL(triggered()), + this, SLOT(close())); +// QApplication::instance(), SLOT(quit())); + + // view menu actions + viewNotation = new QAction(tr("&Show Notation"), this); + viewNotation->setCheckable(true); + connect(viewNotation, SIGNAL(toggled(bool)), + this, SLOT(slot_notation(bool))); + + viewNotationAbove = new QAction(tr("Show notation &above men"), this); + viewNotationAbove->setCheckable(true); + connect(viewNotationAbove, SIGNAL(toggled(bool)), + this, SLOT(slot_notation(bool))); + + // settings menu + settingsKeep = new QAction(tr("&Confirm aborting current game"), this); + settingsKeep->setCheckable(true); + // + settingsClearLog = new QAction(tr("Clear &log on new round"), this); + settingsClearLog->setCheckable(true); + connect(settingsClearLog, SIGNAL(toggled(bool)), + m_view, SLOT(slotClearLog(bool))); + // + QAction* settingsNotationFont = new QAction(tr("&Notation font..."), + this); + connect(settingsNotationFont, SIGNAL(triggered()), + this, SLOT(slot_notation_font())); + + // help menu actions + QAction* helpRules = new QAction(tr("&Rules of Play"), this); + helpRules->setShortcut(tr("F1", "Help|Help")); + connect(helpRules, SIGNAL(triggered()), this, SLOT(slot_help())); + + QAction* helpAbout = new QAction(QIcon(":/icons/logo.png"), + tr("&About")+" "APPNAME, this); + connect(helpAbout, SIGNAL(triggered()), this, SLOT(slot_about())); + + QAction* helpAboutQt = new QAction(tr("About &Qt"), this); + connect(helpAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + + + /* + * toolbar + */ + QToolBar* tb = addToolBar(tr("&Toolbar")); + tb->setMovable(false); + tb->addAction(gameNew); + tb->addAction(gameOpen); + tb->addAction(gameSave); + tb->addSeparator(); + tb->addAction(gameNextRound); + tb->addAction(gameStop); + + + /* + * menus + */ + QMenu* gameMenu = menuBar()->addMenu(tr("&Game")); + gameMenu->addAction(gameNew); + gameMenu->addAction(gameOpen); + gameMenu->addAction(gameSave); + gameMenu->addSeparator(); + gameMenu->addAction(gameNextRound); + gameMenu->addAction(gameStop); + gameMenu->addSeparator(); + gameMenu->addAction(gameQuit); + + viewMenu = menuBar()->addMenu(tr("&View")); + viewMenu->addAction(tb->toggleViewAction()); + viewMenu->addSeparator(); + viewMenu->addAction(viewNotation); + viewMenu->addAction(viewNotationAbove); + + QMenu* settingsMenu = menuBar()->addMenu(tr("&Settings")); + settingsMenu->addAction(settingsKeep); + settingsMenu->addSeparator(); + settingsMenu->addAction(settingsNotationFont); + settingsMenu->addSeparator(); + settingsMenu->addAction(settingsClearLog); + + QMenu* helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(helpRules); + helpMenu->addSeparator(); + helpMenu->addAction(helpAbout); + helpMenu->addAction(helpAboutQt); + + + /* + * THEMES. create a default theme. + */ + QActionGroup* themes_grp = new QActionGroup(this); + themes_grp->setExclusive(true); + + QAction* default_theme = new QAction(tr(DEFAULT_THEME), themes_grp); + default_theme->setCheckable(true); + m_themes[default_theme] = DEFAULT_THEME; + default_theme->setChecked(true); + set_theme(default_theme);//FIXME TODO + themes_grp->addAction(default_theme); + + viewMenu->addSeparator(); + viewMenu->addAction(default_theme); + read_themes(themes_grp, + viewMenu,QDir::homePath()+"/"USER_PATH"/"THEME_DIR); + //TODO-hardcoded + read_themes(themes_grp, + viewMenu, PREFIX"/share/kcheckers/"THEME_DIR); + + connect(themes_grp, SIGNAL(triggered(QAction*)), + this, SLOT(set_theme(QAction*))); +} + + +void myTopLevel::read_themes(QActionGroup* menu_grp, QMenu* menu, + const QString& path) +{ + QDir sharedir(path); + QStringList themes = sharedir.entryList(QDir::Dirs|QDir::Readable); + themes.removeAll("."); + themes.removeAll(".."); + + for(QStringList::iterator it=themes.begin(); it!=themes.end(); ++it) { + sharedir.cd(*it); + + QString theme_dir = sharedir.absolutePath(); + QString errtext; + + QStringList files + = sharedir.entryList(QDir::Files|QDir::Readable); + + // all files are there. + if(files.count()!=8 || + files.indexOf(THEME_TILE1) == -1 || + files.indexOf(THEME_TILE2) == -1 || + files.indexOf(THEME_FRAME) == -1 || + files.indexOf(THEME_MANBLACK) == -1 || + files.indexOf(THEME_MANWHITE) == -1 || + files.indexOf(THEME_KINGBLACK) == -1 || + files.indexOf(THEME_KINGWHITE) == -1 || + files.indexOf(THEME_FILE) == -1) { + // TODO not translated. + errtext += "Wrong number of files. "; + } + files.removeAll(THEME_FILE); + + // check pic size. + QSize size = QPixmap(theme_dir+"/"+files[0]).size(); + if(size.width()>MAX_TILE_SIZE || size.height()>MAX_TILE_SIZE) + // TODO not translated. + errtext += "Picture(s) too big. "; + + if(size.width()==0 || size.height()==0) + // TODO not translated. + errtext += "Width/Height is zero. "; + + // check pics all the same size. + foreach(QString file, files) { + if(QPixmap(theme_dir+"/"+file).size() != size) { + // TODO not translated. + errtext += "Pictures are different in size. "; + break; + } + } + + if(errtext.length()) { + // TODO not translated. + qWarning() << endl << "Theme in" + << sharedir.absolutePath() << endl << errtext; + + } else { + QString themename = sharedir.dirName(); + + /*TODO + QFile file(theme_dir+"/"+THEME_FILE); + if(file.open(QFile::ReadOnly)) { + QTextStream ts(&file); + if(!ts.atEnd()) + themename = ts.readLine(); + // try go get locale theme name + // TODO + QString locale = QString("[%1]=").arg(QTextCodec::locale()); + while(!ts.atEnd()) { + QString line = ts.readLine(); + if(line.startsWith(locale)) { + themename = line.mid(locale.length()); + break; + } + } + file.close(); + } + */ + // + QAction* action = new QAction(themename, this); + menu_grp->addAction(action); + menu->addAction(action); + action->setCheckable(true); + m_themes[action] = theme_dir; + } + + sharedir.cdUp(); + } +} + + +void myTopLevel::restore_settings() +{ + QSettings cfg(APPNAME, APPNAME); + + QString theme_path = cfg.value(CFG_THEME_PATH, DEFAULT_THEME) + .toString(); + for(myThemeMap::iterator it = m_themes.begin(); it!=m_themes.end();it++) + if(it.value() == theme_path) { + it.key()->setChecked(true); + set_theme(it.key()); + break; + } + + filename = cfg.value(CFG_FILENAME).toString(); + + viewNotation->setChecked(cfg.value(CFG_NOTATION, false).toBool()); + viewNotationAbove->setChecked(cfg.value(CFG_NOT_ABOVE, true).toBool()); + slot_notation(true); // here: arg is ignored by the function + + bool clear_log = cfg.value(CFG_CLEAR_LOG, true).toBool(); + settingsClearLog->setChecked(clear_log); + m_view->slotClearLog(clear_log); + + // + settingsKeep->setChecked(cfg.value(CFG_KEEPDIALOG, true).toBool()); + + QFont cfont; + if(cfont.fromString(cfg.value(CFG_NOT_FONT, "").toString())) + m_view->setNotationFont(cfont); + + // new game + m_newgame->readSettings(&cfg); +} + + +void myTopLevel::make_central_widget() +{ + m_view = new myView(this); + + connect(m_view, SIGNAL(working(bool)), + this, SLOT(slot_working(bool))); + + setCentralWidget(m_view); +} + + +void myTopLevel::warning(const QString& text) +{ + QMessageBox::warning(this, tr("Error")+" - "APPNAME, text); +} + + +void myTopLevel::information(const QString& caption, const QString& text) +{ + QDialog* dlg = new QDialog(this); + dlg->setModal(true); + dlg->setWindowTitle(caption+" - "APPNAME); + + // logo left + QLabel* logo = new QLabel(dlg); + logo->setPixmap(QPixmap(":/icons/dialog.png")); + + // text editor + QTextEdit* te = new QTextEdit(text, dlg); + te->setReadOnly(true); + te->setMinimumWidth(m_view->width()-100); + te->setMinimumHeight(m_view->height()-200); + + // close button + QPushButton* button = new QPushButton(tr("&Close"), dlg); + connect(button, SIGNAL(clicked()), dlg, SLOT(accept())); + + // Layout. + QHBoxLayout* hb = new QHBoxLayout(); + hb->addWidget(logo, 0, Qt::AlignTop); + hb->addWidget(te, 1); + + QHBoxLayout* hb_button = new QHBoxLayout(); + hb_button->addStretch(); + hb_button->addWidget(button); + + QVBoxLayout* vb = new QVBoxLayout(dlg); + vb->addLayout(hb, 1); + vb->addSpacing(5); + vb->addLayout(hb_button); + + // go + dlg->exec(); + delete dlg; +} + + +void myTopLevel::slot_save_game() +{ + QString fn = QFileDialog::getSaveFileName(this, + tr("Save Game")+" - "APPNAME, filename, "PDN Files (*."EXT")"); + if(!fn.isEmpty()) { + if(fn.right(3)!=EXT) + fn += "."EXT; + + if(m_view->savePdn(fn)) + filename = fn; + else + warning(tr("Could not save: ")+filename); + } +} + + +void myTopLevel::slot_open_game() +{ + QString fn = QFileDialog::getOpenFileName(this, + tr("Open Game")+" - "APPNAME, filename, "PDN Files (*."EXT")"); + if(!fn.isEmpty()) + open(fn); +} + + +void myTopLevel::open(const QString& fn) +{ + if(m_view->openPdn(fn)) + filename = fn; +} + + +void myTopLevel::closeEvent(QCloseEvent* e) +{ + if(!keep_game()) { + store_settings(); + e->accept(); + } else { + e->ignore(); + } +} + + +void myTopLevel::store_settings() +{ + QSettings config(APPNAME, APPNAME); + + for(myThemeMap::iterator it=m_themes.begin(); it!=m_themes.end(); it++) + if(it.key()->isChecked()) { + config.setValue(CFG_THEME_PATH, it.value()); + break; + } + + config.setValue(CFG_FILENAME, filename); + + config.setValue(CFG_NOTATION, viewNotation->isChecked()); + config.setValue(CFG_NOT_ABOVE, viewNotationAbove->isChecked()); + + config.setValue(CFG_KEEPDIALOG, settingsKeep->isChecked()); + config.setValue(CFG_NOT_FONT, m_view->notationFont().toString()); + config.setValue(CFG_CLEAR_LOG, settingsClearLog->isChecked()); + + // new game + m_newgame->writeSettings(&config); +} + + +void myTopLevel::set_theme(QAction* action) +{ + QString path = m_themes[action]; + m_view->setTheme(path); +} + + +void myTopLevel::slot_help() +{ + QString text = + tr("

In the beginning of game you have 12 checkers (men). " + "The men move forward only. The men can capture:" + "

    " + "
  • by jumping forward only (english rules);" + "
  • by jumping forward or backward (russian rules)." + "
" + "

A man which reaches the far side of the board becomes a king. " + "The kings move forward or backward:" + "

    " + "
  • to one square only (english rules);" + "
  • to any number of squares (russian rules)." + "
" + "

The kings capture by jumping forward or backward. " + "Whenever a player is able to make a capture he must do so."); + + information(tr("Rules of Play"), text); +} + + +void myTopLevel::slot_about() +{ + QString text = + APPNAME", a board game.
Version "VERSION"

" + COPYRIGHT"
" + ""HOMEPAGE"

" + "Contributors:
"CONTRIBS"

" + "This program is distributed under the terms " + "of the GNU General Public License."; + + information(tr("About"), text); +} + + +void myTopLevel::slot_new_game() +{ + if(keep_game()) + return; + + if(m_newgame->exec()==QDialog::Accepted) { + m_view->newGame(m_newgame->rules(), m_newgame->freePlacement(), + m_newgame->name(), + m_newgame->isWhite(), m_newgame->opponent(), + m_newgame->opponentName(), m_newgame->skill()); + } +} + + +void myTopLevel::slot_working(bool working) +{ + bool disable = !working; + + gameNew->setEnabled(disable); + gameSave->setEnabled(disable); + + gameNextRound->setEnabled(disable);// FIXME !m_view->isAborted()); + gameOpen->setEnabled(disable); + gameStop->setEnabled(!disable); + + m_view->setEnabled(disable); +} + + +bool myTopLevel::keep_game() +{ + if(!settingsKeep->isChecked() || m_view->isAborted()) + return false; + + int answer = QMessageBox::question(this, tr("Abort Game?")+" - "APPNAME, + tr("Current game will be lost if you continue.\n" + "Do you really want to discard it?"), + QMessageBox::Yes, QMessageBox::No); + + if(answer == QMessageBox::Yes) + return false; + + return true; +} + + +void myTopLevel::slot_next_round() +{ + if(!keep_game()) + m_view->slotNextRound(); +} + + +void myTopLevel::slot_notation_font() +{ + bool ok; + QFont font = QFontDialog::getFont(&ok, m_view->notationFont(), this); + if(ok) + m_view->setNotationFont(font); +} + + +void myTopLevel::slot_notation(bool) +{ + m_view->setNotation(viewNotation->isChecked(), + viewNotationAbove->isChecked()); +} + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.h new file mode 100644 index 000000000..684dd6553 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/toplevel.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (C) 2002-2003 Andi Peredri * + * andi@ukr.net * + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef _TOPLEVEL_H_ +#define _TOPLEVEL_H_ + +#include +#include +#include + + +class myView; +class myNewGameDlg; + + +class myTopLevel : public QMainWindow +{ + Q_OBJECT + +public: + myTopLevel(); + + void open(const QString& filename); + +protected: + void closeEvent(QCloseEvent*); + +private slots: + void slot_help(); + void slot_about(); + + void slot_new_game(); + void slot_open_game(); + void slot_save_game(); + void slot_next_round(); + + void slot_notation(bool); + void slot_notation_font(); + + void slot_working(bool); + + void set_theme(QAction*); + + void warning(const QString& text); + + +private: + void make_actions(); + void make_central_widget(); + void restore_settings(); + void store_settings(); + + // add themes to this menu. + void read_themes(QActionGroup*, QMenu*, const QString& path); + + void information(const QString& caption, const QString& text); + + // returns true if the user wishes to keep current game + bool keep_game(); + +private: + QMenu* viewMenu; + // + QAction* gameNew; + QAction* gameStop; + QAction* gameOpen; + QAction* gameSave; + QAction* gameNextRound; + // + QAction* viewNotation; + QAction* viewNotationAbove; + // + QAction* settingsKeep; + QAction* settingsClearLog; + + QString filename; // PDN File Name + + myView* m_view; + myNewGameDlg* m_newgame; + + typedef QMap myThemeMap; + myThemeMap m_themes; +}; + +#endif + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.cc b/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.cc new file mode 100644 index 000000000..3628e8c8b --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.cc @@ -0,0 +1,587 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include +#include + +#include "pdn.h" +#include "echeckers.h" +#include "rcheckers.h" +#include "view.h" +#include "common.h" +#include "history.h" +#include "newgamedlg.h" + +#include "player.h" +#include "humanplayer.h" +#include "computerplayer.h" + + +#define MAX_CMD_LEN 80 +#define MOVE_PAUSE 1000 + +// this class is used to note differencies between moves. +class myDiff { +public: + myDiff(int pos, int from, int to) + : m_pos(pos), m_from(from), m_to(to) {} + int m_pos; + int m_from; + int m_to; +}; + + +myView::myView(QWidget* parent) + : QFrame(parent) +{ + /* + * board & info + */ + m_board = new myBoard(this); + connect(m_board, SIGNAL(fieldClicked(int)), + this, SLOT(slot_click(int))); + + m_history = new myHistory(this); + connect(m_history, SIGNAL(previewGame(int)), + this, SLOT(slot_preview_game(int))); + connect(m_history, SIGNAL(applyMoves(const QString&)), + this, SLOT(slot_apply_moves(const QString&))); + connect(m_history, SIGNAL(newMode(bool, bool)), + this, SLOT(slot_new_mode(bool, bool))); + connect(this, SIGNAL(working(bool)), + m_history, SLOT(slotWorking(bool))); + + QHBoxLayout* hb = new QHBoxLayout(0); + hb->addWidget(m_board); + hb->addSpacing(5); + hb->addWidget(m_history); + + + /* + * + */ + m_log = new QTextEdit(this); + m_log->setFixedHeight(100); //FIXME + m_log->setReadOnly(true); + + + /* + * it's the final layout. + */ + QVBoxLayout* vb = new QVBoxLayout(this); + vb->addLayout(hb); + vb->addWidget(m_log); + vb->setSizeConstraint(QLayout::SetFixedSize); + + + /* + * game init + */ + m_player = m_current = 0; +} + + +myView::~myView() +{ + if(m_player) { + delete m_player; + delete m_player->opponent(); + } +} + + +void myView::setEnabled(bool b) +{ + m_board->setEnabled(b); + if(b) + setCursor(Qt::ArrowCursor); // should be m_board bound. + else + setCursor(Qt::WaitCursor); +} + + +void myView::setTheme(const QString& path) +{ + m_board->setTheme(path, m_player ? m_player->isWhite() : true); + m_history->setFixedHeight(m_board->height()); +} + + +void myView::newGame(int rules, bool freeplace, + const QString& name, bool is_white, + int opponent, const QString& opp_name, int skill) +{ + m_freeplace_from = -1; + + if(m_player) { + delete m_player; + delete m_player->opponent(); + } + + m_board->setColorWhite(is_white); + + // create players + myPlayer* plr = new myHumanPlayer(name, is_white, false); + myPlayer* opp = 0; + if(opponent==HUMAN) + opp = new myHumanPlayer(opp_name, !is_white, true); + else + opp = new myComputerPlayer(opp_name, !is_white, skill); + + emit working(true); + + + /* + * set up player stuff. slots/signals. + */ + m_player = plr; + + plr->setOpponent(opp); + opp->setOpponent(plr); + + plr->disconnect(); + opp->disconnect(); + + connect(plr, SIGNAL(moveDone(const QString&)), + this, SLOT(slot_move_done(const QString&))); + + connect(opp, SIGNAL(moveDone(const QString&)), + this, SLOT(slot_move_done(const QString&))); + + + /* + * create game board. + */ + m_board->setGame(rules); + + m_board->reset(); + m_history->clear(); + + begin_game(1, freeplace); +} + + +void myView::begin_game(unsigned int round, bool freeplace) +{ + if(m_clear_log) + m_log->clear(); + + m_board->adjustNotation(m_player->isWhite()); + + m_history->newPdn(APPNAME" Game", freeplace); + m_history->setTag(PdnGame::Type, QString::number(m_board->type())); + m_history->setTag(PdnGame::Date, + QDate::currentDate().toString("yyyy.MM.dd")); + m_history->setTag(PdnGame::Result, "*"); + m_history->setTag(PdnGame::Round, QString::number(round)); + + + /* + * go! + */ + myPlayer* last_player = get_first_player()->opponent(); + + m_game_over = false; + m_aborted = false; + m_current = last_player; + + // setup names + if(m_player->isWhite()) { + m_history->setTag(PdnGame::White, m_player->name()); + m_history->setTag(PdnGame::Black, m_player->opponent()->name()); + } else { + m_history->setTag(PdnGame::White, m_player->opponent()->name()); + m_history->setTag(PdnGame::Black, m_player->name()); + } + + if(m_history->isFreePlacement()) + emit working(false); + else + slot_move_done(m_board->game()->toString(false)); +} + + +bool myView::check_game_over() +{ + if(m_game_over) // no further checks + return true; + + m_game_over = true; + + bool player_can = m_board->game()->checkMove1() + || m_board->game()->checkCapture1(); + bool opp_can = m_board->game()->checkMove2() + || m_board->game()->checkCapture2(); + + // player cannot go but opponent can -> player lost. + if(/*FIXME*/m_player==m_current && !player_can && opp_can) { + you_won(false); + return m_game_over; + } + // player can go but opponent cannot -> player won. + if(/*FIXME*/m_player!=m_current && player_can && !opp_can) { + you_won(true); + return m_game_over; + } + // neither of the player can go -> draw. + if(!player_can && !opp_can) { + add_log(myView::System, tr("Drawn game.")); + m_history->setTag(PdnGame::Result, "1/2-1/2"); + return m_game_over; + } + + m_game_over = false; + return m_game_over; +} + + +void myView::slot_click(int field_num) +{ + if(m_game_over || m_aborted) + return; + + if(m_history->isPaused()) { + if(m_history->isFreePlacement()) { + // FIXME - hightlight fields + if(m_freeplace_from < 0) { + m_freeplace_from = field_num; + m_board->selectField(field_num, true); + } else { + m_board->selectField(m_freeplace_from, false); + m_board->doFreeMove(m_freeplace_from, + field_num); + m_freeplace_from = -1; + } + } + } else { + bool select = false; + QString err_msg; + + if(!m_current->fieldClicked(field_num, &select, err_msg)) { + add_log(myView::Warning, m_current->name()+": " + + (err_msg.length() + ? err_msg + : tr("Invalid move."))); + } else { + m_board->selectField(field_num, select); + } + } +} + + +void myView::slotNextRound() +{ + if(m_aborted) + return; + + m_player->setWhite(!m_player->isWhite()); + m_player->opponent()->setWhite(!m_player->isWhite()); + + m_board->setColorWhite(m_player->isWhite()); + m_board->reset(); + + unsigned int round = m_history->getTag(PdnGame::Round).toUInt() + 1; + begin_game(round, m_history->isFreePlacement()); +} + + +void myView::slotStopGame() +{ + m_player->stop(); + m_player->opponent()->stop(); +} + + +void myView::stop_game(const QString& msg) +{ + m_game_over = true; + m_aborted = true; + + QString text(tr("Game aborted.")+(!msg.isEmpty() ? "\n"+msg : "")); + add_log(myView::System, text); + + emit working(false); +} + + +void myView::slot_move_done(const QString& board_str) +{ + if(m_history->isPaused()) // FIXME - ??? + return; + + perform_jumps(m_board->game()->toString(false), board_str); + + // show who is next? + m_current = m_current->opponent(); + m_history->setCurrent(m_current->name()); + + if(!m_current->isHuman()) { + emit working(true); + } else { + emit working(false); + } + + if(m_current->opponent()->isHuman() && !m_current->isHuman()) + QTimer::singleShot(MOVE_PAUSE, this, + SLOT(slot_move_done_step_two())); + else + slot_move_done_step_two(); +} + +void myView::slot_move_done_step_two() +{ + // + m_current->yourTurn(m_board->game()); + + if(check_game_over()) + emit working(false); +} + + +void myView::you_won(bool yes) +{ + if(yes&&m_player->isWhite() || !yes&&!m_player->isWhite()) { + m_history->setTag(PdnGame::Result, "1-0"); // white wins + add_log(myView::System, tr("White wins!")); + } else { + m_history->setTag(PdnGame::Result, "0-1"); // black wins + add_log(myView::System, tr("Black wins!")); + } + + emit working(false); +} + + +bool myView::openPdn(const QString& fn) +{ + emit working(false); + + m_current->stop(); + + QString log_text; + if(!m_history->openPdn(fn, log_text)) { + return false; + } + + if(log_text.length()) { + add_log(myView::System, tr("Opened:")+" "+fn); + add_log(myView::Error, log_text.trimmed()); + add_log(myView::Warning, tr("Warning! Some errors occured.")); + } + + return true; +} + + +bool myView::savePdn(const QString& fn) +{ + if(!m_history->savePdn(fn)) { + qDebug() << __PRETTY_FUNCTION__ << "failed."; + return false; + } + add_log(myView::System, tr("Saved:")+" "+fn); + return true; +} + + +void myView::slot_new_mode(bool paused, bool freeplace) +{ + if(paused) { + if(freeplace) + m_board->setCursor(Qt::PointingHandCursor); + else + m_board->setCursor(Qt::ForbiddenCursor); + } else { + m_board->setCursor(Qt::ArrowCursor); + } + + // resume game: ask info for who is next, black or white.XXX FIXME TODO + if(!paused) { + myPlayer* next = 0; + if(m_history->moveCount()%2==0) + next = get_first_player(); + else + next = get_first_player()->opponent(); + + m_current = next->opponent(); + slot_move_done(m_board->game()->toString(false)); + } +} + + +void myView::slot_preview_game(int rules) +{ + if(rules!=RUSSIAN && rules!=ENGLISH) { + qDebug() << __PRETTY_FUNCTION__ << rules << "Wrong game type."; + return; + } + + m_board->setGame(rules); + + if(m_player->isWhite() && rules==RUSSIAN) { + m_player->setName(m_history->getTag(PdnGame::White)); + m_player->opponent()->setName(m_history->getTag(PdnGame::Black)); + } else { + m_player->setName(m_history->getTag(PdnGame::Black)); + m_player->opponent()->setName(m_history->getTag(PdnGame::White)); + } + + // FIXME + m_player->setWhite(rules==RUSSIAN);// FIXME TODO + m_player->opponent()->setWhite(!m_player->isWhite()); + m_board->setColorWhite(m_player->isWhite()); + m_board->adjustNotation(m_player->isWhite()); +} + + +void myView::slot_apply_moves(const QString& moves) +{ + QStringList move_list= moves.split(MOVE_SPLIT, QString::SkipEmptyParts); + + m_board->reset(); + + bool white_player = get_first_player()->isWhite(); + foreach(QString move, move_list) { + m_board->doMove(move, white_player); + white_player = !white_player; + } + + // set current player who pulls next. assume is white. + m_current = (m_player->isWhite() ? m_player : m_player->opponent()); + if(!white_player) + m_current = m_current->opponent(); + m_history->setCurrent(m_current->name()); +} + + +void myView::add_log(enum LogType type, const QString& text) +{ + QString str = text; + str = str.replace('<', "<"); + str = str.replace('>', ">"); + + QString tag_b, tag_e; + switch(type) { + case Error: tag_b="

    "; tag_e="
"; break; + case Warning: tag_b=""; tag_e=""; break; + case System: tag_b=""; tag_e=""; break; + default: break; + } + + m_log->append(tag_b + str + tag_e); + + m_log->ensureCursorVisible(); +} + + +void myView::perform_jumps(const QString& from_board, const QString& to_board) +{ + if(from_board==to_board) { + return; + } + + QString new_to_board = to_board; + + //qDebug("F:%s\nT:%s", from_board.latin1(), new_to_board.latin1()); + + // diff + QList diff_list; + + // collect information + for(int i=0; i<32; i++) { + if(from_board[2*i]!=new_to_board[2*i] + || from_board[2*i+1]!=new_to_board[2*i+1]) { + myDiff* diff = new myDiff(i, + from_board.mid(2*i, 2).toInt(), + new_to_board.mid(2*i, 2).toInt()); + diff_list.append(diff); + + //qDebug(">%d: %d->%d", diff->m_pos, diff->m_from, diff->m_to); + } + } + + int from_pos = -1; + int to_pos = -1; + bool captured = (diff_list.count()>2); + + int man = -1; + // find the dest. first: so we have the man moved. + foreach(myDiff* diff, diff_list) { + if(diff->m_to!=FREE) { + man = diff->m_to; + to_pos = diff->m_pos; + break; + } + } + + int king = -1; + switch(man) { + case MAN1: king=KING1; break; + case KING1: king=MAN1; break; + case MAN2: king=KING2; break; + case KING2: king=MAN2; break; + } + // find src. + foreach(myDiff* diff, diff_list) { + if(diff->m_to==FREE) { + if(diff->m_from==man || diff->m_from==king) { + from_pos = diff->m_pos; + break; + } + } + } + + /* + qDebug(" to_pos=%d with man/king=%d from=%d", to_pos, man, + from_pos); + */ + + // finally - animate :) + QString move = m_board->doMove(from_pos, to_pos, m_current->isWhite()); + m_history->appendMove(move.replace("?", captured ? "x" : "-" ), ""); + + qDeleteAll(diff_list); +} + +void myView::setNotation(bool enabled, bool show_above) +{ + // TODO - intermediate function - remove somehow! + m_board->setNotation(enabled, show_above); +} + + +void myView::setNotationFont(const QFont& f) +{ + // TODO - intermediate function - remove somehow! + m_board->setNotationFont(f); +} + + +myPlayer* myView::get_first_player() const +{ + bool white = m_board->type()==RUSSIAN ? true : false; + // it is white. + if((white && m_player->isWhite()) || (!white && !m_player->isWhite())) + return m_player; + return m_player->opponent(); +} + + diff --git a/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.h b/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.h new file mode 100644 index 000000000..7330325d6 --- /dev/null +++ b/retroshare-gui/src/gui/plugins/qcheckers_plugin/view.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 Artur Wiebe * + * wibix@gmx.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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _VIEW_H_ +#define _VIEW_H_ + + +#include +#include +#include +#include + + +#include "board.h" + + +class Pdn; +class myPlayer; +class myHistory; + + +class myView : public QFrame +{ + Q_OBJECT + +public: + myView(QWidget* parent); + ~myView(); + + void newGame(int rules, bool free_place, + const QString& name, bool is_white, + int opponent, const QString& opp_name, int skill); + bool openPdn(const QString& fn); + bool savePdn(const QString& fn); + + void setTheme(const QString& theme_path); + + bool isAborted() const { return m_aborted; } + + void setNotation(bool enabled, bool show_above); + void setNotationFont(const QFont& f); + QFont notationFont() const { return m_board->font(); } + +public slots: + virtual void setEnabled(bool); + + void slotClearLog(bool b) { m_clear_log = b; } + + void slotStopGame(); + void slotNextRound(); + +signals: + void working(bool); + +private slots: + void slot_click(int); + + void slot_move_done(const QString& board_str); + void slot_move_done_step_two(); + + void slot_preview_game(int game_type); + void slot_apply_moves(const QString& moves); + void slot_new_mode(bool paused, bool freeplace); + +private: + void begin_game(unsigned int round, bool freeplacement); + + void perform_jumps(const QString& from_board, const QString& to_board); + bool extract_move(const QString& move, int* from_num, int* to_num); + + void stop_game(const QString&); + void you_won(bool really); + bool check_game_over(); + + enum LogType { + None, + Error, + Warning, + System, + User, + Opponent, + }; + void add_log(enum LogType type, const QString& text); + + myPlayer* get_first_player() const; + +private: + bool m_clear_log; + + bool m_game_over;// need this to avoid multiple calls to isGameOver() + bool m_aborted; + + myPlayer* m_player; + myPlayer* m_current; + + myBoard* m_board; + myHistory* m_history; + QTextEdit* m_log; + + int m_freeplace_from; +}; + + +#endif +