build: split user and data folder, moving user data to Application Support on Mac
This commit is contained in:
+3
-3
@@ -4,10 +4,10 @@
|
||||
|
||||
/bin/app/Debug/
|
||||
/bin/app/Release/
|
||||
/bin/app/data/log/
|
||||
/bin/app/data/projects/ignored/
|
||||
/bin/app/data/ApplicationSettings.xml
|
||||
/bin/app/data/window_settings.ini
|
||||
/bin/app/user/log/
|
||||
/bin/app/user/ApplicationSettings.xml
|
||||
/bin/app/user/window_settings.ini
|
||||
|
||||
/bin/lib/
|
||||
/bin/lib_gui/
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
void lambdaCaller()
|
||||
{
|
||||
[](){}();
|
||||
}
|
||||
|
||||
void lambdaSuperCaller()
|
||||
{
|
||||
lambdaCaller();
|
||||
}
|
||||
|
||||
void lambdaMetaCaller()
|
||||
{
|
||||
[](){
|
||||
lambdaCaller();
|
||||
}();
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/* hallo */
|
||||
|
||||
int a; /* hallo */
|
||||
|
||||
int b = 6/3/2; /* hallo */
|
||||
|
||||
//*
|
||||
int c;
|
||||
//*/
|
||||
|
||||
// /*
|
||||
int d;
|
||||
// */
|
||||
|
||||
/*
|
||||
hallo
|
||||
// */ int e = 0;
|
||||
@@ -1,129 +0,0 @@
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
Point(int x, int y)
|
||||
: x(x)
|
||||
, y(y)
|
||||
{
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
virtual void draw() = 0;
|
||||
};
|
||||
|
||||
|
||||
class Line
|
||||
: public Shape
|
||||
{
|
||||
public:
|
||||
Line(Point start, Point end)
|
||||
: start(start)
|
||||
, end(end)
|
||||
{
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
// line drawing
|
||||
}
|
||||
|
||||
private:
|
||||
Point start;
|
||||
Point end;
|
||||
};
|
||||
|
||||
|
||||
class Circle
|
||||
: public Shape
|
||||
{
|
||||
public:
|
||||
Circle(Point center, int radius)
|
||||
: center(center)
|
||||
, radius(radius)
|
||||
{}
|
||||
|
||||
void draw()
|
||||
{
|
||||
// circle drawing
|
||||
}
|
||||
|
||||
private:
|
||||
Point center;
|
||||
int radius;
|
||||
};
|
||||
|
||||
|
||||
class Image
|
||||
{
|
||||
public:
|
||||
Image(int width, int height)
|
||||
: width(width)
|
||||
, height(height)
|
||||
, idx(0)
|
||||
{
|
||||
shapes = new Shape*[10];
|
||||
}
|
||||
|
||||
~Image()
|
||||
{
|
||||
for (int i = 0; i < idx; i++)
|
||||
{
|
||||
delete shapes[i];
|
||||
}
|
||||
|
||||
delete [] shapes;
|
||||
}
|
||||
|
||||
void addShape(Shape* shape)
|
||||
{
|
||||
if (idx < 10)
|
||||
{
|
||||
shapes[idx] = shape;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
for (int i = 0; i < idx; i++)
|
||||
{
|
||||
shapes[i]->draw();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Shape** shapes;
|
||||
int idx;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
|
||||
void drawStickMan()
|
||||
{
|
||||
Image stickman(100, 200);
|
||||
|
||||
// head
|
||||
stickman.addShape(new Circle(Point(50, 50), 25));
|
||||
|
||||
// torso
|
||||
stickman.addShape(new Line(Point(50, 75), Point(50, 180)));
|
||||
|
||||
// arms
|
||||
stickman.addShape(new Line(Point(50, 100), Point(10, 125)));
|
||||
stickman.addShape(new Line(Point(50, 100), Point(90, 125)));
|
||||
|
||||
// legs
|
||||
stickman.addShape(new Line(Point(50, 100), Point(10, 125)));
|
||||
stickman.addShape(new Line(Point(50, 100), Point(90, 125)));
|
||||
|
||||
stickman.draw();
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
// nothing here
|
||||
// except for text
|
||||
@@ -1,34 +0,0 @@
|
||||
class Player {
|
||||
public:
|
||||
void Do() {}
|
||||
};
|
||||
|
||||
class Base {
|
||||
protected:
|
||||
void Init() {}
|
||||
};
|
||||
|
||||
class Game : public Base {
|
||||
public:
|
||||
Game() {
|
||||
Init();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
player.Do();
|
||||
}
|
||||
|
||||
private:
|
||||
Player player;
|
||||
};
|
||||
|
||||
Game* game;
|
||||
|
||||
int main() {
|
||||
game = new Game();
|
||||
|
||||
game->Run();
|
||||
|
||||
delete game;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
|
||||
int number = 3;
|
||||
|
||||
int calculate();
|
||||
|
||||
int calculate(long i)
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
int calculate()
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
int calculate(int i)
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
#define PI 3.1415
|
||||
|
||||
#define CALL_CALCULATE() \
|
||||
do \
|
||||
{ \
|
||||
calculate(); \
|
||||
} \
|
||||
while(0) \
|
||||
|
||||
int main()
|
||||
{
|
||||
CALL_CALCULATE();
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
void countUp()
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
|
||||
void countDown()
|
||||
{
|
||||
count -= 1;
|
||||
}
|
||||
|
||||
|
||||
void countUpTen()
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
countUp();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
Person(char* name)
|
||||
: name(name)
|
||||
, age(0)
|
||||
, weight(3)
|
||||
, height(50)
|
||||
{
|
||||
}
|
||||
|
||||
char* askForName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void gainWeight(int gain)
|
||||
{
|
||||
weight += gain;
|
||||
}
|
||||
|
||||
void grow(int gain)
|
||||
{
|
||||
height += gain;
|
||||
}
|
||||
|
||||
void celebrateBirthday()
|
||||
{
|
||||
age += 1;
|
||||
|
||||
grow(5);
|
||||
gainWeight(3);
|
||||
}
|
||||
|
||||
private:
|
||||
char* name;
|
||||
int age;
|
||||
|
||||
int height;
|
||||
int weight;
|
||||
};
|
||||
|
||||
|
||||
class Vehicle
|
||||
{
|
||||
protected:
|
||||
int wheelCount;
|
||||
int seatCount;
|
||||
};
|
||||
|
||||
class Car
|
||||
: public Vehicle
|
||||
{
|
||||
public:
|
||||
Car()
|
||||
{
|
||||
wheelCount = 4;
|
||||
seatCount = 5;
|
||||
}
|
||||
};
|
||||
|
||||
class Truck
|
||||
: public Vehicle
|
||||
{
|
||||
public:
|
||||
Truck()
|
||||
{
|
||||
wheelCount = 6;
|
||||
seatCount = 2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
T sum(T a, T b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
class Apple {};
|
||||
class Pear {};
|
||||
|
||||
template<typename Fruit>
|
||||
class Basket
|
||||
{
|
||||
public:
|
||||
Fruit** field;
|
||||
};
|
||||
|
||||
Basket<Apple> apples;
|
||||
Basket<Pear> pears;
|
||||
|
||||
|
||||
class Dog {};
|
||||
|
||||
class Cat
|
||||
{
|
||||
Dog getDog();
|
||||
};
|
||||
|
||||
class Bird
|
||||
{
|
||||
Dog getDog();
|
||||
Cat getCat();
|
||||
};
|
||||
|
||||
class Fish
|
||||
{
|
||||
Dog getDog();
|
||||
Cat getCat();
|
||||
Bird getBird();
|
||||
};
|
||||
|
||||
class Horse
|
||||
: public Dog
|
||||
{
|
||||
Dog getDog();
|
||||
Cat getCat();
|
||||
Bird getBird();
|
||||
Fish getFish();
|
||||
};
|
||||
|
||||
|
||||
class Building {};
|
||||
class House : public Building {};
|
||||
class Tower : public Building {};
|
||||
class SkyScrapper : public Building {};
|
||||
class Mansion : public Building {};
|
||||
class Shard : public House, public Tower, public SkyScrapper, public Mansion {};
|
||||
|
||||
typedef unsigned int uint;
|
||||
uint a = 1 + 2;
|
||||
|
||||
enum Size
|
||||
{
|
||||
SMALL,
|
||||
MEDIUM,
|
||||
LARGE
|
||||
};
|
||||
@@ -1,272 +0,0 @@
|
||||
const bool *abd(int abc, int bca);
|
||||
|
||||
bool const *abc(int a, int b);
|
||||
|
||||
bool *const abcd(int a, int b);
|
||||
|
||||
int main();
|
||||
void foo();
|
||||
int sum(int a, int b);
|
||||
int diff(int a, int b);
|
||||
|
||||
void funk();
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(char c)
|
||||
: m_importantValue(42)
|
||||
, m_importanterValue(c)
|
||||
, m_importantestValue(3.14159265359f)
|
||||
{
|
||||
}
|
||||
|
||||
~A()
|
||||
{
|
||||
}
|
||||
|
||||
void doImportantStuff()
|
||||
{
|
||||
int a = 1;
|
||||
m_importantValue *= a;
|
||||
}
|
||||
|
||||
void doModeratelyImportantStuff()
|
||||
{
|
||||
m_importanterValue = 'R';
|
||||
int answer = sum(21, 21);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_importantValue;
|
||||
char m_importanterValue;
|
||||
const float m_importantestValue;
|
||||
};
|
||||
|
||||
A globalA(' ');
|
||||
|
||||
class B : public A
|
||||
{
|
||||
public:
|
||||
B()
|
||||
: A('b')
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~B()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual float getNumber() = 0;
|
||||
};
|
||||
|
||||
class C
|
||||
{
|
||||
public:
|
||||
C()
|
||||
: m_valuable(0)
|
||||
{
|
||||
globalA.doImportantStuff();
|
||||
s_count++;
|
||||
}
|
||||
|
||||
~C()
|
||||
{
|
||||
s_count--;
|
||||
}
|
||||
|
||||
static int getCount()
|
||||
{
|
||||
return s_count;
|
||||
}
|
||||
|
||||
void solveAllProblems() const
|
||||
{
|
||||
A aInstance('a');
|
||||
aInstance.doImportantStuff();
|
||||
aInstance.doModeratelyImportantStuff();
|
||||
}
|
||||
|
||||
private:
|
||||
static int s_count;
|
||||
int m_valuable;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace noname
|
||||
{
|
||||
struct V
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
}
|
||||
|
||||
enum E
|
||||
{
|
||||
X,
|
||||
Y
|
||||
};
|
||||
}
|
||||
|
||||
noname::V voo;
|
||||
|
||||
typedef A* D;
|
||||
|
||||
D globalD;
|
||||
|
||||
class E
|
||||
{
|
||||
public:
|
||||
E(){}
|
||||
~E(){}
|
||||
|
||||
class SubE
|
||||
{
|
||||
public:
|
||||
SubE(){}
|
||||
~SubE(){}
|
||||
};
|
||||
|
||||
private:
|
||||
int m_importantInt;
|
||||
};
|
||||
|
||||
class AnotherClass
|
||||
: public A
|
||||
{
|
||||
public:
|
||||
AnotherClass()
|
||||
: A('x')
|
||||
{
|
||||
}
|
||||
|
||||
int publicInt;
|
||||
protected:
|
||||
int protectedInt;
|
||||
private:
|
||||
int privateInt;
|
||||
};
|
||||
|
||||
|
||||
class circleA
|
||||
{
|
||||
public:
|
||||
circleA()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
//circleB m_b;
|
||||
};
|
||||
|
||||
class circleB
|
||||
{
|
||||
public:
|
||||
circleB()
|
||||
{
|
||||
m_a = circleA();
|
||||
}
|
||||
|
||||
circleA foo(){return circleA();}
|
||||
|
||||
private:
|
||||
circleA m_a;
|
||||
};
|
||||
|
||||
struct circleC
|
||||
{
|
||||
public:
|
||||
circleC()
|
||||
{
|
||||
m_b = circleB();
|
||||
}
|
||||
|
||||
circleA foo0(){return circleA();}
|
||||
circleB foo1(){return circleB();}
|
||||
|
||||
private:
|
||||
circleB m_b;
|
||||
};
|
||||
|
||||
class circleD
|
||||
{
|
||||
public:
|
||||
circleD()
|
||||
{
|
||||
m_c = circleC();
|
||||
}
|
||||
|
||||
circleC foo(){return circleC();}
|
||||
|
||||
circleA foo2(){return circleA();}
|
||||
circleB foo3(){return circleB();}
|
||||
|
||||
private:
|
||||
circleC m_c;
|
||||
};
|
||||
|
||||
class circleE
|
||||
{
|
||||
public:
|
||||
circleE()
|
||||
{
|
||||
m_d = circleD();
|
||||
}
|
||||
|
||||
circleC foo(){return circleC();}
|
||||
circleB foo1(){return circleB();}
|
||||
circleD foo2(){return circleD();}
|
||||
circleA foo3(){return circleA();}
|
||||
|
||||
private:
|
||||
circleD m_d;
|
||||
};
|
||||
|
||||
class circleF
|
||||
{
|
||||
public:
|
||||
circleF()
|
||||
{
|
||||
m_e = circleE();
|
||||
}
|
||||
|
||||
circleC foo(){return circleC();}
|
||||
circleB foo1(){return circleB();}
|
||||
circleD foo2(){return circleD();}
|
||||
circleA foo3(){return circleA();}
|
||||
circleE foo4(){return circleE();}
|
||||
|
||||
private:
|
||||
circleE m_e;
|
||||
};
|
||||
|
||||
class circleCenter
|
||||
{
|
||||
public:
|
||||
circleCenter()
|
||||
{
|
||||
m_a = circleA();
|
||||
m_b = circleB();
|
||||
m_c = circleC();
|
||||
m_d = circleD();
|
||||
}
|
||||
|
||||
circleA foo0(){return circleA();}
|
||||
circleB foo1(){return circleB();}
|
||||
circleC foo2(){return circleC();}
|
||||
circleD foo3(){return circleD();}
|
||||
circleE foo4(){return circleE();}
|
||||
circleF foo5(){return circleF();}
|
||||
|
||||
private:
|
||||
circleA m_a;
|
||||
circleB m_b;
|
||||
circleC m_c;
|
||||
circleD m_d;
|
||||
|
||||
//AnotherClass m_anotherClass;
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "header.h"
|
||||
|
||||
int main();
|
||||
void foo();
|
||||
int sum(int a, int b);
|
||||
int sum(int* a, int* b);
|
||||
int diff(int a, int b);
|
||||
|
||||
int main()
|
||||
{
|
||||
A aInstance('m');
|
||||
aInstance.doImportantStuff();
|
||||
|
||||
int a = sum(1, 2);
|
||||
int b = diff(a, 3);
|
||||
int c = a * b;
|
||||
|
||||
int x = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sum(int a, int b);
|
||||
|
||||
int diff(int a, int b);
|
||||
|
||||
void foo()
|
||||
{
|
||||
const char* foo = "bar";
|
||||
}
|
||||
|
||||
int diff(int a, int b);
|
||||
|
||||
int sum(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int diff(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
void funk()
|
||||
{
|
||||
A aInstance('x');
|
||||
aInstance.doModeratelyImportantStuff();
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "header.h"
|
||||
|
||||
void test(int i, int b)
|
||||
{
|
||||
|
||||
int x;
|
||||
|
||||
A instanceOfA('v');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include <memory>
|
||||
|
||||
class A
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class B
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a;
|
||||
|
||||
A* aPtr = nullptr;
|
||||
|
||||
std::shared_ptr<A> aSharedPtr = std::make_shared<A>();
|
||||
|
||||
B<A> b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
template <bool B, typename, class F>
|
||||
class Foo
|
||||
{
|
||||
public:
|
||||
void bar()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Fooo
|
||||
{
|
||||
public:
|
||||
void bar()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename T::a::type U>
|
||||
class Foooo1
|
||||
{
|
||||
public:
|
||||
void bar()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename T::type U>
|
||||
class Foooo2
|
||||
{
|
||||
public:
|
||||
void bar()
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "header.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
Foo<true, int, float> ft;
|
||||
ft.bar();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
#include "artificial_player.h"
|
||||
|
||||
ArtificialPlayer::ArtificialPlayer( Field::Token token, const char* name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
|
||||
ArtificialPlayer::~ArtificialPlayer() {
|
||||
}
|
||||
|
||||
Field::Move ArtificialPlayer::Turn( const Field& field ) const {
|
||||
Field fakeField = field.Clone();
|
||||
Node node = MinMax( fakeField, token_ );
|
||||
return node.move;
|
||||
}
|
||||
|
||||
ArtificialPlayer::Node ArtificialPlayer::MinMax( Field& field, Field::Token token ) const {
|
||||
Node node;
|
||||
node.value = -10000;
|
||||
|
||||
Field::Move move;
|
||||
int sameMove;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
move.row = i;
|
||||
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
move.col = j;
|
||||
|
||||
if ( !field.IsEmpty( move ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
field.MakeMove( move, token );
|
||||
|
||||
int turnValue = Evaluate( field, token );
|
||||
if ( !turnValue && !field.IsFull() ) {
|
||||
turnValue = -MinMax( field, Field::Opponent( token ) ).value;
|
||||
}
|
||||
|
||||
field.ClearMove( move );
|
||||
|
||||
if ( turnValue > node.value ) {
|
||||
node.move = move;
|
||||
node.value = turnValue;
|
||||
sameMove = 1;
|
||||
} else if ( turnValue == node.value ) {
|
||||
sameMove++;
|
||||
if ( 1 % sameMove == 0 ) {
|
||||
node.move = move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int ArtificialPlayer::Evaluate( const Field& field, Field::Token token ) const {
|
||||
if ( field.SameInRow( token, 3 ) ) {
|
||||
return 2;
|
||||
} else if ( field.SameInRow( Field::Opponent( token ), 2 ) ) {
|
||||
return -1;
|
||||
} else if ( field.SameInRow( token, 2 ) > 1 ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef _ARTIFICIAL_PLAYER_
|
||||
#define _ARTIFICIAL_PLAYER_
|
||||
|
||||
#include "player.h"
|
||||
|
||||
class ArtificialPlayer : public Player {
|
||||
public:
|
||||
ArtificialPlayer( Field::Token token, const char* name );
|
||||
virtual ~ArtificialPlayer();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const;
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Field::Move move;
|
||||
int value;
|
||||
};
|
||||
|
||||
Node MinMax( Field& field, Field::Token token ) const;
|
||||
|
||||
int Evaluate( const Field& field, Field::Token token ) const;
|
||||
};
|
||||
|
||||
#endif // _ARTIFICIAL_PLAYER_
|
||||
@@ -1,126 +0,0 @@
|
||||
#include "field.h"
|
||||
|
||||
#include "io.h"
|
||||
|
||||
Field::Token Field::Opponent( Token token ) {
|
||||
if ( token == PlayerA ) {
|
||||
return PlayerB;
|
||||
} else if (token == PlayerB){
|
||||
return PlayerA;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Field::Field()
|
||||
: left_( 9 ) {
|
||||
grid_ = new Token* [3];
|
||||
for ( int i = 0; i < 3 ; i++ ) {
|
||||
grid_[i] = new Token[3];
|
||||
}
|
||||
}
|
||||
|
||||
Field::~Field() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
delete [] grid_[i];
|
||||
}
|
||||
delete [] grid_;
|
||||
}
|
||||
|
||||
Field Field::Clone() const {
|
||||
Field field;
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
field.grid_[i][j] = grid_[i][j];
|
||||
}
|
||||
}
|
||||
field.left_ = left_;
|
||||
return field;
|
||||
}
|
||||
|
||||
void Field::Clear() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
grid_[i][j] = None;
|
||||
}
|
||||
}
|
||||
left_ = 9;
|
||||
}
|
||||
|
||||
void Field::Show() const {
|
||||
io::stringOut(" 1 2 3\n");
|
||||
for ( int row = 0; row < 3; row++ ) {
|
||||
io::numberOut(row + 1);
|
||||
io::stringOut(" ");
|
||||
|
||||
for ( int col = 0; col < 3; col++ ) {
|
||||
if ( grid_[row][col] == PlayerA ) {
|
||||
io::stringOut(" X ");
|
||||
} else if ( grid_[row][col] == PlayerB ) {
|
||||
io::stringOut(" O ");
|
||||
} else {
|
||||
io::stringOut(" ");
|
||||
}
|
||||
|
||||
if ( col < 2 ) {
|
||||
io::stringOut("|");
|
||||
}
|
||||
}
|
||||
|
||||
if ( row < 2 ) {
|
||||
io::stringOut("\n -----------\n");
|
||||
}
|
||||
}
|
||||
io::stringOut("\n\n");
|
||||
}
|
||||
|
||||
int Field::SameInRow( Token token, int amount ) const {
|
||||
int sum = amount * token;
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
if ( grid_[i][0] + grid_[i][1] + grid_[i][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[0][i] + grid_[1][i] + grid_[2][i] == sum ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( grid_[0][0] + grid_[1][1] + grid_[2][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[2][0] + grid_[1][1] + grid_[0][2] == sum ) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Field::InRange( const Move& move ) const {
|
||||
return move.row >= 0 && move.row < 3 && move.col >= 0 && move.col < 3;
|
||||
}
|
||||
|
||||
bool Field::IsEmpty( const Move& move ) const {
|
||||
return grid_[move.row][move.col] == None;
|
||||
}
|
||||
|
||||
bool Field::IsFull() const {
|
||||
return left_ == 0;
|
||||
}
|
||||
|
||||
void Field::MakeMove( const Move& move, Token token ) {
|
||||
if ( !InRange( move ) || !IsEmpty( move ) || token == None || !left_ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
grid_[move.row][move.col] = token;
|
||||
left_--;
|
||||
}
|
||||
|
||||
void Field::ClearMove( const Move& move ) {
|
||||
if ( !InRange( move ) || !IsEmpty( move ) || left_ == 9 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
grid_[move.row][move.col] = None;
|
||||
left_++;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef _FIELD_
|
||||
#define _FIELD_
|
||||
|
||||
class Field {
|
||||
public:
|
||||
enum Token {
|
||||
None = 0,
|
||||
PlayerA = 1,
|
||||
PlayerB = 4
|
||||
};
|
||||
|
||||
static Token Opponent( Token token );
|
||||
|
||||
struct Move {
|
||||
int row;
|
||||
int col;
|
||||
};
|
||||
|
||||
Field();
|
||||
~Field();
|
||||
|
||||
Field Clone() const;
|
||||
void Clear();
|
||||
|
||||
void Show() const;
|
||||
|
||||
int SameInRow( Token token, int amount ) const;
|
||||
|
||||
bool InRange( const Move& move ) const;
|
||||
bool IsEmpty( const Move& move ) const;
|
||||
bool IsFull() const;
|
||||
|
||||
void MakeMove( const Move& move, Token token );
|
||||
void ClearMove( const Move& move );
|
||||
|
||||
private:
|
||||
Token** grid_;
|
||||
int left_;
|
||||
};
|
||||
|
||||
#endif // _FIELD_
|
||||
@@ -1,49 +0,0 @@
|
||||
#include "human_player.h"
|
||||
|
||||
#include "io.h"
|
||||
|
||||
HumanPlayer::HumanPlayer( Field::Token token, const char* name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
|
||||
HumanPlayer::~HumanPlayer() {
|
||||
}
|
||||
|
||||
Field::Move HumanPlayer::Turn( const Field& field ) const {
|
||||
Field::Move move;
|
||||
io::stringOut(name_);
|
||||
io::stringOut("\n");
|
||||
|
||||
do {
|
||||
move = Input();
|
||||
move.row -= 1;
|
||||
move.col -= 1;
|
||||
} while ( !Check( field, move ) );
|
||||
return move;
|
||||
}
|
||||
|
||||
Field::Move HumanPlayer::Input() const {
|
||||
Field::Move move;
|
||||
move.row = -1;
|
||||
move.col = -1;
|
||||
|
||||
io::stringOut("Insert row: ");
|
||||
move.row = io::numberIn();
|
||||
|
||||
io::stringOut("Insert column: ");
|
||||
move.col = io::numberIn();
|
||||
|
||||
io::stringOut("\n");
|
||||
return move;
|
||||
}
|
||||
|
||||
bool HumanPlayer::Check( const Field& field, const Field::Move& move ) const {
|
||||
if ( !field.InRange( move ) ) {
|
||||
io::stringOut("Wrong input!\n");
|
||||
return false;
|
||||
} else if ( !field.IsEmpty( move ) ) {
|
||||
io::stringOut("Is occupied!\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef _HUMAN_PLAYER_
|
||||
#define _HUMAN_PLAYER_
|
||||
|
||||
#include "player.h"
|
||||
|
||||
class HumanPlayer : public Player {
|
||||
public:
|
||||
HumanPlayer( Field::Token token, const char* name );
|
||||
virtual ~HumanPlayer();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const;
|
||||
|
||||
private:
|
||||
Field::Move Input() const;
|
||||
|
||||
bool Check( const Field& field, const Field::Move& move ) const;
|
||||
};
|
||||
|
||||
#endif // _HUMAN_PLAYER_
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef _IO_
|
||||
#define _IO_
|
||||
|
||||
namespace io {
|
||||
|
||||
int numberIn();
|
||||
void numberOut(int num);
|
||||
|
||||
void stringOut(const char* str);
|
||||
|
||||
}
|
||||
|
||||
#endif // _IO_
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "tictactoe.h"
|
||||
|
||||
int main() {
|
||||
TicTacToe tictactoe;
|
||||
|
||||
while ( tictactoe.Start() ) {
|
||||
tictactoe.Run();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#include "player.h"
|
||||
|
||||
Player::Player( Field::Token token, const char* name )
|
||||
: token_( token )
|
||||
, name_( name ) {
|
||||
}
|
||||
|
||||
Player::~Player() {
|
||||
}
|
||||
|
||||
const Field::Token& Player::getToken() const
|
||||
{
|
||||
return token_;
|
||||
}
|
||||
|
||||
const char* Player::getName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef _PLAYER_
|
||||
#define _PLAYER_
|
||||
|
||||
#include "field.h"
|
||||
|
||||
class Player {
|
||||
public:
|
||||
Player( Field::Token token, const char* name );
|
||||
virtual ~Player();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const = 0;
|
||||
|
||||
const Field::Token& getToken() const;
|
||||
const char* getName() const;
|
||||
|
||||
protected:
|
||||
const Field::Token token_;
|
||||
const char* name_;
|
||||
};
|
||||
|
||||
#endif // _PLAYER_
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "tictactoe.h"
|
||||
|
||||
#include "artificial_player.h"
|
||||
#include "human_player.h"
|
||||
#include "io.h"
|
||||
|
||||
TicTacToe::TicTacToe() {
|
||||
players_[0] = 0;
|
||||
players_[1] = 0;
|
||||
}
|
||||
|
||||
TicTacToe::~TicTacToe() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool TicTacToe::Start() {
|
||||
Reset();
|
||||
io::stringOut("Tic Tac Toe\n\n[1] Human\n[2] Computer\n[3] Quit\n\n");
|
||||
|
||||
players_[0] = SelectPlayer( Field::PlayerA, "Player A" );
|
||||
if ( !players_[0] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
players_[1] = SelectPlayer( Field::PlayerB, "Player B" );
|
||||
if ( !players_[1] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
io::stringOut("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void TicTacToe::Run() {
|
||||
field_.Show();
|
||||
|
||||
int playerIndex = 0;
|
||||
|
||||
for ( int i = 0; i < 9; i++ ) {
|
||||
Player& player = *players_[playerIndex];
|
||||
|
||||
field_.MakeMove( player.Turn( field_ ), player.getToken() );
|
||||
field_.Show();
|
||||
|
||||
if ( field_.SameInRow( player.getToken(), 3 ) ) {
|
||||
io::stringOut(player.getName());
|
||||
io::stringOut(" won!\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
playerIndex = ( playerIndex + 1 ) % 2;
|
||||
}
|
||||
|
||||
io::stringOut("Game ends in draw!\n\n");
|
||||
}
|
||||
|
||||
void TicTacToe::Reset() {
|
||||
field_.Clear();
|
||||
|
||||
for ( int i = 0; i < 2; i++ ) {
|
||||
if ( players_[i] ) {
|
||||
delete players_[i];
|
||||
players_[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* TicTacToe::SelectPlayer( Field::Token token, const char* name ) const {
|
||||
int selection = 0;
|
||||
|
||||
while ( true ) {
|
||||
io::stringOut("Choose ");
|
||||
io::stringOut(name);
|
||||
io::stringOut(": ");
|
||||
|
||||
selection = io::numberIn();
|
||||
|
||||
switch ( selection ) {
|
||||
case 1 : return new HumanPlayer( token, name );
|
||||
case 2 : return new ArtificialPlayer( token, name );
|
||||
case 3 : return 0;
|
||||
default : io::stringOut("Wrong input!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef _TIC_TAC_TOE_
|
||||
#define _TIC_TAC_TOE_
|
||||
|
||||
#include "field.h"
|
||||
#include "player.h"
|
||||
|
||||
class TicTacToe {
|
||||
public:
|
||||
TicTacToe();
|
||||
~TicTacToe();
|
||||
|
||||
bool Start();
|
||||
void Run();
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
Player* SelectPlayer( Field::Token token, const char* name ) const;
|
||||
|
||||
Player* players_[2];
|
||||
Field field_;
|
||||
};
|
||||
|
||||
#endif // _TIC_TAC_TOE_
|
||||
@@ -1,82 +0,0 @@
|
||||
#ifndef _ARTIFICIAL_
|
||||
#define _ARTIFICIAL_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "player.h"
|
||||
|
||||
class ArtificialPlayer : public Player {
|
||||
public:
|
||||
ArtificialPlayer( Field::Token token, const std::string& name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
virtual ~ArtificialPlayer() {}
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const {
|
||||
// srand( static_cast<unsigned int>( time( NULL ) ) );
|
||||
Field fakeField = field.Clone();
|
||||
Node node = MinMax( fakeField, token_ );
|
||||
return node.move;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Field::Move move;
|
||||
int value;
|
||||
};
|
||||
|
||||
Node MinMax( Field& field, Field::Token token ) const {
|
||||
Node node;
|
||||
node.value = -10000;
|
||||
|
||||
Field::Move move;
|
||||
int sameMove;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
move.row = i;
|
||||
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
move.col = j;
|
||||
|
||||
if ( !field.IsEmpty( move ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
field.MakeMove( move, token );
|
||||
|
||||
int turnValue = Evaluate( field, token );
|
||||
if ( !turnValue && !field.IsFull() ) {
|
||||
turnValue = -MinMax( field, Field::Opponent( token ) ).value;
|
||||
}
|
||||
|
||||
field.ClearMove( move );
|
||||
|
||||
if ( turnValue > node.value ) {
|
||||
node.move = move;
|
||||
node.value = turnValue;
|
||||
sameMove = 1;
|
||||
} else if ( turnValue == node.value ) {
|
||||
sameMove++;
|
||||
if ( 1 % sameMove == 0 ) {
|
||||
node.move = move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int Evaluate( const Field& field, Field::Token token ) const {
|
||||
if ( field.SameInRow( token, 3 ) ) {
|
||||
return 2;
|
||||
} else if ( field.SameInRow( Field::Opponent( token ), 2 ) ) {
|
||||
return -1;
|
||||
} else if ( field.SameInRow( token, 2 ) > 1 ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _ARTIFICIAL_
|
||||
@@ -1,147 +0,0 @@
|
||||
#ifndef _FIELD_
|
||||
#define _FIELD_
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
class Field {
|
||||
public:
|
||||
enum Token {
|
||||
None = 0,
|
||||
PlayerA = 1,
|
||||
PlayerB = 4
|
||||
};
|
||||
|
||||
static Token Opponent( Token token ) {
|
||||
assert( token != None );
|
||||
if ( token == PlayerA ) {
|
||||
return PlayerB;
|
||||
} else {
|
||||
return PlayerA;
|
||||
}
|
||||
}
|
||||
|
||||
struct Move {
|
||||
int row;
|
||||
int col;
|
||||
};
|
||||
|
||||
Field()
|
||||
: left_( 9 ) {
|
||||
grid_ = new Token* [3];
|
||||
for ( int i = 0; i < 3 ; i++ ) {
|
||||
grid_[i] = new Token[3];
|
||||
}
|
||||
}
|
||||
|
||||
~Field() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
delete grid_[i];
|
||||
}
|
||||
delete [] grid_;
|
||||
}
|
||||
|
||||
Field Clone() const {
|
||||
Field field;
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
field.grid_[i][j] = grid_[i][j];
|
||||
}
|
||||
}
|
||||
field.left_ = left_;
|
||||
return field;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
grid_[i][j] = None;
|
||||
}
|
||||
}
|
||||
left_ = 9;
|
||||
}
|
||||
|
||||
void Show() const {
|
||||
std::cout << " 1 2 3\n";
|
||||
for ( int row = 0; row < 3; row++ ) {
|
||||
std::cout << row + 1 << " ";
|
||||
|
||||
for ( int col = 0; col < 3; col++ ) {
|
||||
if ( grid_[row][col] == PlayerA ) {
|
||||
std::cout << " X ";
|
||||
} else if ( grid_[row][col] == PlayerB ) {
|
||||
std::cout << " O ";
|
||||
} else {
|
||||
std::cout << " ";
|
||||
}
|
||||
|
||||
if ( col < 2 ) {
|
||||
std::cout << "|";
|
||||
}
|
||||
}
|
||||
|
||||
if ( row < 2 ) {
|
||||
std::cout << "\n -----------\n";
|
||||
}
|
||||
}
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
|
||||
int SameInRow( Token token, int amount ) const {
|
||||
int sum = amount * token;
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
if ( grid_[i][0] + grid_[i][1] + grid_[i][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[0][i] + grid_[1][i] + grid_[2][i] == sum ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( grid_[0][0] + grid_[1][1] + grid_[2][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[2][0] + grid_[1][1] + grid_[0][2] == sum ) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool InRange( const Move& move ) const {
|
||||
return move.row >= 0 && move.row < 3 && move.col >= 0 && move.col < 3;
|
||||
}
|
||||
|
||||
bool IsEmpty( const Move& move ) const {
|
||||
return grid_[move.row][move.col] == None;
|
||||
}
|
||||
|
||||
bool IsFull() const {
|
||||
return left_ == 0;
|
||||
}
|
||||
|
||||
void MakeMove( const Move& move, Token token ) {
|
||||
assert( InRange( move ) );
|
||||
assert( IsEmpty( move ) );
|
||||
assert( token != None );
|
||||
assert( left_ );
|
||||
|
||||
grid_[move.row][move.col] = token;
|
||||
left_--;
|
||||
}
|
||||
|
||||
void ClearMove( const Move& move ) {
|
||||
assert( InRange(move) );
|
||||
assert( !IsEmpty(move) );
|
||||
assert( left_ < 9 );
|
||||
|
||||
grid_[move.row][move.col] = None;
|
||||
left_++;
|
||||
}
|
||||
|
||||
private:
|
||||
Token** grid_;
|
||||
int left_;
|
||||
};
|
||||
|
||||
#endif // _FIELD_
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef _HUMAN_
|
||||
#define _HUMAN_
|
||||
|
||||
#include "input.h"
|
||||
#include "player.h"
|
||||
|
||||
class HumanPlayer : public Player {
|
||||
public:
|
||||
HumanPlayer( Field::Token token, const std::string& name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
virtual ~HumanPlayer() {}
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const {
|
||||
Field::Move move;
|
||||
std::cout << name_ << '\n';
|
||||
do {
|
||||
move = Input();
|
||||
move.row -= 1;
|
||||
move.col -= 1;
|
||||
} while ( !Check( field, move ) );
|
||||
return move;
|
||||
}
|
||||
|
||||
private:
|
||||
Field::Move Input() const {
|
||||
Field::Move move;
|
||||
|
||||
std::cout << "Insert row: ";
|
||||
input::number( &move.row );
|
||||
|
||||
std::cout << "Insert column: ";
|
||||
input::number( &move.col );
|
||||
|
||||
std::cout << '\n';
|
||||
return move;
|
||||
}
|
||||
|
||||
bool Check( const Field& field, const Field::Move& move ) const {
|
||||
if ( !field.InRange( move ) ) {
|
||||
std::cout << "Wrong input!\n";
|
||||
return false;
|
||||
} else if ( !field.IsEmpty( move ) ) {
|
||||
std::cout << "Is occupied!\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _HUMAN_
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef _INPUT_
|
||||
#define _INPUT_
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace input {
|
||||
|
||||
template<typename T>
|
||||
void number( T* number ) {
|
||||
std::string input;
|
||||
getline( std::cin, input );
|
||||
std::stringstream stream( input );
|
||||
stream >> *number;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // _INPUT_
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "tictactoe.h"
|
||||
|
||||
int main() {
|
||||
TicTacToe tictactoe;
|
||||
|
||||
while ( tictactoe.Start() ) {
|
||||
tictactoe.Run();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef _PLAYER_
|
||||
#define _PLAYER_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "field.h"
|
||||
|
||||
class Player {
|
||||
public:
|
||||
Player( Field::Token token, const std::string& name )
|
||||
: token_( token )
|
||||
, name_( name ) {
|
||||
}
|
||||
virtual ~Player() {}
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const = 0;
|
||||
|
||||
const Field::Token& getToken() const
|
||||
{
|
||||
return token_;
|
||||
}
|
||||
|
||||
const std::string getName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Field::Token token_;
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
#endif // _PLAYER_
|
||||
@@ -1,93 +0,0 @@
|
||||
#ifndef _TIC_TAC_TOE_
|
||||
#define _TIC_TAC_TOE_
|
||||
|
||||
#include "computer.h"
|
||||
#include "field.h"
|
||||
#include "human.h"
|
||||
#include "input.h"
|
||||
#include "player.h"
|
||||
|
||||
class TicTacToe {
|
||||
public:
|
||||
TicTacToe() {
|
||||
players_[0] = NULL;
|
||||
players_[1] = NULL;
|
||||
}
|
||||
|
||||
~TicTacToe() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool Start() {
|
||||
Reset();
|
||||
std::cout << "Tic Tac Toe\n\n[1] Human\n[2] Computer\n[3] Quit\n\n";
|
||||
|
||||
players_[0] = SelectPlayer( Field::PlayerA, "PlayerA" );
|
||||
if ( !players_[0] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
players_[1] = SelectPlayer( Field::PlayerB, "PlayerB" );
|
||||
if ( !players_[1] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
void Run() {
|
||||
field_.Show();
|
||||
|
||||
int playerIndex = 0;
|
||||
|
||||
for ( int i = 0; i < 9; i++ ) {
|
||||
Player& player = *players_[playerIndex];
|
||||
|
||||
field_.MakeMove( player.Turn( field_ ), player.getToken() );
|
||||
field_.Show();
|
||||
|
||||
if ( field_.SameInRow( player.getToken(), 3 ) ) {
|
||||
std::cout << player.getName() << " won!\n\n";
|
||||
return;
|
||||
}
|
||||
|
||||
playerIndex = ( playerIndex + 1 ) % 2;
|
||||
}
|
||||
|
||||
std::cout << "Game ends in draw!\n\n";
|
||||
}
|
||||
|
||||
private:
|
||||
void Reset() {
|
||||
field_.Clear();
|
||||
|
||||
for ( int i = 0; i < 2; i++ ) {
|
||||
if ( players_[i] ) {
|
||||
delete players_[i];
|
||||
players_[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* SelectPlayer( Field::Token token, const std::string& name ) const {
|
||||
int selection;
|
||||
|
||||
while ( true ) {
|
||||
std::cout << "Choose " << name << ": ";
|
||||
input::number( &selection );
|
||||
|
||||
switch ( selection ) {
|
||||
case 1 : return new HumanPlayer( token, name );
|
||||
case 2 : return new ArtificialPlayer( token, name );
|
||||
case 3 : return NULL;
|
||||
default : std::cout << "Wrong input!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* players_[2];
|
||||
Field field_;
|
||||
};
|
||||
|
||||
#endif // _TIC_TAC_TOE_
|
||||
+2
-2
@@ -19,7 +19,7 @@ then
|
||||
elif [ "$2" = "keygen" ]
|
||||
then
|
||||
#echo "release keygen"
|
||||
ninja -C build/Release Coati_keygen && cd bin/gen && Release/Coati_keygen
|
||||
ninja -C build/Release Coati_license_generator && cd bin/license_generator && Release/Coati_license_generator
|
||||
else
|
||||
#echo "release app"
|
||||
ninja -C build/Release Coati && cd bin/app && Release/Coati
|
||||
@@ -36,7 +36,7 @@ then
|
||||
elif [ "$2" = "keygen" ]
|
||||
then
|
||||
#echo "debug keygen"
|
||||
ninja -C build/Debug Coati_keygen && cd bin/gen && Debug/Coati_keygen_d
|
||||
ninja -C build/Debug Coati_license_generator && cd bin/license_generator && Debug/Coati_license_generator_d
|
||||
else
|
||||
#echo "debug app"
|
||||
ninja -C build/Debug Coati && cd bin/app && Debug/Coati
|
||||
|
||||
@@ -74,7 +74,6 @@ cp $APP_NAME $APP_PATH
|
||||
cp bundle_info.plist $BUNDLE_PATH/Contents/Info.plist
|
||||
|
||||
mkdir -p $RES_DIR/data
|
||||
mkdir -p $RES_DIR/data/log
|
||||
mkdir -p $RES_DIR/data/projects
|
||||
|
||||
cp -R ../data/color_schemes $RES_DIR/data/color_schemes
|
||||
@@ -87,8 +86,11 @@ cp -R ../data/projects/tutorial $RES_DIR/data/projects/tutorial
|
||||
rm $RES_DIR/data/projects/tictactoe/tictactoe.coatidb
|
||||
rm $RES_DIR/data/projects/tutorial/tutorial.coatidb
|
||||
|
||||
cp ../data/window_settings.ini $RES_DIR/data/window_settings.ini
|
||||
cp ../data/ApplicationSettings_for_package.xml $RES_DIR/data/ApplicationSettings.xml
|
||||
mkdir -p $RES_DIR/user
|
||||
mkdir -p $RES_DIR/user/log
|
||||
|
||||
cp ../user/window_settings.ini $RES_DIR/user/window_settings.ini
|
||||
cp ../user/ApplicationSettings_for_package.xml $RES_DIR/user/ApplicationSettings.xml
|
||||
|
||||
echo -e $INFO "Copying dynamic libraries."
|
||||
for LIB_PATH in ${DYNLIB_PATHS[@]}
|
||||
|
||||
+48
-17
@@ -1,8 +1,15 @@
|
||||
#include "utility/AppPath.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "utility/logging/ConsoleLogger.h"
|
||||
#include "utility/logging/FileLogger.h"
|
||||
#include "utility/logging/LogManager.h"
|
||||
#include "utility/StandardHeaderDetection.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
#include "utility/UserPaths.h"
|
||||
#include "utility/Version.h"
|
||||
|
||||
#include "Application.h"
|
||||
@@ -17,10 +24,10 @@
|
||||
#include "qt/window/QtSplashScreen.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#include "utility/solution/SolutionParserVisualStudio.h"
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
|
||||
void init()
|
||||
{
|
||||
std::shared_ptr<ConsoleLogger> consoleLogger = std::make_shared<ConsoleLogger>();
|
||||
@@ -29,60 +36,84 @@ void init()
|
||||
|
||||
std::shared_ptr<FileLogger> fileLogger = std::make_shared<FileLogger>();
|
||||
fileLogger->setLogLevel(Logger::LOG_ALL);
|
||||
FileLogger::setFilePath(logPath);
|
||||
FileLogger::setFilePath(UserPaths::getLogPath());
|
||||
LogManager::getInstance()->addLogger(fileLogger);
|
||||
|
||||
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
|
||||
}
|
||||
|
||||
QMainWindow* getMainWindow()
|
||||
{
|
||||
QWidgetList widgets = qApp->topLevelWidgets();
|
||||
for (QWidgetList::iterator i = widgets.begin(); i != widgets.end(); ++i)
|
||||
if ((*i)->objectName() == "MainWindow")
|
||||
return (QMainWindow*) (*i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication::setApplicationName("Coati");
|
||||
|
||||
Version version = Version::fromString(GIT_VERSION_NUMBER);
|
||||
QApplication::setApplicationVersion(version.toDisplayString().c_str());
|
||||
|
||||
setup(argc, argv);
|
||||
|
||||
QtApplication qtApp(argc, argv);
|
||||
QApplication::setApplicationName("Coati");
|
||||
QApplication::setApplicationVersion(version.toDisplayString().c_str());
|
||||
|
||||
qtApp.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
QPixmap whitePixmap(500, 500);
|
||||
whitePixmap.fill(Qt::white);
|
||||
|
||||
QtSplashScreen* splash = new QtSplashScreen(whitePixmap, Qt::WindowStaysOnTopHint);
|
||||
QtSplashScreen* splash = new QtSplashScreen();
|
||||
splash->setMessage("Loading UI");
|
||||
splash->setVersion(version.toDisplayString().c_str());
|
||||
|
||||
// QTimer* timer = new QTimer(splash);
|
||||
// QObject::connect(timer, SIGNAL(timeout()), splash, SLOT(animate()));
|
||||
// timer->start(150);
|
||||
|
||||
splash->exec(qtApp);
|
||||
|
||||
qtApp.processEvents();
|
||||
|
||||
init();
|
||||
|
||||
QtCommandLineParser commandLineParser;
|
||||
commandLineParser.setup();
|
||||
commandLineParser.process(qtApp);
|
||||
|
||||
qtApp.processEvents();
|
||||
|
||||
QtViewFactory viewFactory;
|
||||
QtNetworkFactory networkFactory;
|
||||
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
|
||||
|
||||
QtMainWindow::setWindowSettingsPath(windowSettingsPath);
|
||||
Application::setAppSettingsPath(appSettingsPath);
|
||||
|
||||
if(AppPath::getAppPath().empty())
|
||||
if (AppPath::getAppPath().empty())
|
||||
{
|
||||
AppPath::setAppPath(QCoreApplication::applicationDirPath().toStdString());
|
||||
}
|
||||
|
||||
if(ApplicationSettings::getInstance()->getHeaderSearchPaths().empty())
|
||||
{
|
||||
StandardHeaderDetection headerDetection;
|
||||
headerDetection.detectHeaders();
|
||||
ApplicationSettings::getInstance()->setHeaderSearchPaths(headerDetection.getDefaultHeaderPaths());
|
||||
}
|
||||
|
||||
splash->setMessage("Checking License");
|
||||
LicenseChecker checker;
|
||||
|
||||
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
|
||||
|
||||
checker.setApp(app.get());
|
||||
|
||||
splash->setMessage("Parse Commandline Arguments");
|
||||
commandLineParser.parseCommandline();
|
||||
|
||||
qtApp.processEvents();
|
||||
splash->setMessage("Done");
|
||||
|
||||
if (splash)
|
||||
{
|
||||
delete splash;
|
||||
}
|
||||
|
||||
commandLineParser.parseCommandline();
|
||||
|
||||
return qtApp.exec();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "utility/messaging/type/MessageActivateNodes.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/scheduling/TaskScheduler.h"
|
||||
#include "utility/UserPaths.h"
|
||||
#include "utility/Version.h"
|
||||
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
@@ -15,8 +16,6 @@
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "settings/ColorScheme.h"
|
||||
|
||||
std::string Application::m_appSettingsPath = "data/ApplicationSettings.xml";
|
||||
|
||||
std::shared_ptr<Application> Application::create(
|
||||
const Version& version, ViewFactory* viewFactory, NetworkFactory* networkFactory
|
||||
){
|
||||
@@ -53,7 +52,7 @@ std::shared_ptr<Application> Application::create(
|
||||
|
||||
void Application::loadSettings()
|
||||
{
|
||||
ApplicationSettings::getInstance()->load(FilePath(m_appSettingsPath));
|
||||
ApplicationSettings::getInstance()->load(FilePath(UserPaths::getAppSettingsPath()));
|
||||
ColorScheme::getInstance()->load(ApplicationSettings::getInstance()->getColorSchemePath());
|
||||
|
||||
GraphViewStyle::loadStyleSettings();
|
||||
@@ -114,11 +113,6 @@ void Application::showLicenseScreen()
|
||||
m_mainView->showLicenseScreen();
|
||||
}
|
||||
|
||||
void Application::setAppSettingsPath(const std::string& appSettingsPath)
|
||||
{
|
||||
m_appSettingsPath = appSettingsPath;
|
||||
}
|
||||
|
||||
void Application::handleMessage(MessageActivateWindow* message)
|
||||
{
|
||||
m_mainView->activateWindow();
|
||||
@@ -187,5 +181,5 @@ void Application::updateRecentProjects(const FilePath& projectSettingsFilePath)
|
||||
}
|
||||
|
||||
appSettings->setRecentProjects(recentProjects);
|
||||
appSettings->save(m_appSettingsPath);
|
||||
appSettings->save(UserPaths::getAppSettingsPath());
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ public:
|
||||
void saveProject(const FilePath& projectSettingsFilePath);
|
||||
void showLicenseScreen();
|
||||
|
||||
static void setAppSettingsPath(const std::string& appSettingsPath);
|
||||
|
||||
private:
|
||||
Application();
|
||||
|
||||
@@ -59,8 +57,6 @@ private:
|
||||
std::shared_ptr<ComponentManager> m_componentManager;
|
||||
|
||||
std::shared_ptr<IDECommunicationController> m_ideCommunicationController;
|
||||
|
||||
static std::string m_appSettingsPath;
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
|
||||
@@ -294,6 +294,8 @@ add_files(
|
||||
utility/TimePoint.cpp
|
||||
utility/TimePoint.h
|
||||
utility/types.h
|
||||
utility/UserPaths.cpp
|
||||
utility/UserPaths.h
|
||||
utility/utility.cpp
|
||||
utility/utility.h
|
||||
utility/utilityString.cpp
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// #include "src\lib_gui\includes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "utility/UserPaths.h"
|
||||
|
||||
std::string UserPaths::s_userDataPath = "user/";
|
||||
|
||||
std::string UserPaths::getUserDataPath()
|
||||
{
|
||||
return s_userDataPath;
|
||||
}
|
||||
|
||||
void UserPaths::setUserDataPath(const std::string& path)
|
||||
{
|
||||
s_userDataPath = path;
|
||||
}
|
||||
|
||||
std::string UserPaths::getAppSettingsPath()
|
||||
{
|
||||
return getUserDataPath() + "ApplicationSettings.xml";
|
||||
}
|
||||
|
||||
std::string UserPaths::getWindowSettingsPath()
|
||||
{
|
||||
return getUserDataPath() + "window_settings.ini";
|
||||
}
|
||||
|
||||
std::string UserPaths::getLogPath()
|
||||
{
|
||||
return getUserDataPath() + "log/";
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef USER_PATHS_H
|
||||
#define USER_PATHS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class UserPaths
|
||||
{
|
||||
public:
|
||||
static std::string getUserDataPath();
|
||||
static void setUserDataPath(const std::string& path);
|
||||
|
||||
static std::string getAppSettingsPath();
|
||||
static std::string getWindowSettingsPath();
|
||||
static std::string getLogPath();
|
||||
|
||||
private:
|
||||
static std::string s_userDataPath;
|
||||
};
|
||||
|
||||
#endif // USER_PATHS_H
|
||||
@@ -1,12 +1,13 @@
|
||||
#ifndef INCLUDES_DEFAULT_H
|
||||
#define INCLUDES_DEFAULT_H
|
||||
|
||||
static std::string appSettingsPath = "data/ApplicationSettings.xml";
|
||||
static std::string windowSettingsPath = "data/window_settings.ini";
|
||||
static std::string logPath = "data/log/";
|
||||
#include "utility/UserPaths.h"
|
||||
|
||||
void setup(int argc, char *argv[])
|
||||
{
|
||||
std::string userdir(std::getenv("HOME"));
|
||||
userdir.append("/.config/coati/");
|
||||
UserPaths::setUserDataPath(userdir);
|
||||
}
|
||||
|
||||
#endif // INCLUDES_DEFAULT_H
|
||||
@@ -4,10 +4,10 @@
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
|
||||
static std::string appSettingsPath = "data/ApplicationSettings.xml";
|
||||
static std::string windowSettingsPath = "data/window_settings.ini";
|
||||
static std::string logPath = "data/log/";
|
||||
#include "qt/utility/utilityQt.h"
|
||||
#include "utility/UserPaths.h"
|
||||
|
||||
void setup(int argc, char *argv[])
|
||||
{
|
||||
@@ -47,6 +47,22 @@ void setup(int argc, char *argv[])
|
||||
// printf("after change, libraryPaths=(%s)\n", QCoreApplication::libraryPaths().join(",").toUtf8().data());
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Makes the mac bundle copy the user files to the Application Support folder
|
||||
QString dataPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
|
||||
QDir dataDir(dataPath);
|
||||
if (!dataDir.exists())
|
||||
{
|
||||
dataDir.mkpath(dataPath);
|
||||
}
|
||||
|
||||
utility::copyNewFilesFromDirectory(QString::fromStdString(UserPaths::getUserDataPath()), dataPath);
|
||||
|
||||
UserPaths::setUserDataPath(dataPath.toStdString() + "/");
|
||||
// ----------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
#endif // INCLUDES_MAC_H
|
||||
|
||||
@@ -5,21 +5,15 @@
|
||||
|
||||
#include "vld.h"
|
||||
|
||||
// #define DEPLOY
|
||||
#include "utility/UserPaths.h"
|
||||
|
||||
#ifdef DEPLOY
|
||||
static std::string appSettingsPath = std::string(std::getenv("APPDATA")) + "/../local/Coati Software/Coati/ApplicationSettings.xml";
|
||||
static std::string windowSettingsPath = std::string(std::getenv("APPDATA")) + "/../local/Coati Software/Coati/window_settings.ini";
|
||||
static std::string logPath = std::string(std::getenv("APPDATA")) + "/../local/Coati Software/Coati/log/";
|
||||
#else
|
||||
static std::string appSettingsPath = "data/ApplicationSettings.xml";
|
||||
static std::string windowSettingsPath = "data/window_settings.ini";
|
||||
static std::string logPath = "data/log/";
|
||||
#endif
|
||||
// #define DEPLOY
|
||||
|
||||
void setup(int argc, char *argv[])
|
||||
{
|
||||
|
||||
#ifdef DEPLOY
|
||||
UserPaths::setUserDataPath(std::getenv("APPDATA")) + "/../local/Coati Software/Coati/");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // INCLUDES_WINDOWS_H
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFontDatabase>
|
||||
#include <QPainter>
|
||||
@@ -150,4 +151,29 @@ namespace utility
|
||||
painter.drawImage(0, 0, colorImage);
|
||||
return QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
void copyNewFilesFromDirectory(QString src, QString dst)
|
||||
{
|
||||
QDir dir(src);
|
||||
if (!dir.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
||||
{
|
||||
QString dst_path = dst + QDir::separator() + d;
|
||||
|
||||
dir.mkpath(dst_path);
|
||||
copyNewFilesFromDirectory(src + QDir::separator() + d, dst_path);
|
||||
}
|
||||
|
||||
foreach (QString f, dir.entryList(QDir::Files))
|
||||
{
|
||||
if (!QFile::exists(dst + QDir::separator() + f))
|
||||
{
|
||||
QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace utility
|
||||
std::string getStyleSheet(const std::string& path);
|
||||
|
||||
QPixmap colorizePixmap(const QPixmap& pixmap, QColor color);
|
||||
|
||||
void copyNewFilesFromDirectory(QString src, QString dst);
|
||||
}
|
||||
|
||||
# endif // UTILITY_QT_H
|
||||
|
||||
@@ -34,11 +34,10 @@
|
||||
#include "utility/messaging/type/MessageWindowFocus.h"
|
||||
#include "utility/messaging/type/MessageZoom.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
#include "utility/UserPaths.h"
|
||||
#include "version.h"
|
||||
#include "isTrial.h"
|
||||
|
||||
std::string QtMainWindow::m_windowSettingsPath = "data/window_settings.ini";
|
||||
|
||||
QtViewToggle::QtViewToggle(View* view, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_view(view)
|
||||
@@ -214,7 +213,7 @@ void QtMainWindow::hideView(View* view)
|
||||
|
||||
void QtMainWindow::loadLayout()
|
||||
{
|
||||
QSettings settings(m_windowSettingsPath.c_str(), QSettings::IniFormat);
|
||||
QSettings settings(UserPaths::getWindowSettingsPath().c_str(), QSettings::IniFormat);
|
||||
|
||||
settings.beginGroup("MainWindow");
|
||||
resize(settings.value("size", QSize(600, 400)).toSize());
|
||||
@@ -236,7 +235,7 @@ void QtMainWindow::loadLayout()
|
||||
|
||||
void QtMainWindow::saveLayout()
|
||||
{
|
||||
QSettings settings(m_windowSettingsPath.c_str(), QSettings::IniFormat);
|
||||
QSettings settings(UserPaths::getWindowSettingsPath().c_str(), QSettings::IniFormat);
|
||||
|
||||
settings.beginGroup("MainWindow");
|
||||
settings.setValue("maximized", isMaximized());
|
||||
@@ -557,11 +556,6 @@ void QtMainWindow::updateRecentProjectMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void QtMainWindow::setWindowSettingsPath(const std::string& windowSettingsPath)
|
||||
{
|
||||
m_windowSettingsPath = windowSettingsPath;
|
||||
}
|
||||
|
||||
void QtMainWindow::toggleShowDockWidgetTitleBars()
|
||||
{
|
||||
setShowDockWidgetTitleBars(!m_showDockWidgetTitleBars);
|
||||
|
||||
@@ -130,8 +130,6 @@ public slots:
|
||||
|
||||
void updateRecentProjectMenu();
|
||||
|
||||
static void setWindowSettingsPath(const std::string& windowSettingsPath);
|
||||
|
||||
private slots:
|
||||
void toggleShowDockWidgetTitleBars();
|
||||
|
||||
@@ -172,8 +170,6 @@ private:
|
||||
|
||||
QShortcut* m_escapeShortcut;
|
||||
|
||||
static std::string m_windowSettingsPath;
|
||||
|
||||
QtThreadedFunctor<std::string, std::string, std::vector<std::string>, std::vector<std::string>> m_createNewProjectFunctor;
|
||||
};
|
||||
|
||||
|
||||
+6
-3
@@ -3,6 +3,7 @@
|
||||
#include "utility/logging/FileLogger.h"
|
||||
#include "utility/logging/LogManager.h"
|
||||
#include "utility/ResourcePaths.h"
|
||||
#include "utility/UserPaths.h"
|
||||
#include "utility/Version.h"
|
||||
|
||||
#include "Application.h"
|
||||
@@ -24,7 +25,7 @@ void init()
|
||||
|
||||
std::shared_ptr<FileLogger> fileLogger = std::make_shared<FileLogger>();
|
||||
fileLogger->setLogLevel(Logger::LOG_ALL);
|
||||
FileLogger::setFilePath(logPath);
|
||||
FileLogger::setFilePath(UserPaths::getLogPath());
|
||||
LogManager::getInstance()->addLogger(fileLogger);
|
||||
|
||||
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
|
||||
@@ -32,9 +33,13 @@ void init()
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication::setApplicationName("Coati");
|
||||
|
||||
Version version = Version::fromString(GIT_VERSION_NUMBER);
|
||||
QApplication::setApplicationVersion(version.toDisplayString().c_str());
|
||||
|
||||
setup(argc, argv);
|
||||
|
||||
QtApplication qtApp(argc, argv);
|
||||
|
||||
qtApp.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
@@ -52,8 +57,6 @@ int main(int argc, char *argv[])
|
||||
QtViewFactory viewFactory;
|
||||
QtNetworkFactory networkFactory;
|
||||
|
||||
QtMainWindow::setWindowSettingsPath(windowSettingsPath);
|
||||
Application::setAppSettingsPath(appSettingsPath);
|
||||
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
|
||||
|
||||
if (splash)
|
||||
|
||||
Reference in New Issue
Block a user