<commit_before>// Copyright 2013, 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package commands

import (
	"fmt"
	"io"

	"github.com/juju/cmd"
	"github.com/juju/loggo"
	"launchpad.net/gnuflag"

	"github.com/juju/juju/api"
	"github.com/juju/juju/cmd/modelcmd"
)

func newDebugLogCommand() cmd.Command {
	return modelcmd.Wrap(&debugLogCommand{})
}

type debugLogCommand struct {
	modelcmd.ModelCommandBase

	level  string
	params api.DebugLogParams
}

// defaultLineCount is the default number of lines to
// display, from the end of the consolidated log.
const defaultLineCount = 10

const debuglogDoc = `
Stream the consolidated debug log file. This file contains the log messages
from all nodes in the model.
`

func (c *debugLogCommand) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "debug-log",
		Purpose: "display the consolidated log file",
		Doc:     debuglogDoc,
	}
}

func (c *debugLogCommand) SetFlags(f *gnuflag.FlagSet) {
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "i", "only show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "include", "only show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeEntity), "x", "do not show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeEntity), "exclude", "do not show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeModule), "include-module", "only show log messages for these logging modules")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeModule), "exclude-module", "do not show log messages for these logging modules")

	f.StringVar(&c.level, "l", "", "log level to show, one of [TRACE, DEBUG, INFO, WARNING, ERROR]")
	f.StringVar(&c.level, "level", "", "")

	f.UintVar(&c.params.Backlog, "n", defaultLineCount, "go back this many lines from the end before starting to filter")
	f.UintVar(&c.params.Backlog, "lines", defaultLineCount, "")
	f.UintVar(&c.params.Limit, "limit", 0, "show at most this many lines")
	f.BoolVar(&c.params.Replay, "replay", false, "start filtering from the start")
	f.BoolVar(&c.params.NoTail, "T", false, "stop after returning existing log messages")
	f.BoolVar(&c.params.NoTail, "no-tail", false, "")
}

func (c *debugLogCommand) Init(args []string) error {
	if c.level != "" {
		level, ok := loggo.ParseLevel(c.level)
		if !ok || level < loggo.TRACE || level > loggo.ERROR {
			return fmt.Errorf("level value %q is not one of %q, %q, %q, %q, %q",
				c.level, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR)
		}
		c.params.Level = level
	}
	return cmd.CheckEmpty(args)
}

type DebugLogAPI interface {
	WatchDebugLog(params api.DebugLogParams) (io.ReadCloser, error)
	Close() error
}

var getDebugLogAPI = func(c *debugLogCommand) (DebugLogAPI, error) {
	return c.NewAPIClient()
}

// Run retrieves the debug log via the API.
func (c *debugLogCommand) Run(ctx *cmd.Context) (err error) {
	client, err := getDebugLogAPI(c)
	if err != nil {
		return err
	}
	defer client.Close()
	debugLog, err := client.WatchDebugLog(c.params)
	if err != nil {
		return err
	}
	defer debugLog.Close()
	_, err = io.Copy(ctx.Stdout, debugLog)
	return err
}
<commit_msg>Update debug-log helptext<commit_after>// Copyright 2013, 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package commands

import (
	"fmt"
	"io"

	"github.com/juju/cmd"
	"github.com/juju/loggo"
	"launchpad.net/gnuflag"

	"github.com/juju/juju/api"
	"github.com/juju/juju/cmd/modelcmd"
)

// defaultLineCount is the default number of lines to
// display, from the end of the consolidated log.
const defaultLineCount = 10

var usageDebugLogSummary = `
Displays log messages for a model.`[1:]

var usageDebugLogDetails = `
This command accesses all logged Juju activity on a per-model basis. By
default, the model is the current model.
A log line is written in this format:
<entity> <timestamp> <log-level> <module>:<line-no> <message>
The "entity" is the source of the message: a machine or unit. Both are
obtained in the output to `[1:] + "`juju status`" + `.
The '--include' and '--exclude' options filter by entity. A unit entity is
identified by prefixing 'unit-' to its corresponding unit name and
replacing the slash with a dash. A machine entity is identified by
prefixing 'machine-' to its corresponding machine id.
The '--include-module' and '--exclude-module' options filter by (dotted)
logging module name, which can be truncated.
A combination of machine and unit filtering uses a logical OR whereas a
combination of module and machine/unit filtering uses a logical AND.
Log levels are cumulative; each lower level (more verbose) contains the
preceding higher level (less verbose).

Examples:
Exclude all machine 0 messages; show a maximum of 100 lines; and continue
to append filtered messages:

    juju debug-log --exclude machine-0 --lines 100

Include only unit mysql/0 messages; show a maximum of 50 lines; and then
exit:

    juju debug-log -T --include unit-mysql-0 --lines 50

Show all messages from unit apache2/3 or machine 1 and then exit:

    juju debug-log -T --replay --include unit-apache2-3 --include machine-1

Include all juju.worker.uniter logging module messages that are also unit
wordpress/0 messages and continue to append filtered messages:

    juju debug-log --replay --include-module juju.worker.uniter --include \
        unit-wordpress-0

To see all WARNING and ERROR messages:

    juju debug-log --replay --level WARNING

See also:
    status`

func (c *debugLogCommand) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "debug-log",
		Purpose: usageDebugLogSummary,
		Doc:     usageDebugLogDetails,
	}
}

func newDebugLogCommand() cmd.Command {
	return modelcmd.Wrap(&debugLogCommand{})
}

type debugLogCommand struct {
	modelcmd.ModelCommandBase

	level  string
	params api.DebugLogParams
}

func (c *debugLogCommand) SetFlags(f *gnuflag.FlagSet) {
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "i", "Only show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeEntity), "include", "Only show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeEntity), "x", "Do not show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeEntity), "exclude", "Do not show log messages for these entities")
	f.Var(cmd.NewAppendStringsValue(&c.params.IncludeModule), "include-module", "Only show log messages for these logging modules")
	f.Var(cmd.NewAppendStringsValue(&c.params.ExcludeModule), "exclude-module", "Do not show log messages for these logging modules")

	f.StringVar(&c.level, "l", "", "Log level to show, one of [TRACE, DEBUG, INFO, WARNING, ERROR]")
	f.StringVar(&c.level, "level", "", "")

	f.UintVar(&c.params.Backlog, "n", defaultLineCount, "Show this many of the most recent (possibly filtered) lines, and continue to append")
	f.UintVar(&c.params.Backlog, "lines", defaultLineCount, "")
	f.UintVar(&c.params.Limit, "limit", 0, "Exit once this many of the most recent (possibly filtered) lines are shown")
	f.BoolVar(&c.params.Replay, "replay", false, "Show the entire (possibly filtered) log and continue to append")
	f.BoolVar(&c.params.NoTail, "T", false, "Stop after returning existing log messages")
	f.BoolVar(&c.params.NoTail, "no-tail", false, "")
}

func (c *debugLogCommand) Init(args []string) error {
	if c.level != "" {
		level, ok := loggo.ParseLevel(c.level)
		if !ok || level < loggo.TRACE || level > loggo.ERROR {
			return fmt.Errorf("level value %q is not one of %q, %q, %q, %q, %q",
				c.level, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR)
		}
		c.params.Level = level
	}
	return cmd.CheckEmpty(args)
}

type DebugLogAPI interface {
	WatchDebugLog(params api.DebugLogParams) (io.ReadCloser, error)
	Close() error
}

var getDebugLogAPI = func(c *debugLogCommand) (DebugLogAPI, error) {
	return c.NewAPIClient()
}

