software_challenge_client 22.1.0 → 23.0.2
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/.gitignore +15 -15
- data/.rspec +3 -3
- data/.rubocop.yml +11 -11
- data/.ruby-version +1 -1
- data/.stickler.yml +7 -7
- data/.vscode/launch.json +40 -40
- data/.vscode/settings.json +9 -9
- data/AUTHORS +6 -6
- data/CODE_OF_CONDUCT.md +13 -13
- data/Dockerfile +3 -3
- data/Gemfile +5 -5
- data/Guardfile +45 -45
- data/README.md +172 -147
- data/RELEASES.md +144 -140
- data/Rakefile +7 -7
- data/bin/console +15 -15
- data/bin/setup +7 -7
- data/develop.sh +3 -3
- data/example/client.rb +35 -35
- data/example/main.rb +42 -42
- data/example/start.bat +2 -2
- data/generate-authors.sh +19 -19
- data/lib/software_challenge_client/board.rb +149 -127
- data/lib/software_challenge_client/client_interface.rb +19 -19
- data/lib/software_challenge_client/condition.rb +27 -27
- data/lib/software_challenge_client/coordinates.rb +71 -45
- data/lib/software_challenge_client/debug_hint.rb +17 -17
- data/lib/software_challenge_client/direction.rb +41 -0
- data/lib/software_challenge_client/field.rb +70 -69
- data/lib/software_challenge_client/game_rule_logic.rb +206 -136
- data/lib/software_challenge_client/game_state.rb +57 -29
- data/lib/software_challenge_client/invalid_move_exception.rb +15 -15
- data/lib/software_challenge_client/logging.rb +26 -26
- data/lib/software_challenge_client/move.rb +37 -41
- data/lib/software_challenge_client/network.rb +126 -126
- data/lib/software_challenge_client/piece.rb +43 -81
- data/lib/software_challenge_client/player.rb +31 -31
- data/lib/software_challenge_client/protocol.rb +103 -54
- data/lib/software_challenge_client/runner.rb +36 -36
- data/lib/software_challenge_client/team.rb +23 -25
- data/lib/software_challenge_client/util/constants.rb +9 -9
- data/lib/software_challenge_client/version.rb +5 -5
- data/lib/software_challenge_client.rb +23 -25
- data/lib/update_client_module.sh +15 -15
- data/push_image_production.sh +12 -12
- data/release.sh +9 -9
- data/software_challenge_client.gemspec +41 -41
- metadata +3 -5
- data/lib/software_challenge_client/color.rb +0 -26
- data/lib/software_challenge_client/has_hints.rb +0 -11
- data/lib/software_challenge_client/piece_type.rb +0 -16
data/bin/setup
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
|
5
|
-
bundle install
|
6
|
-
|
7
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/bin/bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
|
5
|
+
bundle install
|
6
|
+
|
7
|
+
# Do any other automated setup that you need to do here
|
data/develop.sh
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
set -x # echo commands as they are executed
|
3
|
-
docker run -it --rm -p 8808:8808 -v "$PWD":/usr/src/app -w /usr/src/app ruby:latest /bin/bash
|
1
|
+
#!/bin/sh
|
2
|
+
set -x # echo commands as they are executed
|
3
|
+
docker run -it --rm -p 8808:8808 -v "$PWD":/usr/src/app -w /usr/src/app ruby:latest /bin/bash
|
data/example/client.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
require 'software_challenge_client'
|
4
|
-
|
5
|
-
# This is an example of a client playing the game using the software challenge
|
6
|
-
# gem.
|
7
|
-
class Client < ClientInterface
|
8
|
-
include Logging
|
9
|
-
|
10
|
-
attr_accessor :gamestate
|
11
|
-
|
12
|
-
def initialize(log_level)
|
13
|
-
logger.level = log_level
|
14
|
-
logger.info 'Einfacher Spieler wurde erstellt.'
|
15
|
-
end
|
16
|
-
|
17
|
-
# gets called, when it's your turn
|
18
|
-
def move_requested
|
19
|
-
logger.info "Spielstand: #{gamestate.points_for_player(gamestate.current_player)} - #{gamestate.points_for_player(gamestate.other_player)}"
|
20
|
-
logger.debug "Board: #{gamestate.board}"
|
21
|
-
move = best_move
|
22
|
-
logger.debug "Zug gefunden: #{move}" unless move.nil?
|
23
|
-
move
|
24
|
-
end
|
25
|
-
|
26
|
-
def best_move
|
27
|
-
# gamestate.board.add_field(Field.new(5, 0))
|
28
|
-
logger.debug "Berechne zuege fuer Board #{gamestate.board}"
|
29
|
-
|
30
|
-
# all possible moves can't be calculated in under two seconds
|
31
|
-
possible_moves = GameRuleLogic.possible_moves(gamestate)
|
32
|
-
logger.debug "#{possible_moves.size} moegliche Zuege gefunden"
|
33
|
-
possible_moves.sample
|
34
|
-
end
|
35
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'software_challenge_client'
|
4
|
+
|
5
|
+
# This is an example of a client playing the game using the software challenge
|
6
|
+
# gem.
|
7
|
+
class Client < ClientInterface
|
8
|
+
include Logging
|
9
|
+
|
10
|
+
attr_accessor :gamestate
|
11
|
+
|
12
|
+
def initialize(log_level)
|
13
|
+
logger.level = log_level
|
14
|
+
logger.info 'Einfacher Spieler wurde erstellt.'
|
15
|
+
end
|
16
|
+
|
17
|
+
# gets called, when it's your turn
|
18
|
+
def move_requested
|
19
|
+
logger.info "Spielstand: #{gamestate.points_for_player(gamestate.current_player)} - #{gamestate.points_for_player(gamestate.other_player)}"
|
20
|
+
logger.debug "Board: #{gamestate.board}"
|
21
|
+
move = best_move
|
22
|
+
logger.debug "Zug gefunden: #{move}" unless move.nil?
|
23
|
+
move
|
24
|
+
end
|
25
|
+
|
26
|
+
def best_move
|
27
|
+
# gamestate.board.add_field(Field.new(5, 0))
|
28
|
+
logger.debug "Berechne zuege fuer Board #{gamestate.board}"
|
29
|
+
|
30
|
+
# all possible moves can't be calculated in under two seconds
|
31
|
+
possible_moves = GameRuleLogic.possible_moves(gamestate)
|
32
|
+
logger.debug "#{possible_moves.size} moegliche Zuege gefunden"
|
33
|
+
possible_moves.sample
|
34
|
+
end
|
35
|
+
end
|
data/example/main.rb
CHANGED
@@ -1,42 +1,42 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
# frozen_string_literal: true
|
4
|
-
require 'software_challenge_client'
|
5
|
-
require 'optparse'
|
6
|
-
require 'ostruct'
|
7
|
-
|
8
|
-
require_relative 'client'
|
9
|
-
|
10
|
-
options = OpenStruct.new
|
11
|
-
options.host = '127.0.0.1'
|
12
|
-
options.port = 13_050
|
13
|
-
options.reservation = ''
|
14
|
-
|
15
|
-
opt_parser = OptionParser.new do |opt|
|
16
|
-
opt.banner = 'Usage: main.rb [OPTIONS]'
|
17
|
-
opt.separator ''
|
18
|
-
opt.separator 'Options'
|
19
|
-
|
20
|
-
opt.on('-p', '--port PORT', Integer, "connect to the server at PORT (default #{options.port})") do |p|
|
21
|
-
options.port = p
|
22
|
-
end
|
23
|
-
|
24
|
-
opt.on('-h', '--host HOST', "the host's IP address (default #{options.host})") do |h|
|
25
|
-
options.host = h
|
26
|
-
end
|
27
|
-
|
28
|
-
opt.on('-r', '--reservation RESERVATION', "the host's RESERVATION (default #{options.reservation})") do |r|
|
29
|
-
options.reservation = r
|
30
|
-
end
|
31
|
-
|
32
|
-
opt.on_tail('-?', '--help', 'Show this message') do
|
33
|
-
puts opt
|
34
|
-
exit
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
opt_parser.parse!(ARGV)
|
39
|
-
|
40
|
-
client = Client.new(Logger::DEBUG)
|
41
|
-
runner = Runner.new(options.host, options.port, client, options.reservation)
|
42
|
-
runner.start
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
require 'software_challenge_client'
|
5
|
+
require 'optparse'
|
6
|
+
require 'ostruct'
|
7
|
+
|
8
|
+
require_relative 'client'
|
9
|
+
|
10
|
+
options = OpenStruct.new
|
11
|
+
options.host = '127.0.0.1'
|
12
|
+
options.port = 13_050
|
13
|
+
options.reservation = ''
|
14
|
+
|
15
|
+
opt_parser = OptionParser.new do |opt|
|
16
|
+
opt.banner = 'Usage: main.rb [OPTIONS]'
|
17
|
+
opt.separator ''
|
18
|
+
opt.separator 'Options'
|
19
|
+
|
20
|
+
opt.on('-p', '--port PORT', Integer, "connect to the server at PORT (default #{options.port})") do |p|
|
21
|
+
options.port = p
|
22
|
+
end
|
23
|
+
|
24
|
+
opt.on('-h', '--host HOST', "the host's IP address (default #{options.host})") do |h|
|
25
|
+
options.host = h
|
26
|
+
end
|
27
|
+
|
28
|
+
opt.on('-r', '--reservation RESERVATION', "the host's RESERVATION (default #{options.reservation})") do |r|
|
29
|
+
options.reservation = r
|
30
|
+
end
|
31
|
+
|
32
|
+
opt.on_tail('-?', '--help', 'Show this message') do
|
33
|
+
puts opt
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
opt_parser.parse!(ARGV)
|
39
|
+
|
40
|
+
client = Client.new(Logger::DEBUG)
|
41
|
+
runner = Runner.new(options.host, options.port, client, options.reservation)
|
42
|
+
runner.start
|
data/example/start.bat
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
:: Gedacht zum ausführen des ruby SimpleClients
|
2
|
-
ruby main.rb %*
|
1
|
+
:: Gedacht zum ausführen des ruby SimpleClients
|
2
|
+
ruby main.rb %*
|
data/generate-authors.sh
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
# Thanks to the docker project!
|
3
|
-
# https://github.com/docker/docker/blob/2c224e4fc09518d33780d818cf74026f6aa32744/hack/generate-authors.sh
|
4
|
-
set -e
|
5
|
-
|
6
|
-
# change to the directory where the script is located, this should be the project root
|
7
|
-
pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")/"
|
8
|
-
|
9
|
-
# see also ".mailmap" for how email addresses and names are deduplicated
|
10
|
-
|
11
|
-
{
|
12
|
-
cat <<-'EOH'
|
13
|
-
# This file lists all individuals having contributed content to the repository.
|
14
|
-
# For how it is generated, see `generate-authors.sh`.
|
15
|
-
EOH
|
16
|
-
echo
|
17
|
-
git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
|
18
|
-
} > AUTHORS
|
19
|
-
popd
|
1
|
+
#!/bin/bash
|
2
|
+
# Thanks to the docker project!
|
3
|
+
# https://github.com/docker/docker/blob/2c224e4fc09518d33780d818cf74026f6aa32744/hack/generate-authors.sh
|
4
|
+
set -e
|
5
|
+
|
6
|
+
# change to the directory where the script is located, this should be the project root
|
7
|
+
pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")/"
|
8
|
+
|
9
|
+
# see also ".mailmap" for how email addresses and names are deduplicated
|
10
|
+
|
11
|
+
{
|
12
|
+
cat <<-'EOH'
|
13
|
+
# This file lists all individuals having contributed content to the repository.
|
14
|
+
# For how it is generated, see `generate-authors.sh`.
|
15
|
+
EOH
|
16
|
+
echo
|
17
|
+
git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf
|
18
|
+
} > AUTHORS
|
19
|
+
popd
|
@@ -1,127 +1,149 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative './util/constants'
|
5
|
-
require_relative 'game_state'
|
6
|
-
require_relative 'field'
|
7
|
-
|
8
|
-
# Ein Spielbrett fuer Ostseeschach
|
9
|
-
class Board
|
10
|
-
include Constants
|
11
|
-
|
12
|
-
# @!attribute [r] fields
|
13
|
-
# @note Besser über die {#field} Methode auf Felder zugreifen.
|
14
|
-
# @return [Array<Array<Field>>] Ein Feld wird an der Position entsprechend
|
15
|
-
# seiner x und y Coordinates im Array gespeichert.
|
16
|
-
attr_reader :fields
|
17
|
-
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#
|
51
|
-
#
|
52
|
-
# @param
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# @return [
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
#
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative './util/constants'
|
5
|
+
require_relative 'game_state'
|
6
|
+
require_relative 'field'
|
7
|
+
|
8
|
+
# Ein Spielbrett fuer Ostseeschach
|
9
|
+
class Board
|
10
|
+
include Constants
|
11
|
+
|
12
|
+
# @!attribute [r] fields
|
13
|
+
# @note Besser über die {#field} Methode auf Felder zugreifen.
|
14
|
+
# @return [Array<Array<Field>>] Ein Feld wird an der Position entsprechend
|
15
|
+
# seiner x und y Coordinates im Array gespeichert.
|
16
|
+
attr_reader :fields
|
17
|
+
|
18
|
+
# --- Init ------------------------------------------------------------
|
19
|
+
|
20
|
+
# Erstellt ein neues leeres Spielbrett.
|
21
|
+
def initialize(fields = [])
|
22
|
+
@fields = Board.empty_game_field
|
23
|
+
fields.each { |f| add_field(f) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Array] leere Felder entsprechend des Spielbrettes angeordnet
|
27
|
+
def self.empty_game_field
|
28
|
+
(0...BOARD_SIZE).to_a.map do |x|
|
29
|
+
(0...BOARD_SIZE).to_a.map do |y|
|
30
|
+
Field.new(x, y)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Entfernt alle Felder des Spielfeldes
|
36
|
+
def clear
|
37
|
+
@fields = []
|
38
|
+
end
|
39
|
+
|
40
|
+
# --- Field Access ------------------------------------------------------------
|
41
|
+
|
42
|
+
# Fügt ein Feld dem Spielbrett hinzu. Das übergebene Feld ersetzt das an den
|
43
|
+
# Koordinaten bestehende Feld.
|
44
|
+
#
|
45
|
+
# @param field [Field] Das einzufügende Feld.
|
46
|
+
def add_field(field)
|
47
|
+
@fields[field.x][field.y] = field
|
48
|
+
end
|
49
|
+
|
50
|
+
# Zugriff auf die Felder des Spielfeldes
|
51
|
+
#
|
52
|
+
# @param x [Integer] Die X-Koordinate des Feldes.
|
53
|
+
# @param y [Integer] Die Y-Koordinate des Feldes.
|
54
|
+
# @return [Field] Das Feld mit den gegebenen Koordinaten. Falls das Feld nicht
|
55
|
+
# exisitert, wird nil zurückgegeben.
|
56
|
+
def field(x, y)
|
57
|
+
fields.dig(x, y) # NOTE that #dig requires ruby 2.3+
|
58
|
+
end
|
59
|
+
|
60
|
+
# Zugriff auf die Felder des Spielfeldes über ein Koordinaten-Paar.
|
61
|
+
#
|
62
|
+
# @param coords [Coordinates] X- und Y-Koordinate als Paar, sonst wie
|
63
|
+
# bei {Board#field}.
|
64
|
+
#
|
65
|
+
# @return [Field] Wie bei {Board#field}.
|
66
|
+
#
|
67
|
+
# @see #field
|
68
|
+
def field_at(coords)
|
69
|
+
field(coords.x, coords.y)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Array] Liste aller Felder
|
73
|
+
def field_list
|
74
|
+
@fields.flatten.reject(&:nil?)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @param coords [Coordinates] Die Koordinaten des Felds
|
78
|
+
# @return Das Feld an den gegebenen Koordinaten
|
79
|
+
def [](coords)
|
80
|
+
field_at(coords)
|
81
|
+
end
|
82
|
+
|
83
|
+
def fields_of_team(team)
|
84
|
+
fields = []
|
85
|
+
|
86
|
+
(0...BOARD_SIZE).to_a.map do |x|
|
87
|
+
(0...BOARD_SIZE).to_a.map do |y|
|
88
|
+
f = field(x,y)
|
89
|
+
if (!f.piece.nil? && f.piece.team == team)
|
90
|
+
fields << f
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
fields
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param field [Field] Das eingabe Feld
|
99
|
+
# @return Die Felder um dem gegebenen Feld
|
100
|
+
def neighbors_of(field)
|
101
|
+
coords = []
|
102
|
+
c = Coordinates.oddr_to_doubled(field.coords)
|
103
|
+
|
104
|
+
Direction.each { |d|
|
105
|
+
disp = d.to_vec()
|
106
|
+
|
107
|
+
x = c.x + disp.x
|
108
|
+
y = c.y + disp.y
|
109
|
+
|
110
|
+
oddr_coords = Coordinates.doubled_to_oddr_int(x, y)
|
111
|
+
if !in_bounds?(oddr_coords)
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
coords.push(oddr_coords)
|
116
|
+
}
|
117
|
+
|
118
|
+
coords.map{ |x| self.field_at(x) }.to_a
|
119
|
+
end
|
120
|
+
|
121
|
+
# --- Other ------------------------------------------------------------
|
122
|
+
|
123
|
+
# @param coords [Coordinates] Die zu untersuchenden Koordinaten
|
124
|
+
# @return [Boolean] Ob die gegebenen Koordinaten auf dem Board liegen oder nicht
|
125
|
+
def in_bounds?(coords)
|
126
|
+
coords.x >= 0 && coords.y >= 0 && coords.x < BOARD_SIZE && coords.y < BOARD_SIZE
|
127
|
+
end
|
128
|
+
|
129
|
+
# Vergleicht zwei Spielbretter. Gleichheit besteht, wenn zwei Spielbretter die
|
130
|
+
# gleichen Felder enthalten.
|
131
|
+
def ==(other)
|
132
|
+
field_list == other.field_list
|
133
|
+
end
|
134
|
+
|
135
|
+
# @return eine unabhaengige Kopie des Spielbretts
|
136
|
+
def clone
|
137
|
+
Marshal.load(Marshal.dump(self))
|
138
|
+
end
|
139
|
+
|
140
|
+
# Gibt eine textuelle Repräsentation des Spielbrettes aus.
|
141
|
+
def to_s
|
142
|
+
"\n" +
|
143
|
+
(0...BOARD_SIZE).to_a.map do |y|
|
144
|
+
(0...BOARD_SIZE).to_a.map do |x|
|
145
|
+
@fields[x][y].to_s
|
146
|
+
end.join(' ')
|
147
|
+
end.join("\n")
|
148
|
+
end
|
149
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# Das Interface sollte von einem Client implementiert werden, damit er über das
|
5
|
-
# Gem an einem Spiel teilnehmen kann.
|
6
|
-
class ClientInterface
|
7
|
-
# Wird automatisch aktualisiert und ist immer der Spielzustand des aktuellen Zuges.
|
8
|
-
attr_accessor :gamestate
|
9
|
-
|
10
|
-
# Wird aufgerufen, wenn der Client einen Zug machen soll. Dies ist der
|
11
|
-
# Einstiegspunkt für die eigentliche Logik des Computerspielers. Er muss auf
|
12
|
-
# Basis des Spielzustandes entscheiden, welchen Zug er machen möchte und diese
|
13
|
-
# zurückgeben.
|
14
|
-
#
|
15
|
-
# @return [Move] Ein für den aktuellen Spielzustand gültiger Spielzug.
|
16
|
-
def move_requested
|
17
|
-
raise 'Not yet implemented'
|
18
|
-
end
|
19
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Das Interface sollte von einem Client implementiert werden, damit er über das
|
5
|
+
# Gem an einem Spiel teilnehmen kann.
|
6
|
+
class ClientInterface
|
7
|
+
# Wird automatisch aktualisiert und ist immer der Spielzustand des aktuellen Zuges.
|
8
|
+
attr_accessor :gamestate
|
9
|
+
|
10
|
+
# Wird aufgerufen, wenn der Client einen Zug machen soll. Dies ist der
|
11
|
+
# Einstiegspunkt für die eigentliche Logik des Computerspielers. Er muss auf
|
12
|
+
# Basis des Spielzustandes entscheiden, welchen Zug er machen möchte und diese
|
13
|
+
# zurückgeben.
|
14
|
+
#
|
15
|
+
# @return [Move] Ein für den aktuellen Spielzustand gültiger Spielzug.
|
16
|
+
def move_requested
|
17
|
+
raise 'Not yet implemented'
|
18
|
+
end
|
19
|
+
end
|
@@ -1,27 +1,27 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
require_relative 'player'
|
4
|
-
|
5
|
-
# Das Ergebnis eines Spieles. Ist im `GameState#condition` zu finden, wenn das Spiel beendet wurde.
|
6
|
-
class Condition
|
7
|
-
# @!attribute [r] winner
|
8
|
-
# @return [Player] Spieler, der das Spiel gewonnen hat.
|
9
|
-
attr_reader :winner
|
10
|
-
|
11
|
-
# @!attribute [r] reason
|
12
|
-
# @return [String] Grund fuer Spielende
|
13
|
-
attr_reader :reason
|
14
|
-
|
15
|
-
# Initializes the winning Condition with a player
|
16
|
-
# @param winner [Player] winning player
|
17
|
-
# @param reason [String] why the player has won
|
18
|
-
def initialize(winner, reason)
|
19
|
-
@winner = winner
|
20
|
-
@reason = reason
|
21
|
-
end
|
22
|
-
|
23
|
-
# Überprüfe ob es ein Unentschieden gab
|
24
|
-
def draw?
|
25
|
-
@winner.nil?
|
26
|
-
end
|
27
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require_relative 'player'
|
4
|
+
|
5
|
+
# Das Ergebnis eines Spieles. Ist im `GameState#condition` zu finden, wenn das Spiel beendet wurde.
|
6
|
+
class Condition
|
7
|
+
# @!attribute [r] winner
|
8
|
+
# @return [Player] Spieler, der das Spiel gewonnen hat.
|
9
|
+
attr_reader :winner
|
10
|
+
|
11
|
+
# @!attribute [r] reason
|
12
|
+
# @return [String] Grund fuer Spielende
|
13
|
+
attr_reader :reason
|
14
|
+
|
15
|
+
# Initializes the winning Condition with a player
|
16
|
+
# @param winner [Player] winning player
|
17
|
+
# @param reason [String] why the player has won
|
18
|
+
def initialize(winner, reason)
|
19
|
+
@winner = winner
|
20
|
+
@reason = reason
|
21
|
+
end
|
22
|
+
|
23
|
+
# Überprüfe ob es ein Unentschieden gab
|
24
|
+
def draw?
|
25
|
+
@winner.nil?
|
26
|
+
end
|
27
|
+
end
|