final commit

This commit is contained in:
2021-11-29 21:24:18 +01:00
parent c2ca8aa9fc
commit c0c29134c8
8 changed files with 261 additions and 548 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ CMakeFiles
a[1-5]
Makefile
target
CMakeCache.txt

View File

@ -3,34 +3,38 @@
## Lösungsidee
Für jede normale Textdatei wird ASCII encoding verwendet bzw. ein Encoding
Standart welcher auf ASCII basiert und zusätzliche Sonderzeichen enthält,
wobei die Werte die bereits in ASCII enthalten übernommen wurden.
Die ASCII codes für die Buchstaben sind entsprechend des Alphabets
Standard, welcher auf ASCII basiert und zusätzliche Sonderzeichen enthält,
wobei die Werte, die bereits in ASCII enthalten sind, übernommen wurden.
Die ASCII Codes für die Buchstaben sind entsprechend des Alphabets
hintereinander angeordnet. Dies ist sehr nützlich, da somit eine Liste der
Buchstaben und deren Position im Alphabet nicht benötigt wird.<br>
Zur Lösung des Parkplatzproblems werden die Autos wenn möglich nach links bzw.
rechts verschoben bis die Parklücke frei ist. Je nachdem in welche Richtung
Buchstaben und deren Position im Alphabet nicht benötigt wird.
Zur Lösung des Parkplatzproblems werden die Autos, wenn möglich nach links bzw.
rechts verschoben, bis die Parklücke frei ist. Je nachdem, in welche Richtung
weniger Autos verschoben werden müssen, wird die Verschiebungsrichtung gewählt.
## Umsetzung
Da die Lösung des Problem keine besondere Library benötigt wird und die Anforderungen
an die Ausführungsgeschwindigkeit gering sind, hätte man fast jede Progmiersprache
wählen können. Ich habe mich für Go entschieden.<br>
Das Programm akzeptiert als Argumente eine beliebige Anzahl an Pfaden zu Parkplatzdatein.
Da die Lösung des Problems keine besondere Library benötigt und die Anforderungen
an die Ausführungsgeschwindigkeit gering sind, hätte man fast jede Programmiersprache
wählen können. Ich habe mich für Go entschieden.
Das Programm akzeptiert als Argumente eine beliebige Anzahl an Pfaden zu Parkplatzdateien.
Für das Iterieren über die Argumente wird eine for-Schleife benutzt.
Innerhalb der Schleife wird die Eingabedatei ausgelesen. Anhand des ersten und letzten
Buchstaben der Autos auf den normalen Parkplätzen wird die die Anzahl an Parkplätzen
Buchstabens der Autos auf den normalen Parkplätzen wird die Anzahl an Parkplätzen
bestimmt. Anschließend wird eine Slice (ein dynamisch vergrößerbares Array in Go)
mit den Buchstaben der quer parkenden Autos befüllt an den Indexen an denen sie die
normalen Parkplätze blockieren.<br>
mit den Buchstaben der quer parkenden Autos befüllt an den Indexen, an denen sie die
normalen Parkplätze blockieren.
In einer for-Schleife wird die "move"-Funktion je Index der Parkplätze doppelt
für beide Verschiebungsrichtungen aufgerufen.
In der "move"-Funktion wird ein Auto verschoben, wenn nicht das Ende des
Parkplatzes erreicht ist. Die Funktion ruft sich recursive auf um weitere Autos zu
verschieben. Je nachdem in welche Richtung weniger Autos verschoben werden müssen
oder, wenn es gleich viele sind, wo die Anzahl der verschobenen Plätze aller Autos
geringer ist, wird sich für das Verschieben in diese Richtung entschieden.
Parkplatzes erreicht ist. Die Funktion ruft sich rekursiv auf, um weitere Autos zu
verschieben. Je nachdem, in welche Richtung weniger Autos verschoben werden müssen,
wird sich für das Verschieben in diese Richtung entschieden.
Wenn es allerdings gleich viele sind, ist die geringere Anzahl der verschobenen
Plätze aller Autos ausschlaggebend für das Verschieben in diese Richtung.
## Beispiele
@ -129,7 +133,7 @@ Außerdem habe ich noch weitere Testfälle erstellt, die sich im Ordner "testdat
befinden. Als Erstes habe ich getestet, ob das Programm auch mit dem Verschieben
sehr vieler Autos klarkommt. Es gibt 26 Parkplätze, wovon alle außer die ersten
beiden mit quer parkenden Autos blockiert sind. Für die quer parkenden Autos
wurde Kleinbuchstaben verwendet, da alle Großbuchstaben schon belegt sind.
wurden Kleinbuchstaben verwendet, da alle Großbuchstaben schon belegt sind.
```
test0.txt:
@ -149,22 +153,33 @@ M: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links
N: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links
O: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links
P: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links
Q: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links
R: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links
S: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links
T: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links
U: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links
V: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links
W: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links, k 2 links
X: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links, k 1 links
Y: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links, h 2 links, i 2 links, j 2 links, k 2 links, l 2 links
Z: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links, h 1 links, i 1 links, j 1 links, k 1 links, l 1 links
Q: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links
R: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links
S: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links
T: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links
U: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links
V: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links
W: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links, k 2 links
X: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links, k 1 links
Y: a 2 links, b 2 links, c 2 links, d 2 links, e 2 links, f 2 links, g 2 links,
h 2 links, i 2 links, j 2 links, k 2 links, l 2 links
Z: a 1 links, b 1 links, c 1 links, d 1 links, e 1 links, f 1 links, g 1 links,
h 1 links, i 1 links, j 1 links, k 1 links, l 1 links
```
Die Autos wurden abwechselend jeweils ein oder zwei Parkplätze verschoben,
je nachdem ob das ausfahrende Auto hinter der linke oder rechten Hälfe des quer
stehenden Autos steht.<br>
Die Bezeichner der Autos müssen auch nicht bei A beginnen; der Beginn bei
Die Autos wurden abwechselend jeweils um ein oder zwei Parkplätze verschoben,
je nachdem ob das ausfahrende Auto hinter der linken oder rechten Hälfe des quer
stehenden Autos steht.
Die Bezeichner der Autos müssen auch nicht bei A beginnen. Der Beginn mit
anderen Buchstaben ist möglich. Dies zeigt das folgende Beispiel an der
Eingabedatei "parkplatz3.txt" mit veränderten Bezeichnern.
@ -185,72 +200,3 @@ N: Q 1 links, R 1 links
O: Q 2 links, R 2 links, S 2 links
P: Q 1 links, R 1 links, S 1 links
```
## Quelltext
```
func main() {
for i := range querAutos {
var currentMoves []movedCar // enthält die Verschiebungen der Autos in die Richtung in der weniger Autos verschoben werden müssen
var carLeastSteps uint32
for _, direction := range []int{-1, 1} { // -1 steht für links und 1 für rechts
movedCars, steps, success := move(i, direction, []movedCar{}, 0, 0)
/* Wenn das Verschieben der Autos in der jeweiligen Richtung erfolgreich ist und noch keine
Verschiebungen abgespeichert wurden, d. h. gerade die Verschiebungen für links berechnet
wurden oder das Verschieben nach links nicht erfolgreich war, da das Ende das Parkplatzes
erreicht wurde, dann werden die Verschiebungen abgespeichert.
Sollten allerdings bereits Verschiebungen für links vorhanden sein, wird das Verschieben nach
rechts bevorzugt, wenn weniger Autos verschoben werden mussten oder die Autos weniger Plätze
verschoben werden mussten. */
if success && (currentMoves == nil || len(movedCars) < len(currentMoves) || len(movedCars) == len(currentMoves) && steps < carLeastSteps) {
currentMoves = movedCars
carLeastSteps = steps
}
}
}
}
// Funktion zur Berechung der Autos, die für einen Parkplatz verschoben werden müssen.
func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uint32) ([]movedCar, uint32, bool) {
querAuto := querAutos[i]
/* Wenn querAuto gleich 0 ist, ist kein Auto vor dem Parkplatz.
Wenn es das gleiche Auto ist wie das zuletzt verschobene, ist auch das Verschieben beendet,
da dieses Auto bereits ausreichend verschoben wurde. */
if querAuto == 0 || querAuto == lastMoved {
return movedCars, totalSteps, true
}
/* Wenn neben unserem Auto in der jeweiligen Richtung kein Parkplatz mehr ist,
dann können auch keine Autos in diese Richtung verschoben werden. */
if outOfBounds(querAutos, i + direction) {
return movedCars, totalSteps, false
}
var steps int
/* Wenn sich eins nach der Verschiebungsrichtung auch unserer quer parkendes Auto befindet,
muss es nur um einen Platz verschoben werden, ansonsten um zwei. */
if querAutos[i + direction] == querAuto {
steps = 1
} else {
steps = 2
}
endCar := i + direction * 2 // ist das Ende des verschobenen Autos, das realtiv zur verschobenen Richtung, vorne ist.
/* müsste das Auto ausserhalb des Parkplatzes geschoben werden,
damit unser normale Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
if outOfBounds(querAutos, endCar) {
return movedCars, totalSteps, false
}
// fügt das gerade verschobene Auto der Slice mit den verschobenen Autos hinzu.
movedCars = append(movedCars, movedCar{querAuto, steps, direction})
/* ruft die Funktion recursive auf, mit dem Index des Parkplatzes an dem
noch ein quer stehendes Auto stehen könnte, das verschoben werden müsste. */
return move(endCar, direction, movedCars, querAuto, totalSteps + uint32(steps))
}
// Funktion um zu überprüfen, ob ein Index innerhalb einer Slice liegt.
func outOfBounds(slice []byte, i int) bool {
return i < 0 || i >= len(slice)
}
```

View File

@ -17,7 +17,7 @@ type movedCar struct {
var querAutos []byte
func main() {
// Dem Programm können beliebig viele Eingabedatein übergeben werden.
// Dem Programm können beliebig viele Eingabedateien übergeben werden.
for _, filepath := range os.Args[1:] {
// ausgeben des Dateipfades, um Zuordnung der Lösung zu der entsprechenden Eingabedatei zu ermöglichen
fmt.Printf("%s:\n", filepath)
@ -39,7 +39,7 @@ func main() {
if len(line) == 0 {
continue
}
// Die Position des des quer stehenden Autos beginnt ab dem 3. Zeichen (Index 2) bis zum Ende der Zeile.
// Die Position des quer stehenden Autos beginnt ab dem 3. Zeichen (Index 2) bis zum Ende der Zeile.
i, err := strconv.Atoi(line[2:])
throw(err)
// Jedes quer stehende Auto blockiert zwei Parkplätze. Deshalb belegt es auch zwei Plätze in unserer Slice.
@ -52,12 +52,14 @@ func main() {
movedCars, steps, success := move(i, direction, []movedCar{}, 0, 0)
/* Wenn das Verschieben der Autos in der jeweiligen Richtung erfolgreich ist und noch keine
Verschiebungen abgespeichert wurden, d. h. gerade die Verschiebungen für links berechnet
wurden oder das Verschieben nach links nicht erfolgreich war, da das Ende das Parkplatzes
erreicht wurde, dann werden die Verschiebungen abgespeichert.
Verschiebungen abgespeichert wurden, werden die Verschiebungen abgespeichert.
Es wurden vorher noch keine Verschiebungen gespeichert, wenn gerade die Verschiebungen
für links berechnet wurden oder das Verschieben nach links nicht erfolgreich war,
da das Ende das Parkplatzes erreicht wurde.
Sollten allerdings bereits Verschiebungen für links vorhanden sein, wird das Verschieben nach
rechts bevorzugt, wenn weniger Autos verschoben werden mussten oder die Autos weniger Plätze
verschoben werden mussten. */
rechts bevorzugt, wenn weniger Autos verschoben werden mussten.
Wenn es allerdings gleich viele sind, ist die geringere Anzahl der verschobenen
Plätze aller Autos ausschlaggebend für das Verschieben in diese Richtung. */
if success && (currentMoves == nil || len(movedCars) < len(currentMoves) || len(movedCars) == len(currentMoves) && steps < carLeastSteps) {
currentMoves = movedCars
carLeastSteps = steps
@ -109,7 +111,7 @@ func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uin
return movedCars, totalSteps, false
}
var steps int
/* Wenn sich eins nach der Verschiebungsrichtung auch unserer quer parkendes Auto befindet,
/* Wenn sich in der Verschiebungsrichtung direkt daneben auch unserer quer parkendes Auto befindet,
muss es nur um einen Platz verschoben werden, ansonsten um zwei. */
if querAutos[i + direction] == querAuto {
steps = 1
@ -118,14 +120,14 @@ func move(i, direction int, movedCars []movedCar, lastMoved byte, totalSteps uin
}
endCar := i + direction * 2 // ist das Ende des verschobenen Autos, das realtiv zur verschobenen Richtung, vorne ist.
/* müsste das Auto ausserhalb des Parkplatzes geschoben werden,
damit unser normale Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
/* müsste das Auto außerhalb des Parkplatzes geschoben werden,
damit unser normaler Parkplatz frei wird, ist das Verschieben in diese Richtung nicht möglich. */
if outOfBounds(querAutos, endCar) {
return movedCars, totalSteps, false
}
// fügt das gerade verschobene Auto der Slice mit den verschobenen Autos hinzu.
movedCars = append(movedCars, movedCar{querAuto, steps, direction})
/* ruft die Funktion recursive auf, mit dem Index des Parkplatzes an dem
/* ruft die Funktion rekursiv auf, mit dem Index des Parkplatzes an dem
noch ein quer stehendes Auto stehen könnte, das verschoben werden müsste. */
return move(endCar, direction, movedCars, querAuto, totalSteps + uint32(steps))
}

View File

@ -1,371 +0,0 @@
# This is the CMakeCache file.
# For build in directory: /home/mrgeorgen/dev/bwinf40-runde1/a2-Vollgeladen
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Path to a program.
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
//Path to a program.
CMAKE_AR:FILEPATH=/usr/bin/ar
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Debug
//Enable/Disable color output during build.
CMAKE_COLOR_MAKEFILE:BOOL=ON
//CXX compiler
CMAKE_CXX_COMPILER:STRING=/usr/bin/c++
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib
//Flags used by the CXX compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the CXX compiler during RELEASE builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//C compiler
CMAKE_C_COMPILER:STRING=/usr/bin/cc
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib
//Flags used by the C compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the C compiler during DEBUG builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
//Flags used by the C compiler during MINSIZEREL builds.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the C compiler during RELEASE builds.
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the C compiler during RELWITHDEBINFO builds.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Path to a program.
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
//Flags used by the linker during all build types.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/usr/bin/ld
//Path to a program.
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
//Flags used by the linker during the creation of modules during
// all build types.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/usr/bin/nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=a2-Vollgeladen
//Path to a program.
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
//Path to a program.
CMAKE_READELF:FILEPATH=/usr/bin/readelf
//Flags used by the linker during the creation of shared libraries
// during all build types.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//Value Computed by CMake
a2-Vollgeladen_BINARY_DIR:STATIC=/home/mrgeorgen/dev/bwinf40-runde1/a2-Vollgeladen
//Value Computed by CMake
a2-Vollgeladen_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
a2-Vollgeladen_SOURCE_DIR:STATIC=/home/mrgeorgen/dev/bwinf40-runde1/a2-Vollgeladen
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_ADDR2LINE
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/mrgeorgen/dev/bwinf40-runde1/a2-Vollgeladen
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=21
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_DLLTOOL
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/mrgeorgen/dev/bwinf40-runde1/a2-Vollgeladen
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_READELF
CMAKE_READELF-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.21
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/usr/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1

View File

@ -19,18 +19,22 @@ Der Quelltext der Library ist im Ordner "lib/advanced_C_standard_library" oder
Das Programm erhält als Argumente eine beliebige Anzahl Dateipfade zu Eingabedateien.
Mit einer for-Schleife wird über die Dateipfade iteriert. In der Schleife wird die
Eingabedatei ausgelesen. Die Anzahl der Hotels und die Gesamtfahrzeit werden jeweils
in einer Variable abgespeichert. Anschließend wird ein Array mit Strukturen die Hotels
darstellen befüllt. In einer do-while-Schleife wird mit einer Bewertung von
5.0, 4.9, ..., 0.1 eine Route zu bilden. Wenn dies bei einer Bewertung erfolgreich
ist wird die Schleife beendet. In dieser Schleife ist wiederum eine for-Schleife
in einer Variable abgespeichert. Anschließend wird ein Array mit Strukturen, die Hotels
darstellen, befüllt. In einer do-while-Schleife wird mit einer Bewertung von
5.0, 4.9, ..., 0.1 versucht eine Route zu bilden.
Im Programm werden die Bewertungen als Integer dargestellt, wobei die Bewertung der
Eingabedatei mit 10 multipliziert wird. Die Ausgabe ist wiederum im ursprünglichen
Format. Wenn dies bei einer Bewertung erfolgreich ist, wird die Schleife beendet.
In dieser Schleife ist wiederum eine for-Schleife,
die über die Hotels iteriert, worin das letzte Hotel gespeichert wird, das
mindestens die angestrebte Bewertung hat.
Ist das Hotel allerdings mehr als 6 Stunden vom letzten Haltepunkt entfernt,
muss das letzte Hotel verwendet werden an dem das Halten möglich ist, falls dieses
vorhanden ist und höchtens an drei Hotels schon gehalten wurde,
ansonsten muss mit der nächsten Bewertung fortgefahren werden.
Nachdem eine Route gefunden wurde, wird diese ausgeben und eventuell mit der
näcshten Eingabedatei fortgefahren.
muss das letzte Hotel verwendet werden, an dem das Halten möglich ist. Es sei
denn es gibt kein Hotel mit der entsprechenden Bewertung
oder es wurde bereits an mehr als drei Hotels gehalten. Dann
muss mit der nächsten Bewertung fortgefahren werden.
Nachdem eine Route gefunden wurde, wird diese ausgegeben und eventuell mit der
nächten Eingabedatei fortgefahren.
## Beispiele
@ -63,45 +67,3 @@ Entfernung vom Start: 636 Minuten, Bewertung: 5.0
Entfernung vom Start: 987 Minuten, Bewertung: 5.0
Entfernung vom Start: 1286 Minuten, Bewertung: 5.0
```
## Quelltext
```
int main() {
uint_least8_t rating = 50;
do {
// Minuten die das letzte Hotel, bei dem angehalten wurde, vom Start entfertn ist
uint_least16_t lastHotelMinutes = 0;
// Zeiger zum letzten Hotel, dessen Bewertung mindestens "rating" ist.
struct hotel *possibleStop = NULL;
stoppedHotels = 0; // setzt Anzahl der Stops zurück
// iteriert über die Hotels
for(struct hotel *currentHotel = hotels; currentHotel - hotels < numberHotels; ++currentHotel) {
/* Wenn das aktuelle Hotel mehr als 360 Minuten vom letzten Hotel entfernt ist,
* muss das letzte Hotel verwendet werden an dem das Halten möglich war.*/
if(currentHotel->minutes - lastHotelMinutes > 360) {
/* Wenn das Halten nicht möglich ist oder bereits schon viermal
* gehalten wurde, muss es mit einer niedrigeren Bewertung versucht
* werden.*/
if(possibleStop == NULL || stoppedHotels >= 4) break;
// hängt das Hotel der Route an
hotelRoute[stoppedHotels] = *possibleStop;
lastHotelMinutes = possibleStop->minutes;
// springt in der Schleife zurück zum Hotel, an dem gestoppt wurde
currentHotel = possibleStop;
++stoppedHotels;
}
// Wenn die Bewertung hoch genug ist, kann gestoppt werden.
if(currentHotel->rating >= rating) possibleStop = currentHotel;
}
--rating;
/* Schleife läuft solange "rating" mindestens Eins ist, da es keine niedrigeren Bewertungen
* gibt. Wenn das letzte Hotel höchtens 360 Minuten vom Zielort entfernt ist, wurde
* erfolgreich eine Route gefunden und die Schleife wird beendet. Allerdings wird dies nur
* überprüft, wenn überhaupt an einem Hotel gehalten wurde, um den Zugriff auf nicht
* definierten Speicher zu vermeiden.*/
} while(rating && (!stoppedHotels || totalMinutes - hotelRoute[stoppedHotels - 1].minutes > 360));
}
```

