-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscene.h
291 lines (272 loc) · 7.92 KB
/
scene.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#pragma once
#include <iostream>
#include <vector>
#include <cuda_runtime.h>
#include <cassert>
#include "math.cuh"
using namespace std;
#define SOKOBAN_EMPTY 0
#define SOKOBAN_WALL 1
#define SOKOBAN_PLAYER_START 2
#define SOKOBAN_PLAYER 3
#define SOKOBAN_BOX 4
#define SOKOBAN_BOX_TARGET 5
#define SOKOBAN_WALL_COLOR float3{210.0f/255.0f, 180.0f/255.0f, 140.0f/255.0f}
#define SOKOBAN_PLAYER_START_COLOR float3{238.0f/255.0f, 130.0f/255.0f, 238.0f/255.0f}
#define SOKOBAN_PLAYER_COLOR float3{65.0f/255.0f, 105.0f/255.0f, 255.0f/255.0f}
#define SOKOBAN_BOX_COLOR float3{205.0f/255.0f, 133.0f/255.0f, 63.0f/255.0f}
#define SOKOBAN_BOX_COLOR_ACTIVE float3{124.0f/255.0f, 252.0f/255.0f, 0.0f/255.0f}
#define SOKOBAN_BOX_TARGET_COLOR float3{173.0f/255.0f, 255.0f/255.0f, 47.0f/255.0f}
#define SOKOBAN_ERROR_COLOR float3{255.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f}
#define SOKOBAN_DEFAULT_INT3 int3{ 0, 0, 0 }
#define SOKOBAN_DEFAULT_UCHAR3 uchar3{ 0u, 0u, 0u }
#define SOKOBAN_DEFAULT_FLOAT3 float3{ -999.0f,-999.0f,-999.0f }
#define SOKOBAN_INACTIVE 0
#define SOKOBAN_ACTIVE 1
#define SOKOBAN_ACTOR_DEFAULT_ROTATION 0
#define SOKOBAN_ACTOR_DEFAULT_ID 255
struct Actor
{
unsigned char ActorType = 255;
unsigned char ActorState = 0;
uchar3 Location = SOKOBAN_DEFAULT_UCHAR3;
//unsigned char Rotation = SOKOBAN_ACTOR_DEFAULT_ROTATION; //Move this to ActorState
unsigned char Id = SOKOBAN_ACTOR_DEFAULT_ID;
__host__ __device__ inline bool operator!=(const Actor& ActorOther) const
{
return (ActorOther.ActorType != ActorType) ||
(ActorOther.ActorState != ActorState) ||
(ActorOther.Location != Location) ||
//(ActorOther.Rotation != Rotation) ||
(ActorOther.Id != Id);
}
__host__ __device__ inline bool operator==(const Actor& ActorOther) const
{
return (ActorOther.ActorType == ActorType) &&
(ActorOther.ActorState == ActorState) &&
(ActorOther.Location == Location) &&
//(ActorOther.Rotation == Rotation) &&
(ActorOther.Id == Id);
}
};
struct RenderData
{
int3 Location = SOKOBAN_DEFAULT_INT3;
float3 TypeColor = SOKOBAN_ERROR_COLOR;
float3 Scale = SOKOBAN_DEFAULT_FLOAT3;
float3 Offset = SOKOBAN_DEFAULT_FLOAT3;
};
// Deprecated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Deprecated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Deprecated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Deprecated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
class Scene
{
public:
//0 represent empty, 1 represent wall
vector<uint8_t> SceneBlock;
vector<Actor> Actors;
int3 SceneSize;
int ActorId = 0;
void SetupScene(const vector<uint8_t>& SceneBlock_, const vector<Actor>& Actors_, int3 SceneSize_)
{
assert(SceneBlock_.size() == SceneSize_.x * SceneSize_.y * SceneSize_.z);
Actors = Actors_;
SceneBlock.resize(SceneBlock_.size());
SceneSize = SceneSize_;
for (uint8_t x = 0; x < SceneSize.x; x++)
{
for (uint8_t y = 0; y < SceneSize.y; y++)
{
for (uint8_t z = 0; z < SceneSize.z; z++)
{
int Index = x + y * SceneSize.x + z * SceneSize.x * SceneSize.y;
uint8_t BlockType = SceneBlock_[Index];
if (BlockType == SOKOBAN_WALL)
{
SceneBlock[Index] = BlockType;
}
else if (BlockType == SOKOBAN_EMPTY)
{
SceneBlock[Index] = BlockType;
}
else if (BlockType == SOKOBAN_PLAYER)
{
AddActor({ SOKOBAN_PLAYER_START, 0, {x, y, z}, SOKOBAN_ACTOR_DEFAULT_ID });
AddActor({ SOKOBAN_PLAYER, 0, {x, y, z}, SOKOBAN_ACTOR_DEFAULT_ID });
std::cout << Actors.size() << "\n";
}
else if (BlockType == SOKOBAN_BOX)
{
AddActor({ SOKOBAN_BOX, 0, {x, y, z}, SOKOBAN_ACTOR_DEFAULT_ID });
std::cout << Actors.size() << "\n";
}
else if (BlockType == SOKOBAN_BOX_TARGET)
{
AddActor({ SOKOBAN_BOX_TARGET, 0, {x, y, z}, SOKOBAN_ACTOR_DEFAULT_ID });
std::cout << Actors.size() << "\n";
}
}
}
}
}
void AddActor(Actor Actor)
{
if (Actor.ActorType == SOKOBAN_PLAYER)
{
for (auto& CurrentActor : Actors)
{
if (CurrentActor.ActorType == SOKOBAN_PLAYER_START && CurrentActor.ActorState == Actor.ActorState)
{
Actor.Location = CurrentActor.Location;
}
}
}
Actor.Id = ActorId;
ActorId++;
Actors.push_back(Actor);
}
bool PositionOutOfBound(int3 Position) const
{
return Position.x < 0 || Position.x >= SceneSize.x || Position.y < 0 || Position.y >= SceneSize.y || Position.z < 0 || Position.z >= SceneSize.z;
}
bool MovePlayer(int2 Move)
{
if (abs(Move.x) == abs(Move.y) && abs(Move.x) == 1)
{
Move.y = 0;
}
for (auto& Actor : Actors)
{
uint8_t ActorsType = Actor.ActorType;
if (ActorsType == SOKOBAN_PLAYER)
{
int3 NewPosition = { Actor.Location.x + Move.x, Actor.Location.y + Move.y, Actor.Location.z };
if (PositionOutOfBound(NewPosition))
{
return false;
}
int NewIndex = NewPosition.x + NewPosition.y * SceneSize.x + NewPosition.z * SceneSize.x * SceneSize.y;
if (SceneBlock[NewIndex] == SOKOBAN_WALL)
{
return false;
}
//Find box
for (auto& ActorW : Actors)
{
if (ActorW.ActorType == SOKOBAN_BOX)
{
if (ActorW.Location == NewPosition) // if push
{
int BoxId = ActorW.Id;
int3 BoxNewPosition = { ActorW.Location.x + Move.x, ActorW.Location.y + Move.y, ActorW.Location.z };
if (PositionOutOfBound(BoxNewPosition))
{
return false;
}
int BoxNewIndex = BoxNewPosition.x + BoxNewPosition.y * SceneSize.x + BoxNewPosition.z * SceneSize.x * SceneSize.y;
if (SceneBlock[BoxNewIndex] == SOKOBAN_WALL) // If box forward is wall
{
return false;
}
//Find box
for (auto& ActorW2 : Actors) // If box forward is one more box
{
if (ActorW2.ActorType == SOKOBAN_BOX)
{
if (ActorW2.Location == BoxNewPosition)
{
int Box2Id = ActorW2.Id;
if (BoxId != Box2Id)
{
return false;
}
}
}
}
// If can push
ActorW.Location = int3_2_uchar3(BoxNewPosition);
}
}
}
Actor.Location = int3_2_uchar3(NewPosition);
return true;
}
}
return false;
}
void UpdatePhysics()
{
//Do physics
//Do after physics
//Find box
for (auto& ActorW : Actors)
{
if (ActorW.ActorType == SOKOBAN_BOX)
{
int3 BoxPosition = uchar3_2_int3(ActorW.Location);
for (auto& ActorW2 : Actors)
{
if (ActorW2.ActorType == SOKOBAN_BOX_TARGET)
{
int3 TargetPosition = uchar3_2_int3(ActorW2.Location);
if (TargetPosition == BoxPosition)
{
ActorW.ActorState = SOKOBAN_ACTIVE;
goto FOR_ELSE;
}
}
}
ActorW.ActorState = SOKOBAN_INACTIVE;
FOR_ELSE:
{
continue;
}
}
}
}
vector<RenderData> GetRenderData()
{
vector<RenderData> Result;
for (int x = 0; x < SceneSize.x; x++)
{
for (int y = 0; y < SceneSize.y; y++)
{
for (int z = 0; z < SceneSize.z; z++)
{
int Index = x + y * SceneSize.x + z * SceneSize.x * SceneSize.y;
uint8_t BlockType = SceneBlock[Index];
if (BlockType == SOKOBAN_WALL)
{
Result.push_back({ {x,y,z},SOKOBAN_WALL_COLOR , {1.0f,1.0f,1.0f}, {0.0f,0.0f,0.0f} });
}
}
}
}
for (auto& Actor : Actors)
{
int ActorsType = Actor.ActorType;
int ActorsState = Actor.ActorState;
int x = Actor.Location.x;
int y = Actor.Location.y;
int z = Actor.Location.z;
if (ActorsType == SOKOBAN_PLAYER_START)
{
Result.push_back({ {x,y,z},SOKOBAN_PLAYER_START_COLOR , {1.0f,0.125f,1.0f}, {0.0f,0.5f-0.0625f,0.0f} });
}
else if (ActorsType == SOKOBAN_PLAYER)
{
Result.push_back({ {x,y,z},SOKOBAN_PLAYER_COLOR , {0.8f,0.8f,0.8f}, {0.0f,0.0f,0.0f} });
}
else if (ActorsType == SOKOBAN_BOX)
{
Result.push_back({ {x,y,z}, (ActorsState == 0 ? SOKOBAN_BOX_COLOR : SOKOBAN_BOX_COLOR_ACTIVE) , {0.95f,0.95f,0.95f}, {0.0f,0.025f,0.0f} });
}
else if (ActorsType == SOKOBAN_BOX_TARGET)
{
Result.push_back({ {x,y,z},SOKOBAN_BOX_TARGET_COLOR , {1.0f,0.125f,1.0f}, {0.0f,0.5f - 0.0625f,0.0f} });
}
}
return Result;
}
};