Commit 3a655366 authored by Matt Williams's avatar Matt Williams
Browse files

Add source files and CMakeLists.txt

svn path=/trunk/playground/games/ksquares/; revision=616140
parents
#PROJECT(ksquares)
#find_package(KDE4 REQUIRED)
#include (KDE4Defaults)
#include (MacroLibrary)
#find_library(KDEGAMES_LIB kdegames ${KDE4_LIB_DIR})
#link_directories (${KDE4_LIB_DIR})
#if (KDEGAMES_LIB)
# add_subdirectory(src)
#endif (KDEGAMES_LIB)
add_subdirectory(src)
\ No newline at end of file
2006-12-23 Matt Williams <matt@milliams.com>
* Imported into the KDE SVN at websvn.kde.org/trunk/playground/games/ksquares
2006-09-26 Matt Williams <matt@milliams.com>
* version 0.1
* Features
* - Can play a two player game of squares with proper scoring, game control etc.
* - Lots of bugs
\ No newline at end of file
PROJECT(ksquares)
FIND_PACKAGE(KDE4 REQUIRED)
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(ksquares_SRCS
ksquares.cpp
main.cpp
gameboardview.cpp
gameboardscene.cpp
ksquaresgame.cpp
newgamedialog.cpp
scoresdialog.cpp
)
kde4_automoc(${ksquares_SRCS})
kde4_add_ui_files(ksquares_SRCS newgamedialog.ui scoresdialog.ui prefs_base.ui)
kde4_add_kcfg_files(ksquares_SRCS GENERATE_MOC settings.kcfgc) #GENERATE_MOC is not needed but it doesn't work without it for some reason :S
kde4_add_executable(ksquares ${ksquares_SRCS})
target_link_libraries(ksquares ${KDE4_KDEUI_LIBS})
install(TARGETS ksquares DESTINATION ${BIN_INSTALL_DIR})
########### install files ###############
install( FILES ksquares.desktop DESTINATION ${XDG_APPS_DIR} )
install( FILES ksquares.kcfg DESTINATION ${KCFG_INSTALL_DIR} )
install( FILES ksquaresui.rc DESTINATION ${DATA_INSTALL_DIR}/ksquares )
/***************************************************************************
* Copyright (C) 2006 by Matthew Williams <matt@milliams.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include <math.h>
#include <iostream>
using std::cout;
using std::endl;
#include <kdebug.h>
#include "settings.h"
#include "gameboardscene.h"
//#include "lineitem.h"
GameBoardScene::GameBoardScene(int newWidth, int newHeight, QWidget *parent) : QGraphicsScene(parent), width(newWidth), height(newHeight), lineDrawn((2.0*newWidth*newHeight + newWidth + newHeight), false)
{
//setObjectName("GameBoardScene");
spacing = 40;
for(int iWidth = 0; iWidth <= width; iWidth++)
{
for(int iHeight = 0; iHeight <= height; iHeight++)
{
int x = iWidth*spacing;
int y = iHeight*spacing;
addEllipse(QRectF(-1,-1,2,2))->setPos(x,y);
}
}
QPen feintPen(Qt::DotLine);
feintPen.setColor(QColor(0,0,0,31));
for(int iWidth = 0; iWidth <= width; iWidth++)
{
addLine(QLineF(spacing*iWidth, 0, spacing*iWidth, spacing*height), feintPen);
}
for(int iHeight = 0; iHeight <= height; iHeight++)
{
addLine(QLineF(0, spacing*iHeight, spacing*width, spacing*iHeight), feintPen);
}
indicatorLine = new QGraphicsLineItem(spacing, spacing, spacing, spacing);
addItem(indicatorLine);
//lineDrawn.resize(2*width*height + width + height); //now done in constructor
squareOwnerTable.fill(0, (width*height));
QGraphicsEllipseItem tempItem;
QGraphicsEllipseItemType = tempItem.type();
}
bool GameBoardScene::isLineAlready(QList<QGraphicsEllipseItem*> pointPair)
{
int index = -1;
if (pointPair.size() == 2) // if it really is a pair
{
qreal pointOneX = pointPair.at(0)->scenePos().x()/spacing;
qreal pointOneY = pointPair.at(0)->scenePos().y()/spacing;
qreal pointTwoX = pointPair.at(1)->scenePos().x()/spacing;
qreal pointTwoY = pointPair.at(1)->scenePos().y()/spacing;
//this int conversion could go bad but SHOULD be safe
int refX; // these two will be the grid-coord of the
int refY; // to and left most point of the two
enum{HORZONTAL, VERTICAL} dir;
if (pointOneX == pointTwoX)
{
dir = VERTICAL;
refX = pointOneX;
if (pointTwoY < pointOneY) //want the topmost point as reference
refY = pointTwoY;
else
refY = pointOneY;
}
else if (pointOneY == pointTwoY)
{
dir = HORZONTAL;
refY = pointOneY;
if (pointOneX < pointTwoX) //want the leftmost point as reference
refX = pointOneX;
else
refX = pointTwoX;
}
if (dir == HORZONTAL)
{
index = refY * ((2*width)+1) + refX;
}
else if (dir == VERTICAL)
{
index = refY * ((2*width)+1) + refX + width;
}
}
if (index == -1)
return true;
return lineDrawn.at(index);
}
void GameBoardScene::addLineToIndex(QList<QGraphicsEllipseItem*> pointPair)
{
int index = -1;
if (pointPair.size() == 2) // if it really is a pair
{
qreal pointOneX = pointPair.at(0)->scenePos().x()/spacing;
qreal pointOneY = pointPair.at(0)->scenePos().y()/spacing;
qreal pointTwoX = pointPair.at(1)->scenePos().x()/spacing;
qreal pointTwoY = pointPair.at(1)->scenePos().y()/spacing;
//this int conversion could go bad but SHOULD be safe
int refX; // these two will be the grid-coord of the
int refY; // to and left most point of the two
enum{HORZONTAL, VERTICAL} dir;
if (pointOneX == pointTwoX)
{
dir = VERTICAL;
refX = pointOneX;
if (pointTwoY < pointOneY) //want the topmost point as reference
refY = pointTwoY;
else
refY = pointOneY;
}
else if (pointOneY == pointTwoY)
{
dir = HORZONTAL;
refY = pointOneY;
if (pointOneX < pointTwoX) //want the leftmost point as reference
refX = pointOneX;
else
refX = pointTwoX;
}
if (dir == HORZONTAL)
{
index = refY * ((2*width)+1) + refX;
}
else if (dir == VERTICAL)
{
index = refY * ((2*width)+1) + refX + width;
}
}
if (index == -1)
return;
lineDrawn[index] = true;
checkForNewSquares();
}
void GameBoardScene::checkForNewSquares()
{
for(int i=0; i < (width*height); i++) //cycle through every box..
{
if (squareOwnerTable.at(i) == 0) //..checking it if there is no current owner
{
//indices of the lines surrounding the box; Correlates to "QVector<bool> lineDrawn"
int index1 = (i/width) * ((2*width) + 1) + (i%width);
int index2 = index1 + width;
int index3 = index2 + 1;
int index4 = index3 + width;
//cout << index1 << ", " << index2 << ", " << index3 << ", " << index4 << " - " << lineDrawn.size() << endl;
if (lineDrawn.at(index1) and lineDrawn.at(index2) and lineDrawn.at(index3) and lineDrawn.at(index4))
{
kdDebug() << "Square " << i << " completed." << endl;
emit squareComplete(i);
}
}
}
emit lineDrawnSig();
}
void GameBoardScene::setSquareOwner(int squareIndex, int owner)
{
kdDebug() << "Square " << squareIndex << " owned by player " << owner << "." << endl;
squareOwnerTable[squareIndex] = owner;
drawSquare(squareIndex);
}
void GameBoardScene::drawSquare(int index)
{
QBrush brush(Qt::SolidPattern);
switch(squareOwnerTable[index])
{
case -1:
brush.setColor(Qt::white); //owner -1 is not a valid player
break;
case 0:
brush.setColor(Qt::red);
break;
case 1:
brush.setColor(Qt::blue);
break;
case 2:
brush.setColor(Qt::green);
break;
case 3:
brush.setColor(Qt::yellow);
break;
default:
brush.setColor(Qt::black); //this probably means there is something wrong (or more than 4 player :S)
}
addRect(QRectF(qreal((index%width)*spacing), qreal((index/width)*spacing), qreal(spacing), qreal(spacing)), QPen(), brush)->setZValue(-1);
}
QSize GameBoardScene::sizeHint()
{
return QSize(width*spacing, height*spacing);
}
void GameBoardScene::mouseDoubleClickEvent (QGraphicsSceneMouseEvent* mouseEvent)
{
//cout << "GameBoardScene::mouseDoubleClickEvent" << endl;
QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
}
void GameBoardScene::mousePressEvent (QGraphicsSceneMouseEvent* mouseEvent)
{
//cout << "GameBoardScene::mousePressEvent" << endl;
buttonPress = mouseEvent->buttons(); //store the buttton press for mouseReleaseEvent()
QGraphicsScene::mousePressEvent(mouseEvent);
}
void GameBoardScene::mouseReleaseEvent (QGraphicsSceneMouseEvent* mouseEvent)
{
//cout << "GameBoardScene::mouseReleaseEvent" << endl;
if (buttonPress == Qt::LeftButton)
{
QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
if (connectList.size() == 2)
{
indicatorLine->setPen(QPen(QBrush(QColor(255,255,0,0), Qt::SolidPattern), 2.0)); //just make the pen invisible
QGraphicsLineItem* newLine = new QGraphicsLineItem(QLineF(connectList.at(0)->scenePos(), connectList.at(1)->scenePos()));
newLine->setPen(QPen(QBrush(QColor(0,0,0), Qt::SolidPattern), 2.5));
addItem(newLine);
//actually add the line to the index
addLineToIndex(connectList);
}
}
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void GameBoardScene::mouseMoveEvent (QGraphicsSceneMouseEvent* mouseEvent)
{
//indicatorLine = 0;
//cout << "GameBoardScene::mouseMoveEvent" << endl;
//cout << "mouseEvent->scenePos(): " << mouseEvent->scenePos().x() << ", " << mouseEvent->scenePos().y() << endl;
QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
if (connectList.size() == 2)
{
if (not isLineAlready(connectList)) // if there is not already a line there
{
indicatorLine->setLine(QLineF(connectList.at(0)->scenePos(), connectList.at(1)->scenePos()));
indicatorLine->setPen(QPen(QBrush(QColor(255,255,0,160), Qt::SolidPattern), 2.0));
}
else
{
indicatorLine->setPen(QPen(QBrush(QColor(255,255,0,0), Qt::SolidPattern), 2.0));
}
}
else
{
indicatorLine->setPen(QPen(QBrush(QColor(255,255,0,0), Qt::SolidPattern), 2.0));
}
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
QList<QGraphicsEllipseItem*> GameBoardScene::getTwoNearestPoints(QPointF pos) const
{
QList<QGraphicsItem *> itemList = items();
QList<QGraphicsEllipseItem*> connectList;
for (int i = 0; i < itemList.size(); ++i)
{
if (itemList.at(i)->type() == QGraphicsEllipseItemType)
{
//cout << "itemList.at(i)->scenePos(): " << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i))->scenePos().x() << ", " << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i))->scenePos().y() << endl;
QPointF dist(pos - itemList.at(i)->scenePos());
qreal distMod = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
//if (distMod < (spacing*0.7071)) //there will only ever be either 1 or 2 items that fulfil this [0.7071 ~ 2^(-0.5)]
if (distMod < spacing-5)
{
connectList << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i));
}
}
}
return connectList;
}
#include "gameboardscene.moc"
/***************************************************************************
* Copyright (C) 2006 by Matthew Williams <matt@milliams.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef GAMEBOARDSCENE_H
#define GAMEBOARDSCENE_H
#include <QtGui>
class GameBoardScene : public QGraphicsScene
{
Q_OBJECT
public:
GameBoardScene(int newWidth, int newHeight, QWidget *parent = 0);
QSize sizeHint();
QVector<int> board() const {return squareOwnerTable;}
public slots:
void setSquareOwner(int squareIndex, int owner);
void drawSquare(int index);
protected:
QList<QGraphicsEllipseItem*> getTwoNearestPoints(QPointF pos) const;
void mousePressEvent (QGraphicsSceneMouseEvent* mouseEvent);
void mouseReleaseEvent (QGraphicsSceneMouseEvent* mouseEvent);
void mouseDoubleClickEvent (QGraphicsSceneMouseEvent* mouseEvent);
void mouseMoveEvent (QGraphicsSceneMouseEvent* mouseEvent);
int width;
int height;
int spacing;
bool isLineAlready(QList<QGraphicsEllipseItem*> pointPair);
void addLineToIndex(QList<QGraphicsEllipseItem*> pointPair);
void checkForNewSquares();
Qt::MouseButtons buttonPress;
QGraphicsLineItem* indicatorLine;
QVector<int> squareOwnerTable; // Along top row, then 2nd row et cetera.
// In this order: top row of horizontal lines, first row of vertical lines, 2nd row of horizontal lines etc...
// Size: 2*width*height + width + height
QVector<bool> lineDrawn;
int QGraphicsEllipseItemType;
signals:
void squareComplete(int); // int is the index associated with 'QVector<int> squareOwnerTable'
void lineDrawnSig();
};
#endif // GAMEBOARDSCENE_H
/***************************************************************************
* Copyright (C) 2006 by Matthew Williams <matt@milliams.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
#include "gameboardview.h"
GameBoardView::GameBoardView(QWidget *parent) : QGraphicsView(parent)
{
gameScene = 0;
}
void GameBoardView::createBoard(int height, int width)
{
/*if (gameScene)
delete gameScene;*/
if ((height == 1) and (width == 1))
return;
gameScene = new GameBoardScene(height, width, this);
setScene(gameScene);
emit gameStarted();
}
void GameBoardView::mouseMoveEvent(QMouseEvent* e)
{
//cout << "GameBoardView::mouseMoveEvent" << endl;
QGraphicsView::mouseMoveEvent(e);
}
#include "gameboardview.moc"
/***************************************************************************
* Copyright (C) 2006 by Matthew Williams <matt@milliams.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef GAMEBOARDVIEW_H
#define GAMEBOARDVIEW_H
#include <QtGui>
#include "gameboardscene.h"
class GameBoardView : public QGraphicsView
{
Q_OBJECT
public:
GameBoardView(QWidget *parent = 0);
GameBoardScene* scene() {return gameScene;}
QSize sizeHint() {return scene()->sizeHint();}
public slots:
void createBoard(int height, int width);
protected:
void mouseMoveEvent(QMouseEvent* e);
GameBoardScene* gameScene;
signals:
void gameStarted();
};
#endif // GAMEBOARDVIEW_H
/***************************************************************************
* Copyright (C) 2006 by Matthew Williams <matt@milliams.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
#include "ksquares.h"
#include "settings.h"
#include <kconfigdialog.h>
#include <kglobal.h>
#include <klocale.h>
#include <kicon.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <kedittoolbar.h>
#include <kstdaccel.h>
#include <kaction.h>
#include <kstandardaction.h>
#include "gameboardscene.h"
#include "newgamedialog.h"
#include "scoresdialog.h"
KSquares::KSquares() : KMainWindow(), m_view(new GameBoardView(this))
{
sGame = new KSquaresGame();
connect(m_view, SIGNAL(gameStarted()), sGame, SLOT(startGame()));
connect(sGame, SIGNAL(playerChangedSig(int)), this, SLOT(playerChanged(int)));
setCentralWidget(m_view);
setupActions();
statusBar()->insertPermanentItem("Player: ", 0);
statusBar()->show();
setAutoSaveSettings();
}
KSquares::~KSquares()
{
}
void KSquares::setupActions()
{
KStandardAction::openNew(this, SLOT(fileNew()), actionCollection());
KStandardAction::quit(kapp, SLOT(quit()), actionCollection());
KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
// custom menu and menu item - the slot is in the class KSquaresView
KAction *custom = new KAction(i18n("Swi&tch Colors"), actionCollection(), "switch_action");
custom->setIcon(KIcon("colorize"));
setupGUI();
}
void KSquares::fileNew()
{
//load settings
NewGameDialog dialog(this);
dialog.spinNumOfPlayers->setValue(Settings::numOfPlayers());
dialog.playerOneName->setText(Settings::playerNames().at(0));
dialog.playerTwoName->setText(Settings::playerNames().at(1));
dialog.spinHeight->setValue(Settings::boardHeight());
dialog.spinWidth->setValue(Settings::boardWidth());
//run dialog
dialog.exec();
//save settings
Settings::setNumOfPlayers(dialog.spinNumOfPlayers->value());
QStringList tempNames;
tempNames.append(dialog.playerOneName->text());
tempNames.append(dialog.playerTwoName->text());
Settings::setPlayerNames(tempNames);
//Settings::setPlayerOneName(dialog.playerOneName->text());
//Settings::setPlayerTwoName(dialog.playerTwoName->text());
Settings::setBoardHeight(dialog.spinHeight->value());
Settings::setBoardWidth(dialog.spinWidth->value());
Settings::writeConfig();
QVector<KSquaresPlayer> playerList;
playerList.append(KSquaresPlayer(true));
playerList.append(KSquaresPlayer(true));
//start game etc.
//sGame->createGame(dialog.spinNumOfPlayers->value(), Settings::boardWidth(), Settings::boardHeight());
sGame->createGame(playerList, Settings::boardWidth(), Settings::boardHeight());
m_view->createBoard(Settings::boardWidth(), Settings::boardHeight());
//cout << "Connecting stuff" << endl;
connect(m_view->scene(), SIGNAL(squareComplete(int)), sGame, SLOT(playerSquareComplete(int)));
connect(m_view->scene(), SIGNAL(lineDrawnSig()), sGame, SLOT(tryEndGo()));
connect(sGame, SIGNAL(setSquareOwnerSig(int,int)), m_view->scene(), SLOT(setSquareOwner(int,int)));
connect(sGame, SIGNAL(gameOverSig(QVector<KSquaresPlayer>)), this, SLOT(gameOver(QVector<KSquaresPlayer>)));
}
void KSquares::gameOver(QVector<KSquaresPlayer> playerList)
{
ScoresDialog scoresDialog(this);
QStandardItemModel* scoreTableModel = new QStandardItemModel();
scoreTableModel->setRowCount(playerList.size());
scoreTableModel->setColumnCount(2);
for(int i = 0; i < playerList.size(); i++)
{
scoreTableModel->setItem(i, 0, new QStandardItem(Settings::playerNames().at(i)));
QString temp;
temp.setNum(playerList.at(i).score());
scoreTableModel->setItem(i, 1, new QStandardItem(temp));
}