codenjoy-client 0.1.002 → 0.1.003
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|