mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
157 lines
3.4 KiB
Go
157 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"math"
|
|
"math/rand"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Position []int
|
|
|
|
func NewPosition() Position {
|
|
p := make([]int, 3)
|
|
return Position(p)
|
|
}
|
|
|
|
func showWelcome() {
|
|
fmt.Print("\033[H\033[2J")
|
|
fmt.Println(" DEPTH CHARGE")
|
|
fmt.Println(" Creative Computing Morristown, New Jersey")
|
|
fmt.Println()
|
|
}
|
|
|
|
func getNumCharges() (int, int) {
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
for {
|
|
fmt.Println("Dimensions of search area?")
|
|
scanner.Scan()
|
|
dim, err := strconv.Atoi(scanner.Text())
|
|
if err != nil {
|
|
fmt.Println("Must enter an integer number. Please try again...")
|
|
continue
|
|
}
|
|
return dim, int(math.Log2(float64(dim))) + 1
|
|
}
|
|
}
|
|
|
|
func askForNewGame() {
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
fmt.Println("Another game (Y or N): ")
|
|
scanner.Scan()
|
|
if strings.ToUpper(scanner.Text()) == "Y" {
|
|
main()
|
|
}
|
|
fmt.Println("OK. Hope you enjoyed yourself")
|
|
os.Exit(1)
|
|
}
|
|
|
|
func showShotResult(shot, location Position) {
|
|
result := "Sonar reports shot was "
|
|
|
|
if shot[1] > location[1] { // y-direction
|
|
result += "north"
|
|
} else if shot[1] < location[1] { // y-direction
|
|
result += "south"
|
|
}
|
|
|
|
if shot[0] > location[0] { // x-direction
|
|
result += "east"
|
|
} else if shot[0] < location[0] { // x-direction
|
|
result += "west"
|
|
}
|
|
|
|
if shot[1] != location[1] || shot[0] != location[0] {
|
|
result += " and "
|
|
}
|
|
if shot[2] > location[2] {
|
|
result += "too low."
|
|
} else if shot[2] < location[2] {
|
|
result += "too high."
|
|
} else {
|
|
result += "depth OK."
|
|
}
|
|
|
|
fmt.Println(result)
|
|
}
|
|
|
|
func getShot() Position {
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
for {
|
|
shotPos := NewPosition()
|
|
fmt.Println("Enter coordinates: ")
|
|
scanner.Scan()
|
|
rawGuess := strings.Split(scanner.Text(), " ")
|
|
if len(rawGuess) != 3 {
|
|
goto there
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
val, err := strconv.Atoi(rawGuess[i])
|
|
if err != nil {
|
|
goto there
|
|
}
|
|
shotPos[i] = val
|
|
}
|
|
return shotPos
|
|
there:
|
|
fmt.Println("Please enter coordinates separated by spaces")
|
|
fmt.Println("Example: 3 2 1")
|
|
}
|
|
}
|
|
|
|
func getRandomPosition(searchArea int) Position {
|
|
pos := NewPosition()
|
|
for i := 0; i < 3; i++ {
|
|
pos[i] = rand.Intn(searchArea)
|
|
}
|
|
return pos
|
|
}
|
|
|
|
func playGame(searchArea, numCharges int) {
|
|
rand.Seed(time.Now().UTC().UnixNano())
|
|
fmt.Println("\nYou are the captain of the destroyer USS Computer.")
|
|
fmt.Println("An enemy sub has been causing you trouble. Your")
|
|
fmt.Printf("mission is to destroy it. You have %d shots.\n", numCharges)
|
|
fmt.Println("Specify depth charge explosion point with a")
|
|
fmt.Println("trio of numbers -- the first two are the")
|
|
fmt.Println("surface coordinates; the third is the depth.")
|
|
fmt.Println("\nGood luck!")
|
|
fmt.Println()
|
|
|
|
subPos := getRandomPosition(searchArea)
|
|
|
|
for c := 0; c < numCharges; c++ {
|
|
fmt.Printf("\nTrial #%d\n", c+1)
|
|
|
|
shot := getShot()
|
|
|
|
if shot[0] == subPos[0] && shot[1] == subPos[1] && shot[2] == subPos[2] {
|
|
fmt.Printf("\nB O O M ! ! You found it in %d tries!\n", c+1)
|
|
askForNewGame()
|
|
} else {
|
|
showShotResult(shot, subPos)
|
|
}
|
|
}
|
|
|
|
// out of depth charges
|
|
fmt.Println("\nYou have been torpedoed! Abandon ship!")
|
|
fmt.Printf("The submarine was at %d %d %d\n", subPos[0], subPos[1], subPos[2])
|
|
askForNewGame()
|
|
|
|
}
|
|
|
|
func main() {
|
|
showWelcome()
|
|
|
|
searchArea, numCharges := getNumCharges()
|
|
|
|
playGame(searchArea, numCharges)
|
|
}
|