Async ai + option dialog + board background
This commit is contained in:
parent
a1bac12ede
commit
39c3cde25e
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ toruschess.kdevses
|
|||||||
*.o
|
*.o
|
||||||
moc_*
|
moc_*
|
||||||
qrc_*
|
qrc_*
|
||||||
|
ui_*
|
||||||
|
BIN
media/board1_dark.png
Normal file
BIN
media/board1_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 581 B |
BIN
media/board1_white.png
Normal file
BIN
media/board1_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 581 B |
BIN
media/board2_dark.png
Normal file
BIN
media/board2_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
BIN
media/board2_white.png
Normal file
BIN
media/board2_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
26
src/ai.cpp
26
src/ai.cpp
@ -58,6 +58,20 @@ namespace toruschess {
|
|||||||
return mx;
|
return mx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Move ai::getMove(Field &field, Player curp, int depth) {
|
||||||
|
int balance = 0;
|
||||||
|
for (int x = 0; x < 8; x++)
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
Pos p(x,y);
|
||||||
|
balance += field.player(p) * piece_value[field.piece(p)];
|
||||||
|
}
|
||||||
|
|
||||||
|
Move move;
|
||||||
|
minimax(field, balance, curp, depth, &move);
|
||||||
|
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Move ai::getMove(const Game *game) {
|
Move ai::getMove(const Game *game) {
|
||||||
Player curp = NOPLAYER;
|
Player curp = NOPLAYER;
|
||||||
@ -73,16 +87,6 @@ namespace toruschess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Field field = *game->field();
|
Field field = *game->field();
|
||||||
int balance = 0;
|
return getMove(field, curp, 2);
|
||||||
for (int x = 0; x < 8; x++)
|
|
||||||
for (int y = 0; y < 8; y++) {
|
|
||||||
Pos p(x,y);
|
|
||||||
balance += field.player(p) * piece_value[field.piece(p)];
|
|
||||||
}
|
|
||||||
|
|
||||||
Move move;
|
|
||||||
minimax(field, balance, curp, 2, &move);
|
|
||||||
|
|
||||||
return move;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
src/ai.h
1
src/ai.h
@ -28,6 +28,7 @@
|
|||||||
namespace toruschess {
|
namespace toruschess {
|
||||||
class ai{
|
class ai{
|
||||||
public:
|
public:
|
||||||
|
static Move getMove(Field &field, Player curp, int depth);
|
||||||
static Move getMove(const Game *game);
|
static Move getMove(const Game *game);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -131,11 +131,9 @@ namespace toruschess {
|
|||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
bool marked = m_marked[x][y];
|
bool marked = m_marked[x][y];
|
||||||
int place = m_game->field()->place(Pos(x, y));
|
int place = m_game->field()->place(Pos(x, y));
|
||||||
/* #D18B47 for dark, #FFCE9E for white */
|
|
||||||
QBrush fieldBG = ((x+y) % 2 == 1) ? QBrush(QColor(0xD1, 0x8B, 0x47)) : QBrush(QColor(0xFF, 0xCE, 0x9E));
|
|
||||||
|
|
||||||
QRect prect(x * pieceWidth, y * pieceHeight, pieceWidth - 1, pieceHeight - 1);
|
QRect prect(x * pieceWidth, y * pieceHeight, pieceWidth - 1, pieceHeight - 1);
|
||||||
pt.fillRect(prect, fieldBG);
|
m_lib->paint_board(pt, (x+y) % 2 == 1, prect);
|
||||||
m_lib->paint(pt, place, prect);
|
m_lib->paint(pt, place, prect);
|
||||||
if (marked) {
|
if (marked) {
|
||||||
int r = qMax(1, (pieceWidth + pieceHeight) / 36);
|
int r = qMax(1, (pieceWidth + pieceHeight) / 36);
|
||||||
|
@ -169,11 +169,9 @@ namespace toruschess {
|
|||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
bool marked = m_marked[x][y];
|
bool marked = m_marked[x][y];
|
||||||
int place = m_game->field()->place(Pos(x, y));
|
int place = m_game->field()->place(Pos(x, y));
|
||||||
/* #D18B47 for dark, #FFCE9E for white */
|
|
||||||
QBrush fieldBG = ((x+y) % 2 == 1) ? QBrush(QColor(0xD1, 0x8B, 0x47)) : QBrush(QColor(0xFF, 0xCE, 0x9E));
|
|
||||||
|
|
||||||
QRect prect(x * pieceSize, y * pieceSize, pieceSize - 1, pieceSize - 1);
|
QRect prect(x * pieceSize, y * pieceSize, pieceSize - 1, pieceSize - 1);
|
||||||
pt.fillRect(prect, fieldBG);
|
m_lib->paint_board(pt, (x+y) % 2 == 1, prect);
|
||||||
m_lib->paint(pt, place, prect);
|
m_lib->paint(pt, place, prect);
|
||||||
if (marked) {
|
if (marked) {
|
||||||
int r = qMax(1, (pieceSize + pieceSize) / 36);
|
int r = qMax(1, (pieceSize + pieceSize) / 36);
|
||||||
|
@ -13,5 +13,9 @@
|
|||||||
<file alias="chess_11.svg">../media/Chess_qdt45.svg</file>
|
<file alias="chess_11.svg">../media/Chess_qdt45.svg</file>
|
||||||
<file alias="chess_12.svg">../media/Chess_kdt45.svg</file>
|
<file alias="chess_12.svg">../media/Chess_kdt45.svg</file>
|
||||||
<file alias="pawn.3ds">../media/pawn.3ds</file>
|
<file alias="pawn.3ds">../media/pawn.3ds</file>
|
||||||
|
<file alias="board1_dark.png">../media/board1_dark.png</file>
|
||||||
|
<file alias="board1_white.png">../media/board1_white.png</file>
|
||||||
|
<file alias="board2_dark.png">../media/board2_dark.png</file>
|
||||||
|
<file alias="board2_white.png">../media/board2_white.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
81
src/optiondlg.cpp
Normal file
81
src/optiondlg.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Stefan Bühler *
|
||||||
|
* stbuehler@web.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 "optiondlg.h"
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
namespace toruschess {
|
||||||
|
|
||||||
|
OptionDlg::OptionDlg(Game *game, QWidget *parent)
|
||||||
|
: QDialog(parent), m_game(game) {
|
||||||
|
m_curMode = m_game->gameMode();
|
||||||
|
m_curAIStrength = m_game->aiStrength();
|
||||||
|
setupUi(this);
|
||||||
|
|
||||||
|
m_bgMode = new QButtonGroup(this);
|
||||||
|
m_bgMode->addButton(rb_mode1, HUMAN_HUMAN);
|
||||||
|
m_bgMode->addButton(rb_mode2, HUMAN_COMPUTER);
|
||||||
|
m_bgMode->addButton(rb_mode3, COMPUTER_HUMAN);
|
||||||
|
m_bgMode->addButton(rb_mode4, COMPUTER_COMPUTER);
|
||||||
|
|
||||||
|
dlgReset();
|
||||||
|
|
||||||
|
connect(m_game, SIGNAL(changedMode(GameMode)), this, SLOT(gameChangedMode(GameMode)));
|
||||||
|
connect(m_game, SIGNAL(changedAIStrength(int)), this, SLOT(gameChangedAIStrength(int)));
|
||||||
|
|
||||||
|
connect(this, SIGNAL(accepted()), this, SLOT(dlgAccept()));
|
||||||
|
connect(this, SIGNAL(rejected()), this, SLOT(dlgReset()));
|
||||||
|
|
||||||
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
|
||||||
|
connect(buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(dlgReset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionDlg::gameChangedMode(GameMode mode) {
|
||||||
|
if (m_curMode != mode) {
|
||||||
|
if (m_bgMode->checkedId() == m_curMode) {
|
||||||
|
m_bgMode->button(mode)->setChecked(true);
|
||||||
|
}
|
||||||
|
m_curMode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionDlg::gameChangedAIStrength(int aiStrength) {
|
||||||
|
if (m_curAIStrength != aiStrength) {
|
||||||
|
if (sb_aiStrength->value() == m_curAIStrength) {
|
||||||
|
sb_aiStrength->setValue(aiStrength);
|
||||||
|
}
|
||||||
|
m_curAIStrength = aiStrength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionDlg::dlgReset() {
|
||||||
|
sb_aiStrength->setValue(m_curAIStrength);
|
||||||
|
m_bgMode->button(m_curMode)->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionDlg::dlgAccept() {
|
||||||
|
m_curAIStrength = sb_aiStrength->value();
|
||||||
|
m_game->setAiStrength(m_curAIStrength);
|
||||||
|
m_curMode = (GameMode) m_bgMode->checkedId();
|
||||||
|
m_game->setGameMode(m_curMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
src/optiondlg.h
Normal file
54
src/optiondlg.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Stefan Bühler *
|
||||||
|
* stbuehler@web.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 TORUSCHESSOPTIONDLG_H
|
||||||
|
#define TORUSCHESSOPTIONDLG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include "ui_optiondlg.h"
|
||||||
|
|
||||||
|
#include "toruschess.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@author Stefan Bühler <stbuehler@web.de>
|
||||||
|
*/
|
||||||
|
namespace toruschess {
|
||||||
|
class OptionDlg : public QDialog, private Ui::OptionDlg {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OptionDlg(Game *game, QWidget *parent = 0);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void gameChangedMode(GameMode mode);
|
||||||
|
void gameChangedAIStrength(int aiStrength);
|
||||||
|
|
||||||
|
void dlgReset();
|
||||||
|
void dlgAccept();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Game *m_game;
|
||||||
|
GameMode m_curMode;
|
||||||
|
int m_curAIStrength;
|
||||||
|
QButtonGroup *m_bgMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
123
src/optiondlg.ui
Normal file
123
src/optiondlg.ui
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<ui version="4.0" >
|
||||||
|
<class>OptionDlg</class>
|
||||||
|
<widget class="QWidget" name="OptionDlg" >
|
||||||
|
<property name="windowModality" >
|
||||||
|
<enum>Qt::ApplicationModal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>373</width>
|
||||||
|
<height>227</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Options</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout" >
|
||||||
|
<item row="0" column="0" colspan="2" >
|
||||||
|
<widget class="QGroupBox" name="groupBox" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>Opponent</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rb_mode1" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Human vs. Human</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rb_mode2" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Human vs. Computer</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rb_mode3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Computer vs. Human</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rb_mode4" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Computer vs. Computer</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||||
|
<property name="sizeConstraint" >
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>Computer strength (recursion depth)</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>sb_aiStrength</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="sb_aiStrength" >
|
||||||
|
<property name="alignment" >
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="minimum" >
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||||
|
<property name="standardButtons" >
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>rb_mode1</tabstop>
|
||||||
|
<tabstop>rb_mode2</tabstop>
|
||||||
|
<tabstop>rb_mode3</tabstop>
|
||||||
|
<tabstop>rb_mode4</tabstop>
|
||||||
|
<tabstop>sb_aiStrength</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -133,6 +133,9 @@ typedef size_t (*Lib3dsIoWriteFunc)(void *self, const void *buffer, size_t size)
|
|||||||
|
|
||||||
PieceLibrary::PieceLibrary(QObject *parent)
|
PieceLibrary::PieceLibrary(QObject *parent)
|
||||||
: QObject(parent), m_pieces(0), m_buffers(0) {
|
: QObject(parent), m_pieces(0), m_buffers(0) {
|
||||||
|
m_board = new QImage*[2];
|
||||||
|
m_board[0] = new QImage(":/media/board2_white.png");
|
||||||
|
m_board[1] = new QImage(":/media/board2_dark.png");
|
||||||
m_pawn = read_3ds(loadResource(":/media/pawn.3ds"));
|
m_pawn = read_3ds(loadResource(":/media/pawn.3ds"));
|
||||||
setSize(45, 45);
|
setSize(45, 45);
|
||||||
}
|
}
|
||||||
@ -141,6 +144,7 @@ typedef size_t (*Lib3dsIoWriteFunc)(void *self, const void *buffer, size_t size)
|
|||||||
if (m_pawn) lib3ds_file_free(m_pawn);
|
if (m_pawn) lib3ds_file_free(m_pawn);
|
||||||
delete [] m_pieces;
|
delete [] m_pieces;
|
||||||
delete [] m_buffers;
|
delete [] m_buffers;
|
||||||
|
delete [] m_board;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PieceLibrary::setSize(int width, int height) {
|
void PieceLibrary::setSize(int width, int height) {
|
||||||
@ -179,6 +183,9 @@ typedef size_t (*Lib3dsIoWriteFunc)(void *self, const void *buffer, size_t size)
|
|||||||
pt.drawImage(rect, *m_buffers[place-1]);
|
pt.drawImage(rect, *m_buffers[place-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PieceLibrary::paint_board(QPainter &pt, bool darkField, const QRect &rect) const {
|
||||||
|
pt.drawImage(rect, *m_board[darkField ? 1 : 0]);
|
||||||
|
}
|
||||||
|
|
||||||
void PieceLibrary::paint_pawn() {
|
void PieceLibrary::paint_pawn() {
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
@ -42,11 +42,13 @@ namespace toruschess {
|
|||||||
void paint(QPainter &pt, int place) const;
|
void paint(QPainter &pt, int place) const;
|
||||||
void paint(QPainter &pt, int place, const QRect &rect) const;
|
void paint(QPainter &pt, int place, const QRect &rect) const;
|
||||||
|
|
||||||
|
void paint_board(QPainter &pt, bool darkField, const QRect &rect) const;
|
||||||
|
|
||||||
void paint_pawn();
|
void paint_pawn();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSvgRenderer **m_pieces;
|
QSvgRenderer **m_pieces;
|
||||||
QImage **m_buffers;
|
QImage **m_buffers, **m_board;
|
||||||
int m_width, m_height;
|
int m_width, m_height;
|
||||||
|
|
||||||
Lib3dsFile *m_pawn;
|
Lib3dsFile *m_pawn;
|
||||||
|
@ -4,7 +4,8 @@ SOURCES += main.cpp \
|
|||||||
field2d.cpp \
|
field2d.cpp \
|
||||||
piecelibrary.cpp \
|
piecelibrary.cpp \
|
||||||
field3d.cpp \
|
field3d.cpp \
|
||||||
ai.cpp
|
ai.cpp \
|
||||||
|
optiondlg.cpp
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
CONFIG += warn_on \
|
CONFIG += warn_on \
|
||||||
thread \
|
thread \
|
||||||
@ -22,7 +23,8 @@ toruschess.h \
|
|||||||
field2d.h \
|
field2d.h \
|
||||||
piecelibrary.h \
|
piecelibrary.h \
|
||||||
field3d.h \
|
field3d.h \
|
||||||
ai.h
|
ai.h \
|
||||||
|
optiondlg.h
|
||||||
|
|
||||||
LIBS += -l3ds
|
LIBS += -l3ds
|
||||||
|
|
||||||
@ -30,3 +32,5 @@ QMAKE_CXXFLAGS_RELEASE += -g
|
|||||||
|
|
||||||
CONFIG -= release
|
CONFIG -= release
|
||||||
|
|
||||||
|
FORMS += optiondlg.ui
|
||||||
|
|
||||||
|
109
src/testgame.cpp
109
src/testgame.cpp
@ -25,6 +25,9 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
|
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
#include "field2d.h"
|
#include "field2d.h"
|
||||||
#include "field3d.h"
|
#include "field3d.h"
|
||||||
|
|
||||||
@ -32,89 +35,7 @@
|
|||||||
|
|
||||||
namespace toruschess {
|
namespace toruschess {
|
||||||
|
|
||||||
TestPlace::TestPlace(QWidget *parent, const PieceLibrary *lib, const Field *field, const Pos &p)
|
TestGame::TestGame(QWidget *parent) : QMainWindow(parent), m_game(new Game()), m_optionDlg(new OptionDlg(m_game, this)) {
|
||||||
: QWidget(parent), m_field(field), m_lib(lib), m_pos(p), m_mark(false) {
|
|
||||||
setMinimumSize(m_lib->minPieceSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize TestPlace::sizeHint() const {
|
|
||||||
return m_lib->pieceSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestPlace::paintEvent(QPaintEvent *) {
|
|
||||||
QPainter pt(this);
|
|
||||||
int pl = m_field->place(m_pos);
|
|
||||||
if ((m_pos.x() + m_pos.y()) % 2) {
|
|
||||||
// #D18B47
|
|
||||||
pt.fillRect(rect(), QBrush(QColor(0xD1, 0x8B, 0x47)));
|
|
||||||
} else {
|
|
||||||
// #FFCE9E
|
|
||||||
pt.fillRect(rect(), QBrush(QColor(0xFF, 0xCE, 0x9E)));
|
|
||||||
}
|
|
||||||
m_lib->paint(pt, pl);
|
|
||||||
if (m_mark) {
|
|
||||||
int r = qMax(1, (rect().width() + rect().height()) / 36);
|
|
||||||
pt.setBrush(pl != 0 ? Qt::green : Qt::white);
|
|
||||||
pt.setPen(Qt::red);
|
|
||||||
pt.drawEllipse(QPoint(rect().width() / 2, rect().height() / 2), r, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TestField::TestField(QWidget *parent, PieceLibrary *lib, Game *game) : QWidget(parent), m_lib(lib), m_game(game) {
|
|
||||||
QGridLayout *layout = new QGridLayout();
|
|
||||||
for (int y = 0; y < 8; y++) {
|
|
||||||
for (int x = 0; x < 8; x++) {
|
|
||||||
m_places[x][y] = new TestPlace(this, m_lib, m_game->field(), Pos(x, y));
|
|
||||||
layout->addWidget(m_places[x][y], y, x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layout->setSpacing(0);
|
|
||||||
setLayout(layout);
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestField::markMoves(const QList<Move> &moves) {
|
|
||||||
foreach(Move m, m_marked) m_places[m.to().x()][m.to().y()]->hideMark();
|
|
||||||
m_marked = moves;
|
|
||||||
foreach(Move m, m_marked) m_places[m.to().x()][m.to().y()]->showMark();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestField::resizeEvent(QResizeEvent *event) {
|
|
||||||
m_lib->setSize(event->size().width()/8, event->size().height()/8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestField::mousePressEvent(QMouseEvent *event) {
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
|
||||||
QList<Move> moves;
|
|
||||||
int x = (event->x() * 8) / width();
|
|
||||||
int y = (event->y() * 8) / height();
|
|
||||||
if (x < 0 || x >= 8 || y < 0 || y >= 8) {
|
|
||||||
markMoves(moves);
|
|
||||||
} else {
|
|
||||||
moves = m_game->field()->validMoves(Pos(x, y));
|
|
||||||
markMoves(moves);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestField::mouseReleaseEvent(QMouseEvent *event) {
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
|
||||||
if (m_marked.size() == 0) return;
|
|
||||||
Pos from = m_marked[0].from();
|
|
||||||
QList<Move> moves;
|
|
||||||
markMoves(QList<Move>());
|
|
||||||
int x = (event->x() * 8) / width();
|
|
||||||
int y = (event->y() * 8) / height();
|
|
||||||
if (x < 0 || x >= 8 || y < 0 || y >= 8) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Move m(m_game->field(), from, Pos(x, y));
|
|
||||||
m_game->move(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TestGame::TestGame(QWidget *parent) : QMainWindow(parent), m_game(new Game()) {
|
|
||||||
setWindowTitle("Torus Chess");
|
setWindowTitle("Torus Chess");
|
||||||
// PieceLibrary *lib = new PieceLibrary(this);
|
// PieceLibrary *lib = new PieceLibrary(this);
|
||||||
// setCentralWidget(new TestField(this, lib, m_game));
|
// setCentralWidget(new TestField(this, lib, m_game));
|
||||||
@ -123,16 +44,34 @@ namespace toruschess {
|
|||||||
connect(m_game, SIGNAL(updated()), this, SLOT(gameUpdated()));
|
connect(m_game, SIGNAL(updated()), this, SLOT(gameUpdated()));
|
||||||
connect(m_game, SIGNAL(changed(GameState)), this, SLOT(gameChanged(GameState)));
|
connect(m_game, SIGNAL(changed(GameState)), this, SLOT(gameChanged(GameState)));
|
||||||
m_game->restart();
|
m_game->restart();
|
||||||
|
|
||||||
|
QMenuBar *menuBar = new QMenuBar(this);
|
||||||
|
QMenu *menuGame = menuBar->addMenu("Game");
|
||||||
|
menuGame->addAction("New Game", this, SLOT(menuRestart()));
|
||||||
|
menuGame->addAction("Options", this, SLOT(menuOptions()));
|
||||||
|
menuGame->addSeparator();
|
||||||
|
menuGame->addAction("Quit", this, SLOT(close()));
|
||||||
|
setMenuBar(menuBar);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGame::gameUpdated() {
|
void TestGame::gameUpdated() {
|
||||||
if (m_game->state() == TURN_BLACK) {
|
/* if (m_game->state() == TURN_BLACK) {
|
||||||
Move m = ai::getMove(m_game);
|
Move m = ai::getMove(m_game);
|
||||||
if (m.valid()) m_game->move(m);
|
if (m.valid()) m_game->move(m);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestGame::gameChanged(GameState state) {
|
void TestGame::gameChanged(GameState state) {
|
||||||
statusBar()->showMessage(state2string(state));
|
statusBar()->showMessage(state2string(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestGame::menuRestart() {
|
||||||
|
m_game->restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestGame::menuOptions() {
|
||||||
|
m_optionDlg->exec();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,53 +28,13 @@
|
|||||||
#include "toruschess.h"
|
#include "toruschess.h"
|
||||||
#include "piecelibrary.h"
|
#include "piecelibrary.h"
|
||||||
|
|
||||||
|
#include "optiondlg.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Stefan Bühler <stbuehler@web.de>
|
@author Stefan Bühler <stbuehler@web.de>
|
||||||
*/
|
*/
|
||||||
namespace toruschess {
|
namespace toruschess {
|
||||||
|
|
||||||
class TestPlace : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
TestPlace(QWidget *parent, const PieceLibrary *lib, const Field *field, const Pos &p);
|
|
||||||
|
|
||||||
const Pos& pos() const { return m_pos; }
|
|
||||||
const Field* field() const { return m_field; }
|
|
||||||
|
|
||||||
virtual QSize sizeHint() const;
|
|
||||||
|
|
||||||
void showMark() { m_mark = true; update(); }
|
|
||||||
void hideMark() { m_mark = false; update(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void paintEvent(QPaintEvent *event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Field *m_field;
|
|
||||||
const PieceLibrary *m_lib;
|
|
||||||
Pos m_pos;
|
|
||||||
bool m_mark;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestField : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
TestField(QWidget *parent, PieceLibrary *lib, Game *m_game);
|
|
||||||
|
|
||||||
void markMoves(const QList<Move> &moves);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void resizeEvent(QResizeEvent *event);
|
|
||||||
virtual void mousePressEvent(QMouseEvent *event);
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
PieceLibrary *m_lib;
|
|
||||||
Game *m_game;
|
|
||||||
TestPlace* m_places[8][8];
|
|
||||||
QList<Move> m_marked;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestGame : public QMainWindow {
|
class TestGame : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -84,8 +44,12 @@ namespace toruschess {
|
|||||||
void gameUpdated();
|
void gameUpdated();
|
||||||
void gameChanged(GameState state);
|
void gameChanged(GameState state);
|
||||||
|
|
||||||
|
void menuRestart();
|
||||||
|
void menuOptions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Game *m_game;
|
Game *m_game;
|
||||||
|
OptionDlg *m_optionDlg;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,18 @@
|
|||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "toruschess.h"
|
#include "toruschess.h"
|
||||||
|
#include "ai.h"
|
||||||
|
|
||||||
namespace toruschess {
|
namespace toruschess {
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
static bool done = FALSE;
|
||||||
|
if (done) return;
|
||||||
|
done = TRUE;
|
||||||
|
qRegisterMetaType<Move>("Move");
|
||||||
|
qRegisterMetaType<Pos>("Pos");
|
||||||
|
}
|
||||||
|
|
||||||
QString state2string(GameState state) {
|
QString state2string(GameState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TURN_WHITE: return "White's turn";
|
case TURN_WHITE: return "White's turn";
|
||||||
@ -318,13 +327,16 @@ namespace toruschess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Game::Game(QObject *parent)
|
Game::Game(QObject *parent)
|
||||||
: QObject(parent), m_field(new Field()), m_state(TURN_WHITE) { }
|
: QObject(parent), m_field(new Field()), m_state(TURN_WHITE), m_gameMode(HUMAN_COMPUTER), m_aiStrength(2), m_aiThread(0) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
Game::~Game() {
|
Game::~Game() {
|
||||||
delete m_field;
|
delete m_field;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::move(const Move &m) {
|
bool Game::move(const Move &m) {
|
||||||
|
if (m_aiThread) return false;
|
||||||
if (!m.valid()) return false;
|
if (!m.valid()) return false;
|
||||||
switch (m_state) {
|
switch (m_state) {
|
||||||
case TURN_WHITE:
|
case TURN_WHITE:
|
||||||
@ -357,6 +369,7 @@ namespace toruschess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
checkAI();
|
||||||
emit moved(m);
|
emit moved(m);
|
||||||
emit changed(m_state);
|
emit changed(m_state);
|
||||||
emit updated();
|
emit updated();
|
||||||
@ -368,6 +381,7 @@ namespace toruschess {
|
|||||||
void Game::restart() {
|
void Game::restart() {
|
||||||
m_state = TURN_WHITE;
|
m_state = TURN_WHITE;
|
||||||
m_field->reset();
|
m_field->reset();
|
||||||
|
checkAI();
|
||||||
emit changed(m_state);
|
emit changed(m_state);
|
||||||
emit started();
|
emit started();
|
||||||
emit updated();
|
emit updated();
|
||||||
@ -393,4 +407,81 @@ namespace toruschess {
|
|||||||
}
|
}
|
||||||
return moves;
|
return moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::setGameMode(GameMode gm) {
|
||||||
|
m_gameMode = gm;
|
||||||
|
checkAI();
|
||||||
|
emit changedMode(m_gameMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::setAiStrength(int s) {
|
||||||
|
m_aiStrength = qMin(7, qMax(2, s));
|
||||||
|
emit changedAIStrength(m_aiStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::checkAI() {
|
||||||
|
if (m_aiThread) {
|
||||||
|
switch (m_gameMode) {
|
||||||
|
case HUMAN_HUMAN:
|
||||||
|
m_ignoreAI = true;
|
||||||
|
break;
|
||||||
|
case HUMAN_COMPUTER:
|
||||||
|
if (m_state != TURN_BLACK) m_ignoreAI = true;
|
||||||
|
break;
|
||||||
|
case COMPUTER_HUMAN:
|
||||||
|
if (m_state != TURN_WHITE) m_ignoreAI = true;
|
||||||
|
break;
|
||||||
|
case COMPUTER_COMPUTER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Player curp = NOPLAYER;
|
||||||
|
switch (m_state) {
|
||||||
|
case TURN_WHITE:
|
||||||
|
curp = WHITE;
|
||||||
|
break;
|
||||||
|
case TURN_BLACK:
|
||||||
|
curp = BLACK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (m_gameMode) {
|
||||||
|
case HUMAN_HUMAN:
|
||||||
|
return;
|
||||||
|
case HUMAN_COMPUTER:
|
||||||
|
if (m_state != TURN_BLACK) return;
|
||||||
|
break;
|
||||||
|
case COMPUTER_HUMAN:
|
||||||
|
if (m_state != TURN_WHITE) return;
|
||||||
|
break;
|
||||||
|
case COMPUTER_COMPUTER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_aiThread = new GameAIThread(*m_field, curp, m_aiStrength, this);
|
||||||
|
m_ignoreAI = false;
|
||||||
|
connect(m_aiThread, SIGNAL(aiFinished(Move)), this, SLOT(finishedAI(Move)));
|
||||||
|
m_aiThread->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::finishedAI(Move m) {
|
||||||
|
m_aiThread->wait();
|
||||||
|
delete m_aiThread;
|
||||||
|
m_aiThread = 0;
|
||||||
|
if (!m_ignoreAI) {
|
||||||
|
move(m);
|
||||||
|
}
|
||||||
|
checkAI();
|
||||||
|
}
|
||||||
|
|
||||||
|
GameAIThread::GameAIThread(const Field &field, Player curp, int depth, QObject *parent)
|
||||||
|
: QThread(parent), m_field(field), m_curp(curp), m_depth(depth) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameAIThread::run() {
|
||||||
|
Move m = ai::getMove(m_field, m_curp, m_depth);
|
||||||
|
emit aiFinished(m);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Stefan Bühler <stbuehler@web.de>
|
@author Stefan Bühler <stbuehler@web.de>
|
||||||
@ -31,10 +33,12 @@ namespace toruschess {
|
|||||||
class Pos;
|
class Pos;
|
||||||
class Field;
|
class Field;
|
||||||
class Game;
|
class Game;
|
||||||
|
class GameAIThread;
|
||||||
|
|
||||||
typedef enum { BLACK = -1, NOPLAYER = 0, WHITE = 1 } Player;
|
typedef enum { BLACK = -1, NOPLAYER = 0, WHITE = 1 } Player;
|
||||||
typedef enum { NOPIECE = 0, PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6 } Piece;
|
typedef enum { NOPIECE = 0, PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6 } Piece;
|
||||||
typedef enum { TURN_WHITE, TURN_BLACK, WON_WHITE, WON_BLACK, DRAW } GameState;
|
typedef enum { TURN_WHITE, TURN_BLACK, WON_WHITE, WON_BLACK, DRAW } GameState;
|
||||||
|
typedef enum { HUMAN_HUMAN, HUMAN_COMPUTER, COMPUTER_HUMAN, COMPUTER_COMPUTER } GameMode;
|
||||||
|
|
||||||
inline Player place2player(int place) {
|
inline Player place2player(int place) {
|
||||||
return (place < 0) ? BLACK : (place > 0) ? WHITE : NOPLAYER;
|
return (place < 0) ? BLACK : (place > 0) ? WHITE : NOPLAYER;
|
||||||
@ -49,7 +53,7 @@ namespace toruschess {
|
|||||||
class Pos {
|
class Pos {
|
||||||
public:
|
public:
|
||||||
Pos() : m_x(0), m_y(0) { }
|
Pos() : m_x(0), m_y(0) { }
|
||||||
Pos(int x, int y) : m_x(x % 8), m_y(y % 8) { }
|
Pos(int x, int y) : m_x(x & 7), m_y(y & 7) { }
|
||||||
|
|
||||||
int x() const { return m_x; }
|
int x() const { return m_x; }
|
||||||
int y() const { return m_y; }
|
int y() const { return m_y; }
|
||||||
@ -132,6 +136,12 @@ namespace toruschess {
|
|||||||
|
|
||||||
QList<Move> possibleMoves() const;
|
QList<Move> possibleMoves() const;
|
||||||
|
|
||||||
|
GameMode gameMode() const { return m_gameMode; }
|
||||||
|
void setGameMode(GameMode gm);
|
||||||
|
|
||||||
|
int aiStrength() const { return m_aiStrength; }
|
||||||
|
void setAiStrength(int s);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void moved(Move m);
|
void moved(Move m);
|
||||||
void updated();
|
void updated();
|
||||||
@ -139,12 +149,46 @@ namespace toruschess {
|
|||||||
void changed(GameState state);
|
void changed(GameState state);
|
||||||
void started();
|
void started();
|
||||||
|
|
||||||
|
void changedMode(GameMode mode);
|
||||||
|
void changedAIStrength(int aiStrength);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void finishedAI(Move m);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void checkAI();
|
||||||
|
|
||||||
Field *m_field;
|
Field *m_field;
|
||||||
GameState m_state;
|
GameState m_state;
|
||||||
|
GameMode m_gameMode;
|
||||||
|
int m_aiStrength;
|
||||||
|
|
||||||
QList<Move> m_moves;
|
QList<Move> m_moves;
|
||||||
|
|
||||||
|
GameAIThread *m_aiThread;
|
||||||
|
bool m_ignoreAI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GameAIThread : public QThread {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
GameAIThread(const Field &field, Player curp, int depth, QObject *parent = 0);
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void aiFinished(Move m);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Field m_field;
|
||||||
|
Player m_curp;
|
||||||
|
int m_depth;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(toruschess::Move)
|
||||||
|
Q_DECLARE_METATYPE(toruschess::Pos)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -144,7 +144,7 @@
|
|||||||
<programargs/>
|
<programargs/>
|
||||||
<directoryradio>executable</directoryradio>
|
<directoryradio>executable</directoryradio>
|
||||||
<globaldebugarguments/>
|
<globaldebugarguments/>
|
||||||
<globalcwd>/home/stefan/studium/7. semester/fapra_vis/src/toruschess</globalcwd>
|
<globalcwd>/home/stefan/develop/toruschess</globalcwd>
|
||||||
<useglobalprogram>false</useglobalprogram>
|
<useglobalprogram>false</useglobalprogram>
|
||||||
<terminal>false</terminal>
|
<terminal>false</terminal>
|
||||||
<autocompile>false</autocompile>
|
<autocompile>false</autocompile>
|
||||||
@ -152,13 +152,13 @@
|
|||||||
<autokdesu>false</autokdesu>
|
<autokdesu>false</autokdesu>
|
||||||
<envvars/>
|
<envvars/>
|
||||||
<runarguments>
|
<runarguments>
|
||||||
<toruschess></toruschess>
|
<toruschess/>
|
||||||
</runarguments>
|
</runarguments>
|
||||||
<cwd>
|
<cwd>
|
||||||
<toruschess>/home/stefan/studium/7. semester/fapra_vis/src/toruschess/..</toruschess>
|
<toruschess>/home/stefan/develop/toruschess</toruschess>
|
||||||
</cwd>
|
</cwd>
|
||||||
<debugarguments>
|
<debugarguments>
|
||||||
<toruschess></toruschess>
|
<toruschess/>
|
||||||
</debugarguments>
|
</debugarguments>
|
||||||
</run>
|
</run>
|
||||||
<general>
|
<general>
|
||||||
@ -213,7 +213,7 @@
|
|||||||
<QMAKE/>
|
<QMAKE/>
|
||||||
<VERSION>0.1</VERSION>
|
<VERSION>0.1</VERSION>
|
||||||
<YEAR>2009</YEAR>
|
<YEAR>2009</YEAR>
|
||||||
<dest>/home/stefan/studium/7. semester/fapra_vis/src/toruschess</dest>
|
<dest>/home/stefan/develop/toruschess</dest>
|
||||||
</substmap>
|
</substmap>
|
||||||
<cppsupportpart>
|
<cppsupportpart>
|
||||||
<filetemplates>
|
<filetemplates>
|
||||||
|
Loading…
Reference in New Issue
Block a user