Skip to content

Commit 05eb9ee

Browse files
authored
integrate editor
1 parent 3358fe2 commit 05eb9ee

File tree

9 files changed

+122
-82
lines changed

9 files changed

+122
-82
lines changed

editor.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ function Editor (mapStr) {
2929
}
3030

3131
Editor.isValid = function (map) {
32+
//Checks for external data only
3233
map = map.split('\n');
34+
//height
3335
if (map.length > 10) {
3436
return false;
3537
}
38+
//width
3639
if (map[0].length === 0 || map[0].length > 10) {
3740
return false;
3841
}
@@ -44,13 +47,27 @@ Editor.isValid = function (map) {
4447
return false;
4548
}
4649
map = map.join('');
50+
//only allowed elements
4751
if (/[^a-eA-Ev<>^# ]/.test(map)) {
4852
return false;
4953
}
54+
//Checks for both internal and external data
55+
//exactly one starting point
5056
if (map.replace(/[^v<>^]/g, '').length !== 1) {
5157
return false;
5258
}
53-
//TODO
59+
//at least one item
60+
if (!/[a-e]/.test(map)) {
61+
return false;
62+
}
63+
//items and targets match
64+
if (
65+
map.replace(/[^a-e]/g, '').split('').sort().join('') !==
66+
map.replace(/[^A-E]/g, '').split('').sort().join('').toLowerCase()
67+
) {
68+
return false;
69+
}
70+
//accept anything else (even if it might be unsolvable)
5471
return true;
5572
};
5673

@@ -79,7 +96,7 @@ Editor.prototype.show = function (level) {
7996
Editor.prototype.hide = function () {
8097
this.unbind();
8198
this.editorArea.hidden = true;
82-
this.runArea.hidden = true;
99+
this.runArea.hidden = false;
83100
};
84101

85102
Editor.prototype.getStr = function () {

game.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
var codeInput, editor, soundCheckbox, levels;
1+
var codeInput, editor, soundCheckbox, levels, bonus;
22

33
codeInput = new CodeInput();
4-
editor = new Editor(' ');
54

65
soundCheckbox = document.getElementById('sound-checkbox');
76

@@ -29,16 +28,22 @@ levels = [
2928
]}
3029
];
3130

32-
/*
31+
3332
if (location.hash) {
34-
levels.push({
33+
bonus = decodeURIComponent(location.hash.slice(1));
34+
if (!Editor.isValid(bonus)) {
35+
bonus = false;
36+
}
37+
}
38+
39+
if (bonus) {
40+
levels.splice(-1, 0, {
3541
title: 'Bonus', levels: [
36-
{title: 'Bonus', map: decodeURIComponent(location.hash.slice(1))} //TODO
42+
{title: 'Bonus', map: bonus}
3743
]
3844
});
3945
}
40-
*/
41-
46+
editor = new Editor(bonus || ' ');
4247
levels = new LevelCollection(levels);
4348

4449
levels.init();

index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,14 @@ <h1 id="title"></h1>
124124
<div id="level-menu">
125125
</div>
126126
<div id="level-wrapper" hidden>
127-
<div id="map"></div>
128127
<div id="editor-area" hidden>
128+
Size: <input id="width-input" type="number" min="1" max="10">x<input id="height-input" type="number" min="1" max="10">
129129
<div id="radio-input"></div>
130130
<button id="done-button">Run level</button>
131-
<input id="width-input" type="number" min="1" max="10">x<input id="height-input" type="number" min="1" max="10">
132131
</div>
132+
<div id="map"></div>
133133
<div id="run-area">
134134
<div id="code"></div>
135-
<div id="error"></div>
136135
<button id="insert-go" data-key="_" class="button"></button>
137136
<button id="insert-left" data-key="&lt;" class="button"></button>
138137
<button id="insert-right" data-key="&gt;" class="button"></button>
@@ -150,6 +149,7 @@ <h1 id="title"></h1>
150149
<button id="cancel-button" class="button"><svg class="cancel"><use xlink:href="#cancel"/></svg></button>
151150
<button id="reset-button" class="button"><svg class="reset"><use xlink:href="#reset"/></svg></button>
152151
<input id="pause-input" type="range" min="0" max="10" value="3">
152+
<div id="error"></div>
153153
</div>
154154
</div>
155155
<footer>

info.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var info, data = [
2-
'<p>Welcome! Your task is to programm a robot to run offline. You enter the code, and once you start the bot, you can no longer change it. You have to collect some items and drop them in special places.</p>',
3-
'<p>Use the virtual keyboard to enter the code for the bot. You have to ' + display.symbol('code-up') + ' take the item, ' + display.symbol('code-go') + ' advance one step, and ' + display.symbol('code-down') + ' drop it.</p><p>Then ' + display.symbol('go') + ' run the code. If the bot crashes, you have to ' + display.symbol('reset') + ' reset it. Use the slider to regulate its speed.</p>',
4-
'<p>You can also turn the bot and repeat parts of the code. For example ' + display.symbol('code-4') + display.symbol('code-right') + display.symbol('code-repeat') + ' will turn the bot four times clockwise, after which everything will be the same. To enter this code, use the ' + display.symbol('code-repeat') + ' key, increment using the + key, and insert the code to repeat in the middle.</p>',
2+
'<p>Welcome! Your task is to programm a robot to run <b>offline</b>. You enter the code, and once you start the bot, you can no longer change it. You have to collect some items and drop them in special places.</p>',
3+
'<p>Use the virtual keyboard to enter the code for the bot. You have to <kbd>' + display.symbol('code-up') + '</kbd> take the item, <kbd>' + display.symbol('code-go') + '</kbd> advance one step, and <kbd>' + display.symbol('code-down') + '</kbd> drop it.</p><p>Then <kbd>' + display.symbol('go') + '</kbd> run the code. If the bot crashes, you have to <kbd>' + display.symbol('reset') + '</kbd> reset it. Use the slider to regulate its speed.</p>',
4+
'<p>You can also turn the bot and repeat parts of the code. For example <kbd>' + display.symbol('code-4') + display.symbol('code-right') + display.symbol('code-repeat') + '</kbd> will turn the bot four times clockwise, after which everything will be the same. To enter this code, use the <kbd>' + display.symbol('code-repeat') + '</kbd> key, increment using the <kbd>' + display.symbol('plus') + '</kbd> key, and insert the code to repeat in the middle (use <kbd>' + display.symbol('left') + display.symbol('right') + '</kbd> to move the cursor).</p>',
55
'This time, you have two items and two targets. Note that the bot can only carry one item at a time.</p>'
66
];
77

level-collection.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ LevelCollection.prototype.buildMenu = function () {
6666
}
6767
return '<h2>' + group.title + '</h2>' + group.levels.map(function (level, j) {
6868
var best, symbol, id;
69-
if (group.editor) {
69+
if (!level.map) {
7070
symbol = '';
7171
} else if (solved < level.req || 0) {
7272
symbol = 'lock';
@@ -88,7 +88,7 @@ LevelCollection.prototype.buildMenu = function () {
8888
if (symbol === 'lock') {
8989
id = 'disabled';
9090
} else {
91-
id = group.editor ? 'data-id="editor"' : 'data-id="' + i + '|' + j + '"';
91+
id = level.map ? 'data-id="' + i + '|' + j + '"' : 'data-id="editor"';
9292
}
9393
return '<button ' + id + '>' + level.title + (symbol ? ' ' + display.symbol(symbol) : '') + '</button>';
9494
}.bind(this)).join('');
@@ -133,10 +133,16 @@ LevelCollection.prototype.showEditor = function () {
133133
var level = new Level(false, false, function (result, callback) {
134134
callback();
135135
if (result !== -1) {
136-
//TODO
137136
console.log(JSON.stringify(result));
138-
this.show();
137+
location = '#' + encodeURIComponent(result);
138+
this.levelGroups[this.levelGroups.length - 1].levels[1] = {
139+
title: 'New level',
140+
map: result,
141+
hash: generateHash(result)
142+
};
143+
this.buildMenu();
139144
}
145+
this.show();
140146
}.bind(this));
141147
this.menuArea.hidden = true;
142148
level.showEditor();

level.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Level.prototype.onStart = function () {
7171
this.resetButton.disabled = false;
7272
this.abortButton.disabled = false;
7373
if (done) {
74-
this.end(input.length); //TODO
74+
this.end(input.length);
7575
}
7676
}.bind(this));
7777
this.onUpdatePause();

map.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Map.prototype.setType = function (x, y, type) {
2222
};
2323

2424
Map.prototype.allDone = function () {
25-
return !/[A-Z]/.test(this.grid.map(function (line) {
25+
return !/[A-E]/.test(this.grid.map(function (line) {
2626
return line.join('');
2727
}).join(''));
2828
};

robot.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Robot.prototype.take = function () {
4848
}
4949
pos = this.getNextPos();
5050
type = this.map.getType(pos[0], pos[1]);
51-
if (['a', 'b', 'c'].indexOf(type) === -1) {
51+
if (['a', 'b', 'c', 'd', 'e'].indexOf(type) === -1) {
5252
throw new Error('Nothing to take!');
5353
}
5454
this.item = type;
@@ -63,12 +63,12 @@ Robot.prototype.drop = function () {
6363
}
6464
pos = this.getNextPos();
6565
type = this.map.getType(pos[0], pos[1]);
66-
if (type !== this.item.toUpperCase()) {
66+
if (type !== ' ' && type !== this.item.toUpperCase()) {
6767
throw new Error('Can\'t drop it here!');
6868
}
69+
this.map.setType(pos[0], pos[1], type === ' ' ? this.item : '*');
6970
this.item = '';
70-
this.map.setType(pos[0], pos[1], '*');
71-
sound.play('drop');
71+
sound.play(type === ' ' ? 'drop' : 'drop-final');
7272
};
7373

7474
Robot.prototype.step = function () {

style.css

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
1+
/*General*/
12
html,
23
body {
34
font-family: sans-serif;
45
margin: 0;
56
padding: 0;
67
}
78

9+
#wrapper {
10+
min-width: 20rem;
11+
max-width: 45rem;
12+
margin: auto;
13+
}
14+
15+
header {
16+
background-color: #48a;
17+
color: white;
18+
height: 3rem;
19+
}
20+
21+
header button {
22+
float: left;
23+
}
24+
25+
header h1 {
26+
margin: 0 3rem;
27+
font-size: 150%;
28+
line-height: 2;
29+
}
30+
31+
header > span {
32+
float: right;
33+
padding-right: 1em;
34+
}
35+
36+
#sound-checkbox {
37+
display: none;
38+
}
39+
40+
#sound-checkbox:checked ~ label .off {
41+
display: none;
42+
}
43+
44+
#sound-checkbox:not(:checked) ~ label .on {
45+
display: none;
46+
}
47+
48+
#level-menu,
49+
#level-wrapper {
50+
margin: 0.5rem;
51+
}
52+
53+
/*SVG*/
854
svg {
955
width: 1.5rem;
1056
height: 1.5rem;
@@ -47,6 +93,7 @@ svg.code-down {
4793
color: blue;
4894
}
4995

96+
/*Buttons*/
5097
.button:not([hidden]) {
5198
display: inline-block;
5299
border: thin solid;
@@ -69,67 +116,14 @@ svg.code-down {
69116
color: #aaa;
70117
}
71118

72-
#pause-input {
73-
display: inline-block;
74-
margin: 0.05em;
75-
height: 3rem;
76-
width: 6.1rem;
77-
-moz-box-sizing: border-box;
78-
box-sizing: border-box;
79-
vertical-align: top;
80-
}
81-
82-
#wrapper {
83-
min-width: 20rem;
84-
max-width: 45rem;
85-
margin: auto;
86-
}
87-
88-
header {
89-
background-color: #48a;
90-
color: white;
91-
height: 3rem;
92-
}
93-
94119
header .button:not([hidden]) {
95120
border: none;
96121
margin: 0;
97122
background-color: transparent;
98123
color: #fff;
99124
}
100125

101-
header button {
102-
float: left;
103-
}
104-
105-
header h1 {
106-
margin: 0 3rem;
107-
font-size: 150%;
108-
line-height: 2;
109-
}
110-
111-
header > span {
112-
float: right;
113-
padding-right: 1em;
114-
}
115-
116-
#sound-checkbox {
117-
display: none;
118-
}
119-
120-
#sound-checkbox:checked ~ label .off {
121-
display: none;
122-
}
123-
124-
#sound-checkbox:not(:checked) ~ label .on {
125-
display: none;
126-
}
127-
128-
#level-menu,
129-
#level-wrapper {
130-
margin: 0.5rem;
131-
}
132-
126+
/*Level Selection*/
133127
#level-menu button {
134128
font-weight: bold;
135129
margin: 0.5rem;
@@ -155,6 +149,7 @@ header > span {
155149
right: 0;
156150
}
157151

152+
/*Level Screen*/
158153
#map table {
159154
margin: auto;
160155
border-collapse: collapse;
@@ -180,11 +175,22 @@ header > span {
180175
color: red;
181176
}
182177

183-
footer {
184-
background-color: black;
185-
color: white;
178+
#pause-input {
179+
display: inline-block;
180+
margin: 0.05em;
181+
height: 3rem;
182+
width: 6.1rem;
183+
-moz-box-sizing: border-box;
184+
box-sizing: border-box;
185+
vertical-align: top;
186186
}
187187

188+
/*Level Editor*/
189+
input[type="number"] {
190+
width: 2em;
191+
}
192+
193+
/*Infobox*/
188194
#overlay {
189195
background: rgba(100, 100, 100, .5);
190196
position: fixed;
@@ -224,4 +230,10 @@ footer {
224230

225231
#info-box {
226232
padding: 0.5em;
233+
}
234+
235+
/*Temporary*/
236+
footer {
237+
background-color: black;
238+
color: white;
227239
}

0 commit comments

Comments
 (0)