Skip to content
This repository was archived by the owner on Feb 5, 2024. It is now read-only.

Commit 7b4bc27

Browse files
committed
AIのプロトタイプと対戦環境
1 parent e4a0eb6 commit 7b4bc27

File tree

12 files changed

+699
-40
lines changed

12 files changed

+699
-40
lines changed

Procon2018/AI.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
#include "Shared/Util.h"
3+
#include "Shared/Field.h"
4+
#include <future>
5+
#include <thread>
6+
7+
namespace Procon2018 {
8+
9+
10+
class AI {
11+
private:
12+
std::optional<std::future<PlayerMove>> m_result;
13+
protected:
14+
virtual PlayerMove calcNextMove(std::optional<std::pair<PlayerMove, PlayerMove>> moves) = 0;
15+
public:
16+
virtual void init(const Field &field, PlayerId playerId) = 0;
17+
virtual void forward(std::optional<std::pair<PlayerMove, PlayerMove>> moves) {
18+
m_result = std::async(std::launch::async, [&, moves](){
19+
return calcNextMove(moves);
20+
});
21+
}
22+
virtual std::optional<PlayerMove> getNextMove() {
23+
if (m_result && m_result->wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) {
24+
auto ret = m_result->get();
25+
m_result.reset();
26+
return ret;
27+
}
28+
return std::optional<PlayerMove>();
29+
}
30+
};
31+
32+
33+
}

