maze-server 0.9.0
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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +31 -0
- data/Rakefile +1 -0
- data/bin/maze-server +9 -0
- data/lib/maze/game/generator/maze_generator.rb +65 -0
- data/lib/maze/game/generator/maze_walker.rb +75 -0
- data/lib/maze/game/maze.rb +66 -0
- data/lib/maze/game/maze_game.rb +49 -0
- data/lib/maze/game/maze_player.rb +43 -0
- data/lib/maze/server/maze_server.rb +53 -0
- data/lib/maze/server/version.rb +3 -0
- data/maze-server.gemspec +25 -0
- data/spec/maze/game/generator/maze_generator_spec.rb +13 -0
- data/spec/maze/game/generator/maze_walker_spec.rb +35 -0
- data/spec/maze/game/maze_game_spec.rb +49 -0
- data/spec/maze/game/maze_player_spec.rb +55 -0
- data/spec/maze/game/maze_spec.rb +86 -0
- data/spec/maze/server/maze_server_spec.rb +41 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 34f4cd0c5ccea108d3136d6b0cb7b91f8e2d0dd7
|
4
|
+
data.tar.gz: 65ced3f4d6b49d967296459a19b790f258febbc3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 72ee7622dbd0ea0dd69905ef6d93b731166caec6cceb29867f6d55d2242ddc67ec417b1f58499a5634a17f9d33d6ea797c8055da911d80dddd24139dea5a7f13
|
7
|
+
data.tar.gz: 0bd05848f581f46e46f03b1a226fd2e07088e8c02dd263ef546a1973fe22c7e45ba4e014d0843429d8f6dbf359c404f07096ab603dfd92ad1cce80da19dcf5b6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Theo Pack
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
= \Maze Server
|
2
|
+
|
3
|
+
* {<img src="https://drone.io/github.com/FuriKuri/maze-server/status.png"/>}[https://drone.io/github.com/FuriKuri/maze-server/latest]
|
4
|
+
* {<img src="https://gemnasium.com/FuriKuri/maze-server.png"/>}[https://gemnasium.com/FuriKuri/maze-server]
|
5
|
+
* {<img src="https://d3s6mut3hikguw.cloudfront.net/github/FuriKuri/maze-server.png" />}[https://codeclimate.com/github/FuriKuri/maze-server]
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'maze-server'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install maze-server
|
20
|
+
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
== Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/maze-server
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative 'maze_walker'
|
2
|
+
|
3
|
+
class MazeGenerator
|
4
|
+
def initialize(width, height)
|
5
|
+
@width = width
|
6
|
+
@height = height
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
fields = init_field
|
11
|
+
start_position = create_exit(fields)
|
12
|
+
create_way(fields, start_position)
|
13
|
+
fields
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def create_exit(fields)
|
18
|
+
exit_orientation = [:top, :right, :bottom, :left].sample
|
19
|
+
case exit_orientation
|
20
|
+
when :top
|
21
|
+
x = rand(1..@width)
|
22
|
+
start_position = [x, 1]
|
23
|
+
fields[[x, 0]] = :exit
|
24
|
+
when :bottom
|
25
|
+
x = rand(1..@width)
|
26
|
+
start_position = [x, @height]
|
27
|
+
fields[[x, @height + 1]] = :exit
|
28
|
+
when :left
|
29
|
+
y = rand(1..@height)
|
30
|
+
start_position = [1, y]
|
31
|
+
fields[[0, y]] = :exit
|
32
|
+
when :right
|
33
|
+
y = rand(1..@height)
|
34
|
+
start_position = [@width, y]
|
35
|
+
fields[[@width + 1, y]] = :exit
|
36
|
+
else
|
37
|
+
start_position = [1, 1]
|
38
|
+
fields[[0, 1]] = :exit
|
39
|
+
end
|
40
|
+
start_position
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_way(fields, start_position)
|
44
|
+
fields[start_position] = :way
|
45
|
+
MazeWalker.new(fields, start_position).create_maze_way
|
46
|
+
3.times do
|
47
|
+
MazeWalker.new(fields, start_position, 4, 20).create_maze_way
|
48
|
+
end
|
49
|
+
9.times do
|
50
|
+
MazeWalker.new(fields, start_position, 10, 20).create_maze_way
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def init_field
|
55
|
+
fields = Hash.new
|
56
|
+
fields[:width] = @width
|
57
|
+
fields[:height] = @height
|
58
|
+
@width.times do |x|
|
59
|
+
@height.times do |y|
|
60
|
+
fields[[x + 1, y + 1]] = :wall
|
61
|
+
end
|
62
|
+
end
|
63
|
+
fields
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class MazeWalker
|
2
|
+
def initialize(fields, start_position, min_step = 3, max_step = 10)
|
3
|
+
@fields = fields
|
4
|
+
@start_position = start_position
|
5
|
+
@max_step = max_step
|
6
|
+
@min_step = min_step
|
7
|
+
@width = fields[:width]
|
8
|
+
@height = fields[:height]
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_maze_way
|
12
|
+
current_position = create_maze(@start_position)
|
13
|
+
go_in_center_direction(current_position)
|
14
|
+
5.times do
|
15
|
+
create_maze(current_position)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def create_maze(start_position)
|
21
|
+
current_position = start_position
|
22
|
+
5.times do
|
23
|
+
diff = [[1, 0], [0, 1], [-1, 0], [0, -1]].sample
|
24
|
+
rand(@min_step..@max_step).times do
|
25
|
+
new_x = current_position[0] + diff[0]
|
26
|
+
new_y = current_position[1] + diff[1]
|
27
|
+
new_position = [new_x, new_y]
|
28
|
+
if @fields[new_position] == :wall
|
29
|
+
@fields[new_position] = :way
|
30
|
+
current_position = new_position
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
current_position
|
35
|
+
end
|
36
|
+
|
37
|
+
def go_in_center_direction(current_position)
|
38
|
+
start_x = @start_position[0]
|
39
|
+
start_y = @start_position[1]
|
40
|
+
current_x = current_position[0]
|
41
|
+
current_y = current_position[1]
|
42
|
+
diff_x = (start_x - current_x).abs
|
43
|
+
diff_y = (start_y - current_y).abs
|
44
|
+
if start_x == 1
|
45
|
+
if diff_x < @width / 2
|
46
|
+
current_position = go_in_x_direction(current_position)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if start_y == 1
|
50
|
+
if diff_y < @height / 2
|
51
|
+
current_position = go_in_y_direction(current_position)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
create_maze(current_position)
|
55
|
+
end
|
56
|
+
|
57
|
+
def go_in_x_direction(current_position)
|
58
|
+
go_in_direction(current_position, @width / 2, :x)
|
59
|
+
end
|
60
|
+
|
61
|
+
def go_in_y_direction(current_position)
|
62
|
+
go_in_direction(current_position, @height / 2, :y)
|
63
|
+
end
|
64
|
+
|
65
|
+
def go_in_direction(current_position, steps, direction)
|
66
|
+
current_x = current_position[0]
|
67
|
+
current_y = current_position[1]
|
68
|
+
steps.times do
|
69
|
+
current_y = current_y + 1 if direction == :y
|
70
|
+
current_x = current_x + 1 if direction == :x
|
71
|
+
@fields[[current_x, current_y]] = :way
|
72
|
+
end
|
73
|
+
[current_x, current_y]
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative 'generator/maze_generator'
|
2
|
+
|
3
|
+
class Maze
|
4
|
+
attr_reader :width, :height, :fields
|
5
|
+
|
6
|
+
def initialize(width, height)
|
7
|
+
@width = width
|
8
|
+
@height = height
|
9
|
+
@fields = MazeGenerator.new(width, height).create
|
10
|
+
end
|
11
|
+
|
12
|
+
def directions_of_way_fields(position)
|
13
|
+
way_fields = []
|
14
|
+
way_fields << :top if way_field? position, [0, -1]
|
15
|
+
way_fields << :bottom if way_field? position, [0, +1]
|
16
|
+
way_fields << :left if way_field? position, [-1, 0]
|
17
|
+
way_fields << :right if way_field? position, [+1, 0]
|
18
|
+
way_fields
|
19
|
+
end
|
20
|
+
|
21
|
+
def exit?(position)
|
22
|
+
@fields[position] == :exit
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s_for_player(player_number = nil, player_position)
|
26
|
+
field_to_s(player_number, player_position)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
field_to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def field_to_s(player_number = nil, player_position = nil)
|
35
|
+
field_as_string = ''
|
36
|
+
(@height + 2).times do |y|
|
37
|
+
(@width + 2).times do |x|
|
38
|
+
field_as_string << map_field_element([x, y], player_number, player_position)
|
39
|
+
end
|
40
|
+
field_as_string << "\n"
|
41
|
+
end
|
42
|
+
field_as_string
|
43
|
+
end
|
44
|
+
|
45
|
+
def way_field?(position, diff)
|
46
|
+
position = [position[0] + diff[0], position[1] + diff[1]]
|
47
|
+
@fields[position] == :way
|
48
|
+
end
|
49
|
+
|
50
|
+
def map_field_element(position, player_number, player_position)
|
51
|
+
case @fields[position]
|
52
|
+
when :wall
|
53
|
+
'x'
|
54
|
+
when :way
|
55
|
+
if player_position == position
|
56
|
+
player_number.to_s
|
57
|
+
else
|
58
|
+
' '
|
59
|
+
end
|
60
|
+
when :exit
|
61
|
+
'O'
|
62
|
+
else
|
63
|
+
'*'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'maze'
|
2
|
+
require_relative 'maze_player'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class MazeGame
|
6
|
+
def initialize(clients)
|
7
|
+
@players = Hash.new
|
8
|
+
@maze = Maze.new(30, 30)
|
9
|
+
start_position = rand_start_position
|
10
|
+
clients.each do |_, client|
|
11
|
+
@players[client] = MazePlayer.new(start_position, client.name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def show_next_moves(client)
|
16
|
+
player_position = @players[client].current_position
|
17
|
+
@maze.directions_of_way_fields player_position
|
18
|
+
end
|
19
|
+
|
20
|
+
def move(client, orientation)
|
21
|
+
@players[client].move(orientation)
|
22
|
+
end
|
23
|
+
|
24
|
+
def maze(client)
|
25
|
+
@maze.to_s_for_player(client.number, @players[client].current_position)
|
26
|
+
end
|
27
|
+
|
28
|
+
def print_current_maze
|
29
|
+
puts 'Maze Field'
|
30
|
+
puts @maze.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def reached_player_exit?
|
34
|
+
!winning_players.empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
def winning_players
|
38
|
+
winning_players = []
|
39
|
+
@players.each do |_, player|
|
40
|
+
winning_players << player if @maze.exit?(player.current_position)
|
41
|
+
end
|
42
|
+
winning_players.map { |player| player.name }
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def rand_start_position
|
47
|
+
@maze.fields.reject{|_, field_type| field_type != :way}.keys.sample
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class MazePlayer
|
2
|
+
attr_reader :current_position, :name
|
3
|
+
|
4
|
+
def initialize(current_position, name)
|
5
|
+
@current_position = current_position
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def move(orientation)
|
10
|
+
case orientation
|
11
|
+
when :top
|
12
|
+
move_top
|
13
|
+
when :bottom
|
14
|
+
move_bottom
|
15
|
+
when :left
|
16
|
+
move_left
|
17
|
+
when :right
|
18
|
+
move_right
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def move_top
|
23
|
+
do_move [0, -1]
|
24
|
+
end
|
25
|
+
|
26
|
+
def move_bottom
|
27
|
+
do_move [0, 1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def move_left
|
31
|
+
do_move [-1, 0]
|
32
|
+
end
|
33
|
+
|
34
|
+
def move_right
|
35
|
+
do_move [1, 0]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def do_move(diff)
|
40
|
+
@current_position = [@current_position[0] + diff[0],
|
41
|
+
@current_position[1] + diff[1]]
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'json'
|
4
|
+
require_relative '../../../lib/maze/game/maze_game'
|
5
|
+
|
6
|
+
Client = Struct.new(:name, :socket, :number)
|
7
|
+
|
8
|
+
class MazeServer
|
9
|
+
def initialize(number_of_players = 1)
|
10
|
+
@players = Hash.new
|
11
|
+
@number_of_players = number_of_players
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
puts 'start server'
|
16
|
+
connected_player = 0
|
17
|
+
server = TCPServer.open(9999)
|
18
|
+
while connected_player < @number_of_players
|
19
|
+
connected_player += 1
|
20
|
+
puts 'wait for player'
|
21
|
+
socket = server.accept
|
22
|
+
socket.puts('{"operation" : "PLAYER_NAME", "messageId": 1, "type": "REQUEST"}')
|
23
|
+
player_name = JSON.parse(socket.gets.chop)['playerName']
|
24
|
+
@players[connected_player] = Client.new(player_name, socket, connected_player)
|
25
|
+
puts "player #{player_name} connected"
|
26
|
+
end
|
27
|
+
puts 'all player are connected'
|
28
|
+
puts 'start game'
|
29
|
+
@maze_game = MazeGame.new(@players)
|
30
|
+
@maze_game.print_current_maze
|
31
|
+
end
|
32
|
+
|
33
|
+
def players
|
34
|
+
@players
|
35
|
+
end
|
36
|
+
|
37
|
+
def start_game
|
38
|
+
until @maze_game.reached_player_exit?
|
39
|
+
@players.each do |player_number, client|
|
40
|
+
puts "Print maze for player #{client.name}"
|
41
|
+
puts @maze_game.maze(client)
|
42
|
+
next_moves = @maze_game.show_next_moves(client).map { |move| move.to_s }
|
43
|
+
client.socket.puts('{"operation" : "NEXT_MOVE", "messageId" : 2, "type": "REQUEST", "data" : ' + next_moves.to_s + '}')
|
44
|
+
move = JSON.parse(client.socket.gets.chop)['move'].to_sym
|
45
|
+
@maze_game.move(client, move)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
puts @maze_game.winning_players
|
49
|
+
@players.each do |player_number, client|
|
50
|
+
client.socket.puts('{"operation" : "WINNING_PLAYERS", "messageId" : 3, "type": "NOTIFICATION", "data" : ' + @maze_game.winning_players.to_s + '}')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/maze-server.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'maze/server/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'maze-server'
|
8
|
+
spec.version = Server::VERSION
|
9
|
+
spec.authors = ['Theo Pack']
|
10
|
+
spec.email = %w(tf.pack@googlemail.com)
|
11
|
+
spec.description = %q{Maze server}
|
12
|
+
spec.summary = %q{Maze server}
|
13
|
+
spec.homepage = 'https://github.com/FuriKuri/maze-server'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = %w(lib)
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'simplecov'
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../../../../lib/maze/game/generator/maze_generator'
|
2
|
+
require_relative '../../../../lib/maze/game/generator/maze_walker'
|
3
|
+
|
4
|
+
describe MazeGenerator do
|
5
|
+
it 'creates a empty maze' do
|
6
|
+
MazeWalker.any_instance.stub(:create_maze_way)
|
7
|
+
Array.any_instance.stub(:sample).and_return(:top)
|
8
|
+
MazeGenerator.any_instance.stub(:rand).with(1..2).and_return(1)
|
9
|
+
fields = MazeGenerator.new(2, 2).create
|
10
|
+
fields.should include([1, 1] =>:way, [1, 2] => :wall, [2, 1] => :wall, [2, 2] => :wall)
|
11
|
+
fields.should include([1, 0] =>:exit)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../../../../lib/maze/game/generator/maze_walker'
|
2
|
+
|
3
|
+
describe MazeWalker do
|
4
|
+
it 'creates a way in a maze' do
|
5
|
+
field = {
|
6
|
+
[1, 1] => :way,
|
7
|
+
[1, 2] => :wall,
|
8
|
+
[1, 3] => :wall,
|
9
|
+
[2, 1] => :wall,
|
10
|
+
[2, 2] => :wall,
|
11
|
+
[2, 3] => :wall,
|
12
|
+
[3, 1] => :wall,
|
13
|
+
[3, 2] => :wall,
|
14
|
+
[3, 3] => :wall,
|
15
|
+
:width => 3,
|
16
|
+
:height => 3
|
17
|
+
}
|
18
|
+
#MazeWalker.any_instance.stub(:rand).with(2..2).and_return([1, 0])
|
19
|
+
Array.any_instance.stub(:sample).and_return([1, 0])
|
20
|
+
|
21
|
+
maze_walker = MazeWalker.new(field, [1, 1], 2, 2)
|
22
|
+
maze_walker.create_maze_way
|
23
|
+
field.should include(
|
24
|
+
[1, 1] =>:way,
|
25
|
+
[1, 2] => :wall,
|
26
|
+
[1, 3] => :wall,
|
27
|
+
[2, 1] => :way,
|
28
|
+
[2, 2] => :wall,
|
29
|
+
[2, 3] => :wall,
|
30
|
+
[3, 1] => :way,
|
31
|
+
[3, 2] => :way,
|
32
|
+
[3, 3] => :wall,
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative '../../../lib/maze/game/maze_game'
|
2
|
+
require_relative '../../../lib/maze/server/maze_server'
|
3
|
+
|
4
|
+
describe MazeGame do
|
5
|
+
before do
|
6
|
+
Maze.any_instance.stub(:fields).and_return(
|
7
|
+
{[1, 1] => :exit,
|
8
|
+
[1, 2] => :way,
|
9
|
+
[2, 1] => :wall,
|
10
|
+
[2, 2] => :way
|
11
|
+
}
|
12
|
+
)
|
13
|
+
Array.any_instance.stub(:sample).and_return([1, 2])
|
14
|
+
@client = Client.new('Player', nil)
|
15
|
+
@maze_game = MazeGame.new({1 => @client})
|
16
|
+
Maze.any_instance.stub(:exit?).with([1, 1]).and_return(true)
|
17
|
+
Maze.any_instance.stub(:exit?).with([1, 2]).and_return(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can show next moves for a player' do
|
21
|
+
Maze.any_instance.stub(:directions_of_way_fields).and_return([:top])
|
22
|
+
@maze_game.show_next_moves(@client).should == [:top]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can say if player has reached the exit' do
|
26
|
+
MazePlayer.any_instance.stub(:current_position).and_return([1, 1])
|
27
|
+
@maze_game.reached_player_exit?.should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'can say if no player has reached the exit' do
|
31
|
+
MazePlayer.any_instance.stub(:current_position).and_return([1, 2])
|
32
|
+
@maze_game.reached_player_exit?.should be_false
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can say which player has reached the exit' do
|
36
|
+
MazePlayer.any_instance.stub(:current_position).and_return([1, 1])
|
37
|
+
@maze_game.winning_players.should == ['Player']
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'move player in maze' do
|
41
|
+
MazePlayer.any_instance.should_receive(:move).with(:top)
|
42
|
+
@maze_game.move(@client, :top)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns maze for player' do
|
46
|
+
Maze.any_instance.stub(:to_s_for_player).and_return('maze')
|
47
|
+
@maze_game.maze(@client).should == 'maze'
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative '../../../lib/maze/game/maze_player'
|
2
|
+
|
3
|
+
describe MazePlayer do
|
4
|
+
before do
|
5
|
+
@player = MazePlayer.new([5, 5], 'Player One')
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'has a name' do
|
9
|
+
@player.name.should == 'Player One'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'has a position' do
|
13
|
+
@player.current_position == [5, 5]
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can move on step to top' do
|
17
|
+
@player.move_top
|
18
|
+
@player.current_position.should == [5, 4]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'can move on step to orientation top' do
|
22
|
+
@player.move(:top)
|
23
|
+
@player.current_position.should == [5, 4]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can move on step to bottom' do
|
27
|
+
@player.move_bottom
|
28
|
+
@player.current_position.should == [5, 6]
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'can move on step to orientation bottom' do
|
32
|
+
@player.move(:bottom)
|
33
|
+
@player.current_position.should == [5, 6]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can move on step to left' do
|
37
|
+
@player.move_left
|
38
|
+
@player.current_position.should == [4, 5]
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can move on step to orientation left' do
|
42
|
+
@player.move(:left)
|
43
|
+
@player.current_position.should == [4, 5]
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'can move on step to right' do
|
47
|
+
@player.move_right
|
48
|
+
@player.current_position.should == [6, 5]
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'can move on step to orientation right' do
|
52
|
+
@player.move(:right)
|
53
|
+
@player.current_position.should == [6, 5]
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative '../../../lib/maze/game/maze'
|
2
|
+
require_relative '../../../lib/maze/game/generator/maze_generator'
|
3
|
+
|
4
|
+
describe Maze do
|
5
|
+
before do
|
6
|
+
@maze = Maze.new(5, 6)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'has a width' do
|
10
|
+
@maze.width.should == 5
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has a height' do
|
14
|
+
@maze.height.should == 6
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'small maze' do
|
18
|
+
before do
|
19
|
+
MazeGenerator.any_instance.stub(:create).and_return(
|
20
|
+
{[1, 1] => :way,
|
21
|
+
[1, 2] => :way,
|
22
|
+
[2, 1] => :wall,
|
23
|
+
[2, 2] => :way
|
24
|
+
})
|
25
|
+
@maze = Maze.new(2, 2)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'generate a maze' do
|
29
|
+
fields = @maze.fields
|
30
|
+
fields[[1, 1]].should == :way
|
31
|
+
fields[[1, 2]].should == :way
|
32
|
+
fields[[2, 1]].should == :wall
|
33
|
+
fields[[2, 2]].should == :way
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'return the maze as string' do
|
37
|
+
@maze.to_s.should == "****\n* x*\n* *\n****\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'return the maze with a player' do
|
41
|
+
@maze.to_s_for_player(1, [1, 1]) == "****\n*1x*\n* *\n****\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'medium maze' do
|
46
|
+
before do
|
47
|
+
MazeGenerator.any_instance.stub(:create).and_return(
|
48
|
+
{[1, 1] => :wall,
|
49
|
+
[1, 2] => :wall,
|
50
|
+
[1, 3] => :wall,
|
51
|
+
[2, 1] => :way,
|
52
|
+
[2, 2] => :way,
|
53
|
+
[2, 3] => :way,
|
54
|
+
[3, 1] => :wall,
|
55
|
+
[3, 2] => :way,
|
56
|
+
[3, 3] => :wall
|
57
|
+
})
|
58
|
+
@maze = Maze.new(3, 3)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'show all directions for a way' do
|
62
|
+
@maze.directions_of_way_fields([2, 2]).should == [:top, :bottom, :right]
|
63
|
+
@maze.directions_of_way_fields([1, 2]).should == [:right]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'small maze with exit' do
|
68
|
+
before do
|
69
|
+
MazeGenerator.any_instance.stub(:create).and_return(
|
70
|
+
{[1, 1] => :exit,
|
71
|
+
[1, 2] => :way,
|
72
|
+
[2, 1] => :wall,
|
73
|
+
[2, 2] => :way
|
74
|
+
})
|
75
|
+
@maze = Maze.new(2, 2)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'has on 1, 1 an exit' do
|
79
|
+
@maze.exit?([1, 1]).should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has on 2, 1 no exit' do
|
83
|
+
@maze.exit?([2, 1]).should be_false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../../../lib/maze/server/maze_server'
|
2
|
+
require_relative '../../../lib/maze/server/version'
|
3
|
+
require_relative '../../../lib/maze/game/maze_game'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
describe MazeServer do
|
7
|
+
|
8
|
+
it 'maze server has a version' do
|
9
|
+
Maze::Server::VERSION.should_not be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'get player name if they are connected' do
|
13
|
+
response = double('response', :chop => '{"playerName" : "player"}')
|
14
|
+
socket = double('socket', :gets => response, :puts => nil)
|
15
|
+
server = double('server', :accept => socket)
|
16
|
+
TCPServer.stub(:open).with(9999).and_return(server)
|
17
|
+
server = MazeServer.new(1)
|
18
|
+
server.start
|
19
|
+
server.players[1].name.should == 'player'
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'server runs' do
|
23
|
+
before do
|
24
|
+
response = double('response', :chop => '{"playerName" : "player"}')
|
25
|
+
socket = double('socket', :gets => response, :puts => nil)
|
26
|
+
server = double('server', :accept => socket)
|
27
|
+
TCPServer.stub(:open).with(9999).and_return(server)
|
28
|
+
@server = MazeServer.new(1)
|
29
|
+
@server.start
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'handle a game' do
|
33
|
+
MazeGame.any_instance.stub(:reached_player_exit?).and_return(false, true)
|
34
|
+
response = double('response', :chop => '{"move" : "left"}')
|
35
|
+
socket = double('socket', :gets => response, :puts => nil)
|
36
|
+
Client.any_instance.stub(:socket).and_return(socket)
|
37
|
+
@server.start_game
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maze-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Theo Pack
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Maze server
|
70
|
+
email:
|
71
|
+
- tf.pack@googlemail.com
|
72
|
+
executables:
|
73
|
+
- maze-server
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.rdoc
|
81
|
+
- Rakefile
|
82
|
+
- bin/maze-server
|
83
|
+
- lib/maze/game/generator/maze_generator.rb
|
84
|
+
- lib/maze/game/generator/maze_walker.rb
|
85
|
+
- lib/maze/game/maze.rb
|
86
|
+
- lib/maze/game/maze_game.rb
|
87
|
+
- lib/maze/game/maze_player.rb
|
88
|
+
- lib/maze/server/maze_server.rb
|
89
|
+
- lib/maze/server/version.rb
|
90
|
+
- maze-server.gemspec
|
91
|
+
- spec/maze/game/generator/maze_generator_spec.rb
|
92
|
+
- spec/maze/game/generator/maze_walker_spec.rb
|
93
|
+
- spec/maze/game/maze_game_spec.rb
|
94
|
+
- spec/maze/game/maze_player_spec.rb
|
95
|
+
- spec/maze/game/maze_spec.rb
|
96
|
+
- spec/maze/server/maze_server_spec.rb
|
97
|
+
homepage: https://github.com/FuriKuri/maze-server
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.0.3
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: Maze server
|
121
|
+
test_files:
|
122
|
+
- spec/maze/game/generator/maze_generator_spec.rb
|
123
|
+
- spec/maze/game/generator/maze_walker_spec.rb
|
124
|
+
- spec/maze/game/maze_game_spec.rb
|
125
|
+
- spec/maze/game/maze_player_spec.rb
|
126
|
+
- spec/maze/game/maze_spec.rb
|
127
|
+
- spec/maze/server/maze_server_spec.rb
|