monkeymusic 0.0.14 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +0 -1
- data/README.md +166 -177
- data/demo_players/java/DemoPlayer.java +250 -0
- data/demo_players/java/install +2 -0
- data/demo_players/java/runme +2 -0
- data/demo_players/python/install +2 -0
- data/demo_players/python/monkey.py +111 -0
- data/demo_players/python/runme +2 -0
- data/demo_players/python/state.pickle +0 -0
- data/demo_players/python/util.py +29 -0
- data/demo_players/python/util.pyc +0 -0
- data/{demo_player → demo_players/ruby/demo_player.rb} +3 -2
- data/levels/demo_level.rb +1 -0
- data/levels/maze.rb +20 -0
- data/levels/metadata.rb +17 -0
- data/levels/walls.rb +20 -0
- data/lib/monkey_music/game.rb +1 -2
- data/lib/monkey_music/level.rb +2 -9
- data/lib/monkey_music/level_loader.rb +4 -0
- data/lib/monkey_music/player.rb +8 -6
- data/lib/monkey_music/runner.rb +15 -12
- data/lib/monkey_music/ui/browser.rb +26 -17
- data/lib/monkey_music/ui/console.rb +13 -15
- data/lib/monkey_music_generate/runner.rb +2 -3
- data/lib/monkey_music_generate/score_system.rb +2 -0
- data/users/demo_user.yaml +250 -250
- metadata +15 -11
- data/levels/testlevel.rb +0 -29
- data/levels/testlevel_maze.rb +0 -24
- data/levels/testmaze_10.rb +0 -38
- data/levels/testmaze_20.rb +0 -38
- data/levels/testmaze_30.rb +0 -38
- data/levels/the_last_crusade.rb +0 -21
- data/levels/travelling_salesmonkeys.rb +0 -0
- data/users/synth.rb +0 -11
@@ -0,0 +1,250 @@
|
|
1
|
+
import java.util.Set;
|
2
|
+
import java.util.List;
|
3
|
+
import java.util.Map;
|
4
|
+
import java.util.HashSet;
|
5
|
+
import java.util.HashMap;
|
6
|
+
import java.util.ArrayList;
|
7
|
+
import java.util.Scanner;
|
8
|
+
import java.io.Serializable;
|
9
|
+
import java.io.ObjectOutputStream;
|
10
|
+
import java.io.FileOutputStream;
|
11
|
+
import java.io.ObjectInputStream;
|
12
|
+
import java.io.FileInputStream;
|
13
|
+
|
14
|
+
public class DemoPlayer {
|
15
|
+
public static void main(String[] args) throws Exception {
|
16
|
+
Scanner sc = new Scanner(System.in);
|
17
|
+
String roundType = sc.nextLine();
|
18
|
+
String id = sc.nextLine();
|
19
|
+
Monkey monkey;
|
20
|
+
if (roundType.equals("INIT")) {
|
21
|
+
monkey = new Monkey(id);
|
22
|
+
monkey.init(sc);
|
23
|
+
} else {
|
24
|
+
monkey = Monkey.readFromCache(id);
|
25
|
+
monkey.turn(sc);
|
26
|
+
}
|
27
|
+
sc.close();
|
28
|
+
monkey.writeToCache();
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
class Monkey implements Serializable {
|
33
|
+
public static final long serialVersionUID = 0;
|
34
|
+
|
35
|
+
static final String CACHE_PREFIX = "cache_";
|
36
|
+
|
37
|
+
final String id;
|
38
|
+
// Position
|
39
|
+
int x, y;
|
40
|
+
// Toplists
|
41
|
+
int topDecade;
|
42
|
+
Set<String> topTracks = new HashSet<String>(),
|
43
|
+
topAlbums = new HashSet<String>(),
|
44
|
+
topArtists = new HashSet<String>(),
|
45
|
+
dislikedArtists = new HashSet<String>();
|
46
|
+
// URI dictionary
|
47
|
+
Map<String, Track> knownURIs = new HashMap<String, Track>();
|
48
|
+
// Tracks
|
49
|
+
List<Track> unknownTracks;
|
50
|
+
List<Track> knownTracks;
|
51
|
+
int turn, turnLimit;
|
52
|
+
int width, height;
|
53
|
+
int remainingCapacity, remainingExecutionTime, boostCooldown;
|
54
|
+
String[][] level;
|
55
|
+
|
56
|
+
Monkey(String id) {
|
57
|
+
this.id = id;
|
58
|
+
}
|
59
|
+
|
60
|
+
void init(Scanner sc) {
|
61
|
+
parseInit(sc);
|
62
|
+
parseToplists(sc);
|
63
|
+
}
|
64
|
+
|
65
|
+
void turn(Scanner sc) {
|
66
|
+
parseTurn(sc);
|
67
|
+
parseMetadata(sc);
|
68
|
+
parseLevel(sc);
|
69
|
+
}
|
70
|
+
|
71
|
+
void parseInit(Scanner sc) {
|
72
|
+
width = sc.nextInt();
|
73
|
+
height = sc.nextInt();
|
74
|
+
turnLimit = sc.nextInt();
|
75
|
+
level = new String[width][height];
|
76
|
+
}
|
77
|
+
|
78
|
+
void parseToplists(Scanner sc) {
|
79
|
+
List<Integer> decades = new ArrayList<Integer>();
|
80
|
+
// Top tracks
|
81
|
+
int numTracks = sc.nextInt();
|
82
|
+
sc.nextLine();
|
83
|
+
for (int i = 0; i < numTracks; i++) {
|
84
|
+
String entry = sc.nextLine();
|
85
|
+
// 0:[track],1:[album],2:[artist],3:[year]
|
86
|
+
String[] parts = entry.split(",");
|
87
|
+
topTracks.add(parts[0]);
|
88
|
+
int decade = Util.toDecade(Integer.parseInt(parts[3]));
|
89
|
+
decades.add(decade);
|
90
|
+
}
|
91
|
+
// Top albums
|
92
|
+
int numAlbums = sc.nextInt();
|
93
|
+
sc.nextLine();
|
94
|
+
for (int i = 0; i < numAlbums; i++) {
|
95
|
+
String entry = sc.nextLine();
|
96
|
+
// 0:[album],1:[artist],2:[year]
|
97
|
+
String[] parts = entry.split(",");
|
98
|
+
topAlbums.add(parts[0]);
|
99
|
+
int decade = Util.toDecade(Integer.parseInt(parts[2]));
|
100
|
+
decades.add(decade);
|
101
|
+
}
|
102
|
+
// Top decade
|
103
|
+
topDecade = Util.getPopularElement(
|
104
|
+
decades.toArray(new Integer[decades.size()]));
|
105
|
+
// Top artists
|
106
|
+
int numArtists = sc.nextInt();
|
107
|
+
sc.nextLine();
|
108
|
+
for (int i = 0; i < numArtists; i++) {
|
109
|
+
// 0:[artist]
|
110
|
+
String entry = sc.nextLine();
|
111
|
+
topArtists.add(entry);
|
112
|
+
}
|
113
|
+
// Disliked artists
|
114
|
+
int numDislikedArtists = sc.nextInt();
|
115
|
+
sc.nextLine();
|
116
|
+
for (int i = 0; i < numDislikedArtists; i++) {
|
117
|
+
// 0:[artist]
|
118
|
+
String entry = sc.nextLine();
|
119
|
+
dislikedArtists.add(entry);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
void parseTurn(Scanner sc) {
|
124
|
+
turn = sc.nextInt();
|
125
|
+
remainingCapacity = sc.nextInt();
|
126
|
+
remainingExecutionTime = sc.nextInt();
|
127
|
+
boostCooldown = sc.nextInt();
|
128
|
+
}
|
129
|
+
|
130
|
+
void parseMetadata(Scanner sc) {
|
131
|
+
int numResults = sc.nextInt();
|
132
|
+
sc.nextLine();
|
133
|
+
for (int i = 0; i < numResults; i++) {
|
134
|
+
String metadata = sc.nextLine();
|
135
|
+
Track knownTrack = Track.fromMetadata(metadata);
|
136
|
+
// 0:[uri],1:[[track],[album],[artist],[year]]
|
137
|
+
String[] parts = metadata.split(",", 1);
|
138
|
+
knownURIs.put(parts[0], knownTrack);
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
void parseLevel(Scanner sc) {
|
143
|
+
unknownTracks = new ArrayList<Track>();
|
144
|
+
knownTracks = new ArrayList<Track>();
|
145
|
+
for (int y = 0; y < height; y++) {
|
146
|
+
String row = sc.nextLine();
|
147
|
+
String[] cells = row.split(",");
|
148
|
+
for (int x = 0; x < width; x++) {
|
149
|
+
level[x][y] = cells[x];
|
150
|
+
if (Util.isURI(cells[x])) {
|
151
|
+
String uri = cells[x];
|
152
|
+
if (!knownURIs.containsKey(uri)) {
|
153
|
+
unknownTracks.add(new Track(uri).place(x, y));
|
154
|
+
} else {
|
155
|
+
knownTracks.add(knownURIs.get(uri).copy().place(x, y));
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
void writeToCache() throws Exception {
|
163
|
+
ObjectOutputStream out =
|
164
|
+
new ObjectOutputStream(new FileOutputStream(CACHE_PREFIX + id));
|
165
|
+
out.writeObject(this);
|
166
|
+
out.close();
|
167
|
+
}
|
168
|
+
|
169
|
+
static Monkey readFromCache(String id) throws Exception {
|
170
|
+
ObjectInputStream in =
|
171
|
+
new ObjectInputStream(new FileInputStream(CACHE_PREFIX + id));
|
172
|
+
Monkey monkey = (Monkey) in.readObject();
|
173
|
+
in.close();
|
174
|
+
return monkey;
|
175
|
+
}
|
176
|
+
|
177
|
+
}
|
178
|
+
|
179
|
+
class Track implements Cloneable, Serializable {
|
180
|
+
public static final long serialVersionUID = 0;
|
181
|
+
|
182
|
+
String uri, name, album, artist, year;
|
183
|
+
int x, y;
|
184
|
+
int value;
|
185
|
+
|
186
|
+
Track (String uri) {
|
187
|
+
this.uri = uri;
|
188
|
+
}
|
189
|
+
|
190
|
+
static Track fromMetadata(String metadata) {
|
191
|
+
// 0:[uri],1:[name],2:[album],3:[artist],4:[year]
|
192
|
+
String[] parts = metadata.split(",");
|
193
|
+
Track track = new Track(parts[0]);
|
194
|
+
track.name = parts[1];
|
195
|
+
track.album = parts[2];
|
196
|
+
track.artist = parts[3];
|
197
|
+
track.year = parts[4];
|
198
|
+
return track;
|
199
|
+
}
|
200
|
+
|
201
|
+
Track place(int x, int y) {
|
202
|
+
this.x = x;
|
203
|
+
this.y = y;
|
204
|
+
return this;
|
205
|
+
}
|
206
|
+
|
207
|
+
Track copy() {
|
208
|
+
Track copy = new Track(uri);
|
209
|
+
copy.name = name;
|
210
|
+
copy.album = album;
|
211
|
+
copy.artist = artist;
|
212
|
+
copy.year = year;
|
213
|
+
copy.value = value;
|
214
|
+
return copy;
|
215
|
+
}
|
216
|
+
|
217
|
+
@Override public int hashCode() { return uri.hashCode(); }
|
218
|
+
}
|
219
|
+
|
220
|
+
class Util {
|
221
|
+
/**
|
222
|
+
* http://stackoverflow.com/questions/8545590/java-find-the-most-popular-element-in-int-array
|
223
|
+
*/
|
224
|
+
static int getPopularElement(Integer[] a) {
|
225
|
+
int count = 1, tempCount;
|
226
|
+
int popular = a[0];
|
227
|
+
int temp = 0;
|
228
|
+
for (int i = 0; i < (a.length - 1); i++) {
|
229
|
+
temp = a[i];
|
230
|
+
tempCount = 0;
|
231
|
+
for (int j = 1; j < a.length; j++) {
|
232
|
+
if (temp == a[j])
|
233
|
+
tempCount++;
|
234
|
+
}
|
235
|
+
if (tempCount > count) {
|
236
|
+
popular = temp;
|
237
|
+
count = tempCount;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
return popular;
|
241
|
+
}
|
242
|
+
|
243
|
+
static int toDecade(int year) {
|
244
|
+
return (year % 100) / 10;
|
245
|
+
}
|
246
|
+
|
247
|
+
static boolean isURI(String s) {
|
248
|
+
return s.length() == 36 && s.substring(0, 14).equals("spotify:track:");
|
249
|
+
}
|
250
|
+
}
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import logging
|
2
|
+
import os.path
|
3
|
+
import pickle
|
4
|
+
import sys
|
5
|
+
|
6
|
+
import util
|
7
|
+
|
8
|
+
STATE_FILENAME = 'state.pickle'
|
9
|
+
TRACK_URI_HEADER = 'spotify:track:'
|
10
|
+
|
11
|
+
class Monkey(object):
|
12
|
+
def __init__(self):
|
13
|
+
self._id = 0
|
14
|
+
self._w = 0
|
15
|
+
self._h = 0
|
16
|
+
self._turn_limit = 0
|
17
|
+
self._turn = 0
|
18
|
+
self._capacity = 0
|
19
|
+
self._time_left = 0
|
20
|
+
self._top_tracks = None
|
21
|
+
self._top_albums = None
|
22
|
+
self._top_artists = None
|
23
|
+
self._bad_artists = None
|
24
|
+
self._bad_tracks = set()
|
25
|
+
self._map = {}
|
26
|
+
self._pos = None
|
27
|
+
self._user = None
|
28
|
+
self._boost_cooldown = 0
|
29
|
+
self._track_pos = {} # pos -> uri
|
30
|
+
self._metadata = {} # uri -> metadata
|
31
|
+
self._objective = None
|
32
|
+
|
33
|
+
@classmethod
|
34
|
+
def process_input(cls, stream):
|
35
|
+
monkey = None
|
36
|
+
line = stream.readline().strip()
|
37
|
+
if line == 'INIT':
|
38
|
+
logging.basicConfig(filename='monkey.log', filemode='w', level=logging.DEBUG)
|
39
|
+
monkey = cls()
|
40
|
+
monkey.initialize(stream)
|
41
|
+
else:
|
42
|
+
logging.basicConfig(filename='monkey.log', filemode='a', level=logging.DEBUG)
|
43
|
+
monkey = cls.load()
|
44
|
+
monkey.update(stream)
|
45
|
+
return monkey
|
46
|
+
|
47
|
+
def initialize(self, stream):
|
48
|
+
self._id = stream.readline().strip()
|
49
|
+
self._w = util.get_int(stream)
|
50
|
+
self._h = util.get_int(stream)
|
51
|
+
self._turn_limit = util.get_int(stream)
|
52
|
+
self._top_tracks = util.get_set(stream)
|
53
|
+
self._top_albums = util.get_set(stream)
|
54
|
+
self._top_artists = util.get_set(stream)
|
55
|
+
self._bad_artists = util.get_set(stream)
|
56
|
+
|
57
|
+
def update(self, stream):
|
58
|
+
self._id = stream.readline().strip()
|
59
|
+
self._turn = util.get_int(stream)
|
60
|
+
self._capacity = util.get_int(stream)
|
61
|
+
self._time_left = util.get_int(stream)
|
62
|
+
self._boost_cooldown = util.get_int(stream)
|
63
|
+
self._track_pos = {}
|
64
|
+
self.browse_result(sys.stdin)
|
65
|
+
for y in xrange(self._h):
|
66
|
+
line = stream.readline().strip()
|
67
|
+
for x, square in enumerate(line.split(',')):
|
68
|
+
|
69
|
+
self._map[x, y] = square
|
70
|
+
if square == self._id:
|
71
|
+
self._pos = (x, y)
|
72
|
+
elif square == 'U':
|
73
|
+
self._user = (x, y)
|
74
|
+
elif square.startswith(TRACK_URI_HEADER):
|
75
|
+
self._track_pos[x, y] = square
|
76
|
+
try:
|
77
|
+
metadata = self._metadata[square]
|
78
|
+
self._map[x, y] = '+' if self.track_value(metadata) > 0 else '-'
|
79
|
+
except KeyError:
|
80
|
+
self._map[x, y] = '?'
|
81
|
+
|
82
|
+
def action(self):
|
83
|
+
if self._turn >= 1:
|
84
|
+
print 'W'
|
85
|
+
|
86
|
+
def browse_result(self, stream):
|
87
|
+
browsed_tracks = util.get_set(sys.stdin)
|
88
|
+
for track in browsed_tracks:
|
89
|
+
logging.debug('[%d] Browsed track: %s', self._turn, track)
|
90
|
+
uri, metadata = track.split(',', 1)
|
91
|
+
self._metadata[uri] = metadata
|
92
|
+
|
93
|
+
def save(self):
|
94
|
+
with open(self.save_path(), 'wb') as f:
|
95
|
+
pickle.dump(self, f, pickle.HIGHEST_PROTOCOL)
|
96
|
+
|
97
|
+
@classmethod
|
98
|
+
def load(cls):
|
99
|
+
with open(cls.save_path(), 'rb') as f:
|
100
|
+
return pickle.load(f)
|
101
|
+
|
102
|
+
@classmethod
|
103
|
+
def save_path(cls):
|
104
|
+
dir_path = os.path.dirname(__file__)
|
105
|
+
return os.path.join(dir_path, STATE_FILENAME)
|
106
|
+
|
107
|
+
if __name__ == '__main__':
|
108
|
+
monkey = Monkey.process_input(sys.stdin)
|
109
|
+
monkey.action()
|
110
|
+
monkey.save()
|
111
|
+
sys.stdout.flush()
|
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
INTEGER = re.compile(r'(\d+).*')
|
4
|
+
|
5
|
+
D_POS = {'W': (-1, 0), 'N': (0, -1), 'E': (1, 0), 'S': (0, 1)}
|
6
|
+
MOVES = dict([(v, k) for k, v in D_POS.iteritems()])
|
7
|
+
|
8
|
+
def distance(p0, p1):
|
9
|
+
return abs(p0[0] - p1[0]) + abs(p0[1] - p1[1])
|
10
|
+
|
11
|
+
def move(p_from, p_to):
|
12
|
+
dx = p_to[0] - p_from[0]
|
13
|
+
dy = p_to[1] - p_from[1]
|
14
|
+
return MOVES[dx, dy]
|
15
|
+
|
16
|
+
def follow_path(self, path):
|
17
|
+
return move(path[0], path[1])
|
18
|
+
|
19
|
+
def get_int(stream):
|
20
|
+
line = stream.readline().strip()
|
21
|
+
match = INTEGER.match(line)
|
22
|
+
return int(match.group(1))
|
23
|
+
|
24
|
+
def get_set(stream):
|
25
|
+
s = set()
|
26
|
+
size = get_int(stream)
|
27
|
+
for ix in xrange(size):
|
28
|
+
s.add(stream.readline().strip())
|
29
|
+
return s
|
Binary file
|
@@ -61,12 +61,13 @@ class DemoPlayer
|
|
61
61
|
@turn = Integer($stdin.gets.chomp)
|
62
62
|
@remaining_capacity = Integer($stdin.gets.chomp)
|
63
63
|
@remaining_time = Integer($stdin.gets.chomp)
|
64
|
+
@boost_cooldown = Integer($stdin.gets.chomp)
|
64
65
|
# Read metadata query responses
|
65
66
|
num_responses = Integer($stdin.gets.chomp)
|
66
67
|
num_responses.times do
|
67
68
|
response = $stdin.gets.chomp.split(",")
|
68
69
|
uri = response.unshift
|
69
|
-
@known_tracks[uri]
|
70
|
+
@known_tracks[uri] = response
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
@@ -76,7 +77,7 @@ class DemoPlayer
|
|
76
77
|
row = $stdin.gets.chomp.split(',')
|
77
78
|
@width.times do |x|
|
78
79
|
case row[x]
|
79
|
-
when
|
80
|
+
when @id then @x, @y = x, y
|
80
81
|
when /spotify:track/ then @track_positions << [x, y]
|
81
82
|
when "U" then @user_position = [x, y]
|
82
83
|
end
|