/usr/share/go-1.8/test/solitaire.go is in golang-1.8-src 1.8.3-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | // build
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test general operation by solving a peg solitaire game.
// A version of this is in the Go playground.
// Don't run it - produces too much output.
// This program solves the (English) peg solitaire board game.
// See also: http://en.wikipedia.org/wiki/Peg_solitaire
package main
const N = 11 + 1 // length of a board row (+1 for newline)
// The board must be surrounded by 2 illegal fields in each direction
// so that move() doesn't need to check the board boundaries. Periods
// represent illegal fields, ● are pegs, and ○ are holes.
var board = []rune(
`...........
...........
....●●●....
....●●●....
..●●●●●●●..
..●●●○●●●..
..●●●●●●●..
....●●●....
....●●●....
...........
...........
`)
// center is the position of the center hole if there is a single one;
// otherwise it is -1.
var center int
func init() {
n := 0
for pos, field := range board {
if field == '○' {
center = pos
n++
}
}
if n != 1 {
center = -1 // no single hole
}
}
var moves int // number of times move is called
// move tests if there is a peg at position pos that can jump over another peg
// in direction dir. If the move is valid, it is executed and move returns true.
// Otherwise, move returns false.
func move(pos, dir int) bool {
moves++
if board[pos] == '●' && board[pos+dir] == '●' && board[pos+2*dir] == '○' {
board[pos] = '○'
board[pos+dir] = '○'
board[pos+2*dir] = '●'
return true
}
return false
}
// unmove reverts a previously executed valid move.
func unmove(pos, dir int) {
board[pos] = '●'
board[pos+dir] = '●'
board[pos+2*dir] = '○'
}
// solve tries to find a sequence of moves such that there is only one peg left
// at the end; if center is >= 0, that last peg must be in the center position.
// If a solution is found, solve prints the board after each move in a backward
// fashion (i.e., the last board position is printed first, all the way back to
// the starting board position).
func solve() bool {
var last, n int
for pos, field := range board {
// try each board position
if field == '●' {
// found a peg
for _, dir := range [...]int{-1, -N, +1, +N} {
// try each direction
if move(pos, dir) {
// a valid move was found and executed,
// see if this new board has a solution
if solve() {
unmove(pos, dir)
println(string(board))
return true
}
unmove(pos, dir)
}
}
last = pos
n++
}
}
// tried each possible move
if n == 1 && (center < 0 || last == center) {
// there's only one peg left
println(string(board))
return true
}
// no solution found for this board
return false
}
func main() {
if !solve() {
println("no solution found")
}
println(moves, "moves tried")
}
|