mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 11:18:06 +00:00
Task 15.1 - install maze generating program (golang, maze-master, git, challenge scenario)
This commit is contained in:
21
modules/utilities/unix/languages/golang/LICENSE
Normal file
21
modules/utilities/unix/languages/golang/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Darren Coxall
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
85
modules/utilities/unix/languages/golang/README.markdown
Normal file
85
modules/utilities/unix/languages/golang/README.markdown
Normal file
@@ -0,0 +1,85 @@
|
||||
# Golang
|
||||
Quickly and easily install the Go programming language with a customisable workspace and version.
|
||||
|
||||
## Usage
|
||||
In order to use this module do the following:
|
||||
|
||||
class { 'golang':
|
||||
version => '1.1.2',
|
||||
workspace => '/usr/local/src/go',
|
||||
}
|
||||
|
||||
This will install go 1.1.2 and setup your workspace in `/usr/local/go`. Your chosen workspace should include a `bin`, `pkg` and `src` directory. The golang module doesn't create these to avoid using the wrong permissions which can cause potential issues using commands like `go get`.
|
||||
|
||||
If you wish to add your own code into the golang workspace but not add the files directly the best method is to create a symlink as demonstrated below:
|
||||
|
||||
file { '/home/user/project':
|
||||
ensure => link,
|
||||
target => '/usr/local/src/go/src/project',
|
||||
}
|
||||
|
||||
Your project can then be accessed by Go:
|
||||
|
||||
$ go test project
|
||||
|
||||
## Additional Options
|
||||
The golang module supports some additional options:
|
||||
|
||||
class { 'golang':
|
||||
arch => 'linux-amd64',
|
||||
download_dir => '/usr/local/src',
|
||||
download_url => 'https://company.intranet/downloads/golang.tar.gz',
|
||||
}
|
||||
|
||||
#### arch
|
||||
The `arch` option is a string which is used in conjunction with the default `download_url`. It is the portion of the url that points to the correct architecture specific download.
|
||||
|
||||
#### download_dir
|
||||
`download_dir` is the location in which the golang tarball is downloaded to. This is configurable in case the default (`/usr/local/src`) is unavailable.
|
||||
|
||||
#### download_url
|
||||
This represents the url in which to download the golang tarball. The default url is made up of `version` and `arch` from the official golang downloads.
|
||||
|
||||
## Contributions
|
||||
This module is fairly young and has only been tested on Debian. All contributions are welcome by forking the project and creating a pull request with your changes.
|
||||
|
||||
## Testing
|
||||
When contributing please add a test/example to confirm everything still works fine.
|
||||
|
||||
git clone <URL> golang
|
||||
# you will also need to puppet module install -i . <dependencies>
|
||||
cd golang
|
||||
for i in examples/*; do; puppet apply --test --noop --modulepath=.. "$i"; done
|
||||
|
||||
The testing is only basic, just ensure the right steps are still executed.
|
||||
|
||||
## Roadmap
|
||||
There are still additional features which would make this module better:
|
||||
|
||||
1. Tests (tut, tut me for not doing them)
|
||||
2. The ability to remove go
|
||||
3. A Go project resource which would automatically symlink the directory?
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Darren Coxall
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
9
modules/utilities/unix/languages/golang/checksums.json
Normal file
9
modules/utilities/unix/languages/golang/checksums.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"LICENSE": "f8a48fc881716de69a658fae9dbb50bf",
|
||||
"README.markdown": "0950eadeb650c56ac6511e60b69a349e",
|
||||
"examples/curl_conflict.pp": "7a4bcaddb50c6103fd61cd0380d72c46",
|
||||
"examples/init.pp": "4de930091b7852fd738722ba9c944569",
|
||||
"manifests/init.pp": "a23ed42a5f92e12961f0dd52ed5c9bf2",
|
||||
"metadata.json": "b08b6b2baa8682ae8d500acdd2f2a81e",
|
||||
"templates/golang.sh.erb": "e1394c9baa0deee28260a1ec2e34b48f"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package { 'curl': ensure => 'present' } ->
|
||||
|
||||
class { 'golang': }
|
||||
7
modules/utilities/unix/languages/golang/examples/init.pp
Normal file
7
modules/utilities/unix/languages/golang/examples/init.pp
Normal file
@@ -0,0 +1,7 @@
|
||||
# Learn more about module testing here:
|
||||
# http://docs.puppetlabs.com/guides/tests_smoke.html
|
||||
|
||||
class { 'golang':
|
||||
version => '1.7.3',
|
||||
workspace => '/usr/local/src/go',
|
||||
}
|
||||
4
modules/utilities/unix/languages/golang/golang.pp
Normal file
4
modules/utilities/unix/languages/golang/golang.pp
Normal file
@@ -0,0 +1,4 @@
|
||||
class { "golang":
|
||||
arch => 'linux-386',
|
||||
version => '1.9',
|
||||
}
|
||||
68
modules/utilities/unix/languages/golang/manifests/init.pp
Normal file
68
modules/utilities/unix/languages/golang/manifests/init.pp
Normal file
@@ -0,0 +1,68 @@
|
||||
# == Class: golang
|
||||
#
|
||||
# Installs the go language allowing you to
|
||||
# execute and compile go.
|
||||
#
|
||||
# === Examples
|
||||
#
|
||||
# class { "golang":}
|
||||
#
|
||||
# === Authors
|
||||
#
|
||||
# Darren Coxall <darren@darrencoxall.com>
|
||||
#
|
||||
class golang (
|
||||
$version = '1.7.3',
|
||||
$workspace = '/vagrant',
|
||||
$arch = 'linux-amd64',
|
||||
$download_dir = '/usr/local/src',
|
||||
$download_url = undef,
|
||||
$download_timeout = 900,
|
||||
) {
|
||||
|
||||
if ($download_url) {
|
||||
$download_location = $download_url
|
||||
} else {
|
||||
$download_location = "https://storage.googleapis.com/golang/go${version}.${arch}.tar.gz"
|
||||
}
|
||||
|
||||
Exec {
|
||||
path => '/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin',
|
||||
}
|
||||
|
||||
$package_prereqs = [
|
||||
'curl',
|
||||
'mercurial',
|
||||
]
|
||||
|
||||
ensure_packages($package_prereqs)
|
||||
|
||||
exec { 'download':
|
||||
command => "curl -o ${download_dir}/go-${version}.tar.gz ${download_location}",
|
||||
creates => "${download_dir}/go-${version}.tar.gz",
|
||||
unless => "which go && go version | grep '${version}'",
|
||||
require => Package['curl'],
|
||||
timeout => $download_timeout,
|
||||
} ->
|
||||
exec { 'unarchive':
|
||||
command => "tar -C /usr/local -xzf ${download_dir}/go-${version}.tar.gz && rm ${download_dir}/go-${version}.tar.gz",
|
||||
onlyif => "test -f ${download_dir}/go-${version}.tar.gz",
|
||||
}
|
||||
|
||||
exec { 'remove-previous':
|
||||
command => 'rm -r /usr/local/go',
|
||||
onlyif => [
|
||||
'test -d /usr/local/go',
|
||||
"which go && test `go version | cut -d' ' -f 3` != 'go${version}'",
|
||||
],
|
||||
before => Exec['unarchive'],
|
||||
}
|
||||
|
||||
file { '/etc/profile.d/golang.sh':
|
||||
content => template('golang/golang.sh.erb'),
|
||||
owner => root,
|
||||
group => root,
|
||||
mode => 'a+x',
|
||||
}
|
||||
|
||||
}
|
||||
14
modules/utilities/unix/languages/golang/metadata.json
Normal file
14
modules/utilities/unix/languages/golang/metadata.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "dcoxall-golang",
|
||||
"version": "1.2.0",
|
||||
"author": "Darren Coxall",
|
||||
"summary": "A barebones Go installation",
|
||||
"license": "MIT",
|
||||
"source": "https://github.com/dcoxall/dcoxall-golang",
|
||||
"project_page": "https://github.com/dcoxall/dcoxall-golang",
|
||||
"issues_url": "https://github.com/dcoxall/dcoxall-golang/issues",
|
||||
"dependencies": [
|
||||
{"name":"puppetlabs/stdlib","version_requirement":">= 4.1.0 < 5.0.0"}
|
||||
],
|
||||
"data_provider": null
|
||||
}
|
||||
24
modules/utilities/unix/languages/golang/secgen_metadata.xml
Normal file
24
modules/utilities/unix/languages/golang/secgen_metadata.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<utility xmlns="http://www.github/cliffe/SecGen/utility"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/utility">
|
||||
<name>Go programming language</name>
|
||||
<author>Darren Coxall</author>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>An installation of the Go programming language</description>
|
||||
|
||||
<type>language</type>
|
||||
<type>go</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
<!--optional details-->
|
||||
<reference>https://forge.puppet.com/dcoxall/golang</reference>
|
||||
<software_name>golang</software_name>
|
||||
<software_license>MIT</software_license>
|
||||
|
||||
<requires>
|
||||
<type>update</type>
|
||||
</requires>
|
||||
</utility>
|
||||
@@ -0,0 +1,3 @@
|
||||
GOPATH="<%= @workspace %>"
|
||||
PATH="$GOPATH/bin:/usr/local/go/bin:$PATH"
|
||||
export GOPATH PATH
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
<!--optional details-->
|
||||
<reference>https://git-scm.com/</reference>
|
||||
<software_name>git</software_name>
|
||||
|
||||
<conflict>
|
||||
<name>Stretch</name>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
include echo_string::install
|
||||
@@ -1,17 +0,0 @@
|
||||
class echo_string::install {
|
||||
$secgen_params = secgen_functions::get_parameters($::base64_inputs_file)
|
||||
$challenge_name = $secgen_params['challenge_name'][0]
|
||||
|
||||
::secgen_functions::install_setgid_script { $challenge_name:
|
||||
source_module_name => $module_name,
|
||||
challenge_name => $challenge_name,
|
||||
script_name => "$challenge_name.rb",
|
||||
script_data => $secgen_params['script_data'],
|
||||
group => $secgen_params['group'],
|
||||
account => $secgen_params['account'],
|
||||
flag => $secgen_params['flag'],
|
||||
port => $secgen_params['port'],
|
||||
storage_directory => $secgen_params['storage_directory'],
|
||||
strings_to_leak => $secgen_params['strings_to_leak'],
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<vulnerability xmlns="http://www.github/cliffe/SecGen/vulnerability"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/vulnerability">
|
||||
<name>Echo String Challenge</name>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>Programming challenge which involves echoing a random string back.</description>
|
||||
|
||||
<type>ctf_challenge</type>
|
||||
<privilege>none</privilege>
|
||||
<access>local</access>
|
||||
<platform>linux</platform>
|
||||
|
||||
<challenge_type>misc</challenge_type>
|
||||
<challenge_subtype>programming</challenge_subtype>
|
||||
<difficulty>low</difficulty>
|
||||
|
||||
<!-- script dropped in account's home directory by default with setuid configuration. -->
|
||||
<read_fact>challenge_name</read_fact>
|
||||
<read_fact>script_data</read_fact>
|
||||
<read_fact>account</read_fact>
|
||||
<read_fact>flag</read_fact>
|
||||
<read_fact>group</read_fact>
|
||||
<!-- storage_directory: Blank by default. If supplied, store the files here. e.g. NFS or SMB storage location -->
|
||||
<read_fact>storage_directory</read_fact>
|
||||
<!-- port: Blank by default. If supplied install script challenge as xinetd program running on given port
|
||||
TODO: investigate why this doesnt work with nc -->
|
||||
<!--<read_fact>port</read_fact>-->
|
||||
|
||||
<default_input into="challenge_name">
|
||||
<value>echo_string</value>
|
||||
</default_input>
|
||||
<default_input into="script_data">
|
||||
<generator module_path=".*echo_string.*"/>
|
||||
</default_input>
|
||||
<default_input into="account">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<value>challenges</value>
|
||||
</input>
|
||||
<input into="password">
|
||||
<value>password</value>
|
||||
</input>
|
||||
</generator>
|
||||
</default_input>
|
||||
<default_input into="group">
|
||||
<value>echo_string</value>
|
||||
</default_input>
|
||||
<default_input into="flag">
|
||||
<generator type="flag_generator"/>
|
||||
</default_input>
|
||||
|
||||
<requires>
|
||||
<module_path>utilities/unix/system/accounts</module_path>
|
||||
</requires>
|
||||
|
||||
<requires>
|
||||
<module_path>utilities/unix/system/binary_script_container</module_path>
|
||||
</requires>
|
||||
|
||||
<requires>
|
||||
<module_path>utilities/unix/languages/ruby</module_path>
|
||||
</requires>
|
||||
|
||||
<requires>
|
||||
<module_path>utilities/unix/system/xinetd</module_path>
|
||||
</requires>
|
||||
|
||||
</vulnerability>
|
||||
4
modules/vulnerabilities/unix/ctf/programming/maze/files/maze-master/.gitignore
vendored
Normal file
4
modules/vulnerabilities/unix/ctf/programming/maze/files/maze-master/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/build
|
||||
/goxz
|
||||
.golint.txt
|
||||
/vendor
|
||||
@@ -0,0 +1,29 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.9
|
||||
env: PATH=/home/travis/gopath/bin:$PATH
|
||||
script:
|
||||
- make test
|
||||
- make lint
|
||||
- make cross
|
||||
deploy:
|
||||
provider: releases
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
secure: El/qxSDFFxk0KCI4e7ed6Jyau6Lw4u8h9CejN1ke2WHez6Nyv9f41uEM+EQFxp/mfdVEAlkjAA/A+nknWP9gJeANqhCpmEaFQ5J3eaW2nECd8fglclqdVP9NZ7Fbl4qTKsQpD7xYfFUk+P++4dVKZXuutNXT9gPUjVbzOx/tCnl1CwktOEFPEpv9fy64vD00ywUg1SaJgSl5dqA2RGunNSh6hr+pELXYjQ0uQzjMG+Gpknga0EWQEZleOXspw0ClUTrMYuqTooM/8yFfmG5d/p/8wQCCvyIBEQYCSOoOL+li7CBO26GnBvuPxMTvEzQ+0jjOxaEEgc+hOLo1elB+NbxT9Wz5NkJYbkmSUSfk9OZ4vmcvRZbQR9aiqZTeLVB8x6ln/Xzk45zeORcjRQI0fXd5k/dYRLKxKc3DQcXpa3ASzM8VXjx4p3YjcmqMvt+KtKhFL+DbSGxsxjuR6ulk3QJtuM3hnnsRkz58VTZunFsknRr3b0s8pHBYpGw+wLwWJ+IOrk0GBl0MBV705upoi+8xJiqZ7LPvkAe3XRDSV2jPZUyvn5+gzTQ597zTk3zZrpzQ0809UdQRWWkQYF7udozQ4K9+qk34j8Z2IAykgn+ClRmgTdiH87DAIBsZmeSEMjvripBMs5Vkbe3ijnyKuGPREjZ4bgEKrNVl9Y5yNg0=
|
||||
file:
|
||||
- goxz/maze_darwin_386.zip
|
||||
- goxz/maze_darwin_amd64.zip
|
||||
- goxz/maze_freebsd_386.tar.gz
|
||||
- goxz/maze_freebsd_amd64.tar.gz
|
||||
- goxz/maze_linux_386.tar.gz
|
||||
- goxz/maze_linux_amd64.tar.gz
|
||||
- goxz/maze_netbsd_386.tar.gz
|
||||
- goxz/maze_netbsd_amd64.tar.gz
|
||||
- goxz/maze_windows_386.zip
|
||||
- goxz/maze_windows_amd64.zip
|
||||
on:
|
||||
repo: itchyny/maze
|
||||
tags: true
|
||||
all_branches: false
|
||||
39
modules/vulnerabilities/unix/ctf/programming/maze/files/maze-master/Gopkg.lock
generated
Normal file
39
modules/vulnerabilities/unix/ctf/programming/maze/files/maze-master/Gopkg.lock
generated
Normal file
@@ -0,0 +1,39 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/codegangsta/cli"
|
||||
packages = ["."]
|
||||
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
|
||||
version = "v1.20.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/nsf/termbox-go"
|
||||
packages = ["."]
|
||||
revision = "aa4a75b1c20a2b03751b1a9f7e41d58bd6f71c43"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "83801418e1b59fb1880e363299581ee543af32ca"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "7ae4b9c97302a35f895e8e4aeaa1bfef36b827a9099b7ab07af89162f5abdee3"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/codegangsta/cli"
|
||||
version = "1.20.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
version = "0.0.3"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/nsf/termbox-go"
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 itchyny
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,41 @@
|
||||
BIN = maze
|
||||
DIR = ./cmd/maze
|
||||
GOROOT ?= /usr/local/go
|
||||
|
||||
all: clean test build
|
||||
|
||||
build: deps
|
||||
go build -o build/$(BIN) $(DIR)
|
||||
|
||||
install: deps
|
||||
go install ./...
|
||||
|
||||
deps:
|
||||
go get -u github.com/golang/dep/cmd/dep
|
||||
dep ensure
|
||||
|
||||
cross: crossdeps
|
||||
goxz -os=linux,darwin,freebsd,netbsd,windows -arch=386,amd64 -n $(BIN) $(DIR)
|
||||
|
||||
crossdeps: deps
|
||||
go get github.com/Songmu/goxz/cmd/goxz
|
||||
|
||||
test: testdeps build
|
||||
go test -v $(DIR)...
|
||||
|
||||
testdeps:
|
||||
go get -d -v -t ./...
|
||||
|
||||
lint: lintdeps build
|
||||
go vet
|
||||
golint -set_exit_status $(go list ./... | grep -v /vendor/)
|
||||
|
||||
lintdeps:
|
||||
go get -d -v -t ./...
|
||||
go get -u github.com/golang/lint/golint
|
||||
|
||||
clean:
|
||||
rm -rf build goxz
|
||||
go clean
|
||||
|
||||
.PHONY: build install deps cross crossdeps test testdeps lint lintdeps clean
|
||||
@@ -0,0 +1,60 @@
|
||||
# maze [](https://travis-ci.org/itchyny/maze)
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
The `maze` command without the arguments prints the random maze to the standard output.
|
||||
```sh
|
||||
maze
|
||||
```
|
||||

|
||||
|
||||
We can play the maze on the terminal with `--interactive`.
|
||||
```sh
|
||||
maze --interactive
|
||||
```
|
||||

|
||||
|
||||
The `--format color` is a good option to print the colored maze. Also we can specify the size of the maze with `--width` and `--height`.
|
||||
```sh
|
||||
maze --width 20 --height 10 --format color
|
||||
```
|
||||

|
||||
|
||||
We can toggle the solution with the `s` key.
|
||||

|
||||
|
||||
If we change the font size of the terminal smaller, we get a large maze.
|
||||

|
||||
|
||||
## Installation
|
||||
### Homebrew
|
||||
```bash
|
||||
$ brew install itchyny/maze/maze
|
||||
```
|
||||
|
||||
### Download binary from GitHub Releases
|
||||
[Releases・itchyny/maze - GitHub](https://github.com/itchyny/maze/releases)
|
||||
|
||||
### Build from source
|
||||
```bash
|
||||
$ go get -u github.com/itchyny/maze/cmd/maze
|
||||
```
|
||||
|
||||
## Bug Tracker
|
||||
Report bug at [Issues・itchyny/maze - GitHub](https://github.com/itchyny/maze/issues).
|
||||
|
||||
## Author
|
||||
itchyny (https://github.com/itchyny)
|
||||
|
||||
## License
|
||||
This software is released under the MIT License, see LICENSE.
|
||||
|
||||
## Special thanks
|
||||
Special thanks to the [termbox-go](https://github.com/nsf/termbox-go) library.
|
||||
|
||||
## References
|
||||
- [Maze generation algorithm - Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Maze_generation_algorithm)
|
||||
- [Maze solving algorithm - Wikipedia, the free encyclopedia](https://en.wikipedia.org/wiki/Maze_solving_algorithm)
|
||||
- [lunixbochs/maze: Maze generation and salvation](https://github.com/lunixbochs/maze)
|
||||
- [willfrew/maze-generation: Some maze generation algorithms written in Go](https://github.com/willfrew/maze-generation)
|
||||
@@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/itchyny/maze"
|
||||
"github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
func action(ctx *cli.Context) error {
|
||||
err := termbox.Init()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, err.Error())
|
||||
return nil
|
||||
}
|
||||
config, errors := makeConfig(ctx)
|
||||
if errors != nil {
|
||||
hasErr := false
|
||||
termbox.Close()
|
||||
for _, err := range errors {
|
||||
if err.Error() != "" {
|
||||
fmt.Fprintf(os.Stderr, err.Error()+"\n")
|
||||
hasErr = true
|
||||
}
|
||||
}
|
||||
if hasErr {
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
}
|
||||
cli.ShowAppHelp(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
maze := createMaze(config)
|
||||
if config.Interactive {
|
||||
defer termbox.Close()
|
||||
interactive(maze, config.Format)
|
||||
} else {
|
||||
termbox.Close()
|
||||
if config.Image {
|
||||
maze.PrintImage(config.Output, config.Format, config.Scale)
|
||||
} else {
|
||||
maze.Print(config.Output, config.Format)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createMaze(config *Config) *maze.Maze {
|
||||
rand.Seed(config.Seed)
|
||||
maze := maze.NewMaze(config.Height, config.Width)
|
||||
maze.Start = config.Start
|
||||
maze.Goal = config.Goal
|
||||
maze.Cursor = config.Start
|
||||
maze.Generate()
|
||||
if config.Solution {
|
||||
maze.Solve()
|
||||
}
|
||||
return maze
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/itchyny/maze"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
// Config is the command configuration
|
||||
type Config struct {
|
||||
Width int
|
||||
Height int
|
||||
Start *maze.Point
|
||||
Goal *maze.Point
|
||||
Interactive bool
|
||||
Image bool
|
||||
Scale int
|
||||
Solution bool
|
||||
Format *maze.Format
|
||||
Seed int64
|
||||
Output io.Writer
|
||||
}
|
||||
|
||||
func makeConfig(ctx *cli.Context) (*Config, []error) {
|
||||
var errs []error
|
||||
|
||||
if ctx.GlobalBool("help") {
|
||||
errs = append(errs, errors.New(""))
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
termWidth, termHeight := termbox.Size()
|
||||
|
||||
width := ctx.GlobalInt("width")
|
||||
if width <= 0 {
|
||||
width = (termWidth - 4) / 4
|
||||
}
|
||||
|
||||
height := ctx.GlobalInt("height")
|
||||
if height <= 0 {
|
||||
height = (termHeight - 5) / 2
|
||||
}
|
||||
|
||||
start := &maze.Point{0, 0}
|
||||
starts := strings.Split(ctx.GlobalString("start"), ",")
|
||||
if len(starts) > 0 {
|
||||
if value, err := strconv.Atoi(starts[0]); err == nil {
|
||||
if 0 <= value && value < height {
|
||||
start.X = value
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(starts) > 1 {
|
||||
if value, err := strconv.Atoi(starts[1]); err == nil {
|
||||
if 0 <= value && value < width {
|
||||
start.Y = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goal := &maze.Point{height - 1, width - 1}
|
||||
goals := strings.Split(ctx.GlobalString("goal"), ",")
|
||||
if len(goals) > 0 {
|
||||
if value, err := strconv.Atoi(goals[0]); err == nil {
|
||||
if 0 <= value && value < height {
|
||||
goal.X = value
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(goals) > 1 {
|
||||
if value, err := strconv.Atoi(goals[1]); err == nil {
|
||||
if 0 <= value && value < width {
|
||||
goal.Y = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interactive := ctx.GlobalBool("interactive")
|
||||
|
||||
solution := ctx.GlobalBool("solution")
|
||||
|
||||
format := maze.Default
|
||||
if ctx.GlobalString("format") == "color" {
|
||||
format = maze.Color
|
||||
}
|
||||
|
||||
output := ctx.App.Writer
|
||||
outfile := ctx.GlobalString("output")
|
||||
if outfile != "" {
|
||||
file, err := os.Create(outfile)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.New("cannot create the output file: "+outfile))
|
||||
} else {
|
||||
output = file
|
||||
}
|
||||
}
|
||||
|
||||
image := ctx.GlobalBool("image")
|
||||
if image {
|
||||
if file, ok := output.(*os.File); ok && isatty.IsTerminal(file.Fd()) {
|
||||
errs = append(errs, errors.New("cannot write binary data into the terminal\nuse -output flag"))
|
||||
}
|
||||
}
|
||||
|
||||
scale := ctx.GlobalInt("scale")
|
||||
|
||||
seed := int64(ctx.GlobalInt("seed"))
|
||||
if !ctx.IsSet("seed") {
|
||||
seed = time.Now().UnixNano()
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return nil, errs
|
||||
}
|
||||
|
||||
return &Config{
|
||||
Width: width,
|
||||
Height: height,
|
||||
Start: start,
|
||||
Goal: goal,
|
||||
Interactive: interactive,
|
||||
Image: image,
|
||||
Scale: scale,
|
||||
Solution: solution,
|
||||
Format: format,
|
||||
Seed: seed,
|
||||
Output: output,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
var flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "width",
|
||||
Usage: "The width of the maze",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "height",
|
||||
Usage: "The height of the maze",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "start",
|
||||
Usage: "The start coordinate",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "goal",
|
||||
Usage: "The goal coordinate",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "interactive",
|
||||
Usage: "Play the maze interactively",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "solution",
|
||||
Usage: "Print the maze with the solution",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "Output format, `default` or `color`",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "output, o",
|
||||
Usage: "Output file name",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "image",
|
||||
Usage: "Generate image",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "scale",
|
||||
Usage: "Scale of the image",
|
||||
Value: 1,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "seed",
|
||||
Usage: "The random seed",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "help, h",
|
||||
Usage: "Shows the help of the command",
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/itchyny/maze"
|
||||
"github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
type keyDir struct {
|
||||
key termbox.Key
|
||||
char rune
|
||||
dir int
|
||||
}
|
||||
|
||||
var keyDirs = []*keyDir{
|
||||
{termbox.KeyArrowUp, 'k', maze.Up},
|
||||
{termbox.KeyArrowDown, 'j', maze.Down},
|
||||
{termbox.KeyArrowLeft, 'h', maze.Left},
|
||||
{termbox.KeyArrowRight, 'l', maze.Right},
|
||||
}
|
||||
|
||||
func interactive(maze *maze.Maze, format *maze.Format) {
|
||||
events := make(chan termbox.Event)
|
||||
go func() {
|
||||
for {
|
||||
events <- termbox.PollEvent()
|
||||
}
|
||||
}()
|
||||
strwriter := make(chan string)
|
||||
ticker := time.NewTicker(10 * time.Millisecond)
|
||||
go printTermbox(maze, strwriter, time.Now())
|
||||
maze.Started = true
|
||||
maze.Write(strwriter, format)
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case event := <-events:
|
||||
if event.Type == termbox.EventKey {
|
||||
if !maze.Finished {
|
||||
for _, keydir := range keyDirs {
|
||||
if event.Key == keydir.key || event.Ch == keydir.char {
|
||||
maze.Move(keydir.dir)
|
||||
if maze.Finished {
|
||||
maze.Solve()
|
||||
}
|
||||
maze.Write(strwriter, format)
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
if event.Key == termbox.KeyCtrlZ || event.Ch == 'u' {
|
||||
maze.Undo()
|
||||
maze.Write(strwriter, format)
|
||||
} else if event.Ch == 's' {
|
||||
if maze.Solved {
|
||||
maze.Clear()
|
||||
} else {
|
||||
maze.Solve()
|
||||
}
|
||||
maze.Write(strwriter, format)
|
||||
}
|
||||
}
|
||||
if event.Ch == 'q' || event.Ch == 'Q' || event.Key == termbox.KeyCtrlC || event.Key == termbox.KeyCtrlD {
|
||||
break loop
|
||||
}
|
||||
}
|
||||
case <-ticker.C:
|
||||
if !maze.Finished {
|
||||
strwriter <- "\u0000"
|
||||
}
|
||||
}
|
||||
}
|
||||
ticker.Stop()
|
||||
}
|
||||
|
||||
func printTermbox(maze *maze.Maze, strwriter chan string, start time.Time) {
|
||||
x, y := 1, 0
|
||||
for {
|
||||
str := <-strwriter
|
||||
switch str {
|
||||
case "\u0000":
|
||||
printFinished(maze, time.Now().Sub(start))
|
||||
termbox.Flush()
|
||||
x, y = 1, 0
|
||||
default:
|
||||
printString(str, &x, &y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printString(str string, x *int, y *int) {
|
||||
attr, skip, d0, d1, d := false, false, '0', '0', false
|
||||
fg, bg := termbox.ColorDefault, termbox.ColorDefault
|
||||
for _, c := range str {
|
||||
if c == '\n' {
|
||||
*x, *y = (*x)+1, 0
|
||||
} else if c == '\x1b' || attr && c == '[' {
|
||||
attr = true
|
||||
} else if attr && unicode.IsDigit(c) {
|
||||
if !skip {
|
||||
if d {
|
||||
d1 = c
|
||||
} else {
|
||||
d0, d = c, true
|
||||
}
|
||||
}
|
||||
} else if attr && c == ';' {
|
||||
skip = true
|
||||
} else if attr && c == 'm' {
|
||||
if d0 == '7' && d1 == '0' {
|
||||
fg, bg = termbox.AttrReverse, termbox.AttrReverse
|
||||
} else if d0 == '3' {
|
||||
fg, bg = termbox.Attribute(uint64(d1-'0'+1)), termbox.ColorDefault
|
||||
} else if d0 == '4' {
|
||||
fg, bg = termbox.ColorDefault, termbox.Attribute(uint64(d1-'0'+1))
|
||||
} else {
|
||||
fg, bg = termbox.ColorDefault, termbox.ColorDefault
|
||||
}
|
||||
attr, skip, d0, d1, d = false, false, '0', '0', false
|
||||
} else {
|
||||
termbox.SetCell(*y, *x, c, fg, bg)
|
||||
*y = *y + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printFinished(maze *maze.Maze, duration time.Duration) {
|
||||
str := fmt.Sprintf("%8d.%02ds ", int64(duration/time.Second), int64((duration%time.Second)/1e7))
|
||||
fg, bg := termbox.ColorDefault, termbox.ColorDefault
|
||||
if maze.Finished {
|
||||
x, y := maze.Height, 2*maze.Width-6
|
||||
if y < 0 {
|
||||
y = 0
|
||||
}
|
||||
for j, s := range []string{
|
||||
" ",
|
||||
" Finished! ",
|
||||
str,
|
||||
" ",
|
||||
" Press q to quit ",
|
||||
" "} {
|
||||
for i, c := range s {
|
||||
termbox.SetCell(y+i, x+j, c, fg, bg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i, c := range str {
|
||||
termbox.SetCell(4*maze.Width+i-8, 1, c, fg, bg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var name = "maze"
|
||||
var version = "v0.0.2"
|
||||
var description = "Maze generating and solving program"
|
||||
var author = "itchyny"
|
||||
|
||||
func main() {
|
||||
os.Exit(run(os.Args))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
build, _ := filepath.Abs("../build")
|
||||
filepath.Walk("../test", func(path string, info os.FileInfo, err error) error {
|
||||
if strings.HasSuffix(path, ".sh") {
|
||||
cmd := exec.Command("bash", filepath.Base(path))
|
||||
cmd.Dir = filepath.Dir(path)
|
||||
cmd.Env = append(os.Environ(), "PATH="+build+":"+"/bin")
|
||||
stderr := new(bytes.Buffer)
|
||||
cmd.Stderr = stderr
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Errorf("FAIL: execution failed: " + path + ": " + err.Error() + " " + stderr.String())
|
||||
} else {
|
||||
outfile := strings.TrimSuffix(path, filepath.Ext(path)) + ".txt"
|
||||
expected, err := ioutil.ReadFile(outfile)
|
||||
if err != nil {
|
||||
t.Errorf("FAIL: error on reading output file: " + outfile)
|
||||
} else if strings.HasPrefix(string(output), strings.TrimSuffix(string(expected), "\n")) {
|
||||
t.Logf("PASS: " + path + "\n")
|
||||
} else {
|
||||
t.Errorf("FAIL: output differs: " + path + "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
func run(args []string) int {
|
||||
app := newApp()
|
||||
if app.Run(args) != nil {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func newApp() *cli.App {
|
||||
app := cli.NewApp()
|
||||
app.Name = name
|
||||
app.HelpName = name
|
||||
app.Usage = description
|
||||
app.Version = version
|
||||
app.Author = author
|
||||
app.Flags = flags
|
||||
app.HideHelp = true
|
||||
app.Action = action
|
||||
return app
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
package maze
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Maze cell configurations
|
||||
// The paths of the maze is represented in the binary representation.
|
||||
const (
|
||||
Up = 1 << iota
|
||||
Down
|
||||
Left
|
||||
Right
|
||||
)
|
||||
|
||||
// The solution path is represented by (Up|Down|Left|Right) << SolutionOffset.
|
||||
// The user's path is represented by (Up|Down|Left|Right) << VisitedOffset.
|
||||
const (
|
||||
SolutionOffset = 4
|
||||
VisitedOffset = 8
|
||||
)
|
||||
|
||||
// Directions is the set of all the directions
|
||||
var Directions = []int{Up, Down, Left, Right}
|
||||
|
||||
// The differences in the x-y coordinate
|
||||
var dx = map[int]int{Up: -1, Down: 1, Left: 0, Right: 0}
|
||||
var dy = map[int]int{Up: 0, Down: 0, Left: -1, Right: 1}
|
||||
|
||||
// Opposite directions
|
||||
var Opposite = map[int]int{Up: Down, Down: Up, Left: Right, Right: Left}
|
||||
|
||||
// Point on the maze
|
||||
type Point struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
// Equal judges the equality of the two points
|
||||
func (point *Point) Equal(target *Point) bool {
|
||||
return point.X == target.X && point.Y == target.Y
|
||||
}
|
||||
|
||||
// Advance the point forward by the argument direction
|
||||
func (point *Point) Advance(direction int) *Point {
|
||||
return &Point{point.X + dx[direction], point.Y + dy[direction]}
|
||||
}
|
||||
|
||||
// Maze represents the configuration of a maze
|
||||
type Maze struct {
|
||||
Directions [][]int
|
||||
Height int
|
||||
Width int
|
||||
Start *Point
|
||||
Goal *Point
|
||||
Cursor *Point
|
||||
Solved bool
|
||||
Started bool
|
||||
Finished bool
|
||||
}
|
||||
|
||||
// NewMaze creates a new maze
|
||||
func NewMaze(height int, width int) *Maze {
|
||||
var directions [][]int
|
||||
for x := 0; x < height; x++ {
|
||||
directions = append(directions, make([]int, width))
|
||||
}
|
||||
return &Maze{directions, height, width, &Point{0, 0}, &Point{height - 1, width - 1}, &Point{0, 0}, false, false, false}
|
||||
}
|
||||
|
||||
// Contains judges whether the argument point is inside the maze or not
|
||||
func (maze *Maze) Contains(point *Point) bool {
|
||||
return 0 <= point.X && point.X < maze.Height && 0 <= point.Y && point.Y < maze.Width
|
||||
}
|
||||
|
||||
// Neighbors gathers the nearest undecided points
|
||||
func (maze *Maze) Neighbors(point *Point) (neighbors []int) {
|
||||
for _, direction := range Directions {
|
||||
next := point.Advance(direction)
|
||||
if maze.Contains(next) && maze.Directions[next.X][next.Y] == 0 {
|
||||
neighbors = append(neighbors, direction)
|
||||
}
|
||||
}
|
||||
return neighbors
|
||||
}
|
||||
|
||||
// Connected judges whether the two points is connected by a path on the maze
|
||||
func (maze *Maze) Connected(point *Point, target *Point) bool {
|
||||
dir := maze.Directions[point.X][point.Y]
|
||||
for _, direction := range Directions {
|
||||
if dir&direction != 0 {
|
||||
next := point.Advance(direction)
|
||||
if next.X == target.X && next.Y == target.Y {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Next advances the maze path randomly and returns the new point
|
||||
func (maze *Maze) Next(point *Point) *Point {
|
||||
neighbors := maze.Neighbors(point)
|
||||
if len(neighbors) == 0 {
|
||||
return nil
|
||||
}
|
||||
direction := neighbors[rand.Int()%len(neighbors)]
|
||||
maze.Directions[point.X][point.Y] |= direction
|
||||
next := point.Advance(direction)
|
||||
maze.Directions[next.X][next.Y] |= Opposite[direction]
|
||||
return next
|
||||
}
|
||||
|
||||
// Generate the maze
|
||||
func (maze *Maze) Generate() {
|
||||
point := maze.Start
|
||||
stack := []*Point{point}
|
||||
for len(stack) > 0 {
|
||||
for {
|
||||
point = maze.Next(point)
|
||||
if point == nil {
|
||||
break
|
||||
}
|
||||
stack = append(stack, point)
|
||||
}
|
||||
i := rand.Int() % ((len(stack) + 1) / 2)
|
||||
point = stack[i]
|
||||
stack = append(stack[:i], stack[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
// Solve the maze
|
||||
func (maze *Maze) Solve() {
|
||||
if maze.Solved {
|
||||
return
|
||||
}
|
||||
point := maze.Start
|
||||
stack := []*Point{point}
|
||||
solution := []*Point{point}
|
||||
visited := 1 << 12
|
||||
// Repeat until we reach the goal
|
||||
for !point.Equal(maze.Goal) {
|
||||
maze.Directions[point.X][point.Y] |= visited
|
||||
for _, direction := range Directions {
|
||||
// Push the nearest points to the stack if not been visited yet
|
||||
if maze.Directions[point.X][point.Y]&direction == direction {
|
||||
next := point.Advance(direction)
|
||||
if maze.Directions[next.X][next.Y]&visited == 0 {
|
||||
stack = append(stack, next)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pop the stack
|
||||
point = stack[len(stack)-1]
|
||||
stack = stack[:len(stack)-1]
|
||||
// We have reached to a dead end so we pop the solution
|
||||
for last := solution[len(solution)-1]; !maze.Connected(point, last); {
|
||||
solution = solution[:len(solution)-1]
|
||||
last = solution[len(solution)-1]
|
||||
}
|
||||
solution = append(solution, point)
|
||||
}
|
||||
// Fill the solution path on the maze
|
||||
for i, point := range solution {
|
||||
if i < len(solution)-1 {
|
||||
next := solution[i+1]
|
||||
for _, direction := range Directions {
|
||||
if maze.Directions[point.X][point.Y]&direction == direction {
|
||||
temp := point.Advance(direction)
|
||||
if next.X == temp.X && next.Y == temp.Y {
|
||||
maze.Directions[point.X][point.Y] |= direction << SolutionOffset
|
||||
maze.Directions[next.X][next.Y] |= Opposite[direction] << SolutionOffset
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
maze.Solved = true
|
||||
}
|
||||
|
||||
// Clear the solution
|
||||
func (maze *Maze) Clear() {
|
||||
all := Up | Down | Left | Right
|
||||
all |= all << VisitedOffset // Do not clear the user's path
|
||||
for _, directions := range maze.Directions {
|
||||
for j := range directions {
|
||||
directions[j] &= all
|
||||
}
|
||||
}
|
||||
maze.Solved = false
|
||||
}
|
||||
|
||||
// Move the cursor
|
||||
func (maze *Maze) Move(direction int) {
|
||||
point := maze.Cursor
|
||||
next := point.Advance(direction)
|
||||
// If there's a path on the maze, we can move the cursor
|
||||
if maze.Contains(next) && maze.Directions[point.X][point.Y]&direction == direction {
|
||||
maze.Directions[point.X][point.Y] ^= direction << VisitedOffset
|
||||
maze.Directions[next.X][next.Y] ^= Opposite[direction] << VisitedOffset
|
||||
maze.Cursor = next
|
||||
}
|
||||
maze.Started = true
|
||||
// Check if the cursor has reached the goal or not
|
||||
maze.Finished = maze.Cursor.Equal(maze.Goal)
|
||||
}
|
||||
|
||||
// Undo the visited path
|
||||
func (maze *Maze) Undo() {
|
||||
point := maze.Cursor
|
||||
next := point
|
||||
for {
|
||||
// Find the previous point
|
||||
for _, direction := range Directions {
|
||||
if (maze.Directions[point.X][point.Y]>>VisitedOffset)&direction != 0 {
|
||||
next = point.Advance(direction)
|
||||
maze.Directions[point.X][point.Y] ^= direction << VisitedOffset
|
||||
maze.Directions[next.X][next.Y] ^= Opposite[direction] << VisitedOffset
|
||||
break
|
||||
}
|
||||
}
|
||||
if point.Equal(next) {
|
||||
// Previous point was not found (for example: the start point)
|
||||
break
|
||||
} else {
|
||||
// Move backward
|
||||
point = next
|
||||
// If there's another path which has not been visited, stop the procedure
|
||||
count := 0
|
||||
for _, direction := range Directions {
|
||||
if maze.Directions[next.X][next.Y]&direction != 0 {
|
||||
count = count + 1
|
||||
}
|
||||
}
|
||||
// The path we came from, we visited once and another
|
||||
if count > 2 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// Move back the cursor
|
||||
maze.Cursor = point
|
||||
maze.Finished = maze.Cursor.Equal(maze.Goal)
|
||||
}
|
||||
|
||||
// Format is the printing format of the maze
|
||||
type Format struct {
|
||||
Wall string
|
||||
Path string
|
||||
StartLeft string
|
||||
StartRight string
|
||||
GoalLeft string
|
||||
GoalRight string
|
||||
Solution string
|
||||
SolutionStartLeft string
|
||||
SolutionStartRight string
|
||||
SolutionGoalLeft string
|
||||
SolutionGoalRight string
|
||||
Visited string
|
||||
VisitedStartLeft string
|
||||
VisitedStartRight string
|
||||
VisitedGoalLeft string
|
||||
VisitedGoalRight string
|
||||
Cursor string
|
||||
}
|
||||
|
||||
// Default format
|
||||
var Default = &Format{
|
||||
Wall: "##",
|
||||
Path: " ",
|
||||
StartLeft: "S ",
|
||||
StartRight: " S",
|
||||
GoalLeft: "G ",
|
||||
GoalRight: " G",
|
||||
Solution: "::",
|
||||
SolutionStartLeft: "S:",
|
||||
SolutionStartRight: ":S",
|
||||
SolutionGoalLeft: "G:",
|
||||
SolutionGoalRight: ":G",
|
||||
Visited: "..",
|
||||
VisitedStartLeft: "S.",
|
||||
VisitedStartRight: ".S",
|
||||
VisitedGoalLeft: "G.",
|
||||
VisitedGoalRight: ".G",
|
||||
Cursor: "::",
|
||||
}
|
||||
|
||||
// Color format
|
||||
var Color = &Format{
|
||||
Wall: "\x1b[7m \x1b[0m",
|
||||
Path: " ",
|
||||
StartLeft: "S ",
|
||||
StartRight: " S",
|
||||
GoalLeft: "G ",
|
||||
GoalRight: " G",
|
||||
Solution: "\x1b[44;1m \x1b[0m",
|
||||
SolutionStartLeft: "\x1b[44;1mS \x1b[0m",
|
||||
SolutionStartRight: "\x1b[44;1m S\x1b[0m",
|
||||
SolutionGoalLeft: "\x1b[44;1mG \x1b[0m",
|
||||
SolutionGoalRight: "\x1b[44;1m G\x1b[0m",
|
||||
Visited: "\x1b[42;1m \x1b[0m",
|
||||
VisitedStartLeft: "\x1b[42;1mS \x1b[0m",
|
||||
VisitedStartRight: "\x1b[42;1m S\x1b[0m",
|
||||
VisitedGoalLeft: "\x1b[42;1mG \x1b[0m",
|
||||
VisitedGoalRight: "\x1b[42;1m G\x1b[0m",
|
||||
Cursor: "\x1b[43;1m \x1b[0m",
|
||||
}
|
||||
|
||||
func plot(img *image.RGBA, x, y, scale int, c color.Color) {
|
||||
for dy := 0; dy < scale; dy++ {
|
||||
for dx := 0; dx < scale; dx++ {
|
||||
img.Set(x*scale+dx, y*scale+dy, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrintImage outputs the maze to the IO writer as PNG image
|
||||
func (maze *Maze) PrintImage(writer io.Writer, format *Format, scale int) {
|
||||
var buf bytes.Buffer
|
||||
maze.Print(&buf, format)
|
||||
lines := strings.Split(strings.TrimSpace(buf.String()), "\n")
|
||||
for i, line := range lines {
|
||||
lines[i] = strings.TrimSpace(line)
|
||||
}
|
||||
width := len(lines[0]) / 2
|
||||
height := len(lines)
|
||||
img := image.NewRGBA(image.Rect(0, 0, width*scale, height*scale))
|
||||
red, green, yellow :=
|
||||
color.RGBA{255, 0, 0, 255},
|
||||
color.RGBA{0, 255, 0, 255},
|
||||
color.RGBA{255, 255, 0, 255}
|
||||
for y := 0; y < height; y++ {
|
||||
if y >= len(lines) {
|
||||
continue
|
||||
}
|
||||
for x := 0; x < width; x++ {
|
||||
if x*2 >= len(lines[y]) {
|
||||
continue
|
||||
}
|
||||
switch lines[y][x*2 : x*2+2] {
|
||||
case "##":
|
||||
plot(img, x, y, scale, color.Black)
|
||||
case "::":
|
||||
plot(img, x, y, scale, yellow)
|
||||
case "S ", " S", "S:", ":S":
|
||||
plot(img, x, y, scale, red)
|
||||
case "G ", " G", "G:", ":G":
|
||||
plot(img, x, y, scale, green)
|
||||
default:
|
||||
plot(img, x, y, scale, color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
png.Encode(writer, img)
|
||||
}
|
||||
|
||||
// Print out the maze to the IO writer
|
||||
func (maze *Maze) Print(writer io.Writer, format *Format) {
|
||||
strwriter := make(chan string)
|
||||
go maze.Write(strwriter, format)
|
||||
for {
|
||||
str := <-strwriter
|
||||
switch str {
|
||||
case "\u0000":
|
||||
return
|
||||
default:
|
||||
fmt.Fprint(writer, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the maze to the writer channel
|
||||
func (maze *Maze) Write(writer chan string, format *Format) {
|
||||
// If solved or started, it changes the appearance of the start and the goal
|
||||
startLeft := format.StartLeft
|
||||
if maze.Solved {
|
||||
startLeft = format.SolutionStartLeft
|
||||
} else if maze.Started {
|
||||
startLeft = format.VisitedStartLeft
|
||||
}
|
||||
startRight := format.StartRight
|
||||
if maze.Solved {
|
||||
startRight = format.SolutionStartRight
|
||||
} else if maze.Started {
|
||||
startRight = format.VisitedStartRight
|
||||
}
|
||||
goalLeft := format.GoalLeft
|
||||
if maze.Solved {
|
||||
goalLeft = format.SolutionGoalLeft
|
||||
} else if maze.Finished {
|
||||
goalLeft = format.VisitedGoalLeft
|
||||
}
|
||||
goalRight := format.GoalRight
|
||||
if maze.Solved {
|
||||
goalRight = format.SolutionGoalRight
|
||||
} else if maze.Finished {
|
||||
goalRight = format.VisitedGoalRight
|
||||
}
|
||||
// We can use & to check if the direction is the solution path or the path user has visited
|
||||
solved := (Up | Down | Left | Right) << SolutionOffset
|
||||
visited := (Up | Down | Left | Right) << VisitedOffset
|
||||
// Print out the maze
|
||||
writer <- "\n"
|
||||
for x, row := range maze.Directions {
|
||||
// There are two lines printed for each maze lines
|
||||
for _, direction := range []int{Up, Right} {
|
||||
writer <- format.Path // The left margin
|
||||
// The left wall
|
||||
if maze.Start.X == x && maze.Start.Y == 0 && direction == Right {
|
||||
writer <- startLeft
|
||||
} else if maze.Goal.X == x && maze.Goal.Y == 0 && maze.Width > 1 && direction == Right {
|
||||
writer <- goalLeft
|
||||
} else {
|
||||
writer <- format.Wall
|
||||
}
|
||||
for y, directions := range row {
|
||||
// In the `direction == Right` line, we print the path cell
|
||||
if direction == Right {
|
||||
if directions&solved != 0 {
|
||||
writer <- format.Solution
|
||||
} else if directions&visited != 0 {
|
||||
if maze.Cursor.X == x && maze.Cursor.Y == y {
|
||||
writer <- format.Cursor
|
||||
} else {
|
||||
writer <- format.Visited
|
||||
}
|
||||
} else {
|
||||
writer <- format.Path
|
||||
}
|
||||
}
|
||||
// Print the start or goal point on the right hand side
|
||||
if maze.Start.X == x && maze.Start.Y == y && y == maze.Width-1 && 0 < y && direction == Right {
|
||||
writer <- startRight
|
||||
} else if maze.Goal.X == x && maze.Goal.Y == y && y == maze.Width-1 && direction == Right {
|
||||
writer <- goalRight
|
||||
} else
|
||||
// Print the start or goal point on the top wall of the maze
|
||||
if maze.Start.X == x && maze.Start.Y == y && x == 0 && maze.Height > 1 && 0 < y && y < maze.Width-1 && direction == Up {
|
||||
writer <- startLeft
|
||||
} else if maze.Goal.X == x && maze.Goal.Y == y && x == 0 && maze.Height > 1 && 0 < y && y < maze.Width-1 && direction == Up {
|
||||
writer <- goalLeft
|
||||
} else
|
||||
// If there is a path in the direction (Up or Right) on the maze
|
||||
if directions&direction != 0 {
|
||||
// Print the path cell, or the solution cell if solved or the visited cells if the user visited
|
||||
if (directions>>SolutionOffset)&direction != 0 {
|
||||
writer <- format.Solution
|
||||
} else if (directions>>VisitedOffset)&direction != 0 {
|
||||
writer <- format.Visited
|
||||
} else {
|
||||
writer <- format.Path
|
||||
}
|
||||
} else {
|
||||
// Print the wall cell
|
||||
writer <- format.Wall
|
||||
}
|
||||
// In the `direction == Up` line, we print the wall cell
|
||||
if direction == Up {
|
||||
writer <- format.Wall
|
||||
}
|
||||
}
|
||||
writer <- "\n"
|
||||
}
|
||||
}
|
||||
// Print the bottom wall of the maze
|
||||
writer <- format.Path
|
||||
writer <- format.Wall
|
||||
for y := 0; y < maze.Width; y++ {
|
||||
if maze.Start.X == maze.Height-1 && maze.Start.Y == y && maze.Height > 1 && 0 < y && y < maze.Width-1 {
|
||||
writer <- startLeft
|
||||
} else if maze.Goal.X == maze.Height-1 && maze.Goal.Y == y && 0 < y && y < maze.Width-1 {
|
||||
writer <- goalRight
|
||||
} else {
|
||||
writer <- format.Wall
|
||||
}
|
||||
writer <- format.Wall
|
||||
}
|
||||
writer <- "\n\n"
|
||||
// Inform that we finished printing the maze
|
||||
writer <- "\u0000"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S:::::::##::::::##::::::::::::::::::::::##
|
||||
######::##::##::##::## ##############::##
|
||||
##::::::##::##::::::## ## ## ##::##
|
||||
##::######::########## ## ## ######::##
|
||||
##::##::::::## ## ## ::##
|
||||
##::##::###### ########## ## ######::##
|
||||
##::::::## ## ##::::::##
|
||||
########## ###### ##############::## ##
|
||||
## ## ## ## ## ##::::::::::## ##
|
||||
## ## ## ## ## ## ##::########## ##
|
||||
## ## ## ## ##::::::::::## ##
|
||||
## ########## ########## ######::######
|
||||
## ## ## ##::::::##
|
||||
###### ## ## ######################::##
|
||||
## ## ## ##::::::::::##
|
||||
## ############## ## ## ##::##########
|
||||
## ## ## ## ##::::::::::##
|
||||
###### ## ## ######################::##
|
||||
## ## ## :::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --format color --width 10 --height 10
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
S [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m
|
||||
[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m G
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --format color --width 10 --height 10 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
[44;1mS [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m[44;1m [0m[7m [0m[44;1m [0m[7m [0m[44;1m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m[44;1m [0m[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[44;1m [0m[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m [7m [0m [7m [0m [44;1m [0m[7m [0m
|
||||
[7m [0m[44;1m [0m[7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m [7m [0m
|
||||
[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [7m [0m [7m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m[7m [0m[7m [0m [7m [0m [7m [0m [7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[44;1m [0m[7m [0m
|
||||
[7m [0m [7m [0m [7m [0m [44;1m [0m[44;1m G[0m
|
||||
[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m[7m [0m
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S ## ## ##
|
||||
###### ## ## ## ## ############## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ###### ########## ## ## ###### ##
|
||||
## ## ## ## ## ##
|
||||
## ## ###### ########## ## ###### ##
|
||||
## ## ## ## ##
|
||||
########## ###### ############## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ########## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ########## ########## ###### ######
|
||||
## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ## ##
|
||||
## ############## ## ## ## ##########
|
||||
## ## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --goal 9,5 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S:::::::##::::::##::::::::::::::::::::::##
|
||||
######::##::##::##::## ##############::##
|
||||
##::::::##::##::::::## ## ## ##::##
|
||||
##::######::########## ## ## ######::##
|
||||
##::##::::::## ## ## ::##
|
||||
##::##::###### ########## ## ######::##
|
||||
##::::::## ## ##::::::##
|
||||
########## ###### ##############::## ##
|
||||
## ## ## ## ## ##::::::::::## ##
|
||||
## ## ## ## ## ## ##::########## ##
|
||||
## ## ## ## ##::::::::::## ##
|
||||
## ########## ########## ######::######
|
||||
## ## ## ##::::::##
|
||||
###### ## ## ######################::##
|
||||
## ## ## ##::::::::::##
|
||||
## ############## ## ## ##::##########
|
||||
## ## ## ## ##::::::::::##
|
||||
###### ## ## ######################::##
|
||||
## ## ## ::::::::::::::::::##
|
||||
######################:G##################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --goal 9,0 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S:::::::##::::::##::::::::::::::::::::::##
|
||||
######::##::##::##::## ##############::##
|
||||
##::::::##::##::::::## ## ## ##::##
|
||||
##::######::########## ## ## ######::##
|
||||
##::##::::::## ## ## ::##
|
||||
##::##::###### ########## ## ######::##
|
||||
##::::::## ## ##::::::##
|
||||
########## ###### ##############::## ##
|
||||
## ## ## ## ## ##::::::::::## ##
|
||||
## ## ## ## ## ## ##::########## ##
|
||||
## ## ## ## ##:: ## ##
|
||||
## ########## ##########::###### ######
|
||||
## ##::::::##:::::::::::::: ## ##
|
||||
######::##::##::###################### ##
|
||||
##::::::##:::::: ## ## ##
|
||||
##::############## ## ## ## ##########
|
||||
##::::::## ## ## ## ##
|
||||
######::## ## ###################### ##
|
||||
G:::::::## ## ##
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --goal 5,0 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S:::::::##::::::##:::::: ##
|
||||
######::##::##::##::##::############## ##
|
||||
##::::::##::##::::::##::## ## ## ##
|
||||
##::######::##########::## ## ###### ##
|
||||
##::##::::::##::::::::::## ## ##
|
||||
##::##::######::########## ## ###### ##
|
||||
##::::::##::::::## ## ##
|
||||
##########::###### ############## ## ##
|
||||
##::::::##::## ## ## ## ## ##
|
||||
##::##::##::## ## ## ## ########## ##
|
||||
G:::##::::::## ## ## ## ##
|
||||
## ########## ########## ###### ######
|
||||
## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ## ##
|
||||
## ############## ## ## ## ##########
|
||||
## ## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ##
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --goal 0,5 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
######################G:##################
|
||||
S:::::::##::::::##:::::: ##
|
||||
######::##::##::##::## ############## ##
|
||||
##::::::##::##::::::## ## ## ## ##
|
||||
##::######::########## ## ## ###### ##
|
||||
##::##::::::## ## ## ##
|
||||
##::##::###### ########## ## ###### ##
|
||||
##::::::## ## ## ##
|
||||
########## ###### ############## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ########## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ########## ########## ###### ######
|
||||
## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ## ##
|
||||
## ############## ## ## ## ##########
|
||||
## ## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ##
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --goal 0,9 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S:::::::##::::::##:::::::::::::::::::::::G
|
||||
######::##::##::##::## ############## ##
|
||||
##::::::##::##::::::## ## ## ## ##
|
||||
##::######::########## ## ## ###### ##
|
||||
##::##::::::## ## ## ##
|
||||
##::##::###### ########## ## ###### ##
|
||||
##::::::## ## ## ##
|
||||
########## ###### ############## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ########## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ########## ########## ###### ######
|
||||
## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ## ##
|
||||
## ############## ## ## ## ##########
|
||||
## ## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ##
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 1
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
##########################################
|
||||
S G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 1 --solution
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
##########################################
|
||||
S::::::::::::::::::::::::::::::::::::::::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --help
|
||||
@@ -0,0 +1,7 @@
|
||||
NAME:
|
||||
maze - Maze generating and solving program
|
||||
|
||||
USAGE:
|
||||
maze [global options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 1 --height 1
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
######
|
||||
S G
|
||||
######
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --output .tmp; cat .tmp; rm .tmp
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S ## ## ##
|
||||
###### ## ## ## ## ############## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ###### ########## ## ## ###### ##
|
||||
## ## ## ## ## ##
|
||||
## ## ###### ########## ## ###### ##
|
||||
## ## ## ## ##
|
||||
########## ###### ############## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ########## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ########## ########## ###### ######
|
||||
## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## ## ##
|
||||
## ############## ## ## ## ##########
|
||||
## ## ## ## ## ##
|
||||
###### ## ## ###################### ##
|
||||
## ## ## G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 1 --width 10 --height 10
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S ## ## ## ## ##
|
||||
## ## ###### ## ## ## ###### ## ##
|
||||
## ## ## ## ## ## ##
|
||||
########## ## ########## ## ###### ##
|
||||
## ## ## ## ##
|
||||
## ############## ############## ## ##
|
||||
## ## ## ##
|
||||
########## ## ## ############## ######
|
||||
## ## ## ## ## ## ##
|
||||
## ## ###### ########## ## ###### ##
|
||||
## ## ## ## ## ##
|
||||
## ########## ## ############## ## ##
|
||||
## ## ## ## ## ## ##
|
||||
########## ###### ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ## ##
|
||||
## ## ## ## ###### ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ## ##
|
||||
## ################## ## ###### ## ##
|
||||
## ## ## G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 2 --width 10 --height 10
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
S ## ## ## ##
|
||||
## ###### ## ## ## ########## ## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ## ## ## ## ########## ##########
|
||||
## ## ## ## ## ## ##
|
||||
## ## ########## ## ## ###### ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ############## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ###### ## ############## ## ######
|
||||
## ## ## ## ##
|
||||
###################### ## ########## ##
|
||||
## ## ## ## ##
|
||||
## ## ###### ## ################## ##
|
||||
## ## ## ## ## ## ##
|
||||
## ## ########## ## ########## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ###### ## ########## ##
|
||||
## ## ## G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 3 --height 3
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
##############
|
||||
S ## ##
|
||||
###### ## ##
|
||||
## ## ##
|
||||
## ###### ##
|
||||
## G
|
||||
##############
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 9,5 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
## ## ## ## ##
|
||||
## ###### ## ###### ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
###### ########## ## ############## ##
|
||||
## ## ## ## ##
|
||||
## ###### ########## ###### ## ######
|
||||
## ## ## ## ## ## ##
|
||||
################## ## ## ## ###### ##
|
||||
## ## ## ## ## ## ##
|
||||
## ## ## ## ###### ## ## ## ######
|
||||
## ## ## ## ## ## ## ## ##
|
||||
## ########## ###### ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ############## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ###### ########## ## ##
|
||||
## ## ## ## ## ##
|
||||
## ## ########## ###### ########## ##
|
||||
## ## ##:::::::::::::::::::G
|
||||
######################S:##################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 9,0 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
## ## ## ## ##
|
||||
## ## ## ########## ###### ## ## ##
|
||||
## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ###### ########## ##
|
||||
## ## ## ## ## ## ##
|
||||
###### ########## ## ########## ######
|
||||
## ## ## ## ## ##
|
||||
## ## ###### ###### ## ########## ##
|
||||
## ## ## ## ##
|
||||
## ## ## ###### ######################
|
||||
## ## ## ## ## ##
|
||||
###### ## ########## ## ## ###### ##
|
||||
## ## ## ##::::::::::## ##
|
||||
## ################## ##::######::######
|
||||
## ## ## ##::::::##::::::##
|
||||
## ## ########## ##########::######::##
|
||||
## ## ##::::::::::## ::##
|
||||
###### ##############::########## ##::##
|
||||
S:::::::::::::::::::::::## ##:::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 9,9 --goal 0,0 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
G:::##::::::##:::::::::::::: ##
|
||||
##::##::##::##::##########::## ##########
|
||||
##::::::##::##::## ##::## ## ##
|
||||
##########::##::## ######::## ## ## ##
|
||||
## ##::::::## ## ::## ## ##
|
||||
## ## ########## ## ##::########## ##
|
||||
## ## ## ## ##::## ## ##
|
||||
## ###### ## ## ######::###### ## ##
|
||||
## ## ## ## ::## ## ##
|
||||
###### ## ########## ##::## ###### ##
|
||||
## ## ## ##::## ## ##
|
||||
## ########## ## ######::## ## ## ##
|
||||
## ## ## ##::## ## ##
|
||||
###### ## ## ##########::## ##########
|
||||
## ## ## ## ::## ##
|
||||
## ## ########## ######::########## ##
|
||||
## ## ## ##::::::::::## ##
|
||||
## ########## ###### ##########::######
|
||||
## ## ##:::::::S
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 5,0 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
## ::::::## ## ##
|
||||
## ##::##::## ## ############## ######
|
||||
## ##::##::## ## ## ## ##
|
||||
######::##::## ########## ## ###### ##
|
||||
##::::::##::## ## ## ## ## ##
|
||||
##::######::## ## ## ## ## ## ######
|
||||
##:: ##::## ## ## ## ##
|
||||
##::######::########## ## ## ###### ##
|
||||
##::::::##:: ## ## ## ## ##
|
||||
######::##::## ############## ###### ##
|
||||
S:::::::##::## ## ## ##
|
||||
## ## ##::############## ## ## ######
|
||||
## ## ##::##::::::## ## ## ## ##
|
||||
## ######::##::##::## ## ## ###### ##
|
||||
## ##::##::##::## ## ## ##
|
||||
###### ##::##::##::## ########## ######
|
||||
## ##::##::##:: ##::::::::::## ##
|
||||
## ######::##::##::######::######::## ##
|
||||
## ##::::::##::::::::::## :::::::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 5,9 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
## ## ## ## ##
|
||||
## ###### ## ###### ## ## ###### ##
|
||||
## ## ## ## ## ## ##
|
||||
## ## ########## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ## ##
|
||||
## ## ## ########## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ## ##
|
||||
## ###### ## ## ## ## ########## ##
|
||||
## ## ## ##::::::::::## ##
|
||||
## ######################::######::######
|
||||
## ## ## ::::::##:::::::S
|
||||
## ## ########## ##########::##########
|
||||
## ## ## ##:::::: ##
|
||||
## ## ############## ##::########## ##
|
||||
## ## ## ## ##::::::::::## ##
|
||||
## ###### ## ###### ##########::######
|
||||
## ## ## ## ## ##::::::##
|
||||
###### ## ###### ## ## ## ######::##
|
||||
## ## ## ## :::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 0,5 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
######################S:##################
|
||||
## ## ##::::::## ## ##
|
||||
########## ## ##########::## ## ## ##
|
||||
## ## ::::::## ## ##
|
||||
## ##################::############## ##
|
||||
## ## ## ##::::::::::## ##
|
||||
## ## ## ## ## ## ######::## ######
|
||||
## ## ## ## ##::::::## ##
|
||||
## ############## ## ##::########## ##
|
||||
## ## ## ## ##::## ##
|
||||
## ## ## ###### ## ##::## ##########
|
||||
## ## ## ## ##::## ## ##
|
||||
## ########## ## ## ##::## ## ## ##
|
||||
## ## ## ## ##::## ## ##
|
||||
## ## ############## ##::########## ##
|
||||
## ## ## ## ##::## ##::::::##
|
||||
## ###### ###### ## ##::## ##::##::##
|
||||
## ## ## ## ##::##::::::##::##
|
||||
###### ## ## ###### ##::##::######::##
|
||||
## ## ##::::::## :::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 10 --height 10 --start 0,9 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
##########################################
|
||||
## ## ## ## ## :::S
|
||||
## ## ## ###### ## ## ###### ##::##
|
||||
## ## ## ## ## ## ##::##
|
||||
## ## ###### ## ##################::##
|
||||
## ## ## ##::::::::::::::##::##
|
||||
## ###### ##########::###### ##::##::##
|
||||
## ## ##::::::::::## ##::##::##
|
||||
## ## ######::## ##############::##::##
|
||||
## ## ::## ## ## ::::::##
|
||||
## ###### ##::## ###### ## ##########
|
||||
## ##::## ## ## ##
|
||||
##############::################## ## ##
|
||||
## ##::::::::::##::::::## ##
|
||||
## ###### ##########::##::##::##########
|
||||
## ## ## ::::::##::::::::::##
|
||||
## ## ###### ############## ######::##
|
||||
## ## ## ## ## ## ::##
|
||||
## ## ########## ## ## ###### ##::##
|
||||
## ## ## ## ##:::G
|
||||
##########################################
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --version
|
||||
@@ -0,0 +1 @@
|
||||
maze version v
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 1 --height 10
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
######
|
||||
S ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## ##
|
||||
## G
|
||||
######
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
maze --seed 0 --width 1 --height 10 --solution
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
######
|
||||
S:::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##::##
|
||||
##:::G
|
||||
######
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
class maze::install {
|
||||
$secgen_params = secgen_functions::get_parameters($::base64_inputs_file)
|
||||
$challenge_name = $secgen_params['test'][0]
|
||||
$maze_dir = '/vagrant/src/maze'
|
||||
|
||||
Exec { path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/go/bin:/vagrant/bin' }
|
||||
|
||||
::secgen_functions::create_directory { "create_$challenge_directory":
|
||||
path => $maze_dir,
|
||||
notify => File['copy maze dir'],
|
||||
}
|
||||
|
||||
file { 'copy maze dir':
|
||||
path => $maze_dir,
|
||||
ensure => directory,
|
||||
recurse => true,
|
||||
source => 'puppet:///modules/maze/maze-master',
|
||||
notify => Exec['make maze'],
|
||||
}
|
||||
|
||||
exec { 'make maze':
|
||||
cwd => $maze_dir,
|
||||
command => 'env DEPNOLOCK=1 make',
|
||||
notify => Exec['install maze'],
|
||||
}
|
||||
|
||||
exec { 'install maze':
|
||||
cwd => "$maze_dir/build",
|
||||
command => 'install maze /usr/local/bin',
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
include maze::install
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<vulnerability xmlns="http://www.github/cliffe/SecGen/vulnerability"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/vulnerability">
|
||||
<name>Maze Solving Challenge</name>
|
||||
<author>itchyny</author>
|
||||
<author>Thomas Shaw</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>TODO</description>
|
||||
|
||||
<type>ctf_challenge</type>
|
||||
<privilege>none</privilege>
|
||||
<access>local</access>
|
||||
<platform>linux</platform>
|
||||
|
||||
<challenge_type>misc</challenge_type>
|
||||
<challenge_subtype>programming</challenge_subtype>
|
||||
<difficulty>medium</difficulty>
|
||||
|
||||
<read_fact>test</read_fact>
|
||||
|
||||
<default_input into="test">
|
||||
<value>asdf</value>
|
||||
</default_input>
|
||||
|
||||
<reference>https://github.com/itchyny/maze</reference>
|
||||
|
||||
<requires>
|
||||
<software_name>golang</software_name>
|
||||
</requires>
|
||||
|
||||
<requires>
|
||||
<software_name>git</software_name>
|
||||
</requires>
|
||||
|
||||
<!--<!– script dropped in account's home directory by default with setuid configuration. –>-->
|
||||
|
||||
<!--<read_fact>script_data</read_fact>-->
|
||||
<!--<read_fact>account</read_fact>-->
|
||||
<!--<read_fact>flag</read_fact>-->
|
||||
<!--<read_fact>group</read_fact>-->
|
||||
<!--<!– storage_directory: Blank by default. If supplied, store the files here. e.g. NFS or SMB storage location –>-->
|
||||
<!--<read_fact>storage_directory</read_fact>-->
|
||||
<!--<!– port: Blank by default. If supplied install script challenge as xinetd program running on given port-->
|
||||
<!--TODO: investigate why this doesnt work with nc –>-->
|
||||
<!--<!–<read_fact>port</read_fact>–>-->
|
||||
|
||||
<!--<default_input into="challenge_name">-->
|
||||
<!--<value>echo_string</value>-->
|
||||
<!--</default_input>-->
|
||||
<!--<default_input into="script_data">-->
|
||||
<!--<generator module_path=".*echo_string.*"/>-->
|
||||
<!--</default_input>-->
|
||||
<!--<default_input into="account">-->
|
||||
<!--<generator type="account">-->
|
||||
<!--<input into="username">-->
|
||||
<!--<value>challenges</value>-->
|
||||
<!--</input>-->
|
||||
<!--<input into="password">-->
|
||||
<!--<value>password</value>-->
|
||||
<!--</input>-->
|
||||
<!--</generator>-->
|
||||
<!--</default_input>-->
|
||||
<!--<default_input into="group">-->
|
||||
<!--<value>echo_string</value>-->
|
||||
<!--</default_input>-->
|
||||
<!--<default_input into="flag">-->
|
||||
<!--<generator type="flag_generator"/>-->
|
||||
<!--</default_input>-->
|
||||
|
||||
<!--<requires>-->
|
||||
<!--<module_path>utilities/unix/system/accounts</module_path>-->
|
||||
<!--</requires>-->
|
||||
|
||||
<!--<requires>-->
|
||||
<!--<module_path>utilities/unix/system/binary_script_container</module_path>-->
|
||||
<!--</requires>-->
|
||||
|
||||
<!--<requires>-->
|
||||
<!--<module_path>utilities/unix/languages/ruby</module_path>-->
|
||||
<!--</requires>-->
|
||||
|
||||
<!--<requires>-->
|
||||
<!--<module_path>utilities/unix/system/xinetd</module_path>-->
|
||||
<!--</requires>-->
|
||||
|
||||
</vulnerability>
|
||||
17
scenarios/examples/ctf_challenge_examples/maze_example.xml
Normal file
17
scenarios/examples/ctf_challenge_examples/maze_example.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<scenario xmlns="http://www.github/cliffe/SecGen/scenario"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario">
|
||||
|
||||
<!-- an example system with a maze solving challenge. -->
|
||||
<system>
|
||||
<system_name>solve_the_maze</system_name>
|
||||
<base platform="linux" type="server"/>
|
||||
|
||||
<vulnerability module_path=".*maze.*"/>
|
||||
|
||||
<network type="private_network" range="dhcp"/>
|
||||
</system>
|
||||
|
||||
</scenario>
|
||||
Reference in New Issue
Block a user