codenjoy-client 0.1.002 → 0.1.003
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +8 -4
- data/lib/codenjoy/client/version.rb +1 -1
- data/lib/codenjoy/game_base_client.rb +2 -1
- data/lib/codenjoy/games/battlecity/board.rb +174 -222
- data/lib/codenjoy/games/tetris/board.rb +265 -0
- data/lib/codenjoy/utils.rb +47 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f6e2b556f20d5339438bcc59a9669cfa865fda7ead39b17a4f0dcdbe5565882
|
4
|
+
data.tar.gz: 425311003e3a408417152608e497aa0ac3000a69dceaca9dfb80a57878b9e03c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97033b697c2ff85718b30178e1876b2e2a2bfacccd4d4dd9af3fd023fff7dc6942155e92e080afbe7d4c34fe30ee7433c4c21d17a604b620318875931086ad83
|
7
|
+
data.tar.gz: 04c31405fcaea56dd5732afff1396e00addd9c92ddc633bc6bbbbf40061e92d742f1e49feb4a43f5af1fa9d2a0fb9c33b62ff6bf1a908add579b1348cd77ac5b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Codenjoy::Client
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
This is ruby client for https://github.com/codenjoyme/codenjoy project. It uses for playing dojorena.io.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,7 +20,11 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
After you install gem, you can create base client:
|
24
|
+
|
25
|
+
$ codenjoy-ruby-client
|
26
|
+
|
27
|
+
The file `game_base_client.rb` created at current folder. You should replace `url` and write your own code at `YourSolver` class.
|
26
28
|
|
27
29
|
## Development
|
28
30
|
|
@@ -30,6 +32,8 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
30
32
|
|
31
33
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
34
|
|
35
|
+
For add new game crate new folder at `lib/codenjoy/games` and add necessary classes.
|
36
|
+
|
33
37
|
## Contributing
|
34
38
|
|
35
39
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/codenjoy-client.
|
@@ -24,7 +24,8 @@ class YourSolver
|
|
24
24
|
end
|
25
25
|
|
26
26
|
game = Codenjoy::Client::Game.new
|
27
|
-
board = Codenjoy::Client::Games::Battlecity::Board.new
|
27
|
+
# board = Codenjoy::Client::Games::Battlecity::Board.new
|
28
|
+
board = Codenjoy::Client::Games::Tetris::Board.new
|
28
29
|
|
29
30
|
url = "https://dojorena.io/codenjoy-contest/board/player/70xewv6o7ddy9yphm1u0?code=2603484461919438773&gameName=battlecity"
|
30
31
|
count = 0
|
@@ -20,57 +20,9 @@
|
|
20
20
|
# #L%
|
21
21
|
###
|
22
22
|
|
23
|
+
require "codenjoy/utils"
|
23
24
|
require 'json'
|
24
25
|
|
25
|
-
# Point class
|
26
|
-
class Point
|
27
|
-
attr_accessor :x
|
28
|
-
attr_accessor :y
|
29
|
-
|
30
|
-
# Coords (1,1) - upper left side of field
|
31
|
-
#
|
32
|
-
# @param [Integer] x X coord
|
33
|
-
# @param [Integer] y Y coord
|
34
|
-
def initialize(x, y)
|
35
|
-
@x = x
|
36
|
-
@y = y
|
37
|
-
end
|
38
|
-
|
39
|
-
# Override of compare method for Point
|
40
|
-
def == (other_object)
|
41
|
-
other_object.x == @x && other_object.y == @y
|
42
|
-
end
|
43
|
-
|
44
|
-
# For better +.inspect+ output
|
45
|
-
def to_s
|
46
|
-
"[#{@x},#{@y}]"
|
47
|
-
end
|
48
|
-
|
49
|
-
# Position of point above current
|
50
|
-
def up
|
51
|
-
Point.new(@x, @y + 1)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Position of point below current
|
55
|
-
def down
|
56
|
-
Point.new(@x, @y - 1)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Position of point on the left side
|
60
|
-
def left
|
61
|
-
Point.new(@x - 1, @y)
|
62
|
-
end
|
63
|
-
|
64
|
-
# Position of point on the right side
|
65
|
-
def right
|
66
|
-
Point.new(@x + 1, @y)
|
67
|
-
end
|
68
|
-
|
69
|
-
def out_of?(board_size)
|
70
|
-
x >= board_size || y >= board_size || x < 0 || y < 0;
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
26
|
class LengthToXY
|
75
27
|
def initialize(board_size)
|
76
28
|
@board_size = board_size
|
@@ -101,205 +53,205 @@ end
|
|
101
53
|
module Codenjoy
|
102
54
|
module Client
|
103
55
|
module Games
|
56
|
+
module Battlecity
|
57
|
+
end
|
104
58
|
end
|
105
59
|
end
|
106
60
|
end
|
107
61
|
|
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
|
-
end
|
62
|
+
class Codenjoy::Client::Games::Battlecity::Board
|
63
|
+
|
64
|
+
ELEMENTS = {
|
65
|
+
NONE: ' ',
|
66
|
+
BATTLE_WALL: '☼',
|
67
|
+
BANG: 'Ѡ',
|
68
|
+
|
69
|
+
CONSTRUCTION: '╬',
|
70
|
+
|
71
|
+
CONSTRUCTION_DESTROYED_DOWN: '╩',
|
72
|
+
CONSTRUCTION_DESTROYED_UP: '╦',
|
73
|
+
CONSTRUCTION_DESTROYED_LEFT: '╠',
|
74
|
+
CONSTRUCTION_DESTROYED_RIGHT: '╣',
|
75
|
+
|
76
|
+
CONSTRUCTION_DESTROYED_DOWN_TWICE: '╨',
|
77
|
+
CONSTRUCTION_DESTROYED_UP_TWICE: '╥',
|
78
|
+
CONSTRUCTION_DESTROYED_LEFT_TWICE: '╞',
|
79
|
+
CONSTRUCTION_DESTROYED_RIGHT_TWICE: '╡',
|
80
|
+
|
81
|
+
CONSTRUCTION_DESTROYED_LEFT_RIGHT: '│',
|
82
|
+
CONSTRUCTION_DESTROYED_UP_DOWN: '─',
|
83
|
+
|
84
|
+
CONSTRUCTION_DESTROYED_UP_LEFT: '┌',
|
85
|
+
CONSTRUCTION_DESTROYED_RIGHT_UP: '┐',
|
86
|
+
CONSTRUCTION_DESTROYED_DOWN_LEFT: '└',
|
87
|
+
CONSTRUCTION_DESTROYED_DOWN_RIGHT: '┘',
|
88
|
+
|
89
|
+
CONSTRUCTION_DESTROYED: ' ',
|
90
|
+
|
91
|
+
BULLET: '•',
|
92
|
+
|
93
|
+
TANK_UP: '▲',
|
94
|
+
TANK_RIGHT: '►',
|
95
|
+
TANK_DOWN: '▼',
|
96
|
+
TANK_LEFT: '◄',
|
97
|
+
|
98
|
+
OTHER_TANK_UP: '˄',
|
99
|
+
OTHER_TANK_RIGHT: '˃',
|
100
|
+
OTHER_TANK_DOWN: '˅',
|
101
|
+
OTHER_TANK_LEFT: '˂',
|
102
|
+
|
103
|
+
AI_TANK_UP: '?',
|
104
|
+
AI_TANK_RIGHT: '»',
|
105
|
+
AI_TANK_DOWN: '¿',
|
106
|
+
AI_TANK_LEFT: '«'
|
107
|
+
}
|
108
|
+
|
109
|
+
ENEMIES = [
|
110
|
+
ELEMENTS[:AI_TANK_UP],
|
111
|
+
ELEMENTS[:AI_TANK_DOWN],
|
112
|
+
ELEMENTS[:AI_TANK_LEFT],
|
113
|
+
ELEMENTS[:AI_TANK_RIGHT],
|
114
|
+
ELEMENTS[:OTHER_TANK_UP],
|
115
|
+
ELEMENTS[:OTHER_TANK_DOWN],
|
116
|
+
ELEMENTS[:OTHER_TANK_LEFT],
|
117
|
+
ELEMENTS[:OTHER_TANK_RIGHT]
|
118
|
+
]
|
119
|
+
|
120
|
+
TANK = [
|
121
|
+
ELEMENTS[:TANK_UP],
|
122
|
+
ELEMENTS[:TANK_DOWN],
|
123
|
+
ELEMENTS[:TANK_LEFT],
|
124
|
+
ELEMENTS[:TANK_RIGHT]
|
125
|
+
]
|
126
|
+
|
127
|
+
BARRIERS = [
|
128
|
+
ELEMENTS[:BATTLE_WALL],
|
129
|
+
ELEMENTS[:CONSTRUCTION],
|
130
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_DOWN],
|
131
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_UP],
|
132
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_LEFT],
|
133
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_RIGHT],
|
134
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_DOWN_TWICE],
|
135
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_UP_TWICE],
|
136
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_LEFT_TWICE],
|
137
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_RIGHT_TWICE],
|
138
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_LEFT_RIGHT],
|
139
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_UP_DOWN],
|
140
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_UP_LEFT],
|
141
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_RIGHT_UP],
|
142
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_DOWN_LEFT],
|
143
|
+
ELEMENTS[:CONSTRUCTION_DESTROYED_DOWN_RIGHT]
|
144
|
+
]
|
145
|
+
|
146
|
+
def process(data)
|
147
|
+
@raw = data
|
148
|
+
end
|
196
149
|
|
197
|
-
|
198
|
-
|
199
|
-
|
150
|
+
def size
|
151
|
+
@size ||= Math.sqrt(@raw.length);
|
152
|
+
end
|
200
153
|
|
201
|
-
|
202
|
-
|
203
|
-
|
154
|
+
def xyl
|
155
|
+
@xyl ||= LengthToXY.new(size);
|
156
|
+
end
|
204
157
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
158
|
+
def getAt(x, y)
|
159
|
+
return false if Point.new(x, y).out_of?(size)
|
160
|
+
@raw[xyl.getLength(x, y)];
|
161
|
+
end
|
209
162
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
163
|
+
def at?(x, y, element)
|
164
|
+
return false if Point.new(x, y).out_of?(size)
|
165
|
+
getAt(x, y) == element;
|
166
|
+
end
|
214
167
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
end
|
221
|
-
result;
|
168
|
+
def findAll(element)
|
169
|
+
result = []
|
170
|
+
@raw.length.times do |i|
|
171
|
+
point = xyl.getXY(i);
|
172
|
+
result.push(point) if at?(point.x, point.y, element)
|
222
173
|
end
|
174
|
+
result;
|
175
|
+
end
|
223
176
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
177
|
+
def get_me
|
178
|
+
me = find_by_list(TANK)
|
179
|
+
return nil if me.nil?
|
180
|
+
find_by_list(TANK).flatten
|
181
|
+
end
|
229
182
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
183
|
+
def find_by_list(list)
|
184
|
+
result = list.map{ |e| findAll(e) }.flatten.map{ |e| [e.x, e.y] }
|
185
|
+
return nil if (result.length == 0)
|
186
|
+
result
|
187
|
+
end
|
235
188
|
|
236
|
-
|
237
|
-
|
238
|
-
|
189
|
+
def get_enemies
|
190
|
+
find_by_list(ENEMIES)
|
191
|
+
end
|
239
192
|
|
240
|
-
|
241
|
-
|
242
|
-
|
193
|
+
def get_bullets
|
194
|
+
find_by_list([ELEMENTS[:BULLET]])
|
195
|
+
end
|
243
196
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
end
|
197
|
+
def get_near(x, y)
|
198
|
+
return false if Point.new(x, y).out_of?(size)
|
199
|
+
result = []
|
200
|
+
(-1..1).each do |dx|
|
201
|
+
(-1..1).each do |dy|
|
202
|
+
next if (dx == 0 && dy == 0)
|
203
|
+
result.push(getAt(x + dx, y + dy))
|
252
204
|
end
|
253
|
-
result;
|
254
205
|
end
|
206
|
+
result;
|
207
|
+
end
|
255
208
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
209
|
+
def barrier_at?(x, y)
|
210
|
+
return false if Point.new(x, y).out_of?(size)
|
211
|
+
get_barriers.include?([x.to_f, y.to_f]);
|
212
|
+
end
|
260
213
|
|
261
|
-
|
262
|
-
|
263
|
-
|
214
|
+
def count_near(x, y, element)
|
215
|
+
get_near(x, y).select{ |e| e == element}.size
|
216
|
+
end
|
264
217
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
218
|
+
def near?(x, y, element)
|
219
|
+
n = get_near(x, y)
|
220
|
+
return false if !n
|
221
|
+
n.include?(element);
|
222
|
+
end
|
270
223
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
224
|
+
def bullet_at?(x, y)
|
225
|
+
return false if Point.new(x, y).out_of?(size)
|
226
|
+
getAt(x, y) == ELEMENTS[:BULLET]
|
227
|
+
end
|
275
228
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
end
|
281
|
-
false;
|
229
|
+
def any_of_at?(x, y, elements = [])
|
230
|
+
return false if Point.new(x, y).out_of?(size)
|
231
|
+
elements.each do |e|
|
232
|
+
return true if at?(x, y, e)
|
282
233
|
end
|
234
|
+
false;
|
235
|
+
end
|
283
236
|
|
284
|
-
|
285
|
-
|
286
|
-
|
237
|
+
def game_over?
|
238
|
+
get_me.nil?;
|
239
|
+
end
|
287
240
|
|
288
|
-
|
289
|
-
|
290
|
-
|
241
|
+
def board_to_s
|
242
|
+
Array.new(size).each_with_index.map{ |e, n| @raw[(n * size)..((n + 1) * size - 1)]}.join("\n")
|
243
|
+
end
|
291
244
|
|
292
|
-
|
293
|
-
|
294
|
-
|
245
|
+
def get_barriers
|
246
|
+
find_by_list(BARRIERS)
|
247
|
+
end
|
295
248
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
end
|
249
|
+
def to_s
|
250
|
+
[
|
251
|
+
"Board:\n#{board_to_s}",
|
252
|
+
"My tank at: #{get_me}",
|
253
|
+
"Enemies at: #{get_enemies}",
|
254
|
+
"Bullets at: #{get_bullets}"
|
255
|
+
].join("\n")
|
304
256
|
end
|
305
257
|
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
###
|
2
|
+
# #%L
|
3
|
+
# Codenjoy - it's a dojo-like platform from developers to developers.
|
4
|
+
# %%
|
5
|
+
# Copyright (C) 2018 Codenjoy
|
6
|
+
# %%
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public
|
18
|
+
# License along with this program. If not, see
|
19
|
+
# <http://www.gnu.org/licenses/gpl-3.0.html>.
|
20
|
+
# #L%
|
21
|
+
###
|
22
|
+
require 'json'
|
23
|
+
|
24
|
+
##################################### ELEMENTS TYPES #########################################################
|
25
|
+
|
26
|
+
ELEMENTS = Hash.new
|
27
|
+
|
28
|
+
# This is glass content
|
29
|
+
ELEMENTS[:I_BLUE] = 'I'
|
30
|
+
ELEMENTS[:J_CYAN] = 'J'
|
31
|
+
ELEMENTS[:L_ORANGE] = 'L'
|
32
|
+
ELEMENTS[:O_YELLOW] = 'O'
|
33
|
+
ELEMENTS[:S_GREEN] = 'S'
|
34
|
+
ELEMENTS[:T_PURPLE] = 'T'
|
35
|
+
ELEMENTS[:Z_RED] = 'Z'
|
36
|
+
ELEMENTS[:NONE] = '.'
|
37
|
+
|
38
|
+
# List of figures
|
39
|
+
FIGURES = [
|
40
|
+
ELEMENTS[:I_BLUE],
|
41
|
+
ELEMENTS[:J_CYAN],
|
42
|
+
ELEMENTS[:L_ORANGE],
|
43
|
+
ELEMENTS[:O_YELLOW],
|
44
|
+
ELEMENTS[:S_GREEN],
|
45
|
+
ELEMENTS[:T_PURPLE],
|
46
|
+
ELEMENTS[:Z_RED]
|
47
|
+
]
|
48
|
+
|
49
|
+
##################################### END OF ELEMENTS TYPES #########################################################
|
50
|
+
|
51
|
+
# Return list of indexes of char +char+ in string +s+ ("STR".index returns only first char/string appear)
|
52
|
+
#
|
53
|
+
# @param [String] s string to search in
|
54
|
+
# @param [String] char substring to search
|
55
|
+
# @return [Array] list of indexes
|
56
|
+
def indexes(s, char)
|
57
|
+
(0 ... s.length).find_all { |i| s[i,1] == char }
|
58
|
+
end
|
59
|
+
|
60
|
+
def compare(pt1, pt2)
|
61
|
+
if (pt1.x <=> pt2.x) != 0
|
62
|
+
pt1.x <=> pt2.x
|
63
|
+
else
|
64
|
+
pt1.y <=> pt2.y
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def sort(array)
|
69
|
+
array.sort { |pt1, pt2| compare(pt1, pt2) }
|
70
|
+
end
|
71
|
+
|
72
|
+
module Codenjoy
|
73
|
+
module Client
|
74
|
+
module Games
|
75
|
+
module Tetris
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Codenjoy::Client::Games::Tetris::Board
|
82
|
+
attr_accessor :board
|
83
|
+
attr_accessor :size
|
84
|
+
attr_accessor :current_figure_type
|
85
|
+
attr_accessor :future_figures
|
86
|
+
attr_accessor :current_figure_point
|
87
|
+
|
88
|
+
def process(str)
|
89
|
+
puts "-------------------------------------------------------------------------------------------"
|
90
|
+
json = JSON.parse(str)
|
91
|
+
@board = json["layers"][0]
|
92
|
+
@size = Math.sqrt(@board.length).round
|
93
|
+
@current_figure_type = json["currentFigureType"]
|
94
|
+
@future_figures = json["futureFigures"]
|
95
|
+
@current_figure_point = Point.new(json["currentFigurePoint"]["x"], json["currentFigurePoint"]["y"])
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_s
|
99
|
+
return ("currentFigure: \"" + @current_figure_type + "\" at: " + @current_figure_point.to_s + "\n" +
|
100
|
+
"futureFigures: " + @future_figures.to_s + "\n" +
|
101
|
+
"board:" + "\n" +
|
102
|
+
@board.scan(/.{#{@size}}|.+/).join("\n"))
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns board size
|
106
|
+
# @return [Integer] board size
|
107
|
+
def size
|
108
|
+
Math.sqrt(board.length).to_i
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get object at position
|
112
|
+
#
|
113
|
+
# @param [Point] point position
|
114
|
+
# @return [String] char with object, compare with +ELEMENTS[...]+
|
115
|
+
def get_at(point)
|
116
|
+
board[coords_to_pos(point)]
|
117
|
+
end
|
118
|
+
|
119
|
+
# Is element type/s is at specified X,Y?
|
120
|
+
#
|
121
|
+
# @param [Point] point position
|
122
|
+
# @param [String, Array] element one or array of +ELEMENTS[...]+
|
123
|
+
# @return [Boolean] if +element+ at position
|
124
|
+
def is_at?(point, element)
|
125
|
+
if element.is_a?(Array)
|
126
|
+
element.include?(get_at(point))
|
127
|
+
elsif element.is_a?(String)
|
128
|
+
get_at(point) == element
|
129
|
+
else
|
130
|
+
raise ArgumentError.new("Invalid argument type #{element.class}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Check if element is near position
|
135
|
+
#
|
136
|
+
# @param [Point] point position
|
137
|
+
# @param [String, Array] element one or array of +ELEMENTS[...]+
|
138
|
+
def get_near(point)
|
139
|
+
res = []
|
140
|
+
|
141
|
+
for dx in -1..1
|
142
|
+
for dy in -1..1
|
143
|
+
if dx == 0 && dy == 0
|
144
|
+
next
|
145
|
+
end
|
146
|
+
res << get_at(Point.new(point.x + dx, point.y + dy))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
res.empty? ? nil : res
|
151
|
+
end
|
152
|
+
|
153
|
+
# Count how many objects of specified type around position
|
154
|
+
#
|
155
|
+
# @param [Point] point position
|
156
|
+
# @param [String, Array] element one or array of +ELEMENTS[...]+
|
157
|
+
# @return [Integer] number of objects around
|
158
|
+
def count_near(point, element)
|
159
|
+
elements = get_near(point)
|
160
|
+
elements.count { |it| it == element }
|
161
|
+
end
|
162
|
+
|
163
|
+
# Count how many objects of specified type around position
|
164
|
+
#
|
165
|
+
# @param [Point] point position
|
166
|
+
# @param [String, Array] element one or array of +ELEMENTS[...]+
|
167
|
+
# @return [Integer] number of objects around
|
168
|
+
def is_near?(point, element)
|
169
|
+
elements = get_near(point)
|
170
|
+
elements.find { |it| it == element } != nil
|
171
|
+
end
|
172
|
+
|
173
|
+
# Check if figures (elements of +FIGURES+ array) at position
|
174
|
+
#
|
175
|
+
# @param [Point] point position
|
176
|
+
# @return [Boolean] true if barrier at
|
177
|
+
def is_free?(point)
|
178
|
+
element = board[coords_to_pos(point)]
|
179
|
+
!FIGURES.include? element
|
180
|
+
end
|
181
|
+
|
182
|
+
# List of given elements
|
183
|
+
#
|
184
|
+
# @param [String, Array] element one or array of +ELEMENTS[...]+
|
185
|
+
# @return [Array[Point]] list of barriers on the filed
|
186
|
+
def get(element)
|
187
|
+
res = []
|
188
|
+
pos = 0
|
189
|
+
board.chars.each do |ch|
|
190
|
+
if element.is_a?(Array)
|
191
|
+
res << pos_to_coords(pos) if element.include? ch
|
192
|
+
elsif element.is_a?(String)
|
193
|
+
res << pos_to_coords(pos) if element == ch
|
194
|
+
else
|
195
|
+
raise ArgumentError.new("Invalid argument type #{element.class}")
|
196
|
+
end
|
197
|
+
pos += 1
|
198
|
+
end
|
199
|
+
|
200
|
+
sort(res)
|
201
|
+
end
|
202
|
+
|
203
|
+
# List of busy spaces in the glass
|
204
|
+
#
|
205
|
+
# @return [Array[Point]] list of barriers on the filed
|
206
|
+
def get_figures
|
207
|
+
get(FIGURES)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Return list of free spaces in the glass
|
211
|
+
#
|
212
|
+
# @return [Array[Point]] array of walls positions
|
213
|
+
def get_free_space
|
214
|
+
get(ELEMENTS[:NONE])
|
215
|
+
end
|
216
|
+
|
217
|
+
# How far specified element from position (strait direction)
|
218
|
+
# Return +size+ if wall in specified direction
|
219
|
+
#
|
220
|
+
# @param [Point] point position
|
221
|
+
# @param [String] direction direction 'UP', 'DOWN', 'LEFT', 'RIGHT'
|
222
|
+
# @param [String] element on of +ELEMENTS[...]+
|
223
|
+
# @return [Integer] distance
|
224
|
+
def next_element_in_direction(point, direction, element)
|
225
|
+
dirs = {
|
226
|
+
'UP' => [0, -1],
|
227
|
+
'DOWN' => [0, +1],
|
228
|
+
'LEFT' => [-1, 0],
|
229
|
+
'RIGHT' => [+1, 0],
|
230
|
+
}
|
231
|
+
|
232
|
+
(1..size).each do |distance|
|
233
|
+
el = get_at(
|
234
|
+
Point.new(
|
235
|
+
(point.x + distance * dirs[direction].first),
|
236
|
+
(point.y + distance * dirs[direction].last)
|
237
|
+
)
|
238
|
+
)
|
239
|
+
|
240
|
+
return size if element == ELEMENTS[:WALL]
|
241
|
+
return distance if element == el
|
242
|
+
end
|
243
|
+
|
244
|
+
size
|
245
|
+
end
|
246
|
+
|
247
|
+
# Converts position in +board+ string to coords
|
248
|
+
#
|
249
|
+
# @param [Integer] pos position in string
|
250
|
+
# @return [Point] point object
|
251
|
+
def pos_to_coords(pos)
|
252
|
+
x = (pos % size)
|
253
|
+
y = size - 1 - (pos / size).to_i
|
254
|
+
|
255
|
+
Point.new x, y
|
256
|
+
end
|
257
|
+
|
258
|
+
# Converts position in +board+ string to coords
|
259
|
+
#
|
260
|
+
# @param [Point] point position
|
261
|
+
# @return [Integer] position in +board+ string
|
262
|
+
def coords_to_pos(point)
|
263
|
+
(size - 1 - point.y) * size + point.x
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Point
|
2
|
+
attr_accessor :x
|
3
|
+
attr_accessor :y
|
4
|
+
|
5
|
+
# Coords (1,1) - upper left side of field
|
6
|
+
#
|
7
|
+
# @param [Integer] x X coord
|
8
|
+
# @param [Integer] y Y coord
|
9
|
+
def initialize(x, y)
|
10
|
+
@x = x
|
11
|
+
@y = y
|
12
|
+
end
|
13
|
+
|
14
|
+
# Override of compare method for Point
|
15
|
+
def == (other_object)
|
16
|
+
other_object.x == @x && other_object.y == @y
|
17
|
+
end
|
18
|
+
|
19
|
+
# For better +.inspect+ output
|
20
|
+
def to_s
|
21
|
+
"[#{@x},#{@y}]"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Position of point above current
|
25
|
+
def up
|
26
|
+
Point.new(@x, @y + 1)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Position of point below current
|
30
|
+
def down
|
31
|
+
Point.new(@x, @y - 1)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Position of point on the left side
|
35
|
+
def left
|
36
|
+
Point.new(@x - 1, @y)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Position of point on the right side
|
40
|
+
def right
|
41
|
+
Point.new(@x + 1, @y)
|
42
|
+
end
|
43
|
+
|
44
|
+
def out_of?(board_size)
|
45
|
+
x >= board_size || y >= board_size || x < 0 || y < 0;
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codenjoy-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.003
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vgulaev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faye-websocket
|
@@ -63,6 +63,8 @@ files:
|
|
63
63
|
- lib/codenjoy/client/version.rb
|
64
64
|
- lib/codenjoy/game_base_client.rb
|
65
65
|
- lib/codenjoy/games/battlecity/board.rb
|
66
|
+
- lib/codenjoy/games/tetris/board.rb
|
67
|
+
- lib/codenjoy/utils.rb
|
66
68
|
homepage: https://github.com/vgulaev/codenjoy-client
|
67
69
|
licenses:
|
68
70
|
- MIT
|