// Run retrieves the debug log via the API.
func (c *debugLogCommand) Run(ctx *cmd.Context) (err error) {
	client, err := getDebugLogAPI(c)
	if err != nil {
		return err
	}
	defer client.Close()
	debugLog, err := client.WatchDebugLog(c.params)
	if err != nil {
		return err
	}
	defer debugLog.Close()
	_, err = io.Copy(ctx.Stdout, debugLog)
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf-tcp-router/config"
	"github.com/cloudfoundry-incubator/cf-tcp-router/configurer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/models"
	"github.com/cloudfoundry-incubator/cf-tcp-router/routing_table"
	"github.com/cloudfoundry-incubator/cf-tcp-router/syncer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/watcher"
	"github.com/cloudfoundry-incubator/routing-api"
	token_fetcher "github.com/cloudfoundry-incubator/uaa-token-fetcher"
	"github.com/cloudfoundry/dropsonde"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

const (
	defaultTokenFetchRetryInterval = 5 * time.Second
	defaultTokenFetchNumRetries    = uint(3)
)

var tcpLoadBalancer = flag.String(
	"tcpLoadBalancer",
	configurer.HaProxyConfigurer,
	"The tcp load balancer to use.",
)

var tcpLoadBalancerBaseCfg = flag.String(
	"tcpLoadBalancerBaseConfig",
	"",
	"The tcp load balancer base configuration file name. This contains the basic header information.",
)

var tcpLoadBalancerCfg = flag.String(
	"tcpLoadBalancerConfig",
	"",
	"The tcp load balancer configuration file name.",
)

var subscriptionRetryInterval = flag.Int(
	"subscriptionRetryInterval",
	5,
	"Retry interval between retries to subscribe for tcp events from routing api (in seconds)",
)

var configFile = flag.String(
	"config",
	"/var/vcap/jobs/router_configurer/config/router_configurer.yml",
	"The Router configurer yml config.",
)

var syncInterval = flag.Duration(
	"syncInterval",
	time.Minute,
	"The interval between syncs of the routing table from routing api.",
)

var tokenFetchMaxRetries = flag.Uint(
	"tokenFetchMaxRetries",
	defaultTokenFetchNumRetries,
	"Maximum number of retries the Token Fetcher will use every time FetchToken is called",
)

var tokenFetchRetryInterval = flag.Duration(
	"tokenFetchRetryInterval",
	defaultTokenFetchRetryInterval,
	"interval to wait before TokenFetcher retries to fetch a token",
)

var tokenFetchExpirationBufferTime = flag.Uint64(
	"tokenFetchExpirationBufferTime",
	30,
	"Buffer time in seconds before the actual token expiration time, when TokenFetcher consider a token expired",
)

const (
	dropsondeDestination = "localhost:3457"
	dropsondeOrigin      = "router-configurer"
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	logger, reconfigurableSink := cf_lager.New("router-configurer")
	logger.Info("starting")
	clock := clock.NewClock()

	initializeDropsonde(logger)

	routingTable := models.NewRoutingTable()
	configurer := configurer.NewConfigurer(logger,
		*tcpLoadBalancer, *tcpLoadBalancerBaseCfg, *tcpLoadBalancerCfg)

	cfg, err := config.New(*configFile)
	if err != nil {
		logger.Error("failed-to-unmarshal-config-file", err)
		os.Exit(1)
	}
	tokenFetcher, err := createTokenFetcher(logger, cfg, clock)
	if err != nil {
		logger.Error("failed-to-get-token-fetcher", err)
		os.Exit(1)
	}
	_, err = tokenFetcher.FetchToken(false)
	if err != nil {
		logger.Error("error-fetching-oauth-token", err)
		os.Exit(1)
	}

	routingAPIAddress := fmt.Sprintf("%s:%d", cfg.RoutingAPI.URI, cfg.RoutingAPI.Port)
	logger.Debug("creating-routing-api-client", lager.Data{"api-location": routingAPIAddress})
	routingAPIClient := routing_api.NewClient(routingAPIAddress)

	updater := routing_table.NewUpdater(logger, &routingTable, configurer, routingAPIClient, tokenFetcher)
	syncChannel := make(chan struct{})
	syncRunner := syncer.New(clock, *syncInterval, syncChannel, logger)
	watcher := watcher.New(routingAPIClient, updater, tokenFetcher, *subscriptionRetryInterval, syncChannel, logger)

	members := grouper.Members{
		{"watcher", watcher},
		{"syncer", syncRunner},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr, reconfigurableSink)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	monitor := ifrit.Invoke(sigmon.New(group))

	logger.Info("started")

	err = <-monitor.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func createTokenFetcher(logger lager.Logger, cfg *config.Config, klok clock.Clock) (token_fetcher.TokenFetcher, error) {
	if cfg.RoutingAPI.AuthDisabled {
		logger.Debug("creating-noop-token-fetcher")
		tknFetcher := token_fetcher.NewNoOpTokenFetcher()
		return tknFetcher, nil
	}
	logger.Debug("creating-uaa-token-fetcher")

	tokenFetcherConfig := token_fetcher.TokenFetcherConfig{
		MaxNumberOfRetries:   uint32(*tokenFetchMaxRetries),
		RetryInterval:        *tokenFetchRetryInterval,
		ExpirationBufferTime: int64(*tokenFetchExpirationBufferTime),
	}
	return token_fetcher.NewTokenFetcher(logger, &cfg.OAuth, tokenFetcherConfig, klok)
}

func initializeDropsonde(logger lager.Logger) {
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed-to-initialize-dropsonde", err)
	}
}
<commit_msg>Configure metrics reporter as ifrit group member.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/cloudfoundry-incubator/cf-debug-server"
	"github.com/cloudfoundry-incubator/cf-lager"
	"github.com/cloudfoundry-incubator/cf-tcp-router/config"
	"github.com/cloudfoundry-incubator/cf-tcp-router/configurer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/metrics_reporter"
	"github.com/cloudfoundry-incubator/cf-tcp-router/metrics_reporter/haproxy_client"
	"github.com/cloudfoundry-incubator/cf-tcp-router/models"
	"github.com/cloudfoundry-incubator/cf-tcp-router/routing_table"
	"github.com/cloudfoundry-incubator/cf-tcp-router/syncer"
	"github.com/cloudfoundry-incubator/cf-tcp-router/watcher"
	"github.com/cloudfoundry-incubator/routing-api"
	token_fetcher "github.com/cloudfoundry-incubator/uaa-token-fetcher"
	"github.com/cloudfoundry/dropsonde"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/sigmon"
)

const (
	defaultTokenFetchRetryInterval = 5 * time.Second
	defaultTokenFetchNumRetries    = uint(3)
)

var tcpLoadBalancer = flag.String(
	"tcpLoadBalancer",
	configurer.HaProxyConfigurer,
	"The tcp load balancer to use.",
)

var tcpLoadBalancerBaseCfg = flag.String(
	"tcpLoadBalancerBaseConfig",
	"",
	"The tcp load balancer base configuration file name. This contains the basic header information.",
)

var tcpLoadBalancerCfg = flag.String(
	"tcpLoadBalancerConfig",
	"",
	"The tcp load balancer configuration file name.",
)

var tcpLoadBalancerStatsUnixSocket = flag.String(
	"tcpLoadBalancerStatsUnixSocket",
	"/var/vcap/jobs/haproxy/config/haproxy.sock",
	"Unix domain socket for tcp load balancer",
)

var subscriptionRetryInterval = flag.Int(
	"subscriptionRetryInterval",
	5,
	"Retry interval between retries to subscribe for tcp events from routing api (in seconds)",
)

var configFile = flag.String(
	"config",
	"/var/vcap/jobs/router_configurer/config/router_configurer.yml",
	"The Router configurer yml config.",
)

var syncInterval = flag.Duration(
	"syncInterval",
	time.Minute,
	"The interval between syncs of the routing table from routing api.",
)

var tokenFetchMaxRetries = flag.Uint(
	"tokenFetchMaxRetries",
	defaultTokenFetchNumRetries,
	"Maximum number of retries the Token Fetcher will use every time FetchToken is called",
)

var tokenFetchRetryInterval = flag.Duration(
	"tokenFetchRetryInterval",
	defaultTokenFetchRetryInterval,
	"interval to wait before TokenFetcher retries to fetch a token",
)

var tokenFetchExpirationBufferTime = flag.Uint64(
	"tokenFetchExpirationBufferTime",
	30,
	"Buffer time in seconds before the actual token expiration time, when TokenFetcher consider a token expired",
)

var statsCollectionInterval = flag.Duration(
	"statsCollectionInterval",
	time.Minute,
	"The interval between collection of stats from tcp load balancer.",
)

var dropsondePort = flag.Int(
	"dropsondePort",
	3457,
	"Port the local metron agent is listening on",
)

const (
	dropsondeOrigin        = "router-configurer"
	statsConnectionTimeout = 10 * time.Second
)

func main() {
	cf_debug_server.AddFlags(flag.CommandLine)
	cf_lager.AddFlags(flag.CommandLine)
	flag.Parse()

	logger, reconfigurableSink := cf_lager.New("router-configurer")
	logger.Info("starting")
	clock := clock.NewClock()

	initializeDropsonde(logger)

	routingTable := models.NewRoutingTable()
	configurer := configurer.NewConfigurer(logger,
		*tcpLoadBalancer, *tcpLoadBalancerBaseCfg, *tcpLoadBalancerCfg)

	cfg, err := config.New(*configFile)
	if err != nil {
		logger.Error("failed-to-unmarshal-config-file", err)
		os.Exit(1)
	}
	tokenFetcher, err := createTokenFetcher(logger, cfg, clock)
	if err != nil {
		logger.Error("failed-to-get-token-fetcher", err)
		os.Exit(1)
	}
	_, err = tokenFetcher.FetchToken(false)
	if err != nil {
		logger.Error("error-fetching-oauth-token", err)
		os.Exit(1)
	}

	routingAPIAddress := fmt.Sprintf("%s:%d", cfg.RoutingAPI.URI, cfg.RoutingAPI.Port)
	logger.Debug("creating-routing-api-client", lager.Data{"api-location": routingAPIAddress})
	routingAPIClient := routing_api.NewClient(routingAPIAddress)

	updater := routing_table.NewUpdater(logger, &routingTable, configurer, routingAPIClient, tokenFetcher)
	syncChannel := make(chan struct{})
	syncRunner := syncer.New(clock, *syncInterval, syncChannel, logger)
	watcher := watcher.New(routingAPIClient, updater, tokenFetcher, *subscriptionRetryInterval, syncChannel, logger)

	haproxyClient := haproxy_client.NewClient(logger, *tcpLoadBalancerStatsUnixSocket, statsConnectionTimeout)
	metricsEmitter := metrics_reporter.NewMetricsEmitter()
	metricsReporter := metrics_reporter.NewMetricsReporter(clock, haproxyClient, metricsEmitter, *statsCollectionInterval)

	members := grouper.Members{
		{"watcher", watcher},
		{"syncer", syncRunner},
		{"metricsReporter", metricsReporter},
	}

	if dbgAddr := cf_debug_server.DebugAddress(flag.CommandLine); dbgAddr != "" {
		members = append(grouper.Members{
			{"debug-server", cf_debug_server.Runner(dbgAddr, reconfigurableSink)},
		}, members...)
	}

	group := grouper.NewOrdered(os.Interrupt, members)

	monitor := ifrit.Invoke(sigmon.New(group))

	logger.Info("started")

	err = <-monitor.Wait()
	if err != nil {
		logger.Error("exited-with-failure", err)
		os.Exit(1)
	}

	logger.Info("exited")
}

func createTokenFetcher(logger lager.Logger, cfg *config.Config, klok clock.Clock) (token_fetcher.TokenFetcher, error) {
	if cfg.RoutingAPI.AuthDisabled {
		logger.Debug("creating-noop-token-fetcher")
		tknFetcher := token_fetcher.NewNoOpTokenFetcher()
		return tknFetcher, nil
	}
	logger.Debug("creating-uaa-token-fetcher")

	tokenFetcherConfig := token_fetcher.TokenFetcherConfig{
		MaxNumberOfRetries:   uint32(*tokenFetchMaxRetries),
		RetryInterval:        *tokenFetchRetryInterval,
		ExpirationBufferTime: int64(*tokenFetchExpirationBufferTime),
	}
	return token_fetcher.NewTokenFetcher(logger, &cfg.OAuth, tokenFetcherConfig, klok)
}

func initializeDropsonde(logger lager.Logger) {
	dropsondeDestination := fmt.Sprintf("localhost:%d", *dropsondePort)
	err := dropsonde.Initialize(dropsondeDestination, dropsondeOrigin)
	if err != nil {
		logger.Error("failed-to-initialize-dropsonde", err)
	}
}
<|endoftext|>


<commit_before>package mine_sweeper

import (
	"fmt"
	"math"
	"math/rand"
	"strconv"
	"strings"
)

type Field struct {
	width  byte
	height byte
	state  [][]int
}

//Field.state == -1 ~ 18
//-1: not open with mine
//0 ~ 8: not open and the number of mine surrounding
//9: open with mine
//10 ~ 18: open and the number of mine surrounding

