Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

AI simplification

  • Loading branch information...
commit a7ace5548bd2d880f166348a78a7a6db3083cedd 1 parent 418503c
@Ignotus authored
View
50 CMakeLists.txt
@@ -55,44 +55,51 @@ IF (UNIX)
SET (PLUGINS_DIR ${DATA_INSTALL_DIR}/kdots/plugins)
ENDIF (UNIX)
-SET (SRCS
- pluginwidgetdelegate.cpp
- brushcombo.cpp
+SET (KDOTSLIB_SRCS
graph.cpp
dottable.cpp
stepqueue.cpp
- tablewidget.cpp
- newgamewidget.cpp
- newgamedialog.cpp
- mainwindow.cpp
polygonfinder.cpp
- plugincontainer.cpp
- pluginmanagerwidget.cpp
gameconfig.cpp
point.cpp
- brushcombodelegate.cpp
- kdots.kcfgc
)
-SET (HEADERS
- pluginwidgetdelegate.hpp
- brushcombo.hpp
+SET (KDOTSLIB_HEADERS
graphpoint.hpp
graph.hpp
dottable.hpp
stepqueue.hpp
- tablewidget.hpp
edgelist.hpp
point.hpp
- newgamedialog.hpp
- newgamewidget.hpp
- mainwindow.hpp
constants.hpp
polygonfinder.hpp
polygon.hpp
+ gameconfig.hpp
+)
+
+SET (SRCS
+ plugincontainer.cpp
+ pluginmanagerwidget.cpp
+ newgamewidget.cpp
+ newgamedialog.cpp
+ mainwindow.cpp
+ tablewidget.cpp
+ pluginwidgetdelegate.cpp
+ brushcombo.cpp
+ brushcombodelegate.cpp
+ main.cpp
+ kdots.kcfgc
+)
+
+SET (HEADERS
plugincontainer.hpp
pluginmanagerwidget.hpp
- gameconfig.hpp
+ newgamedialog.hpp
+ newgamewidget.hpp
+ mainwindow.hpp
+ tablewidget.hpp
+ pluginwidgetdelegate.hpp
+ brushcombo.hpp
brushcombodelegate.hpp
)
@@ -110,6 +117,7 @@ SET (FORMS
ui/boardconfigwidget.ui
)
+
KDE4_ADD_UI_FILES (SRCS ${FORMS})
KDE4_ADD_KCFG_FILES (SRCS kdots.kcfgc)
INSTALL (FILES kdots.kcfg DESTINATION ${KCFG_INSTALL_DIR})
@@ -124,11 +132,11 @@ SET (KDOTS_REQUIRED_LIBS
)
KDE4_ADD_LIBRARY (kdotslib SHARED
- ${SRCS}
+ ${KDOTSLIB_SRCS}
)
KDE4_ADD_EXECUTABLE (kdots
- main.cpp
+ ${SRCS}
${INTERFACE_HEAD}
)
View
2  brushcombo.hpp
@@ -30,7 +30,7 @@
namespace KDots
{
- class KDOTS_EXPORT BrushCombo : public KComboBox
+ class BrushCombo : public KComboBox
{
public:
BrushCombo (QWidget* parent = 0);
View
5 interface/irival.hpp
@@ -47,6 +47,11 @@ namespace KDots
virtual ~IRival ()
{
}
+
+ virtual std::vector<Point> possibleMoves () const
+ {
+ return std::vector<Point> ();
+ }
virtual IConfigurationWidget* configureWidget ()
{
View
2  mainwindow.hpp
@@ -46,7 +46,7 @@ namespace KDots
class TableWidget;
class IRival;
- class KDOTS_EXPORT MainWindow : public KXmlGuiWindow
+ class MainWindow : public KXmlGuiWindow
{
Q_OBJECT
public:
View
8 plugins/simpleai/prioritymap.cpp
@@ -356,6 +356,14 @@ namespace KDots
},
{1, 1},
0.1
+ },
+ {
+ {//34
+ {FI, EM},
+ {EM, CU}
+ },
+ {1, 1},
+ 0.001
}
};
View
200 plugins/simpleai/rival.cpp
@@ -25,7 +25,9 @@
*/
#include "rival.hpp"
#include <ctime>
+#include <iostream>
#include <algorithm>
+#include <stack>
#include <QStatusBar>
#include <QLabel>
#ifdef NEW_LIBKDEGAMES
@@ -61,15 +63,6 @@ namespace KDots
#endif
}
- void Rival::setDifficulty (int diff)
- {
- m_iterations = diff;
- }
-
- Rival::~Rival()
- {
- }
-
bool Rival::isAllow () const
{
if (!m_table)
@@ -78,22 +71,17 @@ namespace KDots
return m_table->stepQueue ()->getCurrentOwner () == m_table->stepQueue ()->firstOwner ();
}
- bool Rival::hasMask (const Point& point, const MapData& mask)
+ bool Rival::hasMask (const Graph& graph, const Point& point, const MapData& mask, const Owner current)
{
- const Graph& graph = m_table->graph ();
- const Owner currentOwner = m_table->stepQueue ()->getCurrentOwner ();
- const Owner otherOwner = StepQueue::other (currentOwner);
-
const MapType& map = mask.m_map;
const Point& currentPoint = mask.m_current;
-
- for (std::size_t j = 0, height = map.size (), i,
- width = map.front ().size (); j < height; ++j)
+ const Owner other = StepQueue::other (current);
+
+ for (std::size_t j = 0, height = map.size (), i, width = map.front ().size (); j < height; ++j)
{
for (i = 0; i < width; ++i)
{
- const Point newPoint (currentPoint.x () - i + point.x (),
- currentPoint.y () - j + point.y ());
+ const Point& newPoint = point - currentPoint + Point (i, j);
if (!graph.isValid (newPoint))
return false;
@@ -101,11 +89,10 @@ namespace KDots
const MapElement el = map[j][i];
const GraphPoint& graphPoint = graph[newPoint];
const Owner own = graphPoint.owner ();
- const bool captured = graphPoint.isCaptured ();
- if (captured)
+ if (graphPoint.isCaptured ())
return false;
-
+
switch (el)
{
case EM: //Empty
@@ -113,25 +100,22 @@ namespace KDots
return false;
break;
case FI: //First
- if (own != otherOwner)
+ if (own != other)
return false;
break;
case SE: //Second
- if (own != currentOwner)
+ if (own != current)
return false;
break;
case PF: // Possibly first
- if (own == currentOwner)
+ if (own == current)
return false;
break;
case PS: // Possibly second
- if (own == otherOwner)
+ if (own == other)
return false;
break;
- case NM: case CU:
- break;
- default:
- kDebug () << "WTF";
+ case NM: case CU: default:
break;
}
}
@@ -140,32 +124,24 @@ namespace KDots
return true;
}
- float Rival::calcImportance(const Point& point)
+ float Rival::calcPriority(const Point& point)
{
- float priority = -0.5;
-
- int id = 0;
+ float priority = 2;
+ const Graph& graph = m_table->graph ();
for (const MapData& table : PriorityMap::instance ().priorityMap ())
{
- if (!hasMask (point, table))
- {
- ++id;
+ if (!hasMask (graph, point, table, m_current))
continue;
+ else
+ {
+ kDebug () << "Found";
}
-// else
-// {
-// kDebug () << "Found mask #" << id << "\n"
-// << table.toString ()
-// << "in the point {" << point.x () << ", " << point.y () << "}";
-// }
-
- if (table.m_priority > priority)
- priority = table.m_priority;
- ++id;
+ if (table.m_priority < priority)
+ priority = table.m_priority;
}
- return priority;
+ return priority > 1.5 ? 0 : priority;
}
namespace
@@ -184,26 +160,6 @@ namespace KDots
return true;
}
-
- bool minSize (const Point& lastPoint, const std::vector<Point> points)
- {
- int distance = 10000;
- int id = 0;
- int index = 0;
- for (const Point& point : points)
- {
- const int sqrDistance = Point::sqrLength (point, lastPoint);
- if (sqrDistance < distance)
- {
- distance = sqrDistance;
- index = id;
- }
-
- ++id;
- }
-
- return index;
- };
}
void Rival::calcRange (int& min_x, int& min_y, int& max_x, int& max_y)
@@ -214,7 +170,7 @@ namespace KDots
for (i = 0; i < max_i; ++i)
{
const GraphPoint& point = graph[Point (i, j)];
- if (point.owner () != NONE)
+ if (point.owner () == m_other)
{
if (i - 1 < min_x)
min_x = i - 1;
@@ -230,7 +186,7 @@ namespace KDots
}
}
- bool Rival::hasCaptured (const Point& point, Owner current)
+ bool Rival::hasCaptured (const KDots::Point& point, KDots::Owner current) const
{
const Graph& graph = m_table->graph ();
auto steps = m_table->stepQueue ();
@@ -239,9 +195,7 @@ namespace KDots
//O(n)
const PolyList& polyList = findPolygon (point);
- const Owner otherOwner = StepQueue::other (current);
-
- const auto& otherOwnerPoints = steps->getPoints (otherOwner);
+ const auto& otherOwnerPoints = steps->getPoints (m_other);
for (const Point& p : otherOwnerPoints)
{
const GraphPoint& gpoint = graph[p];
@@ -250,8 +204,7 @@ namespace KDots
for (const Polygon_ptr& polygon : polyList)
{
- if (DotTable::isInPolygon (polygon, p)
- && gpoint.owner () == otherOwner)
+ if (DotTable::isInPolygon (polygon, p) && gpoint.owner () == m_other)
return true;
}
}
@@ -259,102 +212,51 @@ namespace KDots
return false;
}
+ std::vector<Point> Rival::possibleMoves () const
+ {
+ return m_points;
+ }
+
void Rival::nextStep (const Point& point)
{
if (isAllow ())
return;
- int min_x = point.x () - 1, min_y = point.y () - 1;
- int max_x = point.x () + 1, max_y = point.y () + 1;
- calcRange (min_x, min_y, max_x, max_y);
+ const Graph& graph = m_table->graph ();
- m_pointStack.clear ();
+ m_points.clear ();
- std::vector<Point> points;
- float max_priority = -0.5 * m_iterations;
- const Graph& graph = m_table->graph ();
- for (Graph::const_iterator itr = graph.begin (), itrEnd = graph.end ();
- itr != itrEnd; ++itr)
+ float maxPrio = -2;
+ for (Graph::const_iterator itr = graph.begin (), end = graph.end (); itr != end; ++itr)
{
- if (itr->owner () != NONE || itr->isCaptured ())
- continue;
-
- const Point& newPoint = itr.point ();
-
- if (isEmptyAround (graph, newPoint))
+ if (itr->isCaptured () || itr->owner () != NONE)
continue;
- if (!(newPoint >= Point (min_x, min_y)
- && newPoint <= Point (max_x, max_y)))
- continue;
-
- float imp = 0;
- calcImportanceTree (imp, newPoint, 1);
-
- if (imp == max_priority)
- points.push_back (newPoint);
- else if (imp > max_priority)
+ const Point& curr = itr.point ();
+ const float prio = calcPriority (curr);
+ if (prio > maxPrio)
{
- max_priority = imp;
- kDebug () << "Max priority is changed to" << max_priority;
- points.clear ();
- points.push_back (newPoint);
+ m_points.clear ();
+ maxPrio = prio;
+ m_points.push_back (curr);
}
+ else if (prio == maxPrio)
+ m_points.push_back (curr);
}
- if (!points.empty ())
+ if (!m_points.empty ())
{
- //const int index = minSize (point, points);
- srand (std::time (NULL));
- m_table->pushPoint (points[rand () % points.size ()]);
+ std::srand (std::time (NULL));
+ m_table->pushPoint (m_points[std::rand () % m_points.size ()]);
}
}
- void Rival::calcImportanceTree (float& importance, const Point& point, int iteration)
- {
- const Owner current = m_table->stepQueue ()->getCurrentOwner ();
- if (hasCaptured (point, current))
- importance += 0.9;
- else
- importance += calcImportance (point);
-
- m_pointStack.push_back (point);
- if (iteration == m_iterations) // Need configure this feature
- return;
-
- float max_imp = -m_iterations;
-
- int i = 0;
- const Graph& graph = m_table->graph ();
- for (; i < DIRECTION_COUNT; ++i)
- {
- const Point newPoint (point.x () + GRAPH_DX[i], point.y () + GRAPH_DY[i]);
- if (!graph.isValid (newPoint))
- continue;
-
- const GraphPoint& newGrPoint = graph[newPoint];
-
- if (!newGrPoint.isCaptured () && newGrPoint.owner () == NONE
- && std::find (m_pointStack.begin (), m_pointStack.end (), newPoint) == m_pointStack.end ())
- {
- float imp = 0;
- calcImportanceTree (imp, newPoint, iteration + 1);
-
- if (max_imp == -m_iterations || imp < max_imp)
- max_imp = imp;
- }
- }
-
- if (i != DIRECTION_COUNT)
- importance += max_imp;
- }
-
void Rival::setDotTable (DotTable *table)
{
m_table = table;
- m_current = m_table->stepQueue ()->getCurrentOwner ();
- m_other = StepQueue::other (m_current);
+ m_other = m_table->stepQueue ()->getCurrentOwner ();
+ m_current = StepQueue::other (m_other);
}
}
}
View
25 plugins/simpleai/rival.hpp
@@ -31,35 +31,42 @@
namespace KDots
{
+ class Graph;
namespace simpleai
{
struct MapData;
- class Rival : public KDots::IRival
+ class KDOTS_EXPORT Rival : public KDots::IRival
{
Q_OBJECT
Q_INTERFACES (KDots::IRival)
DotTable *m_table;
- std::vector<Point> m_pointStack;
Owner m_current, m_other;
int m_iterations;
+ std::vector<Point> m_points;
public:
Rival (QObject *parent = 0);
- ~Rival ();
+ ~Rival () {}
+
bool isAllow () const;
+ static bool hasMask (const Graph& graph, const Point& point, const MapData& mask, const Owner current);
+
+ void setDifficulty (int diff)
+ {
+ m_iterations = diff;
+ }
+
+ std::vector<Point> possibleMoves () const;
- void setDifficulty (int diff);
public slots:
void nextStep (const Point& point);
-
void setDotTable (DotTable *table);
+
private:
- bool hasMask (const Point& point, const MapData& mask);
- float calcImportance(const Point& point);
- void calcImportanceTree (float& importance, const Point& point, int iteration);
+ float calcPriority (const Point& point);
void calcRange (int& min_x, int& min_y, int& max_x, int& max_y);
- bool hasCaptured (const Point& point, Owner current);
+ bool hasCaptured (const Point& point, Owner current) const;
signals:
void createDotTable (const GameConfig& config);
View
65 plugins/simpleai/tests/prioritymaptest/prioritymaptest.hpp
@@ -26,6 +26,8 @@
#pragma once
#include <QtTest>
#include <QObject>
+#include <rival.hpp>
+#include <graph.hpp>
#include "prioritymap.hpp"
using namespace KDots::simpleai;
@@ -55,6 +57,69 @@ class PriorityMapTest : public QObject
{
Q_OBJECT
private slots:
+ void maskCheckingTest ()
+ {
+ KDots::Graph graph (3, 3);
+ graph[KDots::Point (0, 1)].setOwner (KDots::FIRST);
+ graph[KDots::Point (1, 0)].setOwner (KDots::FIRST);
+ graph[KDots::Point (2, 1)].setOwner (KDots::FIRST);
+ graph[KDots::Point (2, 2)].setOwner (KDots::FIRST);
+ graph[KDots::Point (1, 1)].setOwner (KDots::SECOND);
+
+ const MapData data {
+ {
+ {NM, FI, NM},
+ {FI, SE, FI},
+ {EM, CU, PF}
+ },
+ {1, 2},
+ 0.9
+ };
+
+ const MapData& newData1 = PriorityMap::rotate (data);
+
+ const MapData checkData1 {
+ {
+ {EM, FI, NM},
+ {CU, SE, FI},
+ {PF, FI, NM}
+ },
+ {0, 1},
+ 0.9
+ };
+ QVERIFY (newData1 == checkData1);
+
+ const MapData& newData2 = PriorityMap::rotate (newData1);
+
+ const MapData checkData2 {
+ {
+ {PF, CU, EM},
+ {FI, SE, FI},
+ {NM, FI, NM}
+ },
+ {1, 0},
+ 0.9
+ };
+
+ QVERIFY (newData2 == checkData2);
+
+ const MapData& newData3 = PriorityMap::rotate (newData2);
+
+ const MapData checkData3 {
+ {
+ {NM, FI, PF},
+ {FI, SE, CU},
+ {NM, FI, EM}
+ },
+ {2, 1},
+ 0.9
+ };
+
+ QVERIFY (newData3 == checkData3);
+
+ QVERIFY (KDots::simpleai::Rival::hasMask (graph, KDots::Point(1, 2), data, KDots::SECOND));
+ }
+
void sizeTest ()
{
const std::list<MapData>& dataList = PriorityMap::instance ().priorityMap ();
View
10 point.hpp
@@ -80,6 +80,16 @@ namespace KDots
return Point (m_x + val, m_y + val);
}
+ Point operator- (const Point& point) const
+ {
+ return Point (m_x + point.m_x, m_y + point.m_y);
+ }
+
+ Point operator+ (const Point& point) const
+ {
+ return Point (m_x - point.m_x, m_y - point.m_y);
+ }
+
bool operator< (const Point& other) const
{
return m_x < other.m_x && m_y < other.m_y;
View
3  stepqueue.hpp
@@ -25,6 +25,7 @@
*/
#ifndef KDOTS_STEPQUEUE_HPP
#define KDOTS_STEPQUEUE_HPP
+#include <KDebug>
#include "point.hpp"
#include "constants.hpp"
@@ -97,6 +98,8 @@ namespace KDots
static Owner other (Owner player)
{
+ if (player == NONE)
+ kWarning () << "player == NONE";
return player == FIRST ? SECOND : FIRST;
}
View
10 tablewidget.cpp
@@ -216,6 +216,16 @@ namespace KDots
const Point& newPoint = lastPoint + 1;
painter.drawEllipse (QPointF (newPoint.x (), newPoint.y ()) * cellSize, 6, 6);
}
+
+ const std::vector<Point>& possiblePoints = m_rival->possibleMoves ();
+ for (const Point& point : possiblePoints)
+ {
+ painter.setPen (Qt::gray);
+
+ painter.setBrush (Qt::NoBrush);
+ const Point& newPoint = point + 1;
+ painter.drawEllipse (QPointF (newPoint.x (), newPoint.y ()) * cellSize, 10, 10);
+ }
}
void TableWidget::drawUnderMousePoint (QPainter& painter, float cellSize)
Please sign in to comment.
Something went wrong with that request. Please try again.