-
Notifications
You must be signed in to change notification settings - Fork 0
/
arduino_markov.ino
123 lines (103 loc) · 2.5 KB
/
arduino_markov.ino
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
#include <IRremote.h>
#include "Move.h"
#include "Track.h"
#include "Markov.h"
#define ACTION_DURATION 200
#define ACTIONS_SIZE 25
#define IR_RECV 12
#define KEY_OK 16712445
#define KEY_UP 16736925
#define KEY_DOWN 16754775
#define KEY_STAR 16728765
#define KEY_HASH 16732845
#define KEY_0 16730805
struct Action {
Markov::State state;
Move::Command move;
};
IRrecv irRecv(IR_RECV);
decode_results irInput;
unsigned long irValue;
unsigned long time;
bool paused = true;
Markov::Process m;
Track::Input prevTrack;
Action actions[ACTIONS_SIZE];
int actionsIndex = 0;
int actionsLength = 0;
void setup() {
Serial.begin(9600);
irRecv.enableIRIn();
m.load();
Track::setup();
Move::setup();
randomSeed(analogRead(0));
}
void loop() {
if (irRecv.decode(&irInput)) {
irValue = irInput.value;
irRecv.resume();
switch (irValue) {
case KEY_OK:
paused = !paused;
if (paused) {
Move::stop();
clearActions();
} else {
nextAction();
}
break;
case KEY_STAR:
m.save();
break;
case KEY_HASH:
m.clear();
break;
case KEY_UP:
rewardActions();
break;
case KEY_DOWN:
punishActions();
break;
case KEY_0:
m.print();
break;
}
}
if (!paused && (millis() - time > ACTION_DURATION)) {
nextAction();
}
}
void nextAction() {
time = millis();
Action a;
if (actionsLength == 0) {
a.state.track0 = a.state.track1 = prevTrack = Track::track();
} else {
a.state.track1 = prevTrack;
a.state.track0 = prevTrack = Track::track();
}
a.move = m.get(a.state);
Move::move(a.move);
actions[actionsIndex] = a;
actionsIndex = (actionsIndex + 1) % ACTIONS_SIZE;
actionsLength = min(actionsLength + 1, ACTIONS_SIZE);
}
void rewardActions() {
for (int i = 0; i < actionsLength; i++) {
Action action = actions[i];
m.loss(action.state, action.move, actionsLength - i);
}
clearActions();
}
void punishActions() {
for (int i = 0; i < actionsLength; i++) {
Action action = actions[i];
m.loss(action.state, action.move, i - actionsLength);
}
clearActions();
}
void clearActions() {
actionsIndex = 0;
actionsLength = 0;
}