Procon2018/FieldView.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void FieldView::update() {
4444
auto drawAgent = [&](int i) {
4545
Point currentPos = m_fld.agentPos((AgentId)i);
4646
Point oldPos = m_oldPlayerPos[i];
47-
PlayerId team = m_fld.teamOf((AgentId)i);
47+
PlayerId team = m_fld.playerOf((AgentId)i);
4848
s3d::Color color = team == PlayerId::B ? s3d::Palette::Red : s3d::Palette::Blue;
4949
s3d::Vec2 end = gridCenter(currentPos);
5050
s3d::Vec2 start = gridCenter(oldPos);

Procon2018/GameLog.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "stdafx.h"
2+
#include "GameLog.h"
3+
4+
5+
GameLog::GameLog() {}
6+
7+
8+
GameLog::~GameLog() {}

Procon2018/GameLog.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
class GameLog {
3+
public:
4+
GameLog();
5+
~GameLog();
6+
};
7+

Procon2018/Main.cpp

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Shared/DnnClient.h"
44
#include "Shared/Mcts.h"
55
#include "Playground.h"
6+
#include "WinjAI/WinjAI.h"
67

78

89
namespace Procon2018 {
@@ -29,7 +30,7 @@ void TrainDataVisualize() {
2930
}
3031
}
3132

32-
void Battle() {
33+
void BattleToDnn() {
3334
auto toMove = [](const std::string &s) {
3435
if (s[0] == 'x') return OptAction();
3536
ActionType type = ActionType::Move;
@@ -100,6 +101,15 @@ void HumanPlay() {
100101
}
101102
}
102103

104+
void BattleToWinjAI() {
105+
SP<AI> winjAI((AI*)new WinjAI::WinjAI());
106+
SP<AI> winjAI2((AI*)new WinjAI::WinjAI());
107+
Playground grd(s3d::RectF(0, 0, s3d::Window::Size()), winjAI, nullptr);
108+
while (s3d::System::Update()) {
109+
grd.update();
110+
}
111+
}
112+
103113

104114
}
105115

@@ -113,32 +123,7 @@ void Main()
113123
Rand::InitializeWithTime();
114124

115125
//TrainDataVisualize();
116-
//Battle();
117-
HumanPlay();
118-
119-
/*
120-
using namespace boost::property_tree;
121-
std::ifstream ifs("2.json");
122-
123-
auto toStr = [](OptAction a) {
124-
if (!a) return std::string(" ");
125-
std::string s = a->type == ActionType::Move ? "m" : "r";
126-
return s + std::to_string(a->dir);
127-
};
128-
ptree pt;
129-
read_json(ifs, pt);
130-
Field state = Field::FromPTree(pt.get_child("state"));
131-
DnnClient dnn("127.0.0.1", 54215);
132-
PolicyPair pp;
133-
double v = dnn.Evaluate(state, pp);
134-
std::cout << "value: " << v << std::endl;
135-
for (int i = 0; i < 2; i++) {
136-
std::cout << std::endl;
137-
for (int j = 0; j < PlayerMove::IntCount(); j++) {
138-
PlayerMove m = PlayerMove::FromInt(j);
139-
std::cout << j << "(" << toStr(m.a0) << "," << toStr(m.a1) << "): " << pp[i][j] << std::endl;
140-
}
141-
}
142-
std::cout << state.value() << std::endl;
143-
*/
126+
//BattleToDnn();
127+
//HumanPlay();
128+
BattleToWinjAI();
144129
}

Procon2018/Playground.cpp

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,41 @@ namespace Procon2018 {
88
Playground::Playground(const s3d::RectF & viewport)
99
: FieldView(viewport, Field::RandomState())
1010
, m_actions()
11-
, m_dragState() {
11+
, m_dragState()
12+
, m_ai() {
13+
}
14+
15+
Playground::Playground(const s3d::RectF & viewport, SP<AI> ai0, SP<AI> ai1)
16+
: FieldView(viewport, Field::RandomState())
17+
, m_actions()
18+
, m_dragState()
19+
, m_ai{ai0, ai1} {
20+
if (ai0) {
21+
ai0->init(m_fld, PlayerId::A);
22+
ai0->forward({});
23+
}
24+
if (ai1) {
25+
ai1->init(m_fld, PlayerId::B);
26+
ai1->forward({});
27+
}
1228
}
1329

1430
void Playground::update() {
1531
FieldView::update();
32+
if (m_fld.isEnd()) return;
33+
34+
bool forwards = s3d::KeyEnter.down();
35+
bool validInput[4] = {};
36+
for (int i = 0; i < 2; i++) {
37+
if (m_ai[i] == nullptr) {
38+
validInput[2*i] = validInput[2*i + 1] = true;
39+
continue;
40+
}
41+
auto move = m_ai[i]->getNextMove();
42+
if (!move) continue;
43+
m_actions[2*i] = move->a0;
44+
m_actions[2*i + 1] = move->a1;
45+
}
1646

1747
auto toGridPos = [&](s3d::Vec2 vec) {
1848
s3d::Vec2 pos = vec - m_v.tl();
@@ -31,6 +61,7 @@ void Playground::update() {
3161
if (s3d::MouseL.down() || s3d::MouseR.down()) {
3262
Point p = toGridPos(mousePos);
3363
for (int i = 0; i < 4; i++) {
64+
if (!validInput[i]) continue;
3465
if (p == m_fld.agentPos((AgentId)i)) {
3566
DragState s;
3667
if (s3d::MouseL.down()) s.type = ActionType::Move;
@@ -79,14 +110,23 @@ void Playground::update() {
79110
drawAction(s3d::Line(gridCenter(p), gridCenter(trg)), m_actions[i]->type);
80111
}
81112

82-
if (s3d::KeyEnter.down()) {
113+
if (forwards && m_fld.resTurn() > 0) {
83114
forward(m_actions[0], m_actions[1], m_actions[2], m_actions[3]);
115+
std::cout << "resTurn: " << m_fld.resTurn() << std::endl;
116+
auto score = m_fld.calcScore();
117+
std::cout << "score: (blue: " << score.first << ", red: " << score.second << ")" << std::endl;
118+
119+
if (m_fld.resTurn() > 0) {
120+
PlayerMove m0 = PlayerMove(m_actions[0], m_actions[1]);
121+
PlayerMove m1 = PlayerMove(m_actions[2], m_actions[3]);
122+
std::optional<std::pair<PlayerMove, PlayerMove>> moves = std::make_pair(m0, m1);
123+
for (int i = 0; i < 2; i++) {
124+
if (m_ai[i]) m_ai[i]->forward(moves);
125+
}
126+
}
84127
for (int i = 0; i < 4; i++) {
85128
m_actions[i].reset();
86129
}
87-
std::cout << "resTurn: " << m_fld.resTurn() << std::endl;
88-
auto score = m_fld.calcScore();
89-
std::cout << "score: (" << score.first << ", " << score.second << ")" << std::endl;
90130
}
91131
}
92132

Procon2018/Playground.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include "Shared/Util.h"
33
#include "FieldView.h"
4+
#include "AI.h"
45

56

67
namespace Procon2018 {
@@ -19,10 +20,14 @@ class Playground : FieldView {
1920

2021
std::optional<DragState> m_dragState;
2122

23+
SP<AI> m_ai[2];
24+
2225
public:
2326

2427
Playground(const s3d::RectF &viewport);
2528

29+
Playground(const s3d::RectF &viewport, SP<AI> ai0, SP<AI> ai1);
30+
2631
void update();
2732

2833
};

Procon2018/Procon2018.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
</ItemDefinitionGroup>
199199
<ItemGroup>
200200
<ClCompile Include="FieldView.cpp" />
201+
<ClCompile Include="GameLog.cpp" />
201202
<ClCompile Include="Main.cpp" />
202203
<ClCompile Include="Playground.cpp" />
203204
<ClCompile Include="Shared\DnnClient.cpp" />
@@ -267,7 +268,9 @@
267268
<Text Include="App\example\test.txt" />
268269
</ItemGroup>
269270
<ItemGroup>
271+
<ClInclude Include="AI.h" />
270272
<ClInclude Include="FieldView.h" />
273+
<ClInclude Include="GameLog.h" />
271274
<ClInclude Include="Playground.h" />
272275
<ClInclude Include="Shared\DnnClient.h" />
273276
<ClInclude Include="Shared\Field.h" />
@@ -277,6 +280,7 @@
277280
<ClInclude Include="Shared\Util.h" />
278281
<ClInclude Include="TrainDataVisualizer.h" />
279282
<ClInclude Include="Visualizer.h" />
283+
<ClInclude Include="WinjAI\WinjAI.h" />
280284
</ItemGroup>
281285
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
282286
<ImportGroup Label="ExtensionTargets">

Procon2018/Procon2018.vcxproj.filters

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
<ClCompile Include="Playground.cpp">
7979
<Filter>Source Files</Filter>
8080
</ClCompile>
81+
<ClCompile Include="GameLog.cpp">
82+
<Filter>Source Files</Filter>
83+
</ClCompile>
8184
</ItemGroup>
8285
<ItemGroup>
8386
<Image Include="App\icon.ico">
@@ -244,5 +247,14 @@
244247
<ClInclude Include="Playground.h">
245248
<Filter>Header Files</Filter>
246249
</ClInclude>
250+
<ClInclude Include="AI.h">
251+
<Filter>Header Files</Filter>
252+
</ClInclude>
253+
<ClInclude Include="WinjAI\WinjAI.h">
254+
<Filter>Header Files</Filter>
255+
</ClInclude>
256+
<ClInclude Include="GameLog.h">
257+
<Filter>Header Files</Filter>
258+
</ClInclude>
247259
</ItemGroup>
248260
</Project>

Procon2018/Shared/Field.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,19 @@ const Grid& Field::grid(const Point &pos) const {
197197
return m_field[pos.y][pos.x];
198198
}
199199

200+
void Field::setColor(const Point & pos, const std::optional<PlayerId> &color) {
201+
m_field[pos.y][pos.x].color = color;
202+
}
203+
204+
void Field::setPos(AgentId agentId, const Point & pos) {
205+
m_agent[(int)agentId] = pos;
206+
}
207+
200208
const Point& Field::agentPos(AgentId playerId) const {
201209
return m_agent[(int)playerId];
202210
}
203211

204-
PlayerId Field::teamOf(AgentId playerId) const {
212+
PlayerId Field::playerOf(AgentId playerId) const {
205213
return (int)playerId < 2 ? PlayerId::A : PlayerId::B;
206214
}
207215

@@ -262,7 +270,7 @@ bool Field::checkValid(AgentId agentId, const Action & a) const {
262270
Point next = m_agent[(int)agentId] + Neighbour8(a.dir);
263271
if (outOfField(next)) return false;
264272
if (auto &c = m_field[next.y][next.x].color)
265-
if (c.value() != teamOf(agentId)) return false;
273+
if (c.value() != playerOf(agentId)) return false;
266274
return true;
267275
}
268276
if (a.type == ActionType::Remove) {
@@ -340,7 +348,7 @@ bool Field::forward(const OptAction& a0,
340348
// 塗り絵処理
341349
for (int i = 0; i < 4; i++) {
342350
m_agent[i] = pos[i];
343-
m_field[pos[i].y][pos[i].x].color = teamOf((AgentId)i);
351+
m_field[pos[i].y][pos[i].x].color = playerOf((AgentId)i);
344352
}
345353

346354
m_resTurn--;
@@ -363,7 +371,7 @@ bool Field::isBad(AgentId agentId, const Action & a) const {
363371
Point next = m_agent[(int)agentId] + Neighbour8(a.dir);
364372
if (outOfField(next)) return true;
365373
if (auto &c = m_field[next.y][next.x].color) {
366-
if (c.value() == teamOf(agentId)) return true;
374+
if (c.value() == playerOf(agentId)) return true;
367375
}
368376
else if (m_field[next.y][next.x].score < 0) return true;
369377
return false;

0 commit comments

Comments
 (0)