const ZERO byte = 48

func NewField(width, height, mineNum byte) *Field {
	field := &Field{width, height, [][]int{}}
	field.state = make([][]int, height+2)

	for i := 0; i < int(height)+2; i++ {
		field.state[i] = make([]int, width+2)
	}

	// set mine
	var pos [][2]byte = make([][2]byte, mineNum)
	idx := rand.Perm(int(width * height)) // [0,n)
	for i := 0; i < int(mineNum); i++ {
		pos[i] = [2]byte{(byte(idx[i]) / width) + 1, (byte(idx[i]) % width) + 1}
		// set surround
		field.state[pos[i][0]-1][pos[i][1]-1] += 1
		field.state[pos[i][0]-1][pos[i][1]] += 1
		field.state[pos[i][0]-1][pos[i][1]+1] += 1
		field.state[pos[i][0]][pos[i][1]-1] += 1
		field.state[pos[i][0]][pos[i][1]+1] += 1
		field.state[pos[i][0]+1][pos[i][1]-1] += 1
		field.state[pos[i][0]+1][pos[i][1]] += 1
		field.state[pos[i][0]+1][pos[i][1]+1] += 1
	}
	for i := 0; i < int(mineNum); i++ {
		// put mine
		field.state[pos[i][0]][pos[i][1]] = -1
	}

	return field
}

func (self *Field) Open(row, column byte) {
	self.state[row][column] += 10
}

func (self *Field) AllOpen() {
	var r, c byte
	for r = 1; r < self.height+1; r++ {
		for c = 1; c < self.width+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				self.Open(r, c)
			}
		}
	}
}

func (self *Field) RecursiveOpen(row, column byte) {
	self.Open(row, column)
	if row == 0 || row == self.height+1 || column == 0 || column == self.width+1 {
		return
	}
	if 0 <= self.state[row-1][column-1] && self.state[row-1][column-1] <= 8 {
		if self.state[row-1][column-1] == 0 {
			self.RecursiveOpen(row-1, column-1)
		} else {
			self.Open(row-1, column-1)
		}
	}
	if 0 <= self.state[row-1][column] && self.state[row-1][column] <= 8 {
		if self.state[row-1][column] == 0 {
			self.RecursiveOpen(row-1, column)
		} else {
			self.Open(row-1, column)
		}
	}
	if 0 <= self.state[row-1][column+1] && self.state[row-1][column+1] <= 8 {
		if self.state[row-1][column+1] == 0 {
			self.RecursiveOpen(row-1, column+1)
		} else {
			self.Open(row-1, column+1)
		}
	}
	if 0 <= self.state[row][column-1] && self.state[row][column-1] <= 8 {
		if self.state[row][column-1] == 0 {
			self.RecursiveOpen(row, column-1)
		} else {
			self.Open(row, column-1)
		}
	}
	if 0 <= self.state[row][column+1] && self.state[row][column+1] <= 8 {
		if self.state[row][column+1] == 0 {
			self.RecursiveOpen(row, column+1)
		} else {
			self.Open(row, column+1)
		}
	}
	if 0 <= self.state[row+1][column-1] && self.state[row+1][column-1] <= 8 {
		if self.state[row+1][column-1] == 0 {
			self.RecursiveOpen(row+1, column-1)
		} else {
			self.Open(row+1, column-1)
		}
	}
	if 0 <= self.state[row+1][column] && self.state[row+1][column] <= 8 {
		if self.state[row+1][column] == 0 {
			self.RecursiveOpen(row+1, column)
		} else {
			self.Open(row+1, column)
		}
	}
	if 0 <= self.state[row+1][column+1] && self.state[row+1][column+1] <= 8 {
		if self.state[row+1][column+1] == 0 {
			self.RecursiveOpen(row+1, column+1)
		} else {
			self.Open(row+1, column+1)
		}
	}
}

func (self *Field) Choose(row, column byte) (gameover bool) {
	gameover = false
	row += 1
	column += 1
	if 0 == self.state[row][column] {
		self.RecursiveOpen(row, column)
	} else if 0 < self.state[row][column] && self.state[row][column] <= 8 {
		self.Open(row, column)
	} else if self.state[row][column] == -1 {
		self.AllOpen() // game over
		return true
	}
	return
}

func (self *Field) FieldString() string {
	// make indices of first row
	header := " "
	for len(header) < int(math.Log10(float64(self.height)))+2 {
		header += " "
	}
	for c := 0; c < int(self.width); c++ {
		tmp := fmt.Sprintf(" %d", c+1)
		for len(tmp) < 4 {
			tmp += " " // TODO: here should be optimized
		}
		header += tmp
	}

	// make rows with index
	field := fmt.Sprintf("%s\n", header)
	for r := 1; r < int(self.height)+1; r++ {
		tmp := fmt.Sprintf("%d", r)
		for len(tmp) < int(math.Log10(float64(self.height)))+2 {
			tmp += " "
		}
		field += tmp

		for c := 1; c < int(self.width)+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				field += CLOSED
			} else if self.state[r][c] == 10 {
				field += OPENED
			} else if 10 < self.state[r][c] {
				field += OPEN_NUM[self.state[r][c]-11]
			} else if self.state[r][c] == 9 {
				field += MINE
			}
			field += " "
		}
		if r < int(self.height) {
			field += "\n"
		}
	}
	return fmt.Sprintf("%s>> ", field)
}

func InputLoop(field *Field) {
	var input, header string
	var pos []string
	var r, c int
	for {
		fmt.Printf("%s\n%s", header, field.FieldString())
		fmt.Scanln(&input)
		pos = strings.Split(input, ",")
		if len(pos) != 2 {
			header = "\x1b[2J\n2 values should be input"
		} else {
			r, _ = strconv.Atoi(pos[0])
			c, _ = strconv.Atoi(pos[1])
			if 0 < byte(r) && byte(r) <= field.height && 0 < byte(r) && byte(c) <= field.width {
				gameover := field.Choose(byte(r)-1, byte(c)-1)
				if gameover {
					header = "\x1b[2J======== GAME OVER ========="
					fmt.Printf("%s\n%s", header, field.FieldString())
					break //messy!!
				} else {
					header = "\x1b[2J"
				}
			} else {
				header = fmt.Sprintf("\x1b[2J\n2 values should be input (1 <= height <= %d, 1 <= width <= %d)",
					field.height, field.width)
			}
		}
	}
}

func PlayGame() {
	var input string
	var field *Field
	//var err error
	var h, w, m int
set:
	fmt.Printf("Input height, width, (num of mine) (e.g : 8,8(,9))\n>> ")
	fmt.Scanln(&input)
	pos := strings.Split(input, ",")
	if len(pos) == 2 || len(pos) == 3 {
		w, _ = strconv.Atoi(pos[0])
		h, _ = strconv.Atoi(pos[1])
		if len(pos) == 2 {
			m = w * h / 4
		} else {
			m, _ = strconv.Atoi(pos[2])
		}
		// err is always nil (bug?), then value is 0
		//if err != nil {
		if w == 0 || h == 0 || m == 0 {
			fmt.Println("Please input 2 or 3 numerical values (value > 0)")
			goto set
		}
		field = NewField(byte(h), byte(w), byte(m))
	} else {
		fmt.Println("Please input 2 or 3 numerical values (value > 0)")
		goto set
	}
	InputLoop(field)
}
<commit_msg>fix bug<commit_after>package mine_sweeper

import (
	"fmt"
	"math"
	"math/rand"
	"strconv"
	"strings"
)

type Field struct {
	width  byte
	height byte
	state  [][]int
}

//Field.state == -1 ~ 18
//-1: not open with mine
//0 ~ 8: not open and the number of mine surrounding
//9: open with mine
//10 ~ 18: open and the number of mine surrounding

const ZERO byte = 48

func NewField(width, height, mineNum byte) *Field {
	field := &Field{width, height, [][]int{}}
	field.state = make([][]int, height+2)

	for i := 0; i < int(height)+2; i++ {
		field.state[i] = make([]int, width+2)
	}

	// set mine
	var pos [][2]byte = make([][2]byte, mineNum)
	idx := rand.Perm(int(width * height)) // [0,n)
	for i := 0; i < int(mineNum); i++ {
		pos[i] = [2]byte{(byte(idx[i]) / width) + 1, (byte(idx[i]) % width) + 1}
		// set surround
		field.state[pos[i][0]-1][pos[i][1]-1] += 1
		field.state[pos[i][0]-1][pos[i][1]] += 1
		field.state[pos[i][0]-1][pos[i][1]+1] += 1
		field.state[pos[i][0]][pos[i][1]-1] += 1
		field.state[pos[i][0]][pos[i][1]+1] += 1
		field.state[pos[i][0]+1][pos[i][1]-1] += 1
		field.state[pos[i][0]+1][pos[i][1]] += 1
		field.state[pos[i][0]+1][pos[i][1]+1] += 1
	}
	for i := 0; i < int(mineNum); i++ {
		// put mine
		field.state[pos[i][0]][pos[i][1]] = -1
	}

	return field
}

func (self *Field) Open(row, column byte) {
	self.state[row][column] += 10
}

func (self *Field) AllOpen() {
	var r, c byte
	for r = 1; r < self.height+1; r++ {
		for c = 1; c < self.width+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				self.Open(r, c)
			}
		}
	}
}

func (self *Field) RecursiveOpen(row, column byte) {
	self.Open(row, column)
	if row == 0 || row == self.height+1 || column == 0 || column == self.width+1 {
		return
	}
	if 0 <= self.state[row-1][column-1] && self.state[row-1][column-1] <= 8 {
		if self.state[row-1][column-1] == 0 {
			self.RecursiveOpen(row-1, column-1)
		} else {
			self.Open(row-1, column-1)
		}
	}
	if 0 <= self.state[row-1][column] && self.state[row-1][column] <= 8 {
		if self.state[row-1][column] == 0 {
			self.RecursiveOpen(row-1, column)
		} else {
			self.Open(row-1, column)
		}
	}
	if 0 <= self.state[row-1][column+1] && self.state[row-1][column+1] <= 8 {
		if self.state[row-1][column+1] == 0 {
			self.RecursiveOpen(row-1, column+1)
		} else {
			self.Open(row-1, column+1)
		}
	}
	if 0 <= self.state[row][column-1] && self.state[row][column-1] <= 8 {
		if self.state[row][column-1] == 0 {
			self.RecursiveOpen(row, column-1)
		} else {
			self.Open(row, column-1)
		}
	}
	if 0 <= self.state[row][column+1] && self.state[row][column+1] <= 8 {
		if self.state[row][column+1] == 0 {
			self.RecursiveOpen(row, column+1)
		} else {
			self.Open(row, column+1)
		}
	}
	if 0 <= self.state[row+1][column-1] && self.state[row+1][column-1] <= 8 {
		if self.state[row+1][column-1] == 0 {
			self.RecursiveOpen(row+1, column-1)
		} else {
			self.Open(row+1, column-1)
		}
	}
	if 0 <= self.state[row+1][column] && self.state[row+1][column] <= 8 {
		if self.state[row+1][column] == 0 {
			self.RecursiveOpen(row+1, column)
		} else {
			self.Open(row+1, column)
		}
	}
	if 0 <= self.state[row+1][column+1] && self.state[row+1][column+1] <= 8 {
		if self.state[row+1][column+1] == 0 {
			self.RecursiveOpen(row+1, column+1)
		} else {
			self.Open(row+1, column+1)
		}
	}
}

func (self *Field) Choose(row, column byte) (gameover bool) {
	gameover = false
	row += 1
	column += 1
	if 0 == self.state[row][column] {
		self.RecursiveOpen(row, column)
	} else if 0 < self.state[row][column] && self.state[row][column] <= 8 {
		self.Open(row, column)
	} else if self.state[row][column] == -1 {
		self.AllOpen() // game over
		return true
	}
	return
}

func (self *Field) FieldString() string {
	// make indices of first row
	header := " "
	for len(header) < int(math.Log10(float64(self.height)))+2 {
		header += " "
	}
	for c := 0; c < int(self.width); c++ {
		tmp := fmt.Sprintf(" %d", c+1)
		for len(tmp) < 4 {
			tmp += " " // TODO: here should be optimized
		}
		header += tmp
	}

	// make rows with index
	field := fmt.Sprintf("%s\n", header)
	for r := 1; r < int(self.height)+1; r++ {
		tmp := fmt.Sprintf("%d", r)
		for len(tmp) < int(math.Log10(float64(self.height)))+2 {
			tmp += " "
		}
		field += tmp

		for c := 1; c < int(self.width)+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				field += CLOSED
			} else if self.state[r][c] == 10 {
				field += OPENED
			} else if 10 < self.state[r][c] {
				field += OPEN_NUM[self.state[r][c]-11]
			} else if self.state[r][c] == 9 {
				field += MINE
			}
			field += " "
		}
		if r < int(self.height) {
			field += "\n"
		}
	}
	return fmt.Sprintf("%s>> ", field)
}

func InputLoop(field *Field) {
	var input, header string
	var pos []string
	var r, c int
	for {
		fmt.Printf("%s\n%s", header, field.FieldString())
		fmt.Scanln(&input)
		pos = strings.Split(input, ",")
		if len(pos) != 2 {
			header = "\x1b[2J\n2 values should be input"
		} else {
			r, _ = strconv.Atoi(pos[0])
			c, _ = strconv.Atoi(pos[1])
			if 0 < byte(r) && byte(r) <= field.height && 0 < byte(c) && byte(c) <= field.width {
				gameover := field.Choose(byte(r)-1, byte(c)-1)
				if gameover {
					header = "\x1b[2J======== GAME OVER ========="
					fmt.Printf("%s\n%s", header, field.FieldString())
					break //messy!!
				} else {
					header = "\x1b[2J"
				}
			} else {
				header = fmt.Sprintf("\x1b[2J\n2 values should be input (1 <= height <= %d, 1 <= width <= %d)",
					field.height, field.width)
			}
		}
	}
}

func PlayGame() {
	var input string
	var field *Field
	//var err error
	var h, w, m int
set:
	fmt.Printf("Input height, width, (num of mine) (e.g : 8,8(,9))\n>> ")
	fmt.Scanln(&input)
	pos := strings.Split(input, ",")
	if len(pos) == 2 || len(pos) == 3 {
		w, _ = strconv.Atoi(pos[0])
		h, _ = strconv.Atoi(pos[1])
		if len(pos) == 2 {
			m = w * h / 4
		} else {
			m, _ = strconv.Atoi(pos[2])
		}
		// err is always nil (bug?), then value is 0
		//if err != nil {
		if w == 0 || h == 0 || m == 0 {
			fmt.Println("Please input 2 or 3 numerical values (value > 0)")
			goto set
		}
		field = NewField(byte(h), byte(w), byte(m))
	} else {
		fmt.Println("Please input 2 or 3 numerical values (value > 0)")
		goto set
	}
	InputLoop(field)
}
<|endoftext|>


<commit_before>// Copyright 2012 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package declarative

import (
	"github.com/lxn/walk"
)

type TreeView struct {
	AssignTo             **walk.TreeView
	Name                 string
	Enabled              Property
	Visible              Property
	Font                 Font
	ToolTipText          Property
	MinSize              Size
	MaxSize              Size
	StretchFactor        int
	Row                  int
	RowSpan              int
	Column               int
	ColumnSpan           int
	ContextMenuActions   []*walk.Action
	OnKeyDown            walk.KeyEventHandler
	OnMouseDown          walk.MouseEventHandler
	OnMouseMove          walk.MouseEventHandler
	OnMouseUp            walk.MouseEventHandler
	OnSizeChanged        walk.EventHandler
	Model                walk.TreeModel
	OnCurrentItemChanged walk.EventHandler
	OnItemCollapsed      walk.TreeItemEventHandler
	OnItemExpanded       walk.TreeItemEventHandler
}

func (tv TreeView) Create(builder *Builder) error {
	w, err := walk.NewTreeView(builder.Parent())
	if err != nil {
		return err
	}

	return builder.InitWidget(tv, w, func() error {
		if err := w.SetModel(tv.Model); err != nil {
			return err
		}

		if tv.OnCurrentItemChanged != nil {
			w.CurrentItemChanged().Attach(tv.OnCurrentItemChanged)
		}

		if tv.OnItemCollapsed != nil {
			w.ItemCollapsed().Attach(tv.OnItemCollapsed)
		}

		if tv.OnItemExpanded != nil {
			w.ItemExpanded().Attach(tv.OnItemExpanded)
		}

		if tv.AssignTo != nil {
			*tv.AssignTo = w
		}

		return nil
	})
}

func (w TreeView) WidgetInfo() (name string, disabled, hidden bool, font *Font, toolTipText string, minSize, maxSize Size, stretchFactor, row, rowSpan, column, columnSpan int, contextMenuActions []*walk.Action, OnKeyDown walk.KeyEventHandler, OnMouseDown walk.MouseEventHandler, OnMouseMove walk.MouseEventHandler, OnMouseUp walk.MouseEventHandler, OnSizeChanged walk.EventHandler) {
	return w.Name, false, false, &w.Font, "", w.MinSize, w.MaxSize, w.StretchFactor, w.Row, w.RowSpan, w.Column, w.ColumnSpan, w.ContextMenuActions, w.OnKeyDown, w.OnMouseDown, w.OnMouseMove, w.OnMouseUp, w.OnSizeChanged
}
<commit_msg>declarative/TreeView: Add OnItemExpanding and OnItemCollapsing<commit_after>// Copyright 2012 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package declarative

import (
	"github.com/lxn/walk"
)

type TreeView struct {
	AssignTo             **walk.TreeView
	Name                 string
	Enabled              Property
	Visible              Property
	Font                 Font
	ToolTipText          Property
	MinSize              Size
	MaxSize              Size
	StretchFactor        int
	Row                  int
	RowSpan              int
	Column               int
	ColumnSpan           int
	ContextMenuActions   []*walk.Action
	OnKeyDown            walk.KeyEventHandler
	OnMouseDown          walk.MouseEventHandler
	OnMouseMove          walk.MouseEventHandler
	OnMouseUp            walk.MouseEventHandler
	OnSizeChanged        walk.EventHandler
	Model                walk.TreeModel
	OnCurrentItemChanged walk.EventHandler
	OnItemCollapsing     walk.TreeItemEventHandler
	OnItemCollapsed      walk.TreeItemEventHandler
	OnItemExpanding      walk.TreeItemEventHandler
	OnItemExpanded       walk.TreeItemEventHandler
}

func (tv TreeView) Create(builder *Builder) error {
	w, err := walk.NewTreeView(builder.Parent())
	if err != nil {
		return err
	}

	return builder.InitWidget(tv, w, func() error {
		if err := w.SetModel(tv.Model); err != nil {
			return err
		}

		if tv.OnCurrentItemChanged != nil {
			w.CurrentItemChanged().Attach(tv.OnCurrentItemChanged)
		}

		if tv.OnItemCollapsing != nil {
			w.ItemCollapsing().Attach(tv.OnItemCollapsing)
		}

		if tv.OnItemCollapsed != nil {
			w.ItemCollapsed().Attach(tv.OnItemCollapsed)
		}

		if tv.OnItemExpanding != nil {
			w.ItemExpanding().Attach(tv.OnItemExpanding)
		}

		if tv.OnItemExpanded != nil {
			w.ItemExpanded().Attach(tv.OnItemExpanded)
		}

		if tv.AssignTo != nil {
			*tv.AssignTo = w
		}

		return nil
	})
}

func (w TreeView) WidgetInfo() (name string, disabled, hidden bool, font *Font, toolTipText string, minSize, maxSize Size, stretchFactor, row, rowSpan, column, columnSpan int, contextMenuActions []*walk.Action, OnKeyDown walk.KeyEventHandler, OnMouseDown walk.MouseEventHandler, OnMouseMove walk.MouseEventHandler, OnMouseUp walk.MouseEventHandler, OnSizeChanged walk.EventHandler) {
	return w.Name, false, false, &w.Font, "", w.MinSize, w.MaxSize, w.StretchFactor, w.Row, w.RowSpan, w.Column, w.ColumnSpan, w.ContextMenuActions, w.OnKeyDown, w.OnMouseDown, w.OnMouseMove, w.OnMouseUp, w.OnSizeChanged
}
<|endoftext|>


<commit_before>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cfgmodel

import (
	"fmt"
	"sync"
	"time"

	"github.com/corestoreio/csfw/config"
	"github.com/corestoreio/csfw/config/cfgpath"
	"github.com/corestoreio/csfw/config/element"
	"github.com/corestoreio/csfw/config/source"
	"github.com/corestoreio/csfw/store/scope"
	"github.com/corestoreio/csfw/util/errors"
)

// PkgBackend used for embedding in the PkgBackend type in each package. The
// mutex protects the init process.
type PkgBackend struct {
	sync.Mutex
}

// optionBox groups different types into one struct to allow multiple option
// functions applied to many different types within this package.
type optionBox struct {
	*baseValue
	*Obscure
	*StringCSV
	*CSV
	*IntCSV
}

// BaseOption as an optional argument for the New*() functions. These options
// will be applied to the underlying unexported baseValue type.
type Option func(*optionBox) error

// WithFieldFromSectionSlice extracts the element.Field from the global
// PackageConfiguration for retrieving the default value of a underlying type
// and for scope permission checking.
func WithFieldFromSectionSlice(cfgStruct element.SectionSlice) Option {
	return func(b *optionBox) error {
		f, _, err := cfgStruct.FindField(b.route)
		if err != nil {
			return errors.Wrap(err, "[cfgmodel] cfgStruct.FindField")
		}
		b.Field = &f
		return nil
	}
}

// WithField adds a Field to the model.
func WithField(f *element.Field) Option {
	return func(b *optionBox) error {
		b.Field = f
		return nil
	}
}

// WithSource sets a source slice for Options() and validation.
func WithSource(vl source.Slice) Option {
	return func(b *optionBox) error {
		b.Source = vl
		return nil
	}
}

// WithSourceByString sets a source slice for Options() and validation.
// Wrapper for source.NewByString
func WithSourceByString(pairs ...string) Option {
	return func(b *optionBox) (err error) {
		b.Source, err = source.NewByString(pairs...)
		return errors.Wrap(err, "[cfgmodel] WithSourceByString")
	}
}

// WithSourceByInt sets a source slice for Options() and validation.
// Wrapper for source.NewByInt
func WithSourceByInt(vli source.Ints) Option {
	return func(b *optionBox) error {
		b.Source = source.NewByInt(vli)
		return nil
	}
}

// baseValue defines the path in the "core_config_data" table like a/b/c. All
// other types in this package inherits from this path type.
type baseValue struct {
	// contains the path like web/cors/exposed_headers but has no scope
	route cfgpath.Route

	// Field is used for scope permission checks and retrieving the default
	// value. A nil field gets ignored. Field will be set through the option
	// functions at creation time of the struct.
	Field *element.Field

	// Source are all available options aka SourceModel in Mage slang. This
	// slice is also used for validation to get and write the correct values.
	// Validation gets triggered only when the slice has been set. The Options()
	// function will be used to access this slice.
	Source source.Slice
	// OptionError might contain an error when an applied function option returns an
	// error. Only used in the function MustNewValue()
	OptionError error
}

// NewValue creates a new baseValue type and the error gets packed into the field
// OptionError which you can check.
func NewValue(path string, opts ...Option) baseValue {
	b := baseValue{
		route: cfgpath.NewRoute(path),
	}
	b.OptionError = (&b).Option(opts...)
	return b
}

// Option sets the options and returns the last set previous option
func (bv *baseValue) Option(opts ...Option) error {
	ob := &optionBox{
		baseValue: bv,
	}
	for _, o := range opts {
		if err := o(ob); err != nil {
			return errors.Wrap(err, "[cfgmodel] baseValue.Option")
		}
	}
	bv = ob.baseValue
	return nil
}

func (bv baseValue) hasField() bool {
	return bv.Field != nil && bv.Field.ID.IsEmpty() == false
}

// Write writes a value v to the config.Writer without checking if the value has
// changed. Checks if the Scope matches as defined in the non-nil
// ConfigStructure.
// Error behaviour: Unauthorized
func (bv baseValue) Write(w config.Writer, v interface{}, s scope.Scope, scopeID int64) error {
	pp, err := bv.ToPath(s, scopeID)
	if err != nil {
		return errors.Wrap(err, "[cfgmodel] baseValue.ToPath")
	}
	return w.Write(pp, v)
}

// String returns the stringyfied route
func (bv baseValue) String() string {
	return bv.route.String()
}

// ToPath creates a new cfgpath.Path bound to a scope. If the argument scope
// does not match the defined scope in the Field, the error behaviour
// Unauthorized gets returned.
func (bv baseValue) ToPath(s scope.Scope, scopeID int64) (cfgpath.Path, error) {

	if err := bv.inScope(s, scopeID); err != nil {
		return cfgpath.Path{}, errors.Wrap(err, "[cfgmodel] ToPath")
	}

	p, err := cfgpath.New(bv.route)
	if err != nil {
		return cfgpath.Path{}, errors.Wrapf(err, "[cfgmodel] cfgpath.New: %q", bv.route)
	}
	return p.Bind(s, scopeID), nil
}

// Route returns a copy of the underlying route.
func (bv baseValue) Route() cfgpath.Route {
	return bv.route.Clone()
}

// InScope checks if a field from a path is allowed for current scope.
// Returns nil on success.
// Error behaviour: Unauthorized
func (bv baseValue) InScope(sg scope.Scoper) (err error) {
	return bv.inScope(sg.Scope())
}

func (bv baseValue) inScope(s scope.Scope, _ int64) (err error) {
	if bv.hasField() && !bv.Field.Scopes.Has(s) {
		err = errors.NewUnauthorizedf("[cfgmodel] Scope permission insufficient: Have %q; Want %q; Route: %q", s, bv.Field.Scopes, bv)
	}
	return
}

// Options returns a source model for all available options for a configuration
// value.
//
// Usually this function gets customized in a sub-type. Customization can have
// different arguments, etc but must always call this function to set source
// slice.
func (bv baseValue) Options() source.Slice {
	return bv.Source
}

// FQ generates a fully qualified configuration path. Example:
// general/country/allow would transform with StrScope scope.StrStores and
// storeID e.g. 4 into: stores/4/general/country/allow
func (bv baseValue) FQ(s scope.Scope, scopeID int64) (string, error) {
	p, err := bv.ToPath(s, scopeID)
	return p.String(), errors.Wrap(err, "[cfgmodel] ToPath")
}

// MustFQ same as FQ but panics on error. Please use only for testing.
func (bv baseValue) MustFQ(s scope.Scope, scopeID int64) string {
	p, err := bv.ToPath(s, scopeID)
	if err != nil {
		panic(err)
	}
	return p.String()
}

// ValidateString checks if string v is contained in Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateString(v string) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValString(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%s' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateInt checks if int v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateInt(v int) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValInt(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%d' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateFloat64 checks if float64 v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateFloat64(v float64) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValFloat64(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%.14f' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateTime checks if time.Time v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateTime(v time.Time) (err error) {
	// todo:
	//if bv.Source != nil && false == bv.Source.ContainsValFloat64(v) {
	//jv, jErr := bv.Source.ToJSON()
	//if jErr != nil {
	//	return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
	//}
	//err = errors.NewNotValidf("[cfgmodel] The value '%s' cannot be found within the allowed Options():\n%s", v, jv)
	//}
	return errors.NewNotValidf("[cfgmodel] @todo once someone requires this feature")
}
<commit_msg>config/cfgmodel: Update documentation<commit_after>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cfgmodel

import (
	"fmt"
	"sync"
	"time"

	"github.com/corestoreio/csfw/config"
	"github.com/corestoreio/csfw/config/cfgpath"
	"github.com/corestoreio/csfw/config/element"
	"github.com/corestoreio/csfw/config/source"
	"github.com/corestoreio/csfw/store/scope"
	"github.com/corestoreio/csfw/util/errors"
)

// PkgBackend used for embedding in the PkgBackend type in each package. The
// mutex protects the init process.
type PkgBackend struct {
	sync.Mutex
}

// optionBox groups different types into one struct to allow multiple option
// functions applied to many different types within this package.
type optionBox struct {
	*baseValue
	*Obscure
	*StringCSV
	*CSV
	*IntCSV
}

// BaseOption as an optional argument for the New*() functions. These options
// will be applied to the underlying unexported baseValue type.
type Option func(*optionBox) error

// WithFieldFromSectionSlice extracts the element.Field from the global
// PackageConfiguration for retrieving the default value of a underlying type
// and for scope permission checking.
func WithFieldFromSectionSlice(cfgStruct element.SectionSlice) Option {
	return func(b *optionBox) error {
		f, _, err := cfgStruct.FindField(b.route)
		if err != nil {
			return errors.Wrap(err, "[cfgmodel] cfgStruct.FindField")
		}
		b.Field = &f
		return nil
	}
}

// WithField adds a Field to the model.
func WithField(f *element.Field) Option {
	return func(b *optionBox) error {
		b.Field = f
		return nil
	}
}

// WithSource sets a source slice for Options() and validation.
func WithSource(vl source.Slice) Option {
	return func(b *optionBox) error {
		b.Source = vl
		return nil
	}
}

// WithSourceByString sets a source slice for Options() and validation.
// Wrapper for source.NewByString
func WithSourceByString(pairs ...string) Option {
	return func(b *optionBox) (err error) {
		b.Source, err = source.NewByString(pairs...)
		return errors.Wrap(err, "[cfgmodel] WithSourceByString")
	}
}

// WithSourceByInt sets a source slice for Options() and validation.
// Wrapper for source.NewByInt
func WithSourceByInt(vli source.Ints) Option {
	return func(b *optionBox) error {
		b.Source = source.NewByInt(vli)
		return nil
	}
}

// baseValue defines the path in the "core_config_data" table like a/b/c. All
// other types in this package inherits from this path type.
type baseValue struct {
	// contains the path like web/cors/exposed_headers but has no scope
	route cfgpath.Route

	// Field is used for scope permission checks and retrieving the default
	// value. A nil field gets ignored. Field will be set through the option
	// functions at creation time of the struct.
	Field *element.Field

	// Source are all available options aka SourceModel in Mage slang. This
	// slice is also used for validation to get and write the correct values.
	// Validation gets triggered only when the slice has been set. The Options()
	// function will be used to access this slice.
	Source source.Slice
	// OptionError might contain an error when an applied function option returns an
	// error. Only used in the function MustNewValue()
	OptionError error
}

// NewValue creates a new baseValue type and the error gets packed into the field
// OptionError which you can check.
func NewValue(path string, opts ...Option) baseValue {
	b := baseValue{
		route: cfgpath.NewRoute(path),
	}
	b.OptionError = (&b).Option(opts...)
	return b
}

// Option sets the options and returns the last set previous option
func (bv *baseValue) Option(opts ...Option) error {
	ob := &optionBox{
		baseValue: bv,
	}
	for _, o := range opts {
		if err := o(ob); err != nil {
			return errors.Wrap(err, "[cfgmodel] baseValue.Option")
		}
	}
	bv = ob.baseValue
	return nil
}

func (bv baseValue) hasField() bool {
	return bv.Field != nil && bv.Field.ID.IsEmpty() == false
}

// Write writes a value v to the config.Writer without checking if the value has
// changed. Checks if the Scope matches as defined in the non-nil
// ConfigStructure.
// Error behaviour: Unauthorized
func (bv baseValue) Write(w config.Writer, v interface{}, s scope.Scope, scopeID int64) error {
	pp, err := bv.ToPath(s, scopeID)
	if err != nil {
		return errors.Wrap(err, "[cfgmodel] baseValue.ToPath")
	}
	return w.Write(pp, v)
}

// String returns the stringyfied route
func (bv baseValue) String() string {
	return bv.route.String()
}

// ToPath creates a new cfgpath.Path bound to a scope. If the argument scope
// does not match the defined scope in the Field, the error behaviour
// Unauthorized gets returned.
//
// If you need a string returned, consider calling FQ(Scope,scopeID) or
// MustFQ(Scope,scopeID). FQ = fully qualified path.
func (bv baseValue) ToPath(s scope.Scope, scopeID int64) (cfgpath.Path, error) {

	if err := bv.inScope(s, scopeID); err != nil {
		return cfgpath.Path{}, errors.Wrap(err, "[cfgmodel] ToPath")
	}

	p, err := cfgpath.New(bv.route)
	if err != nil {
		return cfgpath.Path{}, errors.Wrapf(err, "[cfgmodel] cfgpath.New: %q", bv.route)
	}
	return p.Bind(s, scopeID), nil
}

// Route returns a copy of the underlying route.
func (bv baseValue) Route() cfgpath.Route {
	return bv.route.Clone()
}

// InScope checks if a field from a path is allowed for current scope.
// Returns nil on success.
// Error behaviour: Unauthorized
func (bv baseValue) InScope(sg scope.Scoper) (err error) {
	return bv.inScope(sg.Scope())
}

func (bv baseValue) inScope(s scope.Scope, _ int64) (err error) {
	if bv.hasField() && !bv.Field.Scopes.Has(s) {
		err = errors.NewUnauthorizedf("[cfgmodel] Scope permission insufficient: Have %q; Want %q; Route: %q", s, bv.Field.Scopes, bv)
	}
	return
}

// Options returns a source model for all available options for a configuration
// value.
//
// Usually this function gets customized in a sub-type. Customization can have
// different arguments, etc but must always call this function to set source
// slice.
func (bv baseValue) Options() source.Slice {
	return bv.Source
}

// FQ generates a fully qualified configuration path. Example:
// general/country/allow would transform with StrScope scope.StrStores and
// storeID e.g. 4 into: stores/4/general/country/allow
func (bv baseValue) FQ(s scope.Scope, scopeID int64) (string, error) {
	p, err := bv.ToPath(s, scopeID)
	return p.String(), errors.Wrap(err, "[cfgmodel] ToPath")
}

// MustFQ same as FQ but panics on error. Please use only for testing.
func (bv baseValue) MustFQ(s scope.Scope, scopeID int64) string {
	p, err := bv.ToPath(s, scopeID)
	if err != nil {
		panic(err)
	}
	return p.String()
}

// ValidateString checks if string v is contained in Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateString(v string) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValString(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%s' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateInt checks if int v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateInt(v int) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValInt(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%d' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateFloat64 checks if float64 v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateFloat64(v float64) (err error) {
	if bv.Source != nil && false == bv.Source.ContainsValFloat64(v) {
		jv, jErr := bv.Source.ToJSON()
		if jErr != nil {
			return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
		}
		err = errors.NewNotValidf("[cfgmodel] The value '%.14f' cannot be found within the allowed Options():\n%s", v, jv)
	}
	return
}

// ValidateTime checks if time.Time v is contained in non-nil Source source.Slice.
// Error behaviour: NotValid
func (bv baseValue) ValidateTime(v time.Time) (err error) {
	// todo:
	//if bv.Source != nil && false == bv.Source.ContainsValFloat64(v) {
	//jv, jErr := bv.Source.ToJSON()
	//if jErr != nil {
	//	return errors.NewFatal(err, fmt.Sprintf("[cfgmodel] Source: %#v", bv.Source))
	//}
	//err = errors.NewNotValidf("[cfgmodel] The value '%s' cannot be found within the allowed Options():\n%s", v, jv)
	//}
	return errors.NewNotValidf("[cfgmodel] @todo once someone requires this feature")
}
<|endoftext|>


<commit_before>// field.go
package main

import (
	"fmt"
)

type State int

const ( //Those are all the states of the cell in the battledfield
	empty State = iota
	full
	miss
	hit
)

type Cell struct {
	state  State
	weight float64 //Probability of the ship inside, for AI to target. Will be tricky
}

type Field struct {
	Grid          *[][]Cell
	Length, Width int //Creating field based on rules
}

func newField(length int, width int) (retField *Field) {
	tCell := make([][]Cell, length*width)
	retField.Grid = &tCell
	retField.Length = length //just in case
	retField.Width = width
	return
}

func (Fi *Field) putShips(shs map[string]ship, putter func(field *Field, fat int) error) error {
	for name, params := range shs {
		fmt.Println(name)
		for i := 0; i < params.Numbers; i++ {
			if err := putter(Fi, params.Fatness); err != nil {
				return err
			}
		}
	}

	return nil
}
<commit_msg>Function to change the state of the cell<commit_after>// field.go
package main

import (
	"errors"
	"fmt"
)

type State int

const ( //Those are all the states of the cell in the battledfield
	empty State = iota
	full
	miss
	hit
)

func (st *State) change() error {
	switch *st {
	case empty:
		*st = miss
	case full:
		*st = hit
	case miss, hit:
		return errors.New("Can't shoot at things repeatedly")
	default:
		return errors.New("Wat?")
	}
	return nil
}

type Cell struct {
	state  State
	weight float64 //Probability of the ship inside, for AI to target. Will be tricky
}

type Field struct {
	Grid          *[][]Cell
	Length, Width int //Creating field based on rules
}

func newField(length int, width int) (retField *Field) {
	tCell := make([][]Cell, length*width)
	retField.Grid = &tCell
	retField.Length = length //just in case
	retField.Width = width
	return
}

func (Fi *Field) putShips(shs map[string]ship, putter func(field *Field, fat int) error) error {
	for name, params := range shs {
		fmt.Println(name)
		for i := 0; i < params.Numbers; i++ {
			if err := putter(Fi, params.Fatness); err != nil {
				return err
			}
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"math/rand"
)

type Field struct {
	width  byte
	height byte
	state  [][]int
}

//Field.state == -2 or -1 or 0 ~ 8 or 10 ~ 18
//-2: opened with mine
//-1: not open with mine
//0 ~ 8: not open and the number of mine surrounding
//10 ~ 18: open and the number of mine surrounding

const ZERO byte = 48

func NewField(width, height, mineNum byte) *Field {
	field := &Field{width, height, [][]int{}}
	field.state = make([][]int, height+2)

	var Combination [][2]byte
	Combination = make([][2]byte, width*height)
	for i := 0; i < int(height)+2; i++ {
		field.state[i] = make([]int, width+2)
	}
	for i := 0; i < int(height); i++ {
		for j := 0; j < int(width); j++ {
			Combination[i*int(height)+j][0] = byte(i + 1)
			Combination[i*int(height)+j][1] = byte(j + 1)
		}
	}

	// set mine
	var pos [][2]byte = make([][2]byte, mineNum)
	for i := 0; i < int(mineNum); i++ {
		idx := rand.Intn(int(width*height) - i)
		pos[i] = Combination[idx]
		Combination = append(Combination[:idx], Combination[idx+1:]...)
		// set surround
		field.state[pos[i][0]-1][pos[i][1]-1] += 1
		field.state[pos[i][0]-1][pos[i][1]] += 1
		field.state[pos[i][0]-1][pos[i][1]+1] += 1
		field.state[pos[i][0]][pos[i][1]-1] += 1
		field.state[pos[i][0]][pos[i][1]+1] += 1
		field.state[pos[i][0]+1][pos[i][1]-1] += 1
		field.state[pos[i][0]+1][pos[i][1]] += 1
		field.state[pos[i][0]+1][pos[i][1]+1] += 1
	}
	for i := 0; i < int(mineNum); i++ {
		// put mine
		field.state[pos[i][0]][pos[i][1]] = -1
	}

	return field
}

func (self *Field) RefreshField() {

}

func (self *Field) Open(row, column byte) {
	self.state[row][column] += 10
}

func (self *Field) AllOpen() {
	var r, c byte
	for r = 1; r < self.height+1; r++ {
		for c = 1; c < self.width+1; c++ {
			if self.state[r][c] <= -1 {
				self.state[r][c] -= 1
			} else if self.state[r][c] <= 8 {
				self.Open(r, c)
			}
		}
	}
}

func (self *Field) RecursiveOpen(row, column byte) {
	self.Open(row, column)
	if row == 0 || row == self.height+1 || column == 0 || column == self.width+1 {
		return
	}
	if 0 <= self.state[row-1][column-1] && self.state[row-1][column-1] <= 8 {
		if self.state[row-1][column-1] == 0 {
			self.RecursiveOpen(row-1, column-1)
		} else {
			self.Open(row-1, column-1)
		}
	}
	if 0 <= self.state[row-1][column] && self.state[row-1][column] <= 8 {
		if self.state[row-1][column] == 0 {
			self.RecursiveOpen(row-1, column)
		} else {
			self.Open(row-1, column)
		}
	}
	if 0 <= self.state[row-1][column+1] && self.state[row-1][column+1] <= 8 {
		if self.state[row-1][column+1] == 0 {
			self.RecursiveOpen(row-1, column+1)
		} else {
			self.Open(row-1, column+1)
		}
	}
	if 0 <= self.state[row][column-1] && self.state[row][column-1] <= 8 {
		if self.state[row][column-1] == 0 {
			self.RecursiveOpen(row, column-1)
		} else {
			self.Open(row, column-1)
		}
	}
	if 0 <= self.state[row][column+1] && self.state[row][column+1] <= 8 {
		if self.state[row][column+1] == 0 {
			self.RecursiveOpen(row, column+1)
		} else {
			self.Open(row, column+1)
		}
	}
	if 0 <= self.state[row+1][column-1] && self.state[row+1][column-1] <= 8 {
		if self.state[row+1][column-1] == 0 {
			self.RecursiveOpen(row+1, column-1)
		} else {
			self.Open(row+1, column-1)
		}
	}
	if 0 <= self.state[row+1][column] && self.state[row+1][column] <= 8 {
		if self.state[row+1][column] == 0 {
			self.RecursiveOpen(row+1, column)
		} else {
			self.Open(row+1, column)
		}
	}
	if 0 <= self.state[row+1][column+1] && self.state[row+1][column+1] <= 8 {
		if self.state[row+1][column+1] == 0 {
			self.RecursiveOpen(row+1, column+1)
		} else {
			self.Open(row+1, column+1)
		}
	}
}

func (self *Field) Choose(row, column byte) {
	row += 1
	column += 1
	if 0 == self.state[row][column] {
		self.RecursiveOpen(row, column)
	} else if 0 < self.state[row][column] && self.state[row][column] <= 8 {
		self.Open(row, column)
	} else if self.state[row][column] == -1 {
		self.AllOpen() // game over
	}
}

func (self *Field) FieldString() (out string) {
	header := "  "
	for c := 0; c < int(self.width); c++ {
		header += fmt.Sprintf(" %d  ", c+1)
	}

	field := fmt.Sprintf("%s\n", header)
	for r := 1; r < int(self.height)+1; r++ {
		field += fmt.Sprintf("%d ", r)
		for c := 1; c < int(self.width)+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				field += "[ ]"
			} else if self.state[r][c] == 10 {
				field += "___"
			} else if 10 < self.state[r][c] {
				field += fmt.Sprintf("_%d_", self.state[r][c]-10)
			} else if self.state[r][c] == -2 {
				field += "_*_"
			}
			field += " "
		}
		if r < int(self.height) {
			field += "\n"
		}
	}
	return fmt.Sprintf("%s", field)
}

func InputLoop(field *Field) {
	var input string
	var pos [][]byte
	for {
		fmt.Printf("\r%s", field.FieldString())
		fmt.Scanln(&input)
		in := []byte(input)
		pos = bytes.Split(in, []byte(","))
		if len(pos) != 2 {
			fmt.Println("2 values should be input")
			continue
		}
		field.Choose(pos[0][0]-ZERO-1, pos[1][0]-ZERO-1)
	}
}

func PlayGame() {
	var input string
	var field *Field
set:
	fmt.Printf("Input width, height, (num of mine) (e.g : 8,8(,9))\n>> ")
	fmt.Scanln(&input)
	in := []byte(input)
	pos := bytes.Split(in, []byte(","))
	if len(pos) == 3 {
		field = NewField(pos[0][0]-ZERO, pos[1][0]-ZERO, pos[2][0]-ZERO)
	} else if len(pos) == 2 {
		fmt.Println("The number of mine is set to 25% automatically")
		p := byte((pos[0][0] - ZERO) * (pos[1][0] - ZERO) / 4)
		field = NewField(pos[0][0]-ZERO, pos[1][0]-ZERO, p)
	} else {
		fmt.Println("Please input 3 numerical value")
		goto set
	}
	InputLoop(field)
}

func main() {
	PlayGame()
}
<commit_msg>refresh screen<commit_after>package main

import (
	"bytes"
	"fmt"
	"math/rand"
)

type Field struct {
	width  byte
	height byte
	state  [][]int
}

//Field.state == -2 or -1 or 0 ~ 8 or 10 ~ 18
//-2: opened with mine
//-1: not open with mine
//0 ~ 8: not open and the number of mine surrounding
//10 ~ 18: open and the number of mine surrounding

const ZERO byte = 48

func NewField(width, height, mineNum byte) *Field {
	field := &Field{width, height, [][]int{}}
	field.state = make([][]int, height+2)

	var Combination [][2]byte
	Combination = make([][2]byte, width*height)
	for i := 0; i < int(height)+2; i++ {
		field.state[i] = make([]int, width+2)
	}
	for i := 0; i < int(height); i++ {
		for j := 0; j < int(width); j++ {
			Combination[i*int(height)+j][0] = byte(i + 1)
			Combination[i*int(height)+j][1] = byte(j + 1)
		}
	}

	// set mine
	var pos [][2]byte = make([][2]byte, mineNum)
	for i := 0; i < int(mineNum); i++ {
		idx := rand.Intn(int(width*height) - i)
		pos[i] = Combination[idx]
		Combination = append(Combination[:idx], Combination[idx+1:]...)
		// set surround
		field.state[pos[i][0]-1][pos[i][1]-1] += 1
		field.state[pos[i][0]-1][pos[i][1]] += 1
		field.state[pos[i][0]-1][pos[i][1]+1] += 1
		field.state[pos[i][0]][pos[i][1]-1] += 1
		field.state[pos[i][0]][pos[i][1]+1] += 1
		field.state[pos[i][0]+1][pos[i][1]-1] += 1
		field.state[pos[i][0]+1][pos[i][1]] += 1
		field.state[pos[i][0]+1][pos[i][1]+1] += 1
	}
	for i := 0; i < int(mineNum); i++ {
		// put mine
		field.state[pos[i][0]][pos[i][1]] = -1
	}

	return field
}

func (self *Field) RefreshField() {

}

func (self *Field) Open(row, column byte) {
	self.state[row][column] += 10
}

func (self *Field) AllOpen() {
	var r, c byte
	for r = 1; r < self.height+1; r++ {
		for c = 1; c < self.width+1; c++ {
			if self.state[r][c] <= -1 {
				self.state[r][c] -= 1
			} else if self.state[r][c] <= 8 {
				self.Open(r, c)
			}
		}
	}
}

func (self *Field) RecursiveOpen(row, column byte) {
	self.Open(row, column)
	if row == 0 || row == self.height+1 || column == 0 || column == self.width+1 {
		return
	}
	if 0 <= self.state[row-1][column-1] && self.state[row-1][column-1] <= 8 {
		if self.state[row-1][column-1] == 0 {
			self.RecursiveOpen(row-1, column-1)
		} else {
			self.Open(row-1, column-1)
		}
	}
	if 0 <= self.state[row-1][column] && self.state[row-1][column] <= 8 {
		if self.state[row-1][column] == 0 {
			self.RecursiveOpen(row-1, column)
		} else {
			self.Open(row-1, column)
		}
	}
	if 0 <= self.state[row-1][column+1] && self.state[row-1][column+1] <= 8 {
		if self.state[row-1][column+1] == 0 {
			self.RecursiveOpen(row-1, column+1)
		} else {
			self.Open(row-1, column+1)
		}
	}
	if 0 <= self.state[row][column-1] && self.state[row][column-1] <= 8 {
		if self.state[row][column-1] == 0 {
			self.RecursiveOpen(row, column-1)
		} else {
			self.Open(row, column-1)
		}
	}
	if 0 <= self.state[row][column+1] && self.state[row][column+1] <= 8 {
		if self.state[row][column+1] == 0 {
			self.RecursiveOpen(row, column+1)
		} else {
			self.Open(row, column+1)
		}
	}
	if 0 <= self.state[row+1][column-1] && self.state[row+1][column-1] <= 8 {
		if self.state[row+1][column-1] == 0 {
			self.RecursiveOpen(row+1, column-1)
		} else {
			self.Open(row+1, column-1)
		}
	}
	if 0 <= self.state[row+1][column] && self.state[row+1][column] <= 8 {
		if self.state[row+1][column] == 0 {
			self.RecursiveOpen(row+1, column)
		} else {
			self.Open(row+1, column)
		}
	}
	if 0 <= self.state[row+1][column+1] && self.state[row+1][column+1] <= 8 {
		if self.state[row+1][column+1] == 0 {
			self.RecursiveOpen(row+1, column+1)
		} else {
			self.Open(row+1, column+1)
		}
	}
}

func (self *Field) Choose(row, column byte) {
	row += 1
	column += 1
	if 0 == self.state[row][column] {
		self.RecursiveOpen(row, column)
	} else if 0 < self.state[row][column] && self.state[row][column] <= 8 {
		self.Open(row, column)
	} else if self.state[row][column] == -1 {
		self.AllOpen() // game over
	}
}

func (self *Field) FieldString() (out string) {
	header := "  "
	for c := 0; c < int(self.width); c++ {
		header += fmt.Sprintf(" %d  ", c+1)
	}

	field := fmt.Sprintf("%s\n", header)
	for r := 1; r < int(self.height)+1; r++ {
		field += fmt.Sprintf("%d ", r)
		for c := 1; c < int(self.width)+1; c++ {
			if -1 <= self.state[r][c] && self.state[r][c] <= 8 {
				field += "[ ]"
			} else if self.state[r][c] == 10 {
				field += "___"
			} else if 10 < self.state[r][c] {
				field += fmt.Sprintf("_%d_", self.state[r][c]-10)
			} else if self.state[r][c] == -2 {
				field += "_*_"
			}
			field += " "
		}
		if r < int(self.height) {
			field += "\n"
		}
	}
	return fmt.Sprintf("%s", field)
}

func InputLoop(field *Field) {
	var input string
	var pos [][]byte
	for {
		fmt.Printf("\r%s", field.FieldString())
		fmt.Scanln(&input)
		in := []byte(input)
		pos = bytes.Split(in, []byte(","))
		if len(pos) != 2 {
			fmt.Println("2 values should be input")
			continue
		}
		field.Choose(pos[0][0]-ZERO-1, pos[1][0]-ZERO-1)
		fmt.Println("\x1b[2J")
	}
}