View File

@ -45,7 +45,7 @@ int main(int argc, char *argv[]) {
char *nextnumber;
/* Die Anzahl der Hotels muss noch den Makro "getNumber" verarbeitet werden,
* da dieser vorraussetzt, das der Zeiger "nextnumber" bereits definiert ist.
* da dieser voraussetzt, das der Zeiger "nextnumber" bereits definiert ist.
* Zudem wird noch Eins addiert, weil noch ein "Hotel" hinzugefügt wird,
* das den Zielpunkt darstellt.*/
numberHotels = strtol(inputText, &nextnumber, 10) + 1;
@ -60,7 +60,7 @@ int main(int argc, char *argv[]) {
/* "strtol" verarbeitet nur ganze Zahlen. Deshalb werden die beiden Ziffern einzeln
* verarbeitet. Da für die Bewertung ein Integer-Typ verwendet wird,
* ist die resultierende Bewertung das zehnfache der Bewertung in der Eingabedatei.
* ist die resultierende Bewertung das Zehnfache der Bewertung in der Eingabedatei.
* Diese wird bei der Ausgabe wieder umgewandelt.*/
hotels[i].rating = 10 * getNumber;
hotels[i].rating += getNumber;
@ -80,7 +80,7 @@ int main(int argc, char *argv[]) {
uint_least8_t stoppedHotels; // Anzahl der gemachten Stops
/* In der Schleife wird versucht eine Route mit der Bewertung von mindestens 50 zu bilden.
* Wenn dies nicht erfolgrecih ist, wird es mit 49, 48, ... versucht bis eine Route gefunden wurde.*/
* Wenn dies nicht erfolgreich ist, wird es mit 49, 48, ... versucht bis eine Route gefunden wurde.*/
{
uint_least8_t rating = 50;
do {
@ -94,7 +94,7 @@ int main(int argc, char *argv[]) {
for(struct hotel *currentHotel = hotels; currentHotel - hotels < numberHotels; ++currentHotel) {
/* Wenn das aktuelle Hotel mehr als 360 Minuten vom letzten Hotel entfernt ist,
* muss das letzte Hotel verwendet werden an dem das Halten möglich war.*/
* muss das letzte Hotel verwendet werden, an dem das Halten möglich ist.*/
if(currentHotel->minutes - lastHotelMinutes > 360) {
/* Wenn das Halten nicht möglich ist oder bereits schon viermal
* gehalten wurde, muss es mit einer niedrigeren Bewertung versucht
@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
if(currentHotel->rating >= rating) possibleStop = currentHotel;
}
--rating;
/* Schleife läuft solange "rating" mindestens Eins ist, da es keine niedrigeren Bewertungen
/* Schleife läuft solange "rating" mindestens 1 ist, da es keine niedrigeren Bewertungen
* gibt. Wenn das letzte Hotel höchtens 360 Minuten vom Zielort entfernt ist, wurde
* erfolgreich eine Route gefunden und die Schleife wird beendet. Allerdings wird dies nur
* überprüft, wenn überhaupt an einem Hotel gehalten wurde, um den Zugriff auf nicht

View File

@ -2,4 +2,170 @@
## Lösungsidee
Mithilfe eines Zufallsgenerators kann eine Seite des Würfels und somit die
Augenzahl bestimmt werden. Dann muss entschieden werden welche Figur gezogen
wird. In der folgenden Reihenfolge wird probiert, die Figuren zu ziehen:
1. Wenn eine Figur auf Feld A steht, muss diese gezogen werden.
2. Wurde eine 6 gewürfelt, wird eine neue Figur rausgebracht.
3. Die vorderste Figur auf der Laufbahn, die gezogen werden kann, wird gezogen.
4. Die Figur auf dem Zielfeld, die der Laufbahn am nächsten ist, wird gezogen.
Welche Figur auf dem Zielfeld gezogen wird, ist nicht in den Regeln festgelegt.
Es wäre auch möglich so zu ziehen, dass möglichst keine Figur vor dem Ziel
blockiert wird, d. h. sie mit keinem möglichen Augenzahl gezogen werden kann.
Allerdings wird der Fall, dass zwei verschiedene Figuren auf den Zielfelder
gezogen werden können, selten auftreten. Außerdem wird durch Regeländerung
zu einer festen Priorität der Figuren auf der Laufbahn klar, dass so weit
vorausschauende Lösungen nicht in dieser Aufgabe erwartet werden.
Sollte der Spieler eine 6 würfeln, ist er nochmal dran, ansonsten der andere.
Allerdings stellt sich die Frage, ob dieser auch nochmal dran ist, wenn er
mit der 6 nicht ziehen kann. Nach der Anmerkung gilt "Wenn kein Stein bewegt
werden kann, verfällt der Zug". Hier ist fraglich, was mit "Zug" gemeint ist.
Einerseits können mehrere bewegte Figuren hintereinander als ein Zug angesehen
werden, da der gleiche Spieler dran ist. Allerdings werden zwei Figuren gezogen,
weshalb es auch als zwei Züge angesehen werden kann. Mit "Wer eine „6“ würfelt,
hat nach seinem Zug einen weiteren Wurf frei." wird letzteres unterstützt, weil
"nach seinem Zug" bedeutet, dass bereits ein Zug beendet ist, bevor das zweite Mal
gewürfelt wird. Es sind also zwei Züge sind und nur der erste der beiden verfällt, sodass der
Spieler auch nach Verfallen eines Wurfes mit einer 6 nochmal würfeln darf.
Es ist auch möglich, dass ein Spiel unentschieden ausgeht. Wenn beide Spieler z. B.
keine 1 auf dem Würfel haben, diese aber brauchen, um ins Ziel zu kommen. Stellt
sich die Frage, wie unentschiedene Spiele gezählt werden. Eine Möglichkeit wäre die
Spiele zu wiederholen. Allerdings steht in der Aufgabenstellung: "[...] wie gut diese
Würfel geeignet sind, um das Spiel zu gewinnen". D. h., dass es irrelavant ist, ob
ein Würfel verloren oder unentschieden gespielt hat, sondern nur, wie oft gewonnen
wurde.
## Umsetzung
Das Programm wird in Rust implementiert. Als Argumente müssen Dateipfade zu den
Eingabedateien übergeben werden. Das Spielfeld ist in einer Struktur gespeichert.
Die Laufbahn wird einem 40er-Array innerhalb der Struktur gespeichert. Die
Figuren der beiden Spieler werden durch 0 und 1 dargestellt. Die Spieler werden
auch Spieler 0 und Spieler 1 genannt. Ist an der entsprechenden Stelle keine
Figur, wird dies durch -1 dargestellt. Mit dem gleichen Format hat die Struktur zwei
Arrays für die Zielfelder für die beiden Spieler. Außerdem hat die Struktur ein Attribut, das
die Anzahl der Figuren auf den B-Feldern der beiden Spieler in einem Array speichert.
Schließich hat die Struktur noch ein Attribut, das in einem 2d-Array die Positionen
der Figuren abgespeichert, der erste Index 0 oder 1 entsprechend der beiden Spieler und
der zweite Index für die Figuren des jeweiligen Spielers. Dies ist notwendig, damit schnell
die Figuren gezogen werden können, ohne das das ganze Laufbahn-Array durchsucht werden muss.
Die Methode "step" der "Field"-Struktur zieht die Figuren unter Angabe einer
Figur und dem Würfelergebnis, wenn es möglich ist, und gibt je nach Erfolg
einen Boolean zurück. Außerdem ruft sie die "beat" Methode auf, um die Figur zu
schlagen, die dem Zug im Weg stehen.
In der main Funktion wird mit einer for-Schleife über die Eingabedateien iteriert.
In einer weiteren for-Schleife werden alle möglichen Würfelkombinationen ermittelt.
Wie oft gespielt wird, kann durch die "runs" Variable verändert werden.
Eine while-Schleife läuft solange das Spiel läuft. Mit der "rand"
Bibliothek werden Zufallszahlen erstellt und die Augenzahl bestimmt. Dann wird
entsprechend des oben beschriebenen Algorithmus die "step" Methode aufgerufen.
Wurde erfolgreich ein Zug gemacht, wird überpruft, ob der Spieler gewonnen hat.
Konnte nicht gezogen werden, wird in einem HashSet die Augenzahl gespeichert.
Kann bei keiner Augenzahl bei beiden Spielern eine Figur bewegt werden, wird das Spiel
für Unentschieden erklärt. Wurden alle Spiele simuliert, wird das Ergebnis ausgegeben.
## Beispiele
Ergebnisse für die Beispieldaten:
```
beispieldaten/wuerfel0.txt:
1. Würfel: Würfelseiten: [1, 1, 1, 6, 6, 6], Siege: 977293, Siegwahrscheinlichkeit:
0.977293, Niederlagen: 22707, Niederlagewahrscheinlichkeit: 0.022707, Unentschieden:
0, Unentschiedenwahrscheinlichkeit: 0
2. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6], Siege: 640526, Siegwahrscheinlichkeit:
0.640526, Niederlagen: 359474, Niederlagewahrscheinlichkeit: 0.359474, Unentschieden:
0, Unentschiedenwahrscheinlichkeit: 0
3. Würfel: Würfelseiten: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], Siege: 537390,
Siegwahrscheinlichkeit: 0.53739, Niederlagen: 462610, Niederlagewahrscheinlichkeit:
0.46261, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
4. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], Siege: 528348,
Siegwahrscheinlichkeit: 0.528348, Niederlagen: 471652,
Niederlagewahrscheinlichkeit: 0.471652, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
5. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20], Siege: 316443, Siegwahrscheinlichkeit: 0.316443, Niederlagen:
683557, Niederlagewahrscheinlichkeit: 0.683557, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
6. Würfel: Würfelseiten: [1, 2, 3, 4], Siege: 0, Siegwahrscheinlichkeit: 0,
Niederlagen: 1000000, Niederlagewahrscheinlichkeit: 1, Unentschieden: 0
Unentschiedenwahrscheinlichkeit: 0
```
Der Würfel ohne eine 6, kann natürlich nicht gewinnen.
```
beispieldaten/wuerfel1.txt:
1. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6], Siege: 580726,
Siegwahrscheinlichkeit: 0.580726, Niederlagen: 419274,
eiederlagewahrscheinlichkeit: 0.419274, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
2. Würfel: Würfelseiten: [2, 3, 4, 5, 6, 7], Siege: 568755,
Siegwahrscheinlichkeit: 0.568755, Niederlagen: 327638,
Niederlagewahrscheinlichkeit: 0.327638, Unentschieden: 103607,
Unentschiedenwahrscheinlichkeit: 0.103607
3. Würfel: Würfelseiten: [3, 4, 5, 6, 7, 8], Siege: 497753,
Siegwahrscheinlichkeit: 0.497753, Niederlagen: 325580,
Niederlagewahrscheinlichkeit: 0.32558, Unentschieden: 176667,
Unentschiedenwahrscheinlichkeit: 0.176667
4. Würfel: Würfelseiten: [4, 5, 6, 7, 8, 9], Siege: 406054,
Siegwahrscheinlichkeit: 0.406054, Niederlagen: 363332,
Niederlagewahrscheinlichkeit: 0.363332, Unentschieden: 230614,
Unentschiedenwahrscheinlichkeit: 0.230614
5. Würfel: Würfelseiten: [5, 6, 7, 8, 9, 10], Siege: 247830,
Siegwahrscheinlichkeit: 0.24783, Niederlagen: 463716, Niederlagewahrscheinlichkeit:
0.463716, Unentschieden: 288454, Unentschiedenwahrscheinlichkeit: 0.288454
6. Würfel: Würfelseiten: [6, 7, 8, 9, 10, 11], Siege: 141690,
Siegwahrscheinlichkeit: 0.14169, Niederlagen: 543268,
Niederlagewahrscheinlichkeit: 0.543268, Unentschieden: 315042,
Unentschiedenwahrscheinlichkeit: 0.315042
beispieldaten/wuerfel2.txt:
1. Würfel: Würfelseiten: [1, 6, 6, 6, 6, 6], Siege: 783608,
Siegwahrscheinlichkeit: 0.97951, Niederlagen: 16392, Niederlagewahrscheinlichkeit:
0.02049, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
2. Würfel: Würfelseiten: [1, 1, 6, 6, 6, 6], Siege: 604274,
Siegwahrscheinlichkeit: 0.7553425, Niederlagen: 195726,
Niederlagewahrscheinlichkeit: 0.2446575, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
3. Würfel: Würfelseiten: [1, 1, 1, 6, 6, 6], Siege:
e03792, Siegwahrscheinlichkeit: 0.50474, Niederlagen: 396208,
Niederlagewahrscheinlichkeit: 0.49526, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
4. Würfel: Würfelseiten: [1, 1, 1, 1, 6, 6], Siege: 205269,
Siegwahrscheinlichkeit: 0.25658625, Niederlagen: 594731,
Niederlagewahrscheinlichkeit: 0.74341375, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
5. Würfel: Würfelseiten: [1, 1, 1, 1, 1, 6], Siege: 3057, Siegwahrscheinlichkeit:
0.00382125, Niederlagen: 796943, Niederlagewahrscheinlichkeit: 0.99617875,
Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
beispieldaten/wuerfel3.txt:
1. Würfel: Würfelseiten: [1, 2, 5, 6], Siege: 752618, Siegwahrscheinlichkeit: 0.752618,
Niederlagen: 247382, Niederlagewahrscheinlichkeit: 0.247382, Unentschieden:
0, Unentschiedenwahrscheinlichkeit: 0
2. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6, 7, 8], Siege: 612183,
Siegwahrscheinlichkeit: 0.612183, Niederlagen: 387817,
Niederlagewahrscheinlichkeit: 0.387817, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
3. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6], Siege: 593636, Siegwahrscheinlichkeit:
0.593636, Niederlagen: 406364, Niederlagewahrscheinlichkeit: 0.406364, Unentschieden:
0,
Unentschiedenwahrscheinlichkeit: 0
4. Würfel: Würfelseiten: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], Siege: 447023,
Siegwahrscheinlichkeit: 0.447023, Niederlagen: 552977, Niederlagewahrscheinlichkeit:
0.552977, Unentschieden: 0, Unentschiedenwahrscheinlichkeit: 0
5. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], Siege:
440511, Siegwahrscheinlichkeit: 0.440511, Niederlagen: 559489,
Niederlagewahrscheinlichkeit: 0.559489, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
6. Würfel: Würfelseiten: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20], Siege: 154029, Siegwahrscheinlichkeit: 0.154029, Niederlagen:
845971, Niederlagewahrscheinlichkeit: 0.845971, Unentschieden: 0,
Unentschiedenwahrscheinlichkeit: 0
```
Allgemein sind die Würfel mit der größten Wahrscheinlichkeit eine 6 zu würfeln
am besten. Zum einem, da eine 6 benötigt wird, um raus zu kommen. Außerdem kann man
nochmal würfeln, auch wenn man mit der 6 nicht ziehen konnte. Sehr große Augenzahlen
dagegen sind zwar gut, um viele Schritte auf einmal zu gehen. Allerdings sind sie
kurz vor dem Ziel von Nachteil, da man mit ihnen nicht mehr gehen kann.

View File

@ -17,7 +17,7 @@ struct Dice {
/* Struktur, die das Spielfeld darstellt. Die Member b, destination und pieces sind 2er-Arrays von
* den eigentlichen Arrays (Die Elemente von b sind kein Array. Für diese gilt allerdings das
* gleiche.) Das Array mit dem Index 0 gehört jeweils zu Spieler 0 und das andere zu
* Gleiche.) Das Array mit dem Index 0 gehört jeweils zu Spieler 0 und das andere zu
* Spieler 1. Diesen Spielern sind keine Farben zugeordnet. Wichtig ist nur, dass sie gegenüber
* liegen. */
struct Field {
@ -145,18 +145,24 @@ fn main() {
}
}
// der Würfel tritt gegen alle bereits verarbeiteten an.
// der Würfel tritt gegen alle bereits verarbeiteten Würfel an.
for dice_other in dices.iter_mut() {
let mut selected_dices = [&mut dice, dice_other]; // der Würfel mit dem Index 0, ist auch Spieler 0 und der andere Spieler 1.
for begin in [0, 1] { // das Spiel wird von beiden Spieler gleich oft angefangen
for _ in 0..runs {
let mut turn = begin;
let mut field = Field { // Spielfeld in der Ausgangsstellung
b: [4; 2],
b: [3; 2],
main: [-1; 40],
destination: [[-1; 4]; 2],
pieces: [[-5; 4]; 2],
};
// setzte jeweils eine Figur auf Feld A
field.pieces[0][0] = 0;
field.main[0] = 0;
field.pieces[1][0] = 20;
field.main[20] = 1;
let mut win = false;
while !win { // Schleife solange niemand gewonnen hat.
@ -194,12 +200,12 @@ fn main() {
result
} {
// ein Spieler hat gewonnen wenn alle seine Figuren im Ziel sind.
// Ein Spieler hat gewonnen, wenn alle seine Figuren im Ziel sind.
win = true;
for piece in field.destination[turn] {
win &= piece == turn as i8;
}
if win { // hat jemand gewonnen, werden die Sieges- und Niederlagenzähler erhöht.
if win { // Wenn jemand gewonnen hat, werden die Sieges- und Niederlagenzähler erhöht.
selected_dices[turn].wins += 1;
selected_dices[other_player(turn)].defeats += 1;
}
@ -213,18 +219,19 @@ fn main() {
}
else {
/* Konnte keine Figur gezogen werden, wird die Augenzahl in einem
/* konnte keine Figur gezogen werden, wird die Augenzahl in einem
* HashSet abgespeichert. */
no_move_possible[turn].insert(dice_result);
/* Kann bei keiner möglichen Augenzahl gezogen beider Spieler
/* Kann bei keiner möglichen Augenzahl beider Spieler
* gezogen werden, ist das Spiel unentschieden. */
if no_move_possible[turn].len() as u8 == selected_dices[turn].different_sides_count &&
no_move_possible[other_player(turn)].len() as u8 == selected_dices[other_player(turn)].different_sides_count {
break;
}
}
turn = other_player(turn); // beim nächsten Zug ist der andere Spieler dran.
// beim nächsten Zug ist der andere Spieler dran, außer bei einer 6.
if dice_result != 6 {turn = other_player(turn);}
}
}
}
@ -232,7 +239,7 @@ fn main() {
dices.push(dice);
}
// sotiert die Würfel nach Gewinnen
// sortiert die Würfel nach Gewinnen
dices.sort_unstable_by(|a, b| b.wins.partial_cmp(&a.wins).unwrap());