mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-19 03:18:15 -04:00
added for plugins own dir
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1850 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
97d8640f3a
commit
87344de7d4
809 changed files with 790 additions and 722 deletions
587
plugins/qcheckers_plugin/view.cc
Normal file
587
plugins/qcheckers_plugin/view.cc
Normal file
|
@ -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 <QLayout>
|
||||
#include <QDate>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
#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="<ul><pre>"; tag_e="</pre></ul>"; break;
|
||||
case Warning: tag_b="<b>"; tag_e="</b>"; break;
|
||||
case System: tag_b="<font color=\"blue\">"; tag_e="</font>"; 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<myDiff*> 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();
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue