-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSokoban.cs
141 lines (113 loc) · 4.56 KB
/
Sokoban.cs
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
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Sokoban {
public enum Actions { IDLE = 0, UP = 1, LEFT = 2, DOWN = 3, RIGHT = 4 };
public class Sokoban<TAlgo> : IGame where TAlgo : Base, new() {
public readonly static List<int> ACTIONS = new List<int>() { (int)Actions.UP, (int)Actions.LEFT, (int)Actions.DOWN, (int)Actions.RIGHT };
private Level level;
private IState gameState;
private TAlgo agent;
public void Start() {
if (RL.instance.selectedSokobanLevel == RL.SokobanLevel.Easy)
level = new Level(new List<int>() {
1, 1, 1, 1, 1, 1,
1, 4, 0, 0, 0, 1,
1, 0, 0, 2, 3, 1,
1, 1, 1, 1, 1, 1,
}, 4, 6);
else if (RL.instance.selectedSokobanLevel == RL.SokobanLevel.Medium)
level = new Level(new List<int>() {
1, 1, 1, 1, 1, 1,
1, 4, 0, 0, 0, 1,
1, 0, 0, 2, 3, 1,
1, 0, 0, 2, 3, 1,
1, 0, 0, 2, 3, 1,
1, 1, 1, 1, 1, 1,
}, 6, 6);
else
level = new Level(new List<int>() {
1, 1, 1, 1, 1, 1,
1, 4, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 0, 0, 1, 3, 1,
1, 1, 2, 1, 1, 1,
1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1,
}, 9, 6);
gameState = new State(level); // initial game
agent = new TAlgo();
agent.States = new List<IState>() { gameState };
agent.Transition = Play;
agent.Init();
Render();
}
public void Update() {}
public static Vector2 PlayAction(int action) {
Vector2 move = new Vector2(0, 0);
switch(action) {
case (int)Actions.IDLE:
break;
case (int)Actions.UP:
move = new Vector2(0, 1);
break;
case (int)Actions.LEFT:
move = new Vector2(-1, 0);
break;
case (int)Actions.DOWN:
move = new Vector2(0, -1);
break;
case (int)Actions.RIGHT:
move = new Vector2(1, 0);
break;
default:
Debug.Log("Unkonwn action.");
break;
}
return move;
}
public void TaskOnClick() {
int act = agent.Think(gameState);
Play(gameState, act, out gameState); // update game state
Render(); // update rendering
}
public static Cell Play(IState iState, int action, out IState newIState) {
// execute action
State state = (State) iState;
Vector2 move = PlayAction(action);
Vector2 tmp = state.player + move;
// Mais a jour les boites, si une a été bougé
List<Vector2> tmpBoxes = new List<Vector2>(state.boxes);
for (int i = 0; i < tmpBoxes.Count; i++) {
if (tmp == tmpBoxes[i]) {
tmpBoxes[i] += move;
}
}
// define the new state
newIState = new State(tmp, tmpBoxes);
if (((State) newIState).IsFinal) {
return new Cell { value = 1000 };
}
return new Cell { value = -1 };
}
protected void Render() {
Camera.main.transform.position = new Vector3(level.WIDTH / 2, level.HEIGHT / 2, -10);
RL.instance.goPlayer.transform.position = ((State) gameState).player;
for(int y = 0; y < level.HEIGHT; y++) {
for(int x = 0; x < level.WIDTH; x++) {
Vector2 pos = new Vector2(x, y);
Color color = new Color(1, 1, 1);
if (level.walls.Contains(pos)) color = new Color(0, 0, 0);
if (level.goals.Contains(pos)) color = new Color(1, 0, 0);
if (((State) gameState).boxes.Contains(pos)) color = new Color(0.59f, 0.29f, 0.00f);
Utils.Render.SpawnTile(x, y, RL.instance.tileSprite, color);
}
}
}
}
}