func PlayGame() {
	var input string
	var field *Field
set:
	fmt.Printf("Input width, height, (num of mine) (e.g : 8,8(,9))\n>> ")
	fmt.Scanln(&input)
	in := []byte(input)
	pos := bytes.Split(in, []byte(","))
	if len(pos) == 3 {
		field = NewField(pos[0][0]-ZERO, pos[1][0]-ZERO, pos[2][0]-ZERO)
	} else if len(pos) == 2 {
		fmt.Println("The number of mine is set to 25% automatically")
		p := byte((pos[0][0] - ZERO) * (pos[1][0] - ZERO) / 4)
		field = NewField(pos[0][0]-ZERO, pos[1][0]-ZERO, p)
	} else {
		fmt.Println("Please input 3 numerical value")
		goto set
	}
	InputLoop(field)
}

func main() {
	PlayGame()
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"path/filepath"
)

// Recursively outputs each file in the root directory
func walkFiles(root string) <-chan string {
	out := make(chan string, 1000)

	go func() {
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			// just skip and continue when folders fail
			if err != nil {
				return nil
			}

			abspath, _ := filepath.Abs(path)
			abspathclean := filepath.Clean(abspath)
			if _, elem := filepath.Split(abspathclean); elem != "" {
				// Skip various temporary or "hidden" files or directories.
				if elem[0] == '.' || elem[0] == '$' || elem[0] == '#' || elem[0] == '~' || elem[len(elem)-1] == '~' {
					if info.IsDir() {
						return filepath.SkipDir
					}
					return nil
				}
			}

			if info != nil && info.Mode()&os.ModeType == 0 {
				// out <- abspathclean
				out <- path
			}

			return nil
		})

		close(out)

	}()

	return out
}
<commit_msg>Add code to find git root<commit_after>package main

import (
	"os"
	"path/filepath"
)

func isVolumeRoot(path string) bool {
	return os.IsPathSeparator(path[len(path)-1])
}

func isGitRoot(path string) bool {
	gitpath := filepath.Join(path, ".git")

	fi, err := os.Stat(gitpath)
	if err != nil {
		return false
	}

	return fi.IsDir()
}

func findGitRoot(path string) (bool, string) {
	path = filepath.Clean(path)

	for isVolumeRoot(path) == false {
		if isGitRoot(path) {
			return true, path
		} else {
			path = filepath.Dir(path)
		}
	}
	return false, ""
}

// Recursively outputs each file in the root directory
func walkFiles(root string) <-chan string {
	out := make(chan string, 1000)

	go func() {
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			// just skip and continue when folders fail
			if err != nil {
				return nil
			}

			abspath, _ := filepath.Abs(path)
			abspathclean := filepath.Clean(abspath)
			if _, elem := filepath.Split(abspathclean); elem != "" {
				// Skip various temporary or "hidden" files or directories.
				if elem[0] == '.' || elem[0] == '$' || elem[0] == '#' || elem[0] == '~' || elem[len(elem)-1] == '~' {
					if info.IsDir() {
						return filepath.SkipDir
					}
					return nil
				}
			}

			if info != nil && info.Mode()&os.ModeType == 0 {
				// out <- abspathclean
				out <- path
			}

			return nil
		})

		close(out)

	}()

	return out
}
<|endoftext|>


<commit_before>package vagrantcloud

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
)

type VagrantCloudClient struct {
	// The http client for communicating
	client *http.Client

	// The base URL of the API
	BaseURL string

	// Access token
	AccessToken string
}

type VagrantCloudErrors struct {
	Errors map[string][]string `json:"errors"`
}

func (v VagrantCloudErrors) FormatErrors() string {
	errs := make([]string, 0)
	for e := range v.Errors {
		msg := fmt.Sprintf("%s %s", e, strings.Join(v.Errors[e], ","))
		errs = append(errs, msg)
	}
	return strings.Join(errs, ". ")
}

func (v VagrantCloudClient) New(baseUrl string, token string) (*VagrantCloudClient, error) {
	c := &VagrantCloudClient{
		client: &http.Client{
			Transport: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
			},
		},
		BaseURL:     baseUrl,
		AccessToken: token,
	}

	return c, c.ValidateAuthentication()
}

func decodeBody(resp *http.Response, out interface{}) error {
	defer resp.Body.Close()
	dec := json.NewDecoder(resp.Body)
	return dec.Decode(out)
}

// encodeBody is used to encode a request body
func encodeBody(obj interface{}) (io.Reader, error) {
	buf := bytes.NewBuffer(nil)
	enc := json.NewEncoder(buf)
	if err := enc.Encode(obj); err != nil {
		return nil, err
	}
	return buf, nil
}

func (v *VagrantCloudClient) ValidateAuthentication() error {
	resp, err := v.Get("authenticate")
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return fmt.Errorf(resp.Status)
	}
	return nil
}

func (v *VagrantCloudClient) Get(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	log.Printf("Post-Processor Vagrant Cloud API GET: %s", reqUrl)

	req, _ := v.newRequest("GET", reqUrl, nil)
	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Delete(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	// Scrub API key for logs
	scrubbedUrl := strings.Replace(reqUrl, v.AccessToken, "ACCESS_TOKEN", -1)
	log.Printf("Post-Processor Vagrant Cloud API DELETE: %s", scrubbedUrl)

	req, _ := http.NewRequest("DELETE", reqUrl, nil)
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", v.AccessToken))
	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Upload(path string, url string) (*http.Response, error) {
	file, err := os.Open(path)

	if err != nil {
		return nil, fmt.Errorf("Error opening file for upload: %s", err)
	}

	fi, err := file.Stat()

	if err != nil {
		return nil, fmt.Errorf("Error stating file for upload: %s", err)
	}

	defer file.Close()

	request, err := v.newRequest("PUT", url, file)

	if err != nil {
		return nil, fmt.Errorf("Error preparing upload request: %s", err)
	}

	log.Printf("Post-Processor Vagrant Cloud API Upload: %s %s", path, url)

	request.ContentLength = fi.Size()
	resp, err := v.client.Do(request)

	log.Printf("Post-Processor Vagrant Cloud Upload Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Post(path string, body interface{}) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	encBody, err := encodeBody(body)

	if err != nil {
		return nil, fmt.Errorf("Error encoding body for request: %s", err)
	}

	log.Printf("Post-Processor Vagrant Cloud API POST: %s. \n\n Body: %s", reqUrl, encBody)

	req, _ := v.newRequest("POST", reqUrl, encBody)

	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Put(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	log.Printf("Post-Processor Vagrant Cloud API PUT: %s", reqUrl)

	req, _ := v.newRequest("PUT", reqUrl, nil)

	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) newRequest(method, url string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", v.AccessToken))
	return req, err
}
<commit_msg>fail if the request could not be created<commit_after>package vagrantcloud

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
)

type VagrantCloudClient struct {
	// The http client for communicating
	client *http.Client

	// The base URL of the API
	BaseURL string

	// Access token
	AccessToken string
}

type VagrantCloudErrors struct {
	Errors map[string][]string `json:"errors"`
}

func (v VagrantCloudErrors) FormatErrors() string {
	errs := make([]string, 0)
	for e := range v.Errors {
		msg := fmt.Sprintf("%s %s", e, strings.Join(v.Errors[e], ","))
		errs = append(errs, msg)
	}
	return strings.Join(errs, ". ")
}

func (v VagrantCloudClient) New(baseUrl string, token string) (*VagrantCloudClient, error) {
	c := &VagrantCloudClient{
		client: &http.Client{
			Transport: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
			},
		},
		BaseURL:     baseUrl,
		AccessToken: token,
	}

	return c, c.ValidateAuthentication()
}

func decodeBody(resp *http.Response, out interface{}) error {
	defer resp.Body.Close()
	dec := json.NewDecoder(resp.Body)
	return dec.Decode(out)
}

// encodeBody is used to encode a request body
func encodeBody(obj interface{}) (io.Reader, error) {
	buf := bytes.NewBuffer(nil)
	enc := json.NewEncoder(buf)
	if err := enc.Encode(obj); err != nil {
		return nil, err
	}
	return buf, nil
}

func (v *VagrantCloudClient) ValidateAuthentication() error {
	resp, err := v.Get("authenticate")
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return fmt.Errorf(resp.Status)
	}
	return nil
}

func (v *VagrantCloudClient) Get(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	log.Printf("Post-Processor Vagrant Cloud API GET: %s", reqUrl)

	req, err := v.newRequest("GET", reqUrl, nil)
	if err != nil {
		return nil, err
	}
	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Delete(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	// Scrub API key for logs
	scrubbedUrl := strings.Replace(reqUrl, v.AccessToken, "ACCESS_TOKEN", -1)
	log.Printf("Post-Processor Vagrant Cloud API DELETE: %s", scrubbedUrl)

	req, err := http.NewRequest("DELETE", reqUrl, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", v.AccessToken))
	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Upload(path string, url string) (*http.Response, error) {
	file, err := os.Open(path)

	if err != nil {
		return nil, fmt.Errorf("Error opening file for upload: %s", err)
	}

	fi, err := file.Stat()

	if err != nil {
		return nil, fmt.Errorf("Error stating file for upload: %s", err)
	}

	defer file.Close()

	request, err := v.newRequest("PUT", url, file)

	if err != nil {
		return nil, fmt.Errorf("Error preparing upload request: %s", err)
	}

	log.Printf("Post-Processor Vagrant Cloud API Upload: %s %s", path, url)

	request.ContentLength = fi.Size()
	resp, err := v.client.Do(request)

	log.Printf("Post-Processor Vagrant Cloud Upload Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Post(path string, body interface{}) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	encBody, err := encodeBody(body)

	if err != nil {
		return nil, fmt.Errorf("Error encoding body for request: %s", err)
	}

	log.Printf("Post-Processor Vagrant Cloud API POST: %s. \n\n Body: %s", reqUrl, encBody)

	req, err := v.newRequest("POST", reqUrl, encBody)
	if err != nil {
		return nil, err
	}

	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) Put(path string) (*http.Response, error) {
	reqUrl := fmt.Sprintf("%s/%s", v.BaseURL, path)

	log.Printf("Post-Processor Vagrant Cloud API PUT: %s", reqUrl)

	req, err := v.newRequest("PUT", reqUrl, nil)
	if err != nil {
		return nil, err
	}

	resp, err := v.client.Do(req)

	log.Printf("Post-Processor Vagrant Cloud API Response: \n\n%+v", resp)

	return resp, err
}

func (v *VagrantCloudClient) newRequest(method, url string, body io.Reader) (*http.Request, error) {
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", v.AccessToken))
	return req, err
}
<|endoftext|>