<commit_before>// Copyright (c) 2014-2016 by <NAME>. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import (`fmt`; `os`; `time`)

const Ping = 125 // Check time 8 times a second.

type Clock struct {
	halt        bool     // Stop search immediately when set to true.
	softStop    int64    // Target soft time limit to make a move.
	hardStop    int64    // Immediate stop time limit.
	extra       float32  // Extra time factor based on search volatility.
	start       time.Time
	ticker      *time.Ticker
}

type Options struct {
	ponder      bool     // (-) Pondering mode.
	infinite    bool     // (-) Search until the "stop" command.
	maxDepth    int      // Search X plies only.
	maxNodes    int      // (-) Search X nodes only.
	moveTime    int64    // Search exactly X milliseconds per move.
	movesToGo   int64    // Number of moves to make till time control.
	timeLeft    int64    // Time left for all remaining moves.
	timeInc     int64    // Time increment after the move is made.
}

type Engine struct {
	log         bool     // Enable logging.
	uci	    bool     // Use UCI protocol.
	trace       bool     // Trace evaluation scores.
	fancy       bool     // Represent pieces as UTF-8 characters.
	status      uint8    // Engine status.
	logFile     string   // Log file name.
	bookFile    string   // Polyglot opening book file name.
	cacheSize   float64  // Default cache size.
	clock       Clock
	options     Options
}

// Use single statically allocated variable.
var engine Engine

func NewEngine(args ...interface{}) *Engine {
	engine = Engine{}
	for i := 0; i < len(args); i += 2 {
		switch value := args[i+1]; args[i] {
		case `log`:
			engine.log = value.(bool)
		case `logfile`:
			engine.logFile = value.(string)
		case `bookfile`:
			engine.bookFile = value.(string)
		case `uci`:
			engine.uci = value.(bool)
		case `trace`:
			engine.trace = value.(bool)
		case `fancy`:
			engine.fancy = value.(bool)
		case `depth`:
			engine.options.maxDepth = value.(int)
		case `movetime`:
			engine.options.moveTime = int64(value.(int))
		case `cache`:
			switch value.(type) {
			default: // :-)
				engine.cacheSize = value.(float64)
			case int:
				engine.cacheSize = float64(value.(int))
			}
		}
	}

	return &engine
}

// Dumps the string to standard output.
func (e *Engine) print(arg string) *Engine {
	os.Stdout.WriteString(arg)
	return e
}

// Appends the string to log file. No flush is required as f.Write() and friends
// are unbuffered.
func (e *Engine) debug(args ...interface{}) *Engine {
	if len(e.logFile) != 0 {
		logFile, err := os.OpenFile(e.logFile, os.O_CREATE | os.O_WRONLY | os.O_APPEND, 0666)
		if err == nil {
			defer logFile.Close()
			if len := len(args); len > 1 {
				logFile.WriteString(fmt.Sprintf(args[0].(string), args[1:]...))
			} else {
				logFile.WriteString(args[0].(string))
			}
		}
	}
	return e
}

// Dumps the string to standard output and optionally logs it to file.
func (e *Engine) reply(args ...interface{}) *Engine {
	if len := len(args); len > 1 {
		data := fmt.Sprintf(args[0].(string), args[1:]...)
		e.print(data)
		//\\ e.debug(data)
	} else if len == 1 {
		e.print(args[0].(string))<commit_msg>Flush stdout when running in UCI mode<commit_after>// Copyright (c) 2014-2016 by <NAME>. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import (`fmt`; `os`; `time`)

const Ping = 125 // Check time 8 times a second.

type Clock struct {
	halt        bool     // Stop search immediately when set to true.
	softStop    int64    // Target soft time limit to make a move.
	hardStop    int64    // Immediate stop time limit.
	extra       float32  // Extra time factor based on search volatility.
	start       time.Time
	ticker      *time.Ticker
}

type Options struct {
	ponder      bool     // (-) Pondering mode.
	infinite    bool     // (-) Search until the "stop" command.
	maxDepth    int      // Search X plies only.
	maxNodes    int      // (-) Search X nodes only.
	moveTime    int64    // Search exactly X milliseconds per move.
	movesToGo   int64    // Number of moves to make till time control.
	timeLeft    int64    // Time left for all remaining moves.
	timeInc     int64    // Time increment after the move is made.
}

type Engine struct {
	log         bool     // Enable logging.
	uci	    bool     // Use UCI protocol.
	trace       bool     // Trace evaluation scores.
	fancy       bool     // Represent pieces as UTF-8 characters.
	status      uint8    // Engine status.
	logFile     string   // Log file name.
	bookFile    string   // Polyglot opening book file name.
	cacheSize   float64  // Default cache size.
	clock       Clock
	options     Options
}

// Use single statically allocated variable.
var engine Engine

func NewEngine(args ...interface{}) *Engine {
	engine = Engine{}
	for i := 0; i < len(args); i += 2 {
		switch value := args[i+1]; args[i] {
		case `log`:
			engine.log = value.(bool)
		case `logfile`:
			engine.logFile = value.(string)
		case `bookfile`:
			engine.bookFile = value.(string)
		case `uci`:
			engine.uci = value.(bool)
		case `trace`:
			engine.trace = value.(bool)
		case `fancy`:
			engine.fancy = value.(bool)
		case `depth`:
			engine.options.maxDepth = value.(int)
		case `movetime`:
			engine.options.moveTime = int64(value.(int))
		case `cache`:
			switch value.(type) {
			default: // :-)
				engine.cacheSize = value.(float64)
			case int:
				engine.cacheSize = float64(value.(int))
			}
		}
	}

	return &engine
}

// Dumps the string to standard output.
func (e *Engine) print(arg string) *Engine {
	os.Stdout.WriteString(arg)
	os.Stdout.Sync() // <-- Flush it.
	return e
}

// Appends the string to log file. No flush is required as f.Write() and friends
// are unbuffered.
func (e *Engine) debug(args ...interface{}) *Engine {
	if len(e.logFile) != 0 {
		logFile, err := os.OpenFile(e.logFile, os.O_CREATE | os.O_WRONLY | os.O_APPEND, 0666)
		if err == nil {
			defer logFile.Close()
			if len := len(args); len > 1 {
				logFile.WriteString(fmt.Sprintf(args[0].(string), args[1:]...))
			} else {
				logFile.WriteString(args[0].(string))
			}
		}
	}
	return e
}

// Dumps the string to standard output and optionally logs it to file.
func (e *Engine) reply(args ...interface{}) *Engine {
	if len := len(args); len > 1 {
		data := fmt.Sprintf(args[0].(string), args[1:]...)
		e.print(data)
		//\\ e.debug(data)
	} else if len == 1 {
		e.print(args[0].(string))
{'fraction_non_alphanumeric': 0.12570385025110334, 'fraction_numerical': 0.016131486836098007, 'mean_word_length': 2.5069370330843115, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6378346', 'n_tokens_mistral': 2352, 'n_tokens_neox': 2119, 'n_words